@@ -265,7 +265,6 @@ static esp_ble_adv_params_t bt_adv_params = {
265
265
266
266
static bool mod_bt_allow_resume_deinit ;
267
267
static uint16_t mod_bt_gatts_mtu_restore = 0 ;
268
- static bool mod_bt_is_conn_restore_available ;
269
268
270
269
static nvs_handle modbt_nvs_handle ;
271
270
static uint8_t tx_pwr_level_to_dbm [] = {-12 , -9 , -6 , -3 , 0 , 3 , 6 , 9 };
@@ -324,7 +323,6 @@ void modbt_init0(void) {
324
323
esp_bt_controller_mem_release (ESP_BT_MODE_CLASSIC_BT );
325
324
326
325
mod_bt_allow_resume_deinit = false;
327
- mod_bt_is_conn_restore_available = false;
328
326
}
329
327
330
328
void modbt_deinit (bool allow_reconnect )
@@ -363,11 +361,14 @@ void modbt_deinit(bool allow_reconnect)
363
361
xEventGroupWaitBits (bt_event_group , MOD_BT_GATTS_DISCONN_EVT | MOD_BT_GATTS_CLOSE_EVT , true, true, 1000 /portTICK_PERIOD_MS );
364
362
}
365
363
364
+ esp_ble_gattc_app_unregister (MOD_BT_CLIENT_APP_ID );
365
+ esp_ble_gatts_app_unregister (MOD_BT_SERVER_APP_ID );
366
+
366
367
esp_bluedroid_disable ();
367
368
esp_bluedroid_deinit ();
368
369
esp_bt_controller_disable ();
370
+ esp_bt_controller_deinit ();
369
371
bt_obj .init = false;
370
- mod_bt_is_conn_restore_available = false;
371
372
xEventGroupClearBits (bt_event_group , MOD_BT_GATTC_MTU_EVT | MOD_BT_GATTS_MTU_EVT | MOD_BT_GATTS_DISCONN_EVT | MOD_BT_GATTS_CLOSE_EVT );
372
373
}
373
374
}
@@ -388,39 +389,48 @@ void bt_resume(bool reconnect)
388
389
nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , "Bluetooth enable failed" ));
389
390
}
390
391
392
+ esp_ble_gap_register_callback (gap_events_handler );
393
+ esp_ble_gattc_register_callback (gattc_events_handler );
394
+ esp_ble_gatts_register_callback (gatts_event_handler );
395
+
391
396
esp_ble_gattc_app_register (MOD_BT_CLIENT_APP_ID );
392
397
esp_ble_gatts_app_register (MOD_BT_SERVER_APP_ID );
393
398
394
399
esp_ble_gatt_set_local_mtu (mod_bt_gatts_mtu_restore );
395
400
396
- bt_connection_obj_t * connection_obj = NULL ;
397
-
398
- if (MP_STATE_PORT (btc_conn_list ).len > 0 )
401
+ // If this list has 0 elements it means there were no active connections
402
+ if (MP_STATE_PORT (btc_conn_list ).len > 0 && reconnect )
399
403
{
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
- }
404
+ /* Enable Scan */
405
+ modbt_start_scan (MP_OBJ_NEW_SMALL_INT (-1 ));
406
+ mp_hal_delay_ms (50 );
407
+ while (!bt_obj .scanning ){
408
+ /* Wait for scanning to start */
409
+ }
403
410
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 )));
411
+ /* Re-connect to all previously existing connections */
412
+ // Need to save the old connections into a temporary list because during connect the original list is manipulated (items added)
413
+ mp_obj_list_t btc_conn_list_tmp ;
414
+ mp_obj_list_init (& btc_conn_list_tmp , 0 );
415
+ for (mp_uint_t i = 0 ; i < MP_STATE_PORT (btc_conn_list ).len ; i ++ ) {
416
+ bt_connection_obj_t * connection_obj = ((bt_connection_obj_t * )(MP_STATE_PORT (btc_conn_list ).items [i ]));
417
+ mp_obj_list_append (& btc_conn_list_tmp , connection_obj );
418
+ }
418
419
419
- mod_bt_is_conn_restore_available = true;
420
+ // Connect to the old connections
421
+ for (mp_uint_t i = 0 ; i < btc_conn_list_tmp .len ; i ++ ) {
422
+ bt_connection_obj_t * connection_obj = ((bt_connection_obj_t * )(btc_conn_list_tmp .items [i ]));
423
+ // Initiates re-connection
424
+ bt_connection_obj_t * new_connection_obj = modbt_connect (mp_obj_new_bytes ((const byte * )connection_obj -> srv_bda , 6 ));
425
+ // If new connection object has been created then overwrite the original one so from the MicroPython code the same reference can be used
426
+ if (new_connection_obj != mp_const_none ) {
427
+ memcpy (connection_obj , new_connection_obj , sizeof (bt_connection_obj_t ));
428
+ // As modbt_connect appends the new connection to the original list, it needs to be removed because it is not needed
429
+ mp_obj_list_remove ((void * )& MP_STATE_PORT (btc_conn_list ), new_connection_obj );
420
430
}
421
431
}
422
432
423
- /* See if there was an averstisment active before Sleep */
433
+ /* See if there was an advertisement active before Sleep */
424
434
if (bt_obj .advertising ) {
425
435
esp_ble_gap_start_advertising (& bt_adv_params );
426
436
}
@@ -554,8 +564,7 @@ static void set_pin(uint32_t new_pin)
554
564
static void close_connection (int32_t conn_id ) {
555
565
for (mp_uint_t i = 0 ; i < MP_STATE_PORT (btc_conn_list ).len ; i ++ ) {
556
566
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 )) {
567
+ if (connection_obj -> conn_id == conn_id ) {
559
568
connection_obj -> conn_id = -1 ;
560
569
mp_obj_list_remove ((void * )& MP_STATE_PORT (btc_conn_list ), connection_obj );
561
570
}
@@ -1408,7 +1417,13 @@ static mp_obj_t bt_connect_helper(mp_obj_t addr, TickType_t timeout){
1408
1417
EventBits_t uxBits ;
1409
1418
1410
1419
if (bt_obj .busy ) {
1411
- nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , "operation already in progress" ));
1420
+ // Only drop exception if not called from bt_resume() API, otherwise return with mp_const_none on error
1421
+ if (mod_bt_allow_resume_deinit == false) {
1422
+ nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , "operation already in progress" ));
1423
+ }
1424
+ else {
1425
+ return mp_const_none ;
1426
+ }
1412
1427
}
1413
1428
1414
1429
if (bt_obj .scanning ) {
@@ -1425,15 +1440,28 @@ static mp_obj_t bt_connect_helper(mp_obj_t addr, TickType_t timeout){
1425
1440
1426
1441
/* Initiate a background connection, esp_ble_gattc_open returns immediately */
1427
1442
if (ESP_OK != esp_ble_gattc_open (bt_obj .gattc_if , bufinfo .buf , BLE_ADDR_TYPE_PUBLIC , true)) {
1428
- nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , mpexception_os_operation_failed ));
1443
+ // Only drop exception if not called from bt_resume() API, otherwise return with mp_const_none on error
1444
+ if (mod_bt_allow_resume_deinit == false) {
1445
+ nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , mpexception_os_operation_failed ));
1446
+ }
1447
+ else {
1448
+ return mp_const_none ;
1449
+ }
1429
1450
}
1451
+
1430
1452
MP_THREAD_GIL_EXIT ();
1431
1453
if (xQueueReceive (xScanQueue , & bt_event , timeout ) == pdTRUE )
1432
1454
{
1433
1455
MP_THREAD_GIL_ENTER ();
1434
1456
1435
1457
if (bt_event .connection .conn_id < 0 ) {
1436
- nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , "connection refused" ));
1458
+ // Only drop exception if not called from bt_resume() API, otherwise return with mp_const_none on error
1459
+ if (mod_bt_allow_resume_deinit == false) {
1460
+ nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , "connection refused" ));
1461
+ }
1462
+ else {
1463
+ return mp_const_none ;
1464
+ }
1437
1465
}
1438
1466
1439
1467
// setup the object
@@ -1452,14 +1480,22 @@ static mp_obj_t bt_connect_helper(mp_obj_t addr, TickType_t timeout){
1452
1480
}
1453
1481
memcpy (conn -> srv_bda , bt_event .connection .srv_bda , 6 );
1454
1482
mp_obj_list_append ((void * )& MP_STATE_PORT (btc_conn_list ), conn );
1483
+
1455
1484
return conn ;
1456
1485
}
1457
1486
else
1458
1487
{
1459
1488
MP_THREAD_GIL_ENTER ();
1460
1489
1461
1490
(void )esp_ble_gap_disconnect (bufinfo .buf );
1462
- nlr_raise (mp_obj_new_exception_msg (& mp_type_TimeoutError , "timed out" ));
1491
+
1492
+ // Only drop exception if not called from bt_resume() API, otherwise return with mp_const_none on error
1493
+ if (mod_bt_allow_resume_deinit == false) {
1494
+ nlr_raise (mp_obj_new_exception_msg (& mp_type_TimeoutError , "timed out" ));
1495
+ }
1496
+ else {
1497
+ return mp_const_none ;
1498
+ }
1463
1499
}
1464
1500
return mp_const_none ;
1465
1501
}
@@ -2272,8 +2308,9 @@ STATIC mp_obj_t bt_conn_disconnect(mp_obj_t self_in) {
2272
2308
if (self -> conn_id >= 0 ) {
2273
2309
esp_ble_gattc_close (bt_obj .gattc_if , self -> conn_id );
2274
2310
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 )
2311
+ /* Only reset Conn Id if it is needed that the connection should be established again after wakeup
2312
+ * otherwise this connection will be completely removed in close_connection() call triggered by ESP_GATTC_DISCONNECT_EVT event */
2313
+ if (mod_bt_allow_resume_deinit )
2277
2314
{
2278
2315
self -> conn_id = -1 ;
2279
2316
}
0 commit comments