drivers: wifi: esp_at: fix race condition when waiting for '>'

Sending AT+CIPSEND=<...> command results in following reply:

  OK
  >

modem_cmd_send_nolock() invocation was setting command handlers for '>',
but as 'OK' was received first, it was handled as a generic reply. After
receiving 'OK' this function was unsetting command handlers. Then
modem_cmd_handler_update_cmds() was called once again in order to
register '>' handler once again. There was a small period of time where
'>' was not being handled at all.

Fix that race condition by using just introduced modem_cmd_send_ext(),
which allows to leave commands handlers in place and get rid of race
condition where expected command could be missed.

Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
This commit is contained in:
Marcin Niestroj 2021-07-02 16:55:11 +02:00 committed by Christopher Friedt
commit 01852138ae

View file

@ -233,27 +233,15 @@ static int _sock_send(struct esp_socket *sock, struct net_pkt *pkt)
k_sem_take(&dev->cmd_handler_data.sem_tx_lock, K_FOREVER);
k_sem_reset(&dev->sem_tx_ready);
ret = modem_cmd_send_nolock(&dev->mctx.iface, &dev->mctx.cmd_handler,
cmds, ARRAY_SIZE(cmds), cmd_buf,
&dev->sem_response, ESP_CMD_TIMEOUT);
ret = modem_cmd_send_ext(&dev->mctx.iface, &dev->mctx.cmd_handler,
cmds, ARRAY_SIZE(cmds), cmd_buf,
&dev->sem_response, ESP_CMD_TIMEOUT,
MODEM_NO_TX_LOCK | MODEM_NO_UNSET_CMDS);
if (ret < 0) {
LOG_DBG("Failed to send command");
goto out;
}
ret = modem_cmd_handler_update_cmds(&dev->cmd_handler_data,
cmds, ARRAY_SIZE(cmds),
true);
if (ret < 0) {
goto out;
}
/*
* After modem handlers have been updated the receive buffer
* needs to be processed again since there might now be a match.
*/
k_sem_give(&dev->iface_data.rx_sem);
/* Wait for '>' */
ret = k_sem_take(&dev->sem_tx_ready, K_MSEC(5000));
if (ret < 0) {