From 01852138aebc813ae1219b5f6ab525ccff957ffb Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Fri, 2 Jul 2021 16:55:11 +0200 Subject: [PATCH] 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 --- drivers/wifi/esp_at/esp_offload.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/wifi/esp_at/esp_offload.c b/drivers/wifi/esp_at/esp_offload.c index 6ddff56c583..4c275dac09e 100644 --- a/drivers/wifi/esp_at/esp_offload.c +++ b/drivers/wifi/esp_at/esp_offload.c @@ -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) {