8000 Fix memory leak happens after Bluetooth disconnect, fix a problem in … · pycom/pycom-micropython-sigfox@38f9019 · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit 38f9019

Browse files
committed
Fix memory leak happens after Bluetooth disconnect, fix a problem in Bluetooth.deinit() and fix Bluetooth connection resume after machine.wakeup(True)
1 parent fdedb33 commit 38f9019

File tree

1 file changed

+59
-32
lines changed

1 file changed

+59
-32
lines changed

esp32/mods/modbt.c

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,6 @@ static esp_ble_adv_params_t bt_adv_params = {
265265

266266
static bool mod_bt_allow_resume_deinit;
267267
static uint16_t mod_bt_gatts_mtu_restore = 0;
268-
static bool mod_bt_is_conn_restore_available;
269268

270269
static nvs_handle modbt_nvs_handle;
271270
static uint8_t tx_pwr_level_to_dbm[] = {-12, -9, -6, -3, 0, 3, 6, 9};
@@ -324,7 +323,6 @@ void modbt_init0(void) {
324323
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
325324

326325
mod_bt_allow_resume_deinit = false;
327-
mod_bt_is_conn_restore_available = false;
328326
}
329327

330328
void modbt_deinit(bool allow_reconnect)
@@ -363,11 +361,14 @@ void modbt_deinit(bool allow_reconnect)
363361
xEventGroupWaitBits(bt_event_group, MOD_BT_GATTS_DISCONN_EVT | MOD_BT_GATTS_CLOSE_EVT, true, true, 1000/portTICK_PERIOD_MS);
364362
}
365363

364+
esp_ble_gattc_app_unregister(MOD_BT_CLIENT_APP_ID);
365+
esp_ble_gatts_app_unregister(MOD_BT_SERVER_APP_ID);
366+
366367
esp_bluedroid_disable();
367368
esp_bluedroid_deinit();
368369
esp_bt_controller_disable();
370+
esp_bt_controller_deinit();
369371
bt_obj.init = false;
370-
mod_bt_is_conn_restore_available = false;
371372
xEventGroupClearBits(bt_event_group, MOD_BT_GATTC_MTU_EVT | MOD_BT_GATTS_MTU_EVT | MOD_BT_GATTS_DISCONN_EVT | MOD_BT_GATTS_CLOSE_EVT);
372373
}
373374
}
@@ -393,34 +394,39 @@ void bt_resume(bool reconnect)
393394

394395
esp_ble_gatt_set_local_mtu(mod_bt_gatts_mtu_restore);
395396

396-
bt_connection_obj_t *connection_obj = NULL;
397-
398-
if(MP_STATE_PORT(btc_conn_list).len > 0)
397+
// If this list has 0 elements it means there were no active connections
398+
if(MP_STATE_PORT(btc_conn_list).len > 0 && reconnect)
399399
{
400-
/* Get the Last gattc connection obj before sleep */
401-
connection_obj = ((bt_connection_obj_t *)(MP_STATE_PORT(btc_conn_list).items[MP_STATE_PORT(btc_conn_list).len - 1]));
402-
}
400+
/* Enable Scan */
401+
modbt_start_scan(MP_OBJ_NEW_SMALL_INT(-1));
402+
mp_hal_delay_ms(50);
403+
while(!bt_obj.scanning){
404+
/* Wait for scanning to start */
405+
}
403406

