Skip to content

Commit c4e2529

Browse files
committed
move pairing event handle code to BLEGap
- add bond_init() - move thing around
1 parent 86ea7e7 commit c4e2529

File tree

7 files changed

+342
-213
lines changed

7 files changed

+342
-213
lines changed

libraries/Bluefruit52Lib/src/BLEGap.cpp

Lines changed: 181 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,19 @@ BLEGap::BLEGap(void)
5353
_cfg_central.wr_cmd_qsize = BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT;
5454
#endif
5555

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+
};
5769
}
5870

5971

@@ -83,19 +95,19 @@ uint16_t BLEGap::getMaxMtuByConnCfg(uint8_t conn_cfg)
8395
return (conn_cfg == CONN_CFG_PERIPHERAL) ? _cfg_prph.mtu_max : _cfg_central.mtu_max;
8496
}
8597

86-
uint16_t BLEGap::getMaxMtu (uint8_t conn_handle)
98+
uint16_t BLEGap::getMaxMtu (uint8_t conn_hdl)
8799
{
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;
89101
}
90102

91-
uint8_t BLEGap::getHvnQueueSize (uint8_t conn_handle)
103+
uint8_t BLEGap::getHvnQueueSize (uint8_t conn_hdl)
92104
{
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;
94106
}
95107

96-
uint8_t BLEGap::getWriteCmdQueueSize (uint8_t conn_handle)
108+
uint8_t BLEGap::getWriteCmdQueueSize (uint8_t conn_hdl)
97109
{
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;
99111
}
100112

101113

@@ -142,52 +154,76 @@ bool BLEGap::setAddr(uint8_t mac[6], uint8_t type)
142154
return true;
143155
}
144156

145-
bool BLEGap::connected(uint16_t conn_handle)
157+
bool BLEGap::connected(uint16_t conn_hdl)
146158
{
147-
return _peers[conn_handle].connected;
159+
return _peers[conn_hdl].connected;
148160
}
149161

150-
uint8_t BLEGap::getRole(uint16_t conn_handle)
162+
bool BLEGap::bonded(uint16_t conn_hdl)
151163
{
152-
return _peers[conn_handle].role;
164+
return _peers[conn_hdl].bonded;
153165
}
154166

155-
uint8_t BLEGap::getPeerAddr(uint16_t conn_handle, uint8_t addr[6])
167+
bool BLEGap::requestPairing(uint16_t conn_hdl)
156168
{
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;
159184
}
160185

161-
ble_gap_addr_t BLEGap::getPeerAddr(uint16_t conn_handle)
186+
uint8_t BLEGap::getRole(uint16_t conn_hdl)
162187
{
163-
return _peers[conn_handle].addr;
188+
return _peers[conn_hdl].role;
164189
}
165190

166-
bool BLEGap::getHvnPacket(uint16_t conn_handle)
191+
uint8_t BLEGap::getPeerAddr(uint16_t conn_hdl, uint8_t addr[6])
167192
{
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+
}
169196

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;
171200
}
172201

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)
174210
{
175211
#if SD_VER < 500
176-
return getHvnPacket(conn_handle);
212+
return getHvnPacket(conn_hdl);
177213
#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));
180216
#endif
181217
}
182218

183-
uint16_t BLEGap::getMTU (uint16_t conn_handle)
219+
uint16_t BLEGap::getMTU (uint16_t conn_hdl)
184220
{
185-
return _peers[conn_handle].att_mtu;
221+
return _peers[conn_hdl].att_mtu;
186222
}
187223

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)
189225
{
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);
191227
}
192228

193229
/**
@@ -197,9 +233,9 @@ uint16_t BLEGap::getPeerName(uint16_t conn_handle, char* buf, uint16_t bufsize)
197233
void BLEGap::_eventHandler(ble_evt_t* evt)
198234
{
199235
// 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;
201237

202-
gap_peer_t* peer = &_peers[conn_handle];
238+
gap_peer_t* peer = (conn_hdl == BLE_CONN_HANDLE_INVALID) ? NULL : &_peers[conn_hdl];
203239

204240
switch(evt->header.evt_id)
205241
{
@@ -215,13 +251,13 @@ void BLEGap::_eventHandler(ble_evt_t* evt)
215251
// Init transmission buffer for notification
216252
#if SD_VER < 500
217253
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);
219255
peer->hvn_tx_sem = xSemaphoreCreateCounting(txbuf_max, txbuf_max);
220256
#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));
222258
#endif
223259

224-
peer->wrcmd_tx_sem = xSemaphoreCreateCounting(getWriteCmdQueueSize(conn_handle), getWriteCmdQueueSize(conn_handle));
260+
peer->wrcmd_tx_sem = xSemaphoreCreateCounting(getWriteCmdQueueSize(conn_hdl), getWriteCmdQueueSize(conn_hdl));
225261
}
226262
break;
227263

@@ -230,7 +266,7 @@ void BLEGap::_eventHandler(ble_evt_t* evt)
230266
ble_gap_evt_disconnected_t const* para = &evt->evt.gap_evt.params.disconnected;
231267

232268
// mark as disconnected, but keep the role for sub sequence event handler
233-
peer->connected = false;
269+
peer->connected = peer->bonded = false;
234270

235271
vSemaphoreDelete( peer->hvn_tx_sem );
236272
peer->hvn_tx_sem = NULL;
@@ -241,7 +277,115 @@ void BLEGap::_eventHandler(ble_evt_t* evt)
241277
break;
242278

243279
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
280+
{
244281
// 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+
}
245389
break;
246390

247391
#if SD_VER < 500
@@ -283,7 +427,7 @@ void BLEGap::_eventHandler(ble_evt_t* evt)
283427
param->max_tx_octets, param->max_rx_octets, param->max_tx_time_us, param->max_rx_time_us);
284428

285429
// 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), );
287431
}
288432
break;
289433

@@ -306,7 +450,7 @@ void BLEGap::_eventHandler(ble_evt_t* evt)
306450

307451
// Tell SoftDevice to choose PHY automatically
308452
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);
310454
}
311455
break;
312456

@@ -329,8 +473,8 @@ void BLEGap::_eventHandler(ble_evt_t* evt)
329473

330474
case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
331475
{
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), );
334478

335479
LOG_LV1("GAP", "ATT MTU is changed to %d", peer->att_mtu);
336480
}

0 commit comments

Comments
 (0)