@@ -70,8 +70,6 @@ static volatile bool m_discovery_successful;
7070static bleio_service_obj_t * m_char_discovery_service ;
7171static bleio_characteristic_obj_t * m_desc_discovery_characteristic ;
7272
73- bool dump_events = false;
74-
7573bool connection_on_ble_evt (ble_evt_t * ble_evt , void * self_in ) {
7674 bleio_connection_internal_t * self = (bleio_connection_internal_t * )self_in ;
7775
@@ -84,16 +82,9 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
8482 return false;
8583 }
8684
87- // For debugging.
88- if (dump_events ) {
89- mp_printf (& mp_plat_print , "Connection event: 0x%04x\n" , ble_evt -> header .evt_id );
90- }
91-
9285 switch (ble_evt -> header .evt_id ) {
9386 case BLE_GAP_EVT_DISCONNECTED :
9487 break ;
95- case BLE_GAP_EVT_CONN_PARAM_UPDATE : // 0x12
96- break ;
9788 case BLE_GAP_EVT_PHY_UPDATE_REQUEST : {
9889 ble_gap_phys_t const phys = {
9990 .rx_phys = BLE_GAP_PHY_AUTO ,
@@ -124,15 +115,61 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
124115 sd_ble_gatts_sys_attr_set (self -> conn_handle , NULL , 0 , 0 );
125116 break ;
126117
127- case BLE_GATTS_EVT_HVN_TX_COMPLETE : // Capture this for now. 0x55
118+ #if CIRCUITPY_VERBOSE_BLE
119+ // Use read authorization to snoop on all reads when doing verbose debugging.
120+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST : {
121+
122+ ble_gatts_evt_rw_authorize_request_t * request =
123+ & ble_evt -> evt .gatts_evt .params .authorize_request ;
124+
125+ mp_printf (& mp_plat_print , "Read %x offset %d " , request -> request .read .handle , request -> request .read .offset );
126+ uint8_t value_bytes [22 ];
127+ ble_gatts_value_t value ;
128+ value .offset = request -> request .read .offset ;
129+ value .len = 22 ;
130+ value .p_value = value_bytes ;
131+
132+ sd_ble_gatts_value_get (self -> conn_handle , request -> request .read .handle , & value );
133+ size_t len = value .len ;
134+ if (len > 22 ) {
135+ len = 22 ;
136+ }
137+ for (uint8_t i = 0 ; i < len ; i ++ ) {
138+ mp_printf (& mp_plat_print , " %02x" , value_bytes [i ]);
139+ }
140+ mp_printf (& mp_plat_print , "\n" );
141+ ble_gatts_rw_authorize_reply_params_t reply ;
142+ reply .type = request -> type ;
143+ reply .params .read .gatt_status = BLE_GATT_STATUS_SUCCESS ;
144+ reply .params .read .update = false;
145+ reply .params .read .offset = request -> request .read .offset ;
146+ sd_ble_gatts_rw_authorize_reply (self -> conn_handle , & reply );
128147 break ;
148+ }
149+ #endif
129150
151+ case BLE_GATTS_EVT_HVN_TX_COMPLETE : // Capture this for now. 0x55
152+ break ;
130153 case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST : {
154+ self -> conn_params_updating = true;
131155 ble_gap_evt_conn_param_update_request_t * request =
132156 & ble_evt -> evt .gap_evt .params .conn_param_update_request ;
133157 sd_ble_gap_conn_param_update (self -> conn_handle , & request -> conn_params );
134158 break ;
135159 }
160+ case BLE_GAP_EVT_CONN_PARAM_UPDATE : { // 0x12
161+ ble_gap_evt_conn_param_update_t * result =
162+ & ble_evt -> evt .gap_evt .params .conn_param_update ;
163+
164+ #if CIRCUITPY_VERBOSE_BLE
165+ ble_gap_conn_params_t * cp = & ble_evt -> evt .gap_evt .params .conn_param_update .conn_params ;
166+ mp_printf (& mp_plat_print , "conn params updated: min_ci %d max_ci %d s_l %d sup_timeout %d\n" , cp -> min_conn_interval , cp -> max_conn_interval , cp -> slave_latency , cp -> conn_sup_timeout );
167+ #endif
168+
169+ memcpy (& self -> conn_params , & result -> conn_params , sizeof (ble_gap_conn_params_t ));
170+ self -> conn_params_updating = false;
171+ break ;
172+ }
136173 case BLE_GAP_EVT_SEC_PARAMS_REQUEST : {
137174 ble_gap_sec_keyset_t keyset = {
138175 .keys_own = {
@@ -212,9 +249,9 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
212249
213250 default :
214251 // For debugging.
215- if ( dump_events ) {
252+ # if CIRCUITPY_VERBOSE_BLE
216253 mp_printf (& mp_plat_print , "Unhandled connection event: 0x%04x\n" , ble_evt -> header .evt_id );
217- }
254+ #endif
218255
219256 return false;
220257 }
@@ -262,6 +299,25 @@ void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bo
262299 check_sec_status (self -> sec_status );
263300}
264301
302+ mp_float_t common_hal_bleio_connection_get_connection_interval (bleio_connection_internal_t * self ) {
303+ while (self -> conn_params_updating && !mp_hal_is_interrupted ()) {
304+ RUN_BACKGROUND_TASKS ;
305+ }
306+ return 1.25f * self -> conn_params .min_conn_interval ;
307+ }
308+
309+ void common_hal_bleio_connection_set_connection_interval (bleio_connection_internal_t * self , mp_float_t new_interval ) {
310+ self -> conn_params_updating = true;
311+ uint16_t interval = new_interval / 1.25f ;
312+ self -> conn_params .min_conn_interval = interval ;
313+ self -> conn_params .max_conn_interval = interval ;
314+ uint32_t status = NRF_ERROR_BUSY ;
315+ while (status == NRF_ERROR_BUSY ) {
316+ status = sd_ble_gap_conn_param_update (self -> conn_handle , & self -> conn_params );
317+ RUN_BACKGROUND_TASKS ;
318+ }
319+ check_nrf_error (status );
320+ }
265321
266322// service_uuid may be NULL, to discover all services.
267323STATIC bool discover_next_services (bleio_connection_internal_t * connection , uint16_t start_handle , ble_uuid_t * service_uuid ) {
@@ -600,6 +656,7 @@ STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t
600656 ble_drv_remove_event_handler (discovery_on_ble_evt , self );
601657
602658}
659+
603660mp_obj_tuple_t * common_hal_bleio_connection_discover_remote_services (bleio_connection_obj_t * self , mp_obj_t service_uuids_whitelist ) {
604661 discover_remote_services (self -> connection , service_uuids_whitelist );
605662 // Convert to a tuple and then clear the list so the callee will take ownership.
@@ -609,7 +666,6 @@ mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_conne
609666 return services_tuple ;
610667}
611668
612-
613669uint16_t bleio_connection_get_conn_handle (bleio_connection_obj_t * self ) {
614670 if (self == NULL || self -> connection == NULL ) {
615671 return BLE_CONN_HANDLE_INVALID ;
0 commit comments