Skip to content

Commit 5b84527

Browse files
committed
Fix BluetoothSerial TX Stall
Fixes: #4949
1 parent 5da4a47 commit 5b84527

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

Diff for: libraries/BluetoothSerial/src/BluetoothSerial.cpp

+27-9
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ const char * _spp_server_name = "ESP32SPP";
4242

4343
#define RX_QUEUE_SIZE 512
4444
#define TX_QUEUE_SIZE 32
45+
#define SPP_TX_QUEUE_TIMEOUT 1000
46+
#define SPP_TX_DONE_TIMEOUT 1000
47+
#define SPP_CONGESTED_TIMEOUT 1000
48+
4549
static uint32_t _spp_client = 0;
4650
static xQueueHandle _spp_rx_queue = NULL;
4751
static xQueueHandle _spp_tx_queue = NULL;
@@ -143,7 +147,7 @@ static esp_err_t _spp_queue_packet(uint8_t *data, size_t len){
143147
}
144148
packet->len = len;
145149
memcpy(packet->data, data, len);
146-
if (xQueueSend(_spp_tx_queue, &packet, portMAX_DELAY) != pdPASS) {
150+
if (!_spp_tx_queue || xQueueSend(_spp_tx_queue, &packet, SPP_TX_QUEUE_TIMEOUT) != pdPASS) {
147151
log_e("SPP TX Queue Send Failed!");
148152
free(packet);
149153
return ESP_FAIL;
@@ -156,19 +160,25 @@ static uint8_t _spp_tx_buffer[SPP_TX_MAX];
156160
static uint16_t _spp_tx_buffer_len = 0;
157161

158162
static bool _spp_send_buffer(){
159-
if((xEventGroupWaitBits(_spp_event_group, SPP_CONGESTED, pdFALSE, pdTRUE, portMAX_DELAY) & SPP_CONGESTED) != 0){
163+
if((xEventGroupWaitBits(_spp_event_group, SPP_CONGESTED, pdFALSE, pdTRUE, SPP_CONGESTED_TIMEOUT) & SPP_CONGESTED) != 0){
164+
if(!_spp_client){
165+
log_v("SPP Client Gone!");
166+
return false;
167+
}
168+
log_v("SPP Write %u", _spp_tx_buffer_len);
160169
esp_err_t err = esp_spp_write(_spp_client, _spp_tx_buffer_len, _spp_tx_buffer);
161170
if(err != ESP_OK){
162171
log_e("SPP Write Failed! [0x%X]", err);
163172
return false;
164173
}
165174
_spp_tx_buffer_len = 0;
166-
if(xSemaphoreTake(_spp_tx_done, portMAX_DELAY) != pdTRUE){
175+
if(xSemaphoreTake(_spp_tx_done, SPP_TX_DONE_TIMEOUT) != pdTRUE){
167176
log_e("SPP Ack Failed!");
168177
return false;
169178
}
170179
return true;
171180
}
181+
log_e("SPP Write Congested!");
172182
return false;
173183
}
174184

@@ -194,13 +204,18 @@ static void _spp_tx_task(void * arg){
194204
_spp_tx_buffer_len = SPP_TX_MAX;
195205
data += to_send;
196206
len -= to_send;
197-
_spp_send_buffer();
207+
if(!_spp_send_buffer()){
208+
len = 0;
209+
}
198210
while(len >= SPP_TX_MAX){
199211
memcpy(_spp_tx_buffer, data, SPP_TX_MAX);
200212
_spp_tx_buffer_len = SPP_TX_MAX;
201213
data += SPP_TX_MAX;
202214
len -= SPP_TX_MAX;
203-
_spp_send_buffer();
215+
if(!_spp_send_buffer()){
216+
len = 0;
217+
break;
218+
}
204219
}
205220
if(len){
206221
memcpy(_spp_tx_buffer, data, len);
@@ -236,9 +251,10 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
236251

237252
case ESP_SPP_SRV_OPEN_EVT://Server connection open
238253
if (param->srv_open.status == ESP_SPP_SUCCESS) {
239-
log_i("ESP_SPP_SRV_OPEN_EVT");
254+
log_i("ESP_SPP_SRV_OPEN_EVT: %u", _spp_client);
240255
if (!_spp_client){
241256
_spp_client = param->srv_open.handle;
257+
_spp_tx_buffer_len = 0;
242258
} else {
243259
secondConnectionAttempt = true;
244260
esp_spp_disconnect(param->srv_open.handle);
@@ -252,12 +268,13 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
252268

253269
case ESP_SPP_CLOSE_EVT://Client connection closed
254270
if ((param->close.async == false && param->close.status == ESP_SPP_SUCCESS) || param->close.async) {
255-
log_i("ESP_SPP_CLOSE_EVT");
271+
log_i("ESP_SPP_CLOSE_EVT: %u", secondConnectionAttempt);
256272
if(secondConnectionAttempt) {
257273
secondConnectionAttempt = false;
258274
} else {
259275
_spp_client = 0;
260276
xEventGroupSetBits(_spp_event_group, SPP_DISCONNECTED);
277+
xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
261278
}
262279
xEventGroupClearBits(_spp_event_group, SPP_CONNECTED);
263280
} else {
@@ -279,11 +296,11 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
279296
if(param->write.cong){
280297
xEventGroupClearBits(_spp_event_group, SPP_CONGESTED);
281298
}
282-
xSemaphoreGive(_spp_tx_done);//we can try to send another packet
283299
log_v("ESP_SPP_WRITE_EVT: %u %s", param->write.len, param->write.cong?"CONGESTED":"");
284300
} else {
285301
log_e("ESP_SPP_WRITE_EVT failed!, status:%d", param->write.status);
286302
}
303+
xSemaphoreGive(_spp_tx_done);//we can try to send another packet
287304
break;
288305

289306
case ESP_SPP_DATA_IND_EVT://connection received data
@@ -323,6 +340,7 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
323340
}
324341
xEventGroupClearBits(_spp_event_group, SPP_DISCONNECTED);
325342
xEventGroupSetBits(_spp_event_group, SPP_CONNECTED);
343+
xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
326344
break;
327345

328346
case ESP_SPP_START_EVT://server started
@@ -693,7 +711,7 @@ void BluetoothSerial::flush()
693711
{
694712
if (_spp_tx_queue != NULL){
695713
while(uxQueueMessagesWaiting(_spp_tx_queue) > 0){
696-
delay(5);
714+
delay(100);
697715
}
698716
}
699717
}

0 commit comments

Comments
 (0)