drivers: wifi: esp_at: fix race condition when waiting for 'SEND OK'

This is more or less the flow of AT+CIPSEND:

  RX                         TX
  --                         --
                             AT+CIPSEND=<...>
  OK
  >
                             <data to be sent>
  SEND OK / SEND FAIL

'sem_response' semaphore is released by receiving 'OK'. Then after
receiving '>' (which releases 'sem_tx_ready' semaphore) actual data is
sent. Waiting for 'SEND OK' or 'SEND FAIL' is implemented by waiting on
'sem_response' (the same as for 'OK'), which mean that resetting this
semaphore just after sending all data is racy.

Fix that race condition by resetting 'sem_response' just after receiving
'OK', so that neither 'SEND OK' nor 'SEND FAIL' will appear yet (they
will not be sent as long as we won't send whole payload).

Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
This commit is contained in:
Marcin Niestroj 2021-07-02 17:44:23 +02:00 committed by Christopher Friedt
commit 301243ed06

View file

@ -242,6 +242,9 @@ static int _sock_send(struct esp_socket *sock, struct net_pkt *pkt)
goto out;
}
/* Reset semaphore that will be released by 'SEND OK' or 'SEND FAIL' */
k_sem_reset(&dev->sem_response);
/* Wait for '>' */
ret = k_sem_take(&dev->sem_tx_ready, K_MSEC(5000));
if (ret < 0) {
@ -258,7 +261,6 @@ static int _sock_send(struct esp_socket *sock, struct net_pkt *pkt)
}
/* Wait for 'SEND OK' or 'SEND FAIL' */
k_sem_reset(&dev->sem_response);
ret = k_sem_take(&dev->sem_response, ESP_CMD_TIMEOUT);
if (ret < 0) {
LOG_DBG("No send response");