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

Commit fc10185

Browse files
committed
BLE update
1 parent a5aa0b8 commit fc10185

File tree

5 files changed

+185
-85
lines changed

5 files changed

+185
-85
lines changed

esp32/mods/modbt.c

+109-52
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ typedef struct {
113113
int32_t conn_id;
114114
uint16_t mtu;
115115
esp_gatt_if_t gatt_if;
116+
esp_ble_addr_type_t addr_type;
116117
} bt_connection_obj_t;
117118

118119
typedef struct {
@@ -258,7 +259,6 @@ static esp_ble_adv_params_t bt_adv_params = {
258259

259260
static bool mod_bt_allow_resume_deinit;
260261
static uint16_t mod_bt_gatts_mtu_restore = 0;
261-
static bool mod_bt_is_conn_restore_available;
262262

263263
static nvs_handle modbt_nvs_handle;
264264
static uint8_t tx_pwr_level_to_dbm[] = {-12, -9, -6, -3, 0, 3, 6, 9};
@@ -278,7 +278,7 @@ STATIC void gattc_char_callback_handler(void *arg);
278278
STATIC void gatts_char_callback_handler(void *arg);
279279
static mp_obj_t modbt_start_scan(mp_obj_t timeout);
280280
static mp_obj_t modbt_conn_disconnect(mp_obj_t self_in);
281-
static mp_obj_t modbt_connect(mp_obj_t addr);
281+
static mp_obj_t modbt_connect(mp_obj_t addr, esp_ble_addr_type_t addr_type);
282282

283283
/******************************************************************************
284284
DEFINE PUBLIC FUNCTIONS
@@ -317,7 +317,6 @@ void modbt_init0(void) {
317317
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
318318

319319
mod_bt_allow_resume_deinit = false;
320-
mod_bt_is_conn_restore_available = false;
321320
}
322321

323322
void modbt_deinit(bool allow_reconnect)
@@ -356,11 +355,14 @@ void modbt_deinit(bool allow_reconnect)
356355
xEventGroupWaitBits(bt_event_group, MOD_BT_GATTS_DISCONN_EVT | MOD_BT_GATTS_CLOSE_EVT, true, true, 1000/portTICK_PERIOD_MS);
357356
}
358357

358+
esp_ble_gattc_app_unregister(MOD_BT_CLIENT_APP_ID);
359+
esp_ble_gatts_app_unregister(MOD_BT_SERVER_APP_ID);
360+
359361
esp_bluedroid_disable();
360362
esp_bluedroid_deinit();
361363
esp_bt_controller_disable();
364+
esp_bt_controller_deinit();
362365
bt_obj.init = false;
363-
mod_bt_is_conn_restore_available = false;
364366
xEventGroupClearBits(bt_event_group, MOD_BT_GATTC_MTU_EVT | MOD_BT_GATTS_MTU_EVT | MOD_BT_GATTS_DISCONN_EVT | MOD_BT_GATTS_CLOSE_EVT);
365367
}
366368
}
@@ -381,39 +383,48 @@ void bt_resume(bool reconnect)
381383
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Bluetooth enable failed"));
382384
}
383385

386+
esp_ble_gap_register_callback(gap_events_handler);
387+
esp_ble_gattc_register_callback(gattc_events_handler);
388+
esp_ble_gatts_register_callback(gatts_event_handler);
389+
384390
esp_ble_gattc_app_register(MOD_BT_CLIENT_APP_ID);
385391
esp_ble_gatts_app_register(MOD_BT_SERVER_APP_ID);
386392

387393
esp_ble_gatt_set_local_mtu(mod_bt_gatts_mtu_restore);
388394

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

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

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

416-
/* See if there was an averstisment active before Sleep */
427+
/* See if there was an advertisement active before Sleep */
417428
if(bt_obj.advertising) {
418429
esp_ble_gap_start_advertising(&bt_adv_params);
419430
}
@@ -456,19 +467,19 @@ static void create_hash(uint32_t pin, uint8_t *h_value)
456467
{
457468
bt_hash_obj_t pin_hash;
458469
mbedtls_sha1_context sha1_context;
459-
470+
460471
mbedtls_sha1_init(&sha1_context);
461472
mbedtls_sha1_starts_ret(&sha1_context);
462-
473+
463474
pin_hash.pin = pin;
464475
mbedtls_sha1_update_ret(&sha1_context, pin_hash.value, 4);
465-
476+
466477
mbedtls_sha1_finish_ret(&sha1_context, h_value);
467478
mbedtls_sha1_free(&sha1_context);
468479
}
469480

470-
static bool pin_changed(uint32_t new_pin)
471-
{
481+
static bool pin_changed(uint32_t new_pin)
482+
{
472483
bool ret = false;
473484
uint32_t h_size = MOD_BT_HASH_SIZE;
474485
uint8_t h_stored[MOD_BT_HASH_SIZE] = {0};
@@ -480,17 +491,17 @@ static bool pin_changed(uint32_t new_pin)
480491
mp_printf(&mp_plat_print, "Error opening secure BLE NVS namespace!\n");
481492
}
482493
nvs_get_blob(modbt_nvs_handle, key, h_stored, &h_size);
483-
494+
484495
create_hash(new_pin, h_created);
485-
496+
486497
if (memcmp(h_stored, h_created, MOD_BT_HASH_SIZE) != 0) {
487498
esp_err = nvs_set_blob(modbt_nvs_handle, key, h_created, h_size);
488499
if (esp_err == ESP_OK) {
489500
nvs_commit(modbt_nvs_handle);
490501
ret = true;
491502
}
492503
}
493-
504+
494505
nvs_close(modbt_nvs_handle);
495506

496507
return ret;
@@ -547,8 +558,7 @@ static void set_pin(uint32_t new_pin)
547558
static void close_connection (int32_t conn_id) {
548559
for (mp_uint_t i = 0; i < MP_STATE_PORT(btc_conn_list).len; i++) {
549560
bt_connection_obj_t *connection_obj = ((bt_connection_obj_t *)(MP_STATE_PORT(btc_conn_list).items[i]));
550-
/* Only reset Conn Id if it is a normal disconnect not module de-init to mark conn obj to be restored */
551-
if (connection_obj->conn_id == conn_id && (!mod_bt_allow_resume_deinit)) {
561+
if (connection_obj->conn_id == conn_id) {
552562
connection_obj->conn_id = -1;
553563
mp_obj_list_remove((void *)&MP_STATE_PORT(btc_conn_list), connection_obj);
554564
}
@@ -1371,13 +1381,19 @@ STATIC mp_obj_t bt_events(mp_obj_t self_in) {
13711381
}
13721382
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bt_events_obj, bt_events);
13731383

1374-
static mp_obj_t bt_connect_helper(mp_obj_t addr, TickType_t timeout){
1384+
static mp_obj_t bt_connect_helper(mp_obj_t addr, TickType_t timeout, esp_ble_addr_type_t addr_type){
13751385

13761386
bt_event_result_t bt_event;
13771387
EventBits_t uxBits;
13781388

13791389
if (bt_obj.busy) {
1380-
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "operation already in progress"));
1390+
// Only drop exception if not called from bt_resume() API, otherwise return with mp_const_none on error
1391+
if(mod_bt_allow_resume_deinit == false) {
1392+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "operation already in progress"));
1393+
}
1394+
else {
1395+
return mp_const_none;
1396+
}
13811397
}
13821398

13831399
if (bt_obj.scanning) {
@@ -1393,23 +1409,37 @@ static mp_obj_t bt_connect_helper(mp_obj_t addr, TickType_t timeout){
13931409
bt_obj.busy = true;
13941410

13951411
/* Initiate a background connection, esp_ble_gattc_open returns immediately */
1396-
if (ESP_OK != esp_ble_gattc_open(bt_obj.gattc_if, bufinfo.buf, BLE_ADDR_TYPE_PUBLIC, true)) {
1397-
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
1412+
if (ESP_OK != esp_ble_gattc_open(bt_obj.gattc_if, bufinfo.buf, addr_type, true)) {
1413+
// Only drop exception if not called from bt_resume() API, otherwise return with mp_const_none on error
1414+
if(mod_bt_allow_resume_deinit == false) {
1415+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
1416+
}
1417+
else {
1418+
return mp_const_none;
1419+
}
13981420
}
1421+
13991422
MP_THREAD_GIL_EXIT();
14001423
if (xQueueReceive(xScanQueue, &bt_event, timeout) == pdTRUE)
14011424
{
14021425
MP_THREAD_GIL_ENTER();
14031426

14041427
if (bt_event.connection.conn_id < 0) {
1405-
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "connection refused"));
1428+
// Only drop exception if not called from bt_resume() API, otherwise return with mp_const_none on error
1429+
if(mod_bt_allow_resume_deinit == false) {
1430+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "connection refused"));
1431+
}
1432+
else {
1433+
return mp_const_none;
1434+
}
14061435
}
14071436

14081437
// setup the object
14091438
bt_connection_obj_t *conn = m_new_obj(bt_connection_obj_t);
14101439
conn->base.type = (mp_obj_t)&mod_bt_connection_type;
14111440
conn->conn_id = bt_event.connection.conn_id;
14121441
conn->gatt_if = bt_event.connection.gatt_if;
1442+
conn->addr_type = addr_type;
14131443

14141444
MP_THREAD_GIL_EXIT();
14151445
uxBits = xEventGroupWaitBits(bt_event_group, MOD_BT_GATTC_MTU_EVT, true, true, 1000/portTICK_PERIOD_MS);
@@ -1421,14 +1451,22 @@ static mp_obj_t bt_connect_helper(mp_obj_t addr, TickType_t timeout){
14211451
}
14221452
memcpy(conn->srv_bda, bt_event.connection.srv_bda, 6);
14231453
mp_obj_list_append((void *)&MP_STATE_PORT(btc_conn_list), conn);
1454+
14241455
return conn;
14251456
}
14261457
else
14271458
{
14281459
MP_THREAD_GIL_ENTER();
14291460

14301461
(void)esp_ble_gap_disconnect(bufinfo.buf);
1431-
nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out"));
1462+
1463+
// Only drop exception if not called from bt_resume() API, otherwise return with mp_const_none on error
1464+
if(mod_bt_allow_resume_deinit == false) {
1465+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out"));
1466+
}
1467+
else {
1468+
return mp_const_none;
1469+
}
14321470
}
14331471
return mp_const_none;
14341472
}
@@ -1439,6 +1477,7 @@ STATIC mp_obj_t bt_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t
14391477
STATIC const mp_arg_t allowed_args[] = {
14401478
{ MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_OBJ, },
14411479
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
1480+
{ MP_QSTR_addr_type, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}},
14421481
};
14431482

