4343#include "shared-bindings/_bleio/__init__.h"
4444#include "shared-bindings/_bleio/Adapter.h"
4545#include "shared-bindings/_bleio/Address.h"
46+ #include "shared-bindings/_bleio/Characteristic.h"
47+ #include "shared-bindings/_bleio/Service.h"
4648#include "shared-bindings/nvm/ByteArray.h"
4749#include "shared-bindings/_bleio/Connection.h"
4850#include "shared-bindings/_bleio/ScanEntry.h"
7072
7173bleio_connection_internal_t bleio_connections [BLEIO_TOTAL_CONNECTION_COUNT ];
7274
75+ STATIC void check_enabled (bleio_adapter_obj_t * adapter ) {
76+ if (!common_hal_bleio_adapter_get_enabled (adapter )) {
77+ mp_raise_bleio_BluetoothError (translate ("Adapter not enabled" ));
78+ }
79+ }
80+
7381// STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
7482// bleio_adapter_obj_t *self = (bleio_adapter_obj_t*)self_in;
7583
@@ -232,6 +240,14 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
232240
233241 self -> enabled = enabled ;
234242
243+ // We must poll for input from the HCI adapter.
244+ // TODO Can we instead trigger an interrupt on UART input traffic?
245+ if (enabled ) {
246+ supervisor_enable_tick ();
247+ } else {
248+ supervisor_disable_tick ();
249+ }
250+
235251 // Stop any current activity; reset to known state.
236252 check_hci_error (hci_reset ());
237253 self -> now_advertising = false;
@@ -253,6 +269,8 @@ bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self) {
253269}
254270
255271bleio_address_obj_t * common_hal_bleio_adapter_get_address (bleio_adapter_obj_t * self ) {
272+ check_enabled (self );
273+
256274 bt_addr_t addr ;
257275 check_hci_error (hci_read_bd_addr (& addr ));
258276
@@ -306,6 +324,8 @@ void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char* na
306324// }
307325
308326mp_obj_t common_hal_bleio_adapter_start_scan (bleio_adapter_obj_t * self , uint8_t * prefixes , size_t prefix_length , bool extended , mp_int_t buffer_size , mp_float_t timeout , mp_float_t interval , mp_float_t window , mp_int_t minimum_rssi , bool active ) {
327+ check_enabled (self );
328+
309329 if (self -> scan_results != NULL ) {
310330 if (!shared_module_bleio_scanresults_get_done (self -> scan_results )) {
311331 mp_raise_bleio_BluetoothError (translate ("Scan already in progess. Stop with stop_scan." ));
@@ -350,6 +370,8 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t*
350370}
351371
352372void common_hal_bleio_adapter_stop_scan (bleio_adapter_obj_t * self ) {
373+ check_enabled (self );
374+
353375 check_hci_error (hci_le_set_scan_enable (BT_HCI_LE_SCAN_DISABLE , BT_HCI_LE_SCAN_FILTER_DUP_DISABLE ));
354376 shared_module_bleio_scanresults_set_done (self -> scan_results , true);
355377 self -> scan_results = NULL ;
@@ -385,6 +407,8 @@ void common_hal_bleio_adapter_stop_scan(bleio_adapter_obj_t *self) {
385407
386408mp_obj_t common_hal_bleio_adapter_connect (bleio_adapter_obj_t * self , bleio_address_obj_t * address , mp_float_t timeout ) {
387409
410+ check_enabled (self );
411+
388412 // ble_gap_addr_t addr;
389413
390414 // addr.addr_type = address->type;
@@ -482,6 +506,8 @@ STATIC void check_data_fit(size_t data_len, bool connectable) {
482506// }
483507
484508uint32_t _common_hal_bleio_adapter_start_advertising (bleio_adapter_obj_t * self , bool connectable , bool anonymous , uint32_t timeout , float interval , uint8_t * advertising_data , uint16_t advertising_data_len , uint8_t * scan_response_data , uint16_t scan_response_data_len ) {
509+ check_enabled (self );
510+
485511 if (self -> now_advertising ) {
486512 if (self -> circuitpython_advertising ) {
487513 common_hal_bleio_adapter_stop_advertising (self );
@@ -603,6 +629,8 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
603629}
604630
605631void common_hal_bleio_adapter_start_advertising (bleio_adapter_obj_t * self , bool connectable , bool anonymous , uint32_t timeout , mp_float_t interval , mp_buffer_info_t * advertising_data_bufinfo , mp_buffer_info_t * scan_response_data_bufinfo ) {
632+ check_enabled (self );
633+
606634 // interval value has already been validated.
607635
608636 check_data_fit (advertising_data_bufinfo -> len , connectable );
@@ -638,6 +666,8 @@ void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool
638666}
639667
640668void common_hal_bleio_adapter_stop_advertising (bleio_adapter_obj_t * self ) {
669+ check_enabled (self );
670+
641671 self -> now_advertising = false;
642672 self -> extended_advertising = false;
643673 self -> circuitpython_advertising = false;
@@ -651,10 +681,14 @@ void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) {
651681}
652682
653683bool common_hal_bleio_adapter_get_advertising (bleio_adapter_obj_t * self ) {
684+ check_enabled (self );
685+
654686 return self -> now_advertising ;
655687}
656688
657689bool common_hal_bleio_adapter_get_connected (bleio_adapter_obj_t * self ) {
690+ check_enabled (self );
691+
658692 for (size_t i = 0 ; i < BLEIO_TOTAL_CONNECTION_COUNT ; i ++ ) {
659693 bleio_connection_internal_t * connection = & bleio_connections [i ];
660694 if (connection -> conn_handle != BLE_CONN_HANDLE_INVALID ) {
@@ -665,6 +699,8 @@ bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self) {
665699}
666700
667701mp_obj_t common_hal_bleio_adapter_get_connections (bleio_adapter_obj_t * self ) {
702+ check_enabled (self );
703+
668704 if (self -> connection_objs != NULL ) {
669705 return self -> connection_objs ;
670706 }
@@ -685,24 +721,40 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
685721}
686722
687723void common_hal_bleio_adapter_erase_bonding (bleio_adapter_obj_t * self ) {
724+ check_enabled (self );
725+
688726 //FIX bonding_erase_storage();
689727}
690728
691729uint16_t bleio_adapter_add_attribute (bleio_adapter_obj_t * adapter , mp_obj_t * attribute ) {
730+ check_enabled (adapter );
731+
692732 // The handle is the index of this attribute in the attributes list.
693733 uint16_t handle = (uint16_t ) adapter -> attributes -> len ;
694734 mp_obj_list_append (adapter -> attributes , attribute );
735+
736+ if (MP_OBJ_IS_TYPE (attribute , & bleio_service_type )) {
737+ adapter -> last_added_service_handle = handle ;
738+ }
739+ if (MP_OBJ_IS_TYPE (attribute , & bleio_characteristic_type )) {
740+ adapter -> last_added_characteristic_handle = handle ;
741+ }
742+
695743 return handle ;
696744}
697745
698746mp_obj_t * bleio_adapter_get_attribute (bleio_adapter_obj_t * adapter , uint16_t handle ) {
747+ check_enabled (adapter );
748+
699749 if (handle == 0 || handle >= adapter -> attributes -> len ) {
700750 return mp_const_none ;
701751 }
702752 return adapter -> attributes -> items [handle ];
703753}
704754
705755uint16_t bleio_adapter_max_attribute_handle (bleio_adapter_obj_t * adapter ) {
756+ check_enabled (adapter );
757+
706758 return adapter -> attributes -> len - 1 ;
707759}
708760
@@ -713,6 +765,10 @@ void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter) {
713765}
714766
715767void bleio_adapter_reset (bleio_adapter_obj_t * adapter ) {
768+ if (!common_hal_bleio_adapter_get_enabled (adapter )) {
769+ return ;
770+ }
771+
716772 common_hal_bleio_adapter_stop_scan (adapter );
717773 if (adapter -> now_advertising ) {
718774 common_hal_bleio_adapter_stop_advertising (adapter );
@@ -731,6 +787,10 @@ void bleio_adapter_reset(bleio_adapter_obj_t* adapter) {
731787}
732788
733789void bleio_adapter_background (bleio_adapter_obj_t * adapter ) {
790+ if (!common_hal_bleio_adapter_get_enabled (adapter )) {
791+ return ;
792+ }
793+
734794 if (adapter -> advertising_timeout_msecs > 0 &&
735795 supervisor_ticks_ms64 () - adapter -> advertising_start_ticks > adapter -> advertising_timeout_msecs ) {
736796 adapter -> advertising_timeout_msecs = 0 ;
0 commit comments