@@ -53,7 +53,19 @@ BLEGap::BLEGap(void)
53
53
_cfg_central.wr_cmd_qsize = BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT;
54
54
#endif
55
55
56
-
56
+ _sec_param = (ble_gap_sec_params_t )
57
+ {
58
+ .bond = 1 ,
59
+ .mitm = 0 ,
60
+ .lesc = 0 ,
61
+ .keypress = 0 ,
62
+ .io_caps = BLE_GAP_IO_CAPS_NONE,
63
+ .oob = 0 ,
64
+ .min_key_size = 7 ,
65
+ .max_key_size = 16 ,
66
+ .kdist_own = { .enc = 1 , .id = 1 },
67
+ .kdist_peer = { .enc = 1 , .id = 1 },
68
+ };
57
69
}
58
70
59
71
@@ -83,19 +95,19 @@ uint16_t BLEGap::getMaxMtuByConnCfg(uint8_t conn_cfg)
83
95
return (conn_cfg == CONN_CFG_PERIPHERAL) ? _cfg_prph.mtu_max : _cfg_central.mtu_max ;
84
96
}
85
97
86
- uint16_t BLEGap::getMaxMtu (uint8_t conn_handle )
98
+ uint16_t BLEGap::getMaxMtu (uint8_t conn_hdl )
87
99
{
88
- return (getRole (conn_handle ) == BLE_GAP_ROLE_PERIPH) ? _cfg_prph.mtu_max : _cfg_central.mtu_max ;
100
+ return (getRole (conn_hdl ) == BLE_GAP_ROLE_PERIPH) ? _cfg_prph.mtu_max : _cfg_central.mtu_max ;
89
101
}
90
102
91
- uint8_t BLEGap::getHvnQueueSize (uint8_t conn_handle )
103
+ uint8_t BLEGap::getHvnQueueSize (uint8_t conn_hdl )
92
104
{
93
- return (getRole (conn_handle ) == BLE_GAP_ROLE_PERIPH) ? _cfg_prph.hvn_tx_qsize : _cfg_central.hvn_tx_qsize ;
105
+ return (getRole (conn_hdl ) == BLE_GAP_ROLE_PERIPH) ? _cfg_prph.hvn_tx_qsize : _cfg_central.hvn_tx_qsize ;
94
106
}
95
107
96
- uint8_t BLEGap::getWriteCmdQueueSize (uint8_t conn_handle )
108
+ uint8_t BLEGap::getWriteCmdQueueSize (uint8_t conn_hdl )
97
109
{
98
- return (getRole (conn_handle ) == BLE_GAP_ROLE_PERIPH) ? _cfg_prph.wr_cmd_qsize : _cfg_central.wr_cmd_qsize ;
110
+ return (getRole (conn_hdl ) == BLE_GAP_ROLE_PERIPH) ? _cfg_prph.wr_cmd_qsize : _cfg_central.wr_cmd_qsize ;
99
111
}
100
112
101
113
@@ -142,52 +154,76 @@ bool BLEGap::setAddr(uint8_t mac[6], uint8_t type)
142
154
return true ;
143
155
}
144
156
145
- bool BLEGap::connected (uint16_t conn_handle )
157
+ bool BLEGap::connected (uint16_t conn_hdl )
146
158
{
147
- return _peers[conn_handle ].connected ;
159
+ return _peers[conn_hdl ].connected ;
148
160
}
149
161
150
- uint8_t BLEGap::getRole (uint16_t conn_handle )
162
+ bool BLEGap::bonded (uint16_t conn_hdl )
151
163
{
152
- return _peers[conn_handle]. role ;
164
+ return _peers[conn_hdl]. bonded ;
153
165
}
154
166
155
- uint8_t BLEGap::getPeerAddr (uint16_t conn_handle, uint8_t addr[ 6 ] )
167
+ bool BLEGap::requestPairing (uint16_t conn_hdl )
156
168
{
157
- memcpy (addr, _peers[conn_handle].addr .addr , BLE_GAP_ADDR_LEN);
158
- return _peers[conn_handle].addr .addr_type ;
169
+ gap_peer_t * peer = &_peers[conn_hdl];
170
+
171
+ // skip if already bonded
172
+ if ( peer->bonded ) return true ;
173
+
174
+ VERIFY_STATUS ( sd_ble_gap_authenticate (conn_hdl, &_sec_param ), false );
175
+ uint32_t start = millis ();
176
+
177
+ // timeout in 30 seconds
178
+ while ( ! ((volatile bool ) peer->bonded ) && (start + 30000 > millis ()) )
179
+ {
180
+ yield ();
181
+ }
182
+
183
+ return peer->bonded ;
159
184
}
160
185
161
- ble_gap_addr_t BLEGap::getPeerAddr (uint16_t conn_handle )
186
+ uint8_t BLEGap::getRole (uint16_t conn_hdl )
162
187
{
163
- return _peers[conn_handle]. addr ;
188
+ return _peers[conn_hdl]. role ;
164
189
}
165
190
166
- bool BLEGap::getHvnPacket (uint16_t conn_handle )
191
+ uint8_t BLEGap::getPeerAddr (uint16_t conn_hdl, uint8_t addr[ 6 ] )
167
192
{
168
- VERIFY ( (conn_handle < BLE_MAX_CONN) && (_peers[conn_handle].hvn_tx_sem != NULL ) );
193
+ memcpy (addr, _peers[conn_hdl].addr .addr , BLE_GAP_ADDR_LEN);
194
+ return _peers[conn_hdl].addr .addr_type ;
195
+ }
169
196
170
- return xSemaphoreTake (_peers[conn_handle].hvn_tx_sem , ms2tick (BLE_GENERIC_TIMEOUT));
197
+ ble_gap_addr_t BLEGap::getPeerAddr (uint16_t conn_hdl)
198
+ {
199
+ return _peers[conn_hdl].addr ;
171
200
}
172
201
173
- bool BLEGap::getWriteCmdPacket (uint16_t conn_handle)
202
+ bool BLEGap::getHvnPacket (uint16_t conn_hdl)
203
+ {
204
+ VERIFY ( (conn_hdl < BLE_MAX_CONN) && (_peers[conn_hdl].hvn_tx_sem != NULL ) );
205
+
206
+ return xSemaphoreTake (_peers[conn_hdl].hvn_tx_sem , ms2tick (BLE_GENERIC_TIMEOUT));
207
+ }
208
+
209
+ bool BLEGap::getWriteCmdPacket (uint16_t conn_hdl)
174
210
{
175
211
#if SD_VER < 500
176
- return getHvnPacket (conn_handle );
212
+ return getHvnPacket (conn_hdl );
177
213
#else
178
- VERIFY ( (conn_handle < BLE_MAX_CONN) && (_peers[conn_handle ].wrcmd_tx_sem != NULL ) );
179
- return xSemaphoreTake (_peers[conn_handle ].wrcmd_tx_sem , ms2tick (BLE_GENERIC_TIMEOUT));
214
+ VERIFY ( (conn_hdl < BLE_MAX_CONN) && (_peers[conn_hdl ].wrcmd_tx_sem != NULL ) );
215
+ return xSemaphoreTake (_peers[conn_hdl ].wrcmd_tx_sem , ms2tick (BLE_GENERIC_TIMEOUT));
180
216
#endif
181
217
}
182
218
183
- uint16_t BLEGap::getMTU (uint16_t conn_handle )
219
+ uint16_t BLEGap::getMTU (uint16_t conn_hdl )
184
220
{
185
- return _peers[conn_handle ].att_mtu ;
221
+ return _peers[conn_hdl ].att_mtu ;
186
222
}
187
223
188
- uint16_t BLEGap::getPeerName (uint16_t conn_handle , char * buf, uint16_t bufsize)
224
+ uint16_t BLEGap::getPeerName (uint16_t conn_hdl , char * buf, uint16_t bufsize)
189
225
{
190
- return Bluefruit.Gatt .readCharByUuid (conn_handle , BLEUuid (BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME), buf, bufsize);
226
+ return Bluefruit.Gatt .readCharByUuid (conn_hdl , BLEUuid (BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME), buf, bufsize);
191
227
}
192
228
193
229
/* *
@@ -197,9 +233,9 @@ uint16_t BLEGap::getPeerName(uint16_t conn_handle, char* buf, uint16_t bufsize)
197
233
void BLEGap::_eventHandler (ble_evt_t * evt)
198
234
{
199
235
// conn handle has fixed offset regardless of event type
200
- const uint16_t conn_handle = evt->evt .common_evt .conn_handle ;
236
+ const uint16_t conn_hdl = evt->evt .common_evt .conn_handle ;
201
237
202
- gap_peer_t * peer = &_peers[conn_handle ];
238
+ gap_peer_t * peer = (conn_hdl == BLE_CONN_HANDLE_INVALID) ? NULL : &_peers[conn_hdl ];
203
239
204
240
switch (evt->header .evt_id )
205
241
{
@@ -215,13 +251,13 @@ void BLEGap::_eventHandler(ble_evt_t* evt)
215
251
// Init transmission buffer for notification
216
252
#if SD_VER < 500
217
253
uint8_t txbuf_max;
218
- (void ) sd_ble_tx_packet_count_get (conn_handle , &txbuf_max);
254
+ (void ) sd_ble_tx_packet_count_get (conn_hdl , &txbuf_max);
219
255
peer->hvn_tx_sem = xSemaphoreCreateCounting (txbuf_max, txbuf_max);
220
256
#else
221
- peer->hvn_tx_sem = xSemaphoreCreateCounting (getHvnQueueSize (conn_handle ), getHvnQueueSize (conn_handle ));
257
+ peer->hvn_tx_sem = xSemaphoreCreateCounting (getHvnQueueSize (conn_hdl ), getHvnQueueSize (conn_hdl ));
222
258
#endif
223
259
224
- peer->wrcmd_tx_sem = xSemaphoreCreateCounting (getWriteCmdQueueSize (conn_handle ), getWriteCmdQueueSize (conn_handle ));
260
+ peer->wrcmd_tx_sem = xSemaphoreCreateCounting (getWriteCmdQueueSize (conn_hdl ), getWriteCmdQueueSize (conn_hdl ));
225
261
}
226
262
break ;
227
263
@@ -230,7 +266,7 @@ void BLEGap::_eventHandler(ble_evt_t* evt)
230
266
ble_gap_evt_disconnected_t const * para = &evt->evt .gap_evt .params .disconnected ;
231
267
232
268
// mark as disconnected, but keep the role for sub sequence event handler
233
- peer->connected = false ;
269
+ peer->connected = peer-> bonded = false ;
234
270
235
271
vSemaphoreDelete ( peer->hvn_tx_sem );
236
272
peer->hvn_tx_sem = NULL ;
@@ -241,7 +277,115 @@ void BLEGap::_eventHandler(ble_evt_t* evt)
241
277
break ;
242
278
243
279
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
280
+ {
244
281
// Pairing in progress, Peer asking for our info
282
+ peer->bond_data = (bond_data_t *) rtos_malloc ( sizeof (bond_data_t ));
283
+ VERIFY (peer->bond_data , );
284
+
285
+ bond_data_t * bdata = peer->bond_data ;
286
+ memclr (bdata, sizeof (bond_data_t ));
287
+
288
+ peer->ediv = 0xFFFF ; // invalid value for ediv
289
+
290
+ /* Step 1: Pairing/Bonding
291
+ * - Central supplies its parameters
292
+ * - We replies with our security parameters
293
+ */
294
+ // ble_gap_sec_params_t* peer = &evt->evt.gap_evt.params.sec_params_request.peer_params;
295
+ COMMENT_OUT (
296
+ // Change security parameter according to authentication type
297
+ if ( _auth_type == BLE_GAP_AUTH_KEY_TYPE_PASSKEY)
298
+ {
299
+ sec_para.mitm = 1 ;
300
+ sec_para.io_caps = BLE_GAP_IO_CAPS_DISPLAY_ONLY;
301
+ }
302
+ )
303
+
304
+ ble_gap_sec_keyset_t keyset =
305
+ {
306
+ .keys_own = {
307
+ .p_enc_key = &bdata->own_enc ,
308
+ .p_id_key = NULL ,
309
+ .p_sign_key = NULL ,
310
+ .p_pk = NULL
311
+ },
312
+
313
+ .keys_peer = {
314
+ .p_enc_key = &bdata->peer_enc ,
315
+ .p_id_key = &bdata->peer_id ,
316
+ .p_sign_key = NULL ,
317
+ .p_pk = NULL
318
+ }
319
+ };
320
+
321
+ VERIFY_STATUS (sd_ble_gap_sec_params_reply (evt->evt .gap_evt .conn_handle , BLE_GAP_SEC_STATUS_SUCCESS, &_sec_param, &keyset), RETURN_VOID);
322
+ }
323
+ break ;
324
+
325
+ case BLE_GAP_EVT_AUTH_STATUS:
326
+ {
327
+ // Bonding process completed
328
+ ble_gap_evt_auth_status_t * status = &evt->evt .gap_evt .params .auth_status ;
329
+
330
+ // Pairing/Bonding succeeded --> save encryption keys
331
+ if (BLE_GAP_SEC_STATUS_SUCCESS == status->auth_status )
332
+ {
333
+ peer->bonded = true ;
334
+ peer->ediv = peer->bond_data ->own_enc .master_id .ediv ;
335
+
336
+ bond_save_keys (conn_hdl, peer->bond_data );
337
+ }else
338
+ {
339
+ PRINT_HEX (status->auth_status );
340
+ }
341
+
342
+ rtos_free (peer->bond_data );
343
+ peer->bond_data = NULL ;
344
+ }
345
+ break ;
346
+
347
+ case BLE_GAP_EVT_SEC_INFO_REQUEST:
348
+ {
349
+ // Reconnection. If bonded previously, Central will ask for stored keys.
350
+ // return security information. Otherwise NULL
351
+ ble_gap_evt_sec_info_request_t * sec_req = (ble_gap_evt_sec_info_request_t *) &evt->evt .gap_evt .params .sec_info_request ;
352
+
353
+ bond_data_t bdata;
354
+ varclr (&bdata);
355
+
356
+ if ( bond_load_keys (sec_req->master_id .ediv , &bdata) )
357
+ {
358
+ sd_ble_gap_sec_info_reply (evt->evt .gap_evt .conn_handle , &bdata.own_enc .enc_info , &bdata.peer_id .id_info , NULL );
359
+
360
+ peer->ediv = bdata.own_enc .master_id .ediv ;
361
+ } else
362
+ {
363
+ sd_ble_gap_sec_info_reply (evt->evt .gap_evt .conn_handle , NULL , NULL , NULL );
364
+ }
365
+ }
366
+ break ;
367
+
368
+ case BLE_GAP_EVT_CONN_SEC_UPDATE:
369
+ // Connection is secured aka Paired
370
+
371
+ // Previously bonded --> secure by re-connection process
372
+ // --> Load & Set Sys Attr (Apply Service Context)
373
+ // Else Init Sys Attr
374
+ bond_load_cccd (conn_hdl, peer->ediv );
375
+
376
+ // Paired is Bonded (as we always save keys)
377
+ peer->bonded = true ;
378
+ break ;
379
+
380
+ case BLE_GAP_EVT_PASSKEY_DISPLAY:
381
+ {
382
+ // ble_gap_evt_passkey_display_t const* passkey_display = &evt->evt.gap_evt.params.passkey_display;
383
+ //
384
+ // PRINT_INT(passkey_display->match_request);
385
+ // PRINT_BUFFER(passkey_display->passkey, 6);
386
+
387
+ // sd_ble_gap_auth_key_reply
388
+ }
245
389
break ;
246
390
247
391
#if SD_VER < 500
@@ -283,7 +427,7 @@ void BLEGap::_eventHandler(ble_evt_t* evt)
283
427
param->max_tx_octets , param->max_rx_octets , param->max_tx_time_us , param->max_rx_time_us );
284
428
285
429
// Let Softdevice decide the data length
286
- VERIFY_STATUS ( sd_ble_gap_data_length_update (conn_handle , NULL , NULL ), );
430
+ VERIFY_STATUS ( sd_ble_gap_data_length_update (conn_hdl , NULL , NULL ), );
287
431
}
288
432
break ;
289
433
@@ -306,7 +450,7 @@ void BLEGap::_eventHandler(ble_evt_t* evt)
306
450
307
451
// Tell SoftDevice to choose PHY automatically
308
452
ble_gap_phys_t phy = { BLE_GAP_PHY_AUTO, BLE_GAP_PHY_AUTO };
309
- (void ) sd_ble_gap_phy_update (conn_handle , &phy);
453
+ (void ) sd_ble_gap_phy_update (conn_hdl , &phy);
310
454
}
311
455
break ;
312
456
@@ -329,8 +473,8 @@ void BLEGap::_eventHandler(ble_evt_t* evt)
329
473
330
474
case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
331
475
{
332
- peer->att_mtu = minof (evt->evt .gatts_evt .params .exchange_mtu_request .client_rx_mtu , getMaxMtu (conn_handle ));
333
- VERIFY_STATUS ( sd_ble_gatts_exchange_mtu_reply (conn_handle , peer->att_mtu ), );
476
+ peer->att_mtu = minof (evt->evt .gatts_evt .params .exchange_mtu_request .client_rx_mtu , getMaxMtu (conn_hdl ));
477
+ VERIFY_STATUS ( sd_ble_gatts_exchange_mtu_reply (conn_hdl , peer->att_mtu ), );
334
478
335
479
LOG_LV1 (" GAP" , " ATT MTU is changed to %d" , peer->att_mtu );
336
480
}
0 commit comments