14441483
// parse arguments
@@ -1447,7 +1486,7 @@ STATIC mp_obj_t bt_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t
14471486

14481487
mp_obj_t addr = args[0].u_obj;
14491488

1450-
/* Timeout parameter is in miliseconds */
1489+
/* Timeout parameter is in milliseconds */
14511490
TickType_t timeout;
14521491
if(args[1].u_obj == MP_OBJ_NULL){
14531492
timeout = portMAX_DELAY;
@@ -1463,13 +1502,30 @@ STATIC mp_obj_t bt_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t
14631502
}
14641503
}
14651504

1466-
return bt_connect_helper(addr, timeout);
1505+
/* addr_type parameter */
1506+
uint32_t addr_type;
1507+
if(args[2].u_obj == MP_OBJ_NULL){
1508+
addr_type = BLE_ADDR_TYPE_PUBLIC;
1509+
}
1510+
else
1511+
{
1512+
if(MP_OBJ_IS_SMALL_INT(args[2].u_obj) == true) {
1513+
addr_type = mp_obj_get_int(args[2].u_obj);
1514+
}
1515+
else
1516+
{
1517+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "If addr_type is specified it must be a valid integer number"));
1518+
}
1519+
}
1520+
1521+
1522+
return bt_connect_helper(addr, timeout, addr_type);
14671523
}
14681524
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bt_connect_obj, 1, bt_connect);
14691525