404-
if (reconnect)
405-
{
406-
/* Check if there was a gattc connection Active before sleep */
407-
if (connection_obj != NULL) {
408-
if (connection_obj->conn_id >= 0) {
409-
/* Enable Scan */
410-
modbt_start_scan(MP_OBJ_NEW_SMALL_INT(-1));
411-
mp_hal_delay_ms(50);
412-
while(!bt_obj.scanning){
413-
/* Wait for scanning to start */
414-
}
415-
/* re-connect to Last Connection */
416-
mp_obj_list_remove((void *)&MP_STATE_PORT(btc_conn_list), connection_obj);
417-
mp_obj_list_append((void *)&MP_STATE_PORT(btc_conn_list), modbt_connect(mp_obj_new_bytes((const byte *)connection_obj->srv_bda, 6)));
407+
/* Re-connect to all previously existing connections */
408+
// Need to save the old connections into a temporary list because during connect the original list is manipulated (items added)
409+
mp_obj_list_t btc_conn_list_tmp;
410+
mp_obj_list_init(&btc_conn_list_tmp, 0);
411+
for (mp_uint_t i = 0; i < MP_STATE_PORT(btc_conn_list).len; i++) {
412+
bt_connection_obj_t *connection_obj = ((bt_connection_obj_t *)(MP_STATE_PORT(btc_conn_list).items[i]));
413+
mp_obj_list_append(&btc_conn_list_tmp, connection_obj);
414+
}
418415

419-
mod_bt_is_conn_restore_available = true;
416+
// Connect to the old connections
417+
for (mp_uint_t i = 0; i < btc_conn_list_tmp.len; i++) {
418+
bt_connection_obj_t *connection_obj = ((bt_connection_obj_t *)(btc_conn_list_tmp.items[i]));
419+
// Initiates re-connection
420+
bt_connection_obj_t *new_connection_obj = modbt_connect(mp_obj_new_bytes((const byte *)connection_obj->srv_bda, 6));
421+
// If new connection object has been created then overwrite the original one so from the MicroPython code the same reference can be used
422+
if(new_connection_obj != mp_const_none) {
423+
memcpy(connection_obj, new_connection_obj, sizeof(bt_connection_obj_t));
424+
// As modbt_connect appends the new connection to the original list, it needs to be removed because it is not needed
425+
mp_obj_list_remove((void *)&MP_STATE_PORT(btc_conn_list), new_connection_obj);
420426
}
421427
}
422428

423-
/* See if there was an averstisment active before Sleep */
429+
/* See if there was an advertisement active before Sleep */
424430
if(bt_obj.advertising) {
425431
esp_ble_gap_start_advertising(&bt_adv_params);
426432
}
@@ -554,8 +560,7 @@ static void set_pin(uint32_t new_pin)
554560
static void close_connection (int32_t conn_id) {
555561
for (mp_uint_t i = 0; i < MP_STATE_PORT(btc_conn_list).len; i++) {
556562
bt_connection_obj_t *connection_obj = ((bt_connection_obj_t *)(MP_STATE_PORT(btc_conn_list).items[i]));
557-
/* Only reset Conn Id if it is a normal disconnect not module de-init to mark conn obj to be restored */
558-
if (connection_obj->conn_id == conn_id && (!mod_bt_allow_resume_deinit)) {
563+
if (connection_obj->conn_id == conn_id) {
559564
connection_obj->conn_id = -1;
560565
mp_obj_list_remove((void *)&MP_STATE_PORT(btc_conn_list), connection_obj);
561566
}
@@ -1408,7 +1413,13 @@ static mp_obj_t bt_connect_helper(mp_obj_t addr, TickType_t timeout){
14081413
EventBits_t uxBits;
14091414

14101415
if (bt_obj.busy) {
1411-
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "operation already in progress"));
1416+
// Only drop exception if not called from bt_resume() API, otherwise return with mp_const_none on error
1417+
if(mod_bt_allow_resume_deinit == false) {
1418+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "operation already in progress"));
1419+
}
1420+
else {
1421+
return mp_const_none;
1422+
}
14121423
}
14131424

14141425
if (bt_obj.scanning) {
@@ -1427,13 +1438,20 @@ static mp_obj_t bt_connect_helper(mp_obj_t addr, TickType_t timeout){
14271438
if (ESP_OK != esp_ble_gattc_open(bt_obj.gattc_if, bufinfo.buf, BLE_ADDR_TYPE_PUBLIC, true)) {
14281439
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
14291440
}
1441+
14301442
MP_THREAD_GIL_EXIT();
14311443
if (xQueueReceive(xScanQueue, &bt_event, timeout) == pdTRUE)
14321444
{
14331445
MP_THREAD_GIL_ENTER();
14341446

14351447
if (bt_event.connection.conn_id < 0) {
1436-
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "connection refused"));
1448+
// Only drop exception if not called from bt_resume() API, otherwise return with mp_const_none on error
1449+
if(mod_bt_allow_resume_deinit == false) {
1450+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "connection refused"));
1451+
}
1452+
else {
1453+
return mp_const_none;
1454+
}
14371455
}
14381456

14391457
// setup the object
@@ -1452,14 +1470,22 @@ static mp_obj_t bt_connect_helper(mp_obj_t addr, TickType_t timeout){
14521470
}
14531471
memcpy(conn->srv_bda, bt_event.connection.srv_bda, 6);
14541472
mp_obj_list_append((void *)&MP_STATE_PORT(btc_conn_list), conn);
1473+
14551474
return conn;
14561475
}
14571476
else
14581477
{
14591478
MP_THREAD_GIL_ENTER();
14601479

14611480
(void)esp_ble_gap_disconnect(bufinfo.buf);
1462-
nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out"));
1481+
1482+
// Only drop exception if not called from bt_resume() API, otherwise return with mp_const_none on error
1483+
if(mod_bt_allow_resume_deinit == false) {
1484+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out"));
1485+
}
1486+
else {
1487+
return mp_const_none;
1488+
}
14631489
}
14641490
return mp_const_none;
14651491
}
@@ -2272,8 +2298,9 @@ STATIC mp_obj_t bt_conn_disconnect(mp_obj_t self_in) {
22722298
if (self->conn_id >= 0) {
22732299
esp_ble_gattc_close(bt_obj.gattc_if, self->conn_id);
22742300
esp_ble_gap_disconnect(self->srv_bda);
2275-
/* Only reset Conn Id if it is a normal disconnect not module de-init to mark conn obj to be restored */
2276-
if(!mod_bt_allow_resume_deinit)
2301+
/* Only reset Conn Id if it is needed that the connection should be established again after wakeup
2302+
* otherwise this connection will be completely removed in close_connection() call triggered by ESP_GATTC_DISCONNECT_EVT event */
2303+
if(mod_bt_allow_resume_deinit)
22772304
{
22782305
self->conn_id = -1;
22792306
}

0 commit comments

Comments
 (0)
0