@@ -67,7 +67,7 @@ STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) {
6767 reset_into_safe_mode (NORDIC_SOFT_DEVICE_ASSERT );
6868}
6969
70- bleio_connection_internal_t connections [BLEIO_TOTAL_CONNECTION_COUNT ];
70+ bleio_connection_internal_t bleio_connections [BLEIO_TOTAL_CONNECTION_COUNT ];
7171
7272// Linker script provided ram start.
7373extern uint32_t _ram_start ;
@@ -133,6 +133,15 @@ STATIC uint32_t ble_stack_enable(void) {
133133 return err_code ;
134134 }
135135
136+ // Set ATT_MTU so that the maximum MTU we can negotiate is up to the full characteristic size.
137+ memset (& ble_conf , 0 , sizeof (ble_conf ));
138+ ble_conf .conn_cfg .conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM ;
139+ ble_conf .conn_cfg .params .gatt_conn_cfg .att_mtu = BLE_GATTS_VAR_ATTR_LEN_MAX ;
140+ err_code = sd_ble_cfg_set (BLE_CONN_CFG_GATT , & ble_conf , app_ram_start );
141+ if (err_code != NRF_SUCCESS ) {
142+ return err_code ;
143+ }
144+
136145 // Triple the GATT Server attribute size to accomodate both the CircuitPython built-in service
137146 // and anything the user does.
138147 memset (& ble_conf , 0 , sizeof (ble_conf ));
@@ -142,14 +151,29 @@ STATIC uint32_t ble_stack_enable(void) {
142151 return err_code ;
143152 }
144153
145- // TODO set ATT_MTU so that the maximum MTU we can negotiate is higher than the default.
154+ // Increase the number of vendor UUIDs supported. Apple uses a complete random number per
155+ // service and characteristic.
156+ memset (& ble_conf , 0 , sizeof (ble_conf ));
157+ ble_conf .common_cfg .vs_uuid_cfg .vs_uuid_count = 32 ; // Defaults to 10.
158+ err_code = sd_ble_cfg_set (BLE_COMMON_CFG_VS_UUID , & ble_conf , app_ram_start );
159+ if (err_code != NRF_SUCCESS ) {
160+ return err_code ;
161+ }
146162
147163 // This sets app_ram_start to the minimum value needed for the settings set above.
148164 err_code = sd_ble_enable (& app_ram_start );
149165 if (err_code != NRF_SUCCESS ) {
150166 return err_code ;
151167 }
152168
169+ // Turn on connection event extension so we can transmit for a longer period of time as needed.
170+ ble_opt_t opt ;
171+ opt .common_opt .conn_evt_ext .enable = true;
172+ err_code = sd_ble_opt_set (BLE_COMMON_OPT_CONN_EVT_EXT , & opt );
173+ if (err_code != NRF_SUCCESS ) {
174+ return err_code ;
175+ }
176+
153177 ble_gap_conn_params_t gap_conn_params = {
154178 .min_conn_interval = BLE_MIN_CONN_INTERVAL ,
155179 .max_conn_interval = BLE_MAX_CONN_INTERVAL ,
@@ -177,7 +201,7 @@ STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
177201 // total connection limit.
178202 bleio_connection_internal_t * connection ;
179203 for (size_t i = 0 ; i < BLEIO_TOTAL_CONNECTION_COUNT ; i ++ ) {
180- connection = & connections [i ];
204+ connection = & bleio_connections [i ];
181205 if (connection -> conn_handle == BLE_CONN_HANDLE_INVALID ) {
182206 break ;
183207 }
@@ -189,6 +213,7 @@ STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
189213 connection -> conn_handle = ble_evt -> evt .gap_evt .conn_handle ;
190214 connection -> connection_obj = mp_const_none ;
191215 connection -> pair_status = PAIR_NOT_PAIRED ;
216+ connection -> mtu = 0 ;
192217
193218 ble_drv_add_event_handler_entry (& connection -> handler_entry , connection_on_ble_evt , connection );
194219 self -> connection_objs = NULL ;
@@ -216,7 +241,7 @@ STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
216241 // Find the connection that was disconnected.
217242 bleio_connection_internal_t * connection ;
218243 for (size_t i = 0 ; i < BLEIO_TOTAL_CONNECTION_COUNT ; i ++ ) {
219- connection = & connections [i ];
244+ connection = & bleio_connections [i ];
220245 if (connection -> conn_handle == ble_evt -> evt .gap_evt .conn_handle ) {
221246 break ;
222247 }
@@ -293,7 +318,7 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
293318 // Add a handler for incoming peripheral connections.
294319 if (enabled ) {
295320 for (size_t i = 0 ; i < BLEIO_TOTAL_CONNECTION_COUNT ; i ++ ) {
296- bleio_connection_internal_t * connection = & connections [i ];
321+ bleio_connection_internal_t * connection = & bleio_connections [i ];
297322 connection -> conn_handle = BLE_CONN_HANDLE_INVALID ;
298323 }
299324 bleio_adapter_reset_name (self );
@@ -497,14 +522,25 @@ mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_addre
497522
498523 ble_drv_remove_event_handler (connect_on_ble_evt , & event_info );
499524
500- if (event_info .conn_handle == BLE_CONN_HANDLE_INVALID ) {
525+ uint16_t conn_handle = event_info .conn_handle ;
526+ if (conn_handle == BLE_CONN_HANDLE_INVALID ) {
501527 mp_raise_bleio_BluetoothError (translate ("Failed to connect: timeout" ));
502528 }
503529
530+ // Negotiate for better PHY, larger MTU and data lengths since we are the central. These are
531+ // nice-to-haves so ignore any errors.
532+ ble_gap_phys_t const phys = {
533+ .rx_phys = BLE_GAP_PHY_AUTO ,
534+ .tx_phys = BLE_GAP_PHY_AUTO ,
535+ };
536+ sd_ble_gap_phy_update (conn_handle , & phys );
537+ sd_ble_gattc_exchange_mtu_request (conn_handle , BLE_GATTS_VAR_ATTR_LEN_MAX );
538+ sd_ble_gap_data_length_update (conn_handle , NULL , NULL );
539+
504540 // Make the connection object and return it.
505541 for (size_t i = 0 ; i < BLEIO_TOTAL_CONNECTION_COUNT ; i ++ ) {
506- bleio_connection_internal_t * connection = & connections [i ];
507- if (connection -> conn_handle == event_info . conn_handle ) {
542+ bleio_connection_internal_t * connection = & bleio_connections [i ];
543+ if (connection -> conn_handle == conn_handle ) {
508544 return bleio_connection_new_from_internal (connection );
509545 }
510546 }
@@ -628,7 +664,7 @@ void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) {
628664
629665bool common_hal_bleio_adapter_get_connected (bleio_adapter_obj_t * self ) {
630666 for (size_t i = 0 ; i < BLEIO_TOTAL_CONNECTION_COUNT ; i ++ ) {
631- bleio_connection_internal_t * connection = & connections [i ];
667+ bleio_connection_internal_t * connection = & bleio_connections [i ];
632668 if (connection -> conn_handle != BLE_CONN_HANDLE_INVALID ) {
633669 return true;
634670 }
@@ -643,7 +679,7 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
643679 size_t total_connected = 0 ;
644680 mp_obj_t items [BLEIO_TOTAL_CONNECTION_COUNT ];
645681 for (size_t i = 0 ; i < BLEIO_TOTAL_CONNECTION_COUNT ; i ++ ) {
646- bleio_connection_internal_t * connection = & connections [i ];
682+ bleio_connection_internal_t * connection = & bleio_connections [i ];
647683 if (connection -> conn_handle != BLE_CONN_HANDLE_INVALID ) {
648684 if (connection -> connection_obj == mp_const_none ) {
649685 connection -> connection_obj = bleio_connection_new_from_internal (connection );
@@ -658,15 +694,15 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
658694
659695void bleio_adapter_gc_collect (bleio_adapter_obj_t * adapter ) {
660696 gc_collect_root ((void * * )adapter , sizeof (bleio_adapter_obj_t ) / sizeof (size_t ));
661- gc_collect_root ((void * * )connections , sizeof (connections ) / sizeof (size_t ));
697+ gc_collect_root ((void * * )bleio_connections , sizeof (bleio_connections ) / sizeof (size_t ));
662698}
663699
664700void bleio_adapter_reset (bleio_adapter_obj_t * adapter ) {
665701 common_hal_bleio_adapter_stop_scan (adapter );
666702 common_hal_bleio_adapter_stop_advertising (adapter );
667703 adapter -> connection_objs = NULL ;
668704 for (size_t i = 0 ; i < BLEIO_TOTAL_CONNECTION_COUNT ; i ++ ) {
669- bleio_connection_internal_t * connection = & connections [i ];
705+ bleio_connection_internal_t * connection = & bleio_connections [i ];
670706 connection -> connection_obj = mp_const_none ;
671707 }
672708}
0 commit comments