1470-
static mp_obj_t modbt_connect(mp_obj_t addr)
1526+
static mp_obj_t modbt_connect(mp_obj_t addr, esp_ble_addr_type_t addr_type)
14711527
{
1472-
return bt_connect_helper(addr, portMAX_DELAY);
1528+
return bt_connect_helper(addr, portMAX_DELAY, addr_type);
14731529
}
14741530

14751531

@@ -1482,7 +1538,7 @@ STATIC mp_obj_t bt_set_advertisement_params (mp_uint_t n_args, const mp_obj_t *p
14821538
{ MP_QSTR_channel_map, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
14831539
{ MP_QSTR_adv_filter_policy, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
14841540
};
1485-
1541+
14861542
// parse args
14871543
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
14881544
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), allowed_args, args);
@@ -1635,14 +1691,14 @@ STATIC mp_obj_t bt_set_advertisement_raw(mp_obj_t self_in, mp_obj_t raw_data) {
16351691
memcpy(data, (uint8_t *)bufinfo.buf, sizeof(data));
16361692
data_len = sizeof(data);
16371693
}
1638-
1694+
16391695
esp_ble_gap_config_adv_data_raw(data, data_len);
1640-
1696+
16411697
// wait for the advertisement data to be configured
16421698
bt_gatts_event_result_t gatts_event;
16431699
xQueueReceive(xGattsQueue, &gatts_event, portMAX_DELAY);
16441700
}
1645-
1701+
16461702
return mp_const_none;
16471703
}
16481704
STATIC MP_DEFINE_CONST_FUN_OBJ_2(bt_set_advertisement_raw_obj, bt_set_advertisement_raw);
@@ -2241,8 +2297,9 @@ STATIC mp_obj_t bt_conn_disconnect(mp_obj_t self_in) {
22412297
if (self->conn_id >= 0) {
22422298
esp_ble_gattc_close(bt_obj.gattc_if, self->conn_id);
22432299
esp_ble_gap_disconnect(self->srv_bda);
2244-
/* Only reset Conn Id if it is a normal disconnect not module de-init to mark conn obj to be restored */
2245-
if(!mod_bt_allow_resume_deinit)
2300+
/* Only reset Conn Id if it is needed that the connection should be established again after wakeup
2301+
* otherwise this connection will be completely removed in close_connection() call triggered by ESP_GATTC_DISCONNECT_EVT event */
2302+
if(mod_bt_allow_resume_deinit)
22462303
{
22472304
self->conn_id = -1;
22482305
}

esp32/mods/modmachine.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ STATIC mp_obj_t machine_sleep (uint n_args, const mp_obj_t *arg) {
223223
}
224224

225225
modbt_deinit(reconnect);
226-
wlan_deinit(NULL);
226+
// TRUE means wlan_deinit is called from machine_sleep
227+
wlan_deinit(mp_const_true);
227228

228229
if(ESP_OK != esp_light_sleep_start())
229230
{

0 commit comments

Comments
 (0)