@@ -39,6 +39,10 @@ static const char *TAG = "websocket_client";
3939#define WEBSOCKET_KEEP_ALIVE_INTERVAL (5)
4040#define WEBSOCKET_KEEP_ALIVE_COUNT (3)
4141
42+ #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK
43+ #define WEBSOCKET_TX_LOCK_TIMEOUT_MS (CONFIG_ESP_WS_CLIENT_TX_LOCK_TIMEOUT_MS)
44+ #endif
45+
4246#define ESP_WS_CLIENT_MEM_CHECK (TAG , a , action ) if (!(a)) { \
4347 ESP_LOGE(TAG,"%s(%d): %s", __FUNCTION__, __LINE__, "Memory exhausted"); \
4448 action; \
@@ -131,6 +135,9 @@ struct esp_websocket_client {
131135 bool selected_for_destroying ;
132136 EventGroupHandle_t status_bits ;
133137 SemaphoreHandle_t lock ;
138+ #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK
139+ SemaphoreHandle_t tx_lock ;
140+ #endif
134141 size_t errormsg_size ;
135142 char * errormsg_buffer ;
136143 char * rx_buffer ;
@@ -441,6 +448,9 @@ static void destroy_and_free_resources(esp_websocket_client_handle_t client)
441448 esp_transport_list_destroy (client -> transport_list );
442449 }
443450 vSemaphoreDelete (client -> lock );
451+ #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK
452+ vSemaphoreDelete (client -> tx_lock );
453+ #endif
444454 free (client -> tx_buffer );
445455 free (client -> rx_buffer );
446456 free (client -> errormsg_buffer );
@@ -610,10 +620,17 @@ static int esp_websocket_client_send_with_exact_opcode(esp_websocket_client_hand
610620 return -1 ;
611621 }
612622
623+ #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK
624+ if (xSemaphoreTakeRecursive (client -> tx_lock , timeout ) != pdPASS ) {
625+ ESP_LOGE (TAG , "Could not lock ws-client within %" PRIu32 " timeout" , timeout );
626+ return -1 ;
627+ }
628+ #else
613629 if (xSemaphoreTakeRecursive (client -> lock , timeout ) != pdPASS ) {
614630 ESP_LOGE (TAG , "Could not lock ws-client within %" PRIu32 " timeout" , timeout );
615631 return -1 ;
616632 }
633+ #endif
617634
618635 if (esp_websocket_new_buf (client , true) != ESP_OK ) {
619636 ESP_LOGE (TAG , "Failed to setup tx buffer" );
@@ -653,7 +670,11 @@ static int esp_websocket_client_send_with_exact_opcode(esp_websocket_client_hand
653670 ret = widx ;
654671
655672unlock_and_return :
673+ #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK
674+ xSemaphoreGiveRecursive (client -> tx_lock );
675+ #else
656676 xSemaphoreGiveRecursive (client -> lock );
677+ #endif
657678 return ret ;
658679}
659680
@@ -689,6 +710,11 @@ esp_websocket_client_handle_t esp_websocket_client_init(const esp_websocket_clie
689710 client -> lock = xSemaphoreCreateRecursiveMutex ();
690711 ESP_WS_CLIENT_MEM_CHECK (TAG , client -> lock , goto _websocket_init_fail );
691712
713+ #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK
714+ client -> tx_lock = xSemaphoreCreateRecursiveMutex ();
715+ ESP_WS_CLIENT_MEM_CHECK (TAG , client -> tx_lock , goto _websocket_init_fail );
716+ #endif
717+
692718 client -> config = calloc (1 , sizeof (websocket_config_storage_t ));
693719 ESP_WS_CLIENT_MEM_CHECK (TAG , client -> config , goto _websocket_init_fail );
694720
@@ -967,8 +993,17 @@ static esp_err_t esp_websocket_client_recv(esp_websocket_client_handle_t client)
967993 if (client -> last_opcode == WS_TRANSPORT_OPCODES_PING ) {
968994 const char * data = (client -> payload_len == 0 ) ? NULL : client -> rx_buffer ;
969995 ESP_LOGD (TAG , "Sending PONG with payload len=%d" , client -> payload_len );
996+ #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK
997+ if (xSemaphoreTakeRecursive (client -> tx_lock , WEBSOCKET_TX_LOCK_TIMEOUT_MS ) != pdPASS ) {
998+ ESP_LOGE (TAG , "Could not lock ws-client within %d timeout" , WEBSOCKET_TX_LOCK_TIMEOUT_MS );
999+ return ESP_FAIL ;
1000+ }
1001+ #endif
9701002 esp_transport_ws_send_raw (client -> transport , WS_TRANSPORT_OPCODES_PONG | WS_TRANSPORT_OPCODES_FIN , data , client -> payload_len ,
9711003 client -> config -> network_timeout_ms );
1004+ #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK
1005+ xSemaphoreGiveRecursive (client -> tx_lock );
1006+ #endif
9721007 } else if (client -> last_opcode == WS_TRANSPORT_OPCODES_PONG ) {
9731008 client -> wait_for_pong_resp = false;
9741009 } else if (client -> last_opcode == WS_TRANSPORT_OPCODES_CLOSE ) {
@@ -1050,8 +1085,16 @@ static void esp_websocket_client_task(void *pv)
10501085 if (_tick_get_ms () - client -> ping_tick_ms > client -> config -> ping_interval_sec * 1000 ) {
10511086 client -> ping_tick_ms = _tick_get_ms ();
10521087 ESP_LOGD (TAG , "Sending PING..." );
1088+ #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK
1089+ if (xSemaphoreTakeRecursive (client -> tx_lock , WEBSOCKET_TX_LOCK_TIMEOUT_MS ) != pdPASS ) {
1090+ ESP_LOGE (TAG , "Could not lock ws-client within %d timeout" , WEBSOCKET_TX_LOCK_TIMEOUT_MS );
1091+ break ;
1092+ }
1093+ #endif
10531094 esp_transport_ws_send_raw (client -> transport , WS_TRANSPORT_OPCODES_PING | WS_TRANSPORT_OPCODES_FIN , NULL , 0 , client -> config -> network_timeout_ms );
1054-
1095+ #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK
1096+ xSemaphoreGiveRecursive (client -> tx_lock );
1097+ #endif
10551098 if (!client -> wait_for_pong_resp && client -> config -> pingpong_timeout_sec ) {
10561099 client -> pingpong_tick_ms = _tick_get_ms ();
10571100 client -> wait_for_pong_resp = true;
@@ -1086,7 +1129,16 @@ static void esp_websocket_client_task(void *pv)
10861129 // if closing not initiated by the client echo the close message back
10871130 if ((CLOSE_FRAME_SENT_BIT & xEventGroupGetBits (client -> status_bits )) == 0 ) {
10881131 ESP_LOGD (TAG , "Closing initiated by the server, sending close frame" );
1132+ #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK
1133+ if (xSemaphoreTakeRecursive (client -> tx_lock , WEBSOCKET_TX_LOCK_TIMEOUT_MS ) != pdPASS ) {
1134+ ESP_LOGE (TAG , "Could not lock ws-client within %d timeout" , WEBSOCKET_TX_LOCK_TIMEOUT_MS );
1135+ break ;
1136+ }
1137+ #endif
10891138 esp_transport_ws_send_raw (client -> transport , WS_TRANSPORT_OPCODES_CLOSE | WS_TRANSPORT_OPCODES_FIN , NULL , 0 , client -> config -> network_timeout_ms );
1139+ #ifdef CONFIG_ESP_WS_CLIENT_SEPARATE_TX_LOCK
1140+ xSemaphoreGiveRecursive (client -> tx_lock );
1141+ #endif
10901142 xEventGroupSetBits (client -> status_bits , CLOSE_FRAME_SENT_BIT );
10911143 }
10921144 break ;
0 commit comments