3939#include "common-hal/_bleio/Connection.h"
4040
4141#include "esp_bt.h"
42+ #include "esp_mac.h"
4243#include "esp_nimble_hci.h"
4344#include "nvs_flash.h"
4445
4849
4950bleio_connection_internal_t bleio_connections [BLEIO_TOTAL_CONNECTION_COUNT ];
5051
51- // static void bluetooth_adapter_background(void *data) {
52- // supervisor_bluetooth_background();
53- // bleio_background();
54- // }
55-
5652bool ble_active = false;
5753
5854static void nimble_host_task (void * param ) {
@@ -63,7 +59,7 @@ static void nimble_host_task(void *param) {
6359static TaskHandle_t cp_task = NULL ;
6460
6561static void _on_sync (void ) {
66- int rc = ble_hs_util_ensure_addr (0 );
62+ int rc = ble_hs_util_ensure_addr (false );
6763 assert (rc == 0 );
6864
6965 xTaskNotifyGive (cp_task );
@@ -72,6 +68,8 @@ static void _on_sync(void) {
7268// All examples have this. It'd make sense in a header.
7369void ble_store_config_init (void );
7470
71+ char default_ble_name [] = { 'C' , 'I' , 'R' , 'C' , 'U' , 'I' , 'T' , 'P' , 'Y' , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
72+
7573void common_hal_bleio_adapter_set_enabled (bleio_adapter_obj_t * self , bool enabled ) {
7674 const bool is_enabled = common_hal_bleio_adapter_get_enabled (self );
7775
@@ -81,15 +79,6 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
8179 }
8280
8381 if (enabled ) {
84- esp_err_t err = nvs_flash_init ();
85- if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND ) {
86- // NVS partition was truncated and needs to be erased
87- // Retry nvs_flash_init
88- ESP_ERROR_CHECK (nvs_flash_erase ());
89- err = nvs_flash_init ();
90- }
91- ESP_ERROR_CHECK (err );
92-
9382 CHECK_ESP_RESULT (nimble_port_init ());
9483
9584 // ble_hs_cfg.reset_cb = blecent_on_reset;
@@ -104,8 +93,8 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
10493 ble_hs_cfg .sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC ;
10594 ble_hs_cfg .sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC ;
10695
107- ble_hs_cfg .sm_mitm = 1 ;
108- ble_hs_cfg .sm_sc = 1 ;
96+ ble_hs_cfg .sm_mitm = 0 ;
97+ ble_hs_cfg .sm_sc = 0 ;
10998 /* Stores the IRK */
11099 ble_hs_cfg .sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ID ;
111100 ble_hs_cfg .sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ID ;
@@ -122,7 +111,17 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
122111 } else
123112 #endif
124113 {
125- ble_svc_gap_device_name_set ("CIRCUITPY" );
114+ uint8_t mac [6 ];
115+ esp_read_mac (mac , ESP_MAC_BT );
116+ mp_int_t len = sizeof (default_ble_name ) - 1 ;
117+ default_ble_name [len - 6 ] = nibble_to_hex_lower [mac [3 ] >> 4 & 0xf ];
118+ default_ble_name [len - 5 ] = nibble_to_hex_lower [mac [3 ] & 0xf ];
119+ default_ble_name [len - 4 ] = nibble_to_hex_lower [mac [4 ] >> 4 & 0xf ];
120+ default_ble_name [len - 3 ] = nibble_to_hex_lower [mac [4 ] & 0xf ];
121+ default_ble_name [len - 2 ] = nibble_to_hex_lower [mac [5 ] >> 4 & 0xf ];
122+ default_ble_name [len - 1 ] = nibble_to_hex_lower [mac [5 ] & 0xf ];
123+ default_ble_name [len ] = '\0' ; // for now we add null for compatibility with C ASCIIZ strings
124+ ble_svc_gap_device_name_set (default_ble_name );
126125 }
127126
128127 // Clear all of the internal connection objects.
@@ -180,6 +179,14 @@ bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, bleio_addre
180179 return result == 0 ;
181180}
182181
182+ uint16_t bleio_adapter_get_name (char * buf , uint16_t len ) {
183+ const char * name = ble_svc_gap_device_name ();
184+ uint16_t full_len = strlen (name );
185+ memcpy (buf , name , MIN (full_len , len ));
186+
187+ return full_len ;
188+ }
189+
183190mp_obj_str_t * common_hal_bleio_adapter_get_name (bleio_adapter_obj_t * self ) {
184191 const char * name = ble_svc_gap_device_name ();
185192
@@ -401,7 +408,8 @@ mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_addre
401408 _connect_event , self ));
402409
403410 int error_code ;
404- CHECK_NOTIFY (xTaskNotifyWait (0 , 0 , (uint32_t * )& error_code , 200 ));
411+ // Wait an extra 50 ms to give the connect method the opportunity to time out.
412+ CHECK_NOTIFY (xTaskNotifyWait (0 , 0 , (uint32_t * )& error_code , pdMS_TO_TICKS (timeout * 1000 + 50 )));
405413 // Negative values are error codes, connection handle otherwise.
406414 if (error_code < 0 ) {
407415 CHECK_BLE_ERROR (- error_code );
@@ -487,6 +495,7 @@ static int _advertising_event(struct ble_gap_event *event, void *self_in) {
487495 #endif
488496 break ;
489497 }
498+ background_callback_add_core (& bleio_background_callback );
490499 return 0 ;
491500}
492501
@@ -499,6 +508,8 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
499508 if (ble_gap_adv_active () && !self -> user_advertising ) {
500509 return BLE_HS_EBUSY ;
501510 }
511+ // Override anonymous because it isn't working with the ESP-IDF.
512+ anonymous = false;
502513
503514 uint32_t rc ;
504515
@@ -521,12 +532,19 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
521532 bool extended = advertising_data_len > BLE_ADV_LEGACY_DATA_MAX_LEN ||
522533 scan_response_data_len > BLE_ADV_LEGACY_DATA_MAX_LEN ;
523534
535+ bool scannable = scan_response_data_len > 0 ;
536+ bool legacy_pdu = !extended && !anonymous ;
537+ if (legacy_pdu && connectable ) {
538+ // Connectable legacy advertisements are always scannable too.
539+ scannable = true;
540+ }
541+
524542 struct ble_gap_ext_adv_params adv_params = {
525543 .connectable = connectable ,
526- .scannable = scan_response_data_len > 0 ,
544+ .scannable = scannable ,
527545 .directed = directed_to != NULL ,
528546 .high_duty_directed = high_duty_directed ,
529- .legacy_pdu = ! extended ,
547+ .legacy_pdu = legacy_pdu ,
530548 .anonymous = anonymous ,
531549 .include_tx_power = extended ,
532550 .scan_req_notif = false,
@@ -712,14 +730,46 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
712730 return self -> connection_objs ;
713731}
714732
733+ #define NIMBLE_NVS_PEER_SEC_KEY "peer_sec"
734+ #define NIMBLE_NVS_OUR_SEC_KEY "our_sec"
735+ #define NIMBLE_NVS_CCCD_SEC_KEY "cccd_sec"
736+ #define NIMBLE_NVS_PEER_RECORDS_KEY "p_dev_rec"
737+ #define NIMBLE_NVS_NAMESPACE "nimble_bond"
738+
739+ // Implement bonding control ourselves when the adapter isn't enabled so that it
740+ // can run when BLE is off.
715741void common_hal_bleio_adapter_erase_bonding (bleio_adapter_obj_t * self ) {
716- ble_store_clear ();
742+ if (common_hal_bleio_adapter_get_enabled (self )) {
743+ ble_store_clear ();
744+ } else {
745+ nvs_handle_t nimble_handle ;
746+ esp_err_t err = nvs_open (NIMBLE_NVS_NAMESPACE , NVS_READWRITE , & nimble_handle );
747+ if (err != ESP_OK ) {
748+ return ;
749+ }
750+ nvs_erase_all (nimble_handle );
751+ nvs_commit (nimble_handle );
752+ nvs_close (nimble_handle );
753+ }
717754}
718755
719756bool common_hal_bleio_adapter_is_bonded_to_central (bleio_adapter_obj_t * self ) {
720- int count ;
721- ble_store_util_count (BLE_STORE_OBJ_TYPE_PEER_SEC , & count );
722- return count > 0 ;
757+ if (common_hal_bleio_adapter_get_enabled (self )) {
758+ int count ;
759+ ble_store_util_count (BLE_STORE_OBJ_TYPE_PEER_SEC , & count );
760+ return count > 0 ;
761+ }
762+ nvs_handle_t nimble_handle ;
763+ esp_err_t err = nvs_open (NIMBLE_NVS_NAMESPACE , NVS_READONLY , & nimble_handle );
764+ if (err != ESP_OK ) {
765+ return false;
766+ }
767+ err = nvs_find_key (nimble_handle , "peer_sec_1" , NULL );
768+ nvs_close (nimble_handle );
769+ if (err == ESP_OK ) {
770+ return true;
771+ }
772+ return false;
723773}
724774
725775void bleio_adapter_gc_collect (bleio_adapter_obj_t * adapter ) {
0 commit comments