@@ -67,7 +67,7 @@ STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) {
67
67
reset_into_safe_mode (NORDIC_SOFT_DEVICE_ASSERT );
68
68
}
69
69
70
- bleio_connection_internal_t connections [BLEIO_TOTAL_CONNECTION_COUNT ];
70
+ bleio_connection_internal_t bleio_connections [BLEIO_TOTAL_CONNECTION_COUNT ];
71
71
72
72
// Linker script provided ram start.
73
73
extern uint32_t _ram_start ;
@@ -133,6 +133,15 @@ STATIC uint32_t ble_stack_enable(void) {
133
133
return err_code ;
134
134
}
135
135
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
+
136
145
// Triple the GATT Server attribute size to accomodate both the CircuitPython built-in service
137
146
// and anything the user does.
138
147
memset (& ble_conf , 0 , sizeof (ble_conf ));
@@ -142,14 +151,29 @@ STATIC uint32_t ble_stack_enable(void) {
142
151
return err_code ;
143
152
}
144
153
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
+ }
146
162
147
163
// This sets app_ram_start to the minimum value needed for the settings set above.
148
164
err_code = sd_ble_enable (& app_ram_start );
149
165
if (err_code != NRF_SUCCESS ) {
150
166
return err_code ;
151
167
}
152
168
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
+
153
177
ble_gap_conn_params_t gap_conn_params = {
154
178
.min_conn_interval = BLE_MIN_CONN_INTERVAL ,
155
179
.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) {
177
201
// total connection limit.
178
202
bleio_connection_internal_t * connection ;
179
203
for (size_t i = 0 ; i < BLEIO_TOTAL_CONNECTION_COUNT ; i ++ ) {
180
- connection = & connections [i ];
204
+ connection = & bleio_connections [i ];
181
205
if (connection -> conn_handle == BLE_CONN_HANDLE_INVALID ) {
182
206
break ;
183
207
}
@@ -189,6 +213,7 @@ STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
189
213
connection -> conn_handle = ble_evt -> evt .gap_evt .conn_handle ;
190
214
connection -> connection_obj = mp_const_none ;
191
215
connection -> pair_status = PAIR_NOT_PAIRED ;
216
+ connection -> mtu = 0 ;
192
217
193
218
ble_drv_add_event_handler_entry (& connection -> handler_entry , connection_on_ble_evt , connection );
194
219
self -> connection_objs = NULL ;
@@ -216,7 +241,7 @@ STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
216
241
// Find the connection that was disconnected.
217
242
bleio_connection_internal_t * connection ;
218
243
for (size_t i = 0 ; i < BLEIO_TOTAL_CONNECTION_COUNT ; i ++ ) {
219
- connection = & connections [i ];
244
+ connection = & bleio_connections [i ];
220
245
if (connection -> conn_handle == ble_evt -> evt .gap_evt .conn_handle ) {
221
246
break ;
222
247
}
@@ -293,7 +318,7 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
293
318
// Add a handler for incoming peripheral connections.
294
319
if (enabled ) {
295
320
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 ];
297
322
connection -> conn_handle = BLE_CONN_HANDLE_INVALID ;
298
323
}
299
324
bleio_adapter_reset_name (self );
@@ -497,14 +522,25 @@ mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_addre
497
522
498
523
ble_drv_remove_event_handler (connect_on_ble_evt , & event_info );
499
524
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 ) {
501
527
mp_raise_bleio_BluetoothError (translate ("Failed to connect: timeout" ));
502
528
}
503
529
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
+
504
540
// Make the connection object and return it.
505
541
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 ) {
508
544
return bleio_connection_new_from_internal (connection );
509
545
}
510
546
}
@@ -628,7 +664,7 @@ void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) {
628
664
629
665
bool common_hal_bleio_adapter_get_connected (bleio_adapter_obj_t * self ) {
630
666
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 ];
632
668
if (connection -> conn_handle != BLE_CONN_HANDLE_INVALID ) {
633
669
return true;
634
670
}
@@ -643,7 +679,7 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
643
679
size_t total_connected = 0 ;
644
680
mp_obj_t items [BLEIO_TOTAL_CONNECTION_COUNT ];
645
681
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 ];
647
683
if (connection -> conn_handle != BLE_CONN_HANDLE_INVALID ) {
648
684
if (connection -> connection_obj == mp_const_none ) {
649
685
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) {
658
694
659
695
void bleio_adapter_gc_collect (bleio_adapter_obj_t * adapter ) {
660
696
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 ));
662
698
}
663
699
664
700
void bleio_adapter_reset (bleio_adapter_obj_t * adapter ) {
665
701
common_hal_bleio_adapter_stop_scan (adapter );
666
702
common_hal_bleio_adapter_stop_advertising (adapter );
667
703
adapter -> connection_objs = NULL ;
668
704
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 ];
670
706
connection -> connection_obj = mp_const_none ;
671
707
}
672
708
}
0 commit comments