4646#include "shared-bindings/_bleio/Characteristic.h"
4747#include "shared-bindings/_bleio/Service.h"
4848#include "shared-bindings/_bleio/UUID.h"
49+ #include "supervisor/shared/tick.h"
50+
51+ #include "common-hal/_bleio/bonding.h"
4952
5053#define BLE_ADV_LENGTH_FIELD_SIZE 1
5154#define BLE_ADV_AD_TYPE_FIELD_SIZE 1
5255#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1
5356
5457static const ble_gap_sec_params_t pairing_sec_params = {
55- .bond = 0 ,
58+ .bond = 1 ,
5659 .mitm = 0 ,
5760 .lesc = 0 ,
5861 .keypress = 0 ,
@@ -64,6 +67,13 @@ static const ble_gap_sec_params_t pairing_sec_params = {
6467 .kdist_peer = { .enc = 1 , .id = 1 },
6568};
6669
70+ #define CONNECTION_DEBUG (1)
71+ #if CONNECTION_DEBUG
72+ #define CONNECTION_DEBUG_PRINTF (...) printf(__VA_ARGS__)
73+ #else
74+ #define CONNECTION_DEBUG_PRINTF (...)
75+ #endif
76+
6777static volatile bool m_discovery_in_process ;
6878static volatile bool m_discovery_successful ;
6979
@@ -84,6 +94,7 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
8494
8595 switch (ble_evt -> header .evt_id ) {
8696 case BLE_GAP_EVT_DISCONNECTED :
97+ // Adapter.c does the work for this event.
8798 break ;
8899
89100 case BLE_GAP_EVT_PHY_UPDATE_REQUEST : {
@@ -137,6 +148,22 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
137148 break ;
138149 }
139150
151+ case BLE_GATTS_EVT_WRITE :
152+ // A client wrote a value.
153+ // If we are bonded and it's a CCCD (UUID 0x2902), store the CCCD value.
154+ if (self -> conn_handle != BLE_CONN_HANDLE_INVALID &&
155+ self -> pair_status == PAIR_PAIRED &&
156+ ble_evt -> evt .gatts_evt .params .write .uuid .type == BLE_UUID_TYPE_BLE &&
157+ ble_evt -> evt .gatts_evt .params .write .uuid .uuid == 0x2902 ) {
158+ //
159+ // Save sys_attr data (CCCD state) in bonding area at
160+ // next opportunity, but also remember time of this
161+ // request, so we can consolidate closely-spaced requests.
162+ self -> do_bond_cccds = true;
163+ self -> do_bond_cccds_request_time = supervisor_ticks_ms64 ();
164+ }
165+ break ;
166+
140167 case BLE_GATTS_EVT_SYS_ATTR_MISSING :
141168 sd_ble_gatts_sys_attr_set (self -> conn_handle , NULL , 0 , 0 );
142169 break ;
@@ -197,6 +224,15 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
197224 break ;
198225 }
199226 case BLE_GAP_EVT_SEC_PARAMS_REQUEST : {
227+ // First time pairing.
228+ // 1. Either we or peer initiate the process
229+ // 2. Peer asks for security parameters using BLE_GAP_EVT_SEC_PARAMS_REQUEST.
230+ // 3. Pair Key exchange ("just works" implemented now; TODO: out-of-band key pairing)
231+ // 4. Connection is secured: BLE_GAP_EVT_CONN_SEC_UPDATE
232+ // 5. Long-term Keys exchanged: BLE_GAP_EVT_AUTH_STATUS
233+
234+ bonding_clear_keys (& self -> bonding_keys );
235+ self -> ediv = EDIV_INVALID ;
200236 ble_gap_sec_keyset_t keyset = {
201237 .keys_own = {
202238 .p_enc_key = & self -> bonding_keys .own_enc ,
@@ -214,7 +250,8 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
214250 };
215251
216252 sd_ble_gap_sec_params_reply (self -> conn_handle , BLE_GAP_SEC_STATUS_SUCCESS ,
217- & pairing_sec_params , & keyset );
253+ self -> is_central ? NULL : & pairing_sec_params ,
254+ & keyset );
218255 break ;
219256 }
220257
@@ -224,13 +261,16 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
224261 break ;
225262
226263 case BLE_GAP_EVT_AUTH_STATUS : { // 0x19
227- // Pairing process completed
264+ // Key exchange completed.
228265 ble_gap_evt_auth_status_t * status = & ble_evt -> evt .gap_evt .params .auth_status ;
229266 self -> sec_status = status -> auth_status ;
230267 if (status -> auth_status == BLE_GAP_SEC_STATUS_SUCCESS ) {
231- // TODO _ediv = bonding_keys-> own_enc.master_id.ediv;
268+ self -> ediv = self -> bonding_keys . own_enc .master_id .ediv ;
232269 self -> pair_status = PAIR_PAIRED ;
270+ // Save keys in bonding area at next opportunity.
271+ self -> do_bond_keys = true;
233272 } else {
273+ // Inform busy-waiter pairing has failed.
234274 self -> pair_status = PAIR_NOT_PAIRED ;
235275 }
236276 break ;
@@ -242,17 +282,22 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
242282 // - Else return NULL --> Initiate key exchange
243283 ble_gap_evt_sec_info_request_t * sec_info_request = & ble_evt -> evt .gap_evt .params .sec_info_request ;
244284 (void ) sec_info_request ;
245- //if ( bond_load_keys(_role, sec_req->master_id.ediv, &bkeys) ) {
246- //sd_ble_gap_sec_info_reply(_conn_hdl, &bkeys.own_enc.enc_info, &bkeys.peer_id.id_info, NULL);
247- //
248- //_ediv = bkeys.own_enc.master_id.ediv;
249- // } else {
285+ if ( bonding_load_keys (self -> is_central , sec_info_request -> master_id .ediv , & self -> bonding_keys ) ) {
286+ sd_ble_gap_sec_info_reply (
287+ self -> conn_handle ,
288+ & self -> bonding_keys .own_enc .enc_info ,
289+ & self -> bonding_keys .peer_id .id_info ,
290+ NULL );
291+ self -> ediv = self -> bonding_keys .own_enc .master_id .ediv ;
292+ } else {
293+ // We don't have stored keys. Ask for keys.
250294 sd_ble_gap_sec_info_reply (self -> conn_handle , NULL , NULL , NULL );
251- // }
252- break ;
295+ }
296+ break ;
253297 }
254298
255299 case BLE_GAP_EVT_CONN_SEC_UPDATE : { // 0x1a
300+ // We get this both on first-time pairing and on subsequent pairings using stored keys.
256301 ble_gap_conn_sec_t * conn_sec = & ble_evt -> evt .gap_evt .params .conn_sec_update .conn_sec ;
257302 if (conn_sec -> sec_mode .sm <= 1 && conn_sec -> sec_mode .lv <= 1 ) {
258303 // Security setup did not succeed:
@@ -261,18 +306,17 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
261306 // mode >=1 and/or level >=1 means encryption is set up
262307 self -> pair_status = PAIR_NOT_PAIRED ;
263308 } else {
264- //if ( !bond_load_cccd(_role, _conn_hdl, _ediv) ) {
265- if (true) { // TODO: no bonding yet
266- // Initialize system attributes fresh.
309+ if (bonding_load_cccd_info (self -> is_central , self -> conn_handle , self -> ediv )) {
310+ // Did an sd_ble_gatts_sys_attr_set() with the stored sys_attr values.
311+ } else {
312+ // No matching bonding found, so use fresh system attributes.
267313 sd_ble_gatts_sys_attr_set (self -> conn_handle , NULL , 0 , 0 );
268314 }
269- // Not quite paired yet: wait for BLE_GAP_EVT_AUTH_STATUS SUCCESS.
270- self -> ediv = self -> bonding_keys .own_enc .master_id .ediv ;
315+ self -> pair_status = PAIR_PAIRED ;
271316 }
272317 break ;
273318 }
274319
275-
276320 default :
277321 return false;
278322 }
@@ -284,8 +328,7 @@ void bleio_connection_clear(bleio_connection_internal_t *self) {
284328
285329 self -> conn_handle = BLE_CONN_HANDLE_INVALID ;
286330 self -> pair_status = PAIR_NOT_PAIRED ;
287-
288- memset (& self -> bonding_keys , 0 , sizeof (self -> bonding_keys ));
331+ bonding_clear_keys (& self -> bonding_keys );
289332}
290333
291334bool common_hal_bleio_connection_get_paired (bleio_connection_obj_t * self ) {
@@ -565,8 +608,7 @@ STATIC bool discovery_on_ble_evt(ble_evt_t *ble_evt, mp_obj_t payload) {
565608 break ;
566609
567610 default :
568- // For debugging.
569- // mp_printf(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id);
611+ // CONNECTION_DEBUG_PRINTF(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id);
570612 return false;
571613 break ;
572614 }
0 commit comments