Skip to content

Commit 301e527

Browse files
committed
Nordic BLE: Store locally role for a given connection.
1 parent 5c7b8c8 commit 301e527

File tree

4 files changed

+168
-2
lines changed

4 files changed

+168
-2
lines changed

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF51/source/nRF5xGap.cpp

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ nRF5xGap::nRF5xGap() : Gap(),
104104
_privacy_enabled(false),
105105
_peripheral_privacy_configuration(default_peripheral_privacy_configuration),
106106
_central_privacy_configuration(default_central_privacy_configuration),
107-
_non_private_address_type(LegacyAddressType::RANDOM_STATIC)
107+
_non_private_address_type(LegacyAddressType::RANDOM_STATIC),
108+
_connections_role()
108109
{
109110
m_connectionHandle = BLE_CONN_HANDLE_INVALID;
110111
}
@@ -682,6 +683,8 @@ ble_error_t nRF5xGap::reset(void)
682683
/* Clear the internal whitelist */
683684
whitelistAddressesSize = 0;
684685

686+
/* Reset existing mapping between a connection and its role */
687+
release_all_connections_role();
685688

686689
return BLE_ERROR_NONE;
687690
}
@@ -1195,6 +1198,8 @@ void nRF5xGap::processDisconnectionEvent(
11951198
Handle_t handle,
11961199
DisconnectionReason_t reason
11971200
) {
1201+
release_connection_role(handle);
1202+
11981203
if (_connection_event_handler) {
11991204
_connection_event_handler->on_disconnected(
12001205
handle,
@@ -1214,6 +1219,9 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t
12141219
// set the new connection handle as the _default_ handle in gap
12151220
setConnectionHandle(handle);
12161221

1222+
// add the connection and the role of the device in the local table
1223+
allocate_connection_role(handle, static_cast<Role_t>(evt.role));
1224+
12171225
// deal with own address
12181226
LegacyAddressType_t own_addr_type;
12191227
Address_t own_address;
@@ -1375,5 +1383,46 @@ void nRF5xGap::on_advertising_packet(const ble_gap_evt_adv_report_t &evt) {
13751383
);
13761384
}
13771385

1386+
ble_error_t nRF5xGap::get_role(ble::connection_handle_t connection, Role_t& role) {
1387+
for (size_t i = 0; i < max_connections_count; ++i) {
1388+
connection_role_t& c = _connections_role[i];
1389+
if (c.is_allocated && c.connection == connection) {
1390+
role = c.is_peripheral ? PERIPHERAL : CENTRAL;
1391+
return BLE_ERROR_NONE;
1392+
1393+
}
1394+
}
1395+
1396+
return BLE_ERROR_INVALID_PARAM;
1397+
}
1398+
1399+
void nRF5xGap::allocate_connection_role(
1400+
ble::connection_handle_t connection,
1401+
Role_t role
1402+
) {
1403+
for (size_t i = 0; i < max_connections_count; ++i) {
1404+
connection_role_t& c = _connections_role[i];
1405+
if (c.is_allocated == false) {
1406+
c.connection = connection;
1407+
c.is_peripheral = (role == Gap::PERIPHERAL);
1408+
c.is_allocated = true;
1409+
return;
1410+
}
1411+
}
1412+
}
1413+
void nRF5xGap::release_connection_role(ble::connection_handle_t connection) {
1414+
for (size_t i = 0; i < max_connections_count; ++i) {
1415+
connection_role_t& c = _connections_role[i];
1416+
if (c.is_allocated && c.connection == connection) {
1417+
c.is_allocated = false;
1418+
return;
1419+
}
1420+
}
1421+
}
13781422

1423+
void nRF5xGap::release_all_connections_role() {
1424+
for (size_t i = 0; i < max_connections_count; ++i) {
1425+
_connections_role[i].is_allocated = false;
1426+
}
1427+
}
13791428

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF51/source/nRF5xGap.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,26 @@ class nRF5xGap : public ::Gap, public ble::pal::ConnectionEventMonitor {
259259
DisconnectionReason_t reason
260260
);
261261

262+
/**
263+
* Return the role of the local peripheral for a given connection.
264+
*
265+
* @param[in] connection The connection queried.
266+
* @param[out] role The role of the local device in the connection.
267+
*
268+
* @return BLE_ERROR_NONE in case of success or an appropriate error code.
269+
*/
270+
ble_error_t get_role(ble::connection_handle_t connection, Role_t& role);
271+
262272
private:
263273
friend void btle_handler(ble_evt_t *p_ble_evt);
264274

265275
void on_connection(Handle_t handle, const ble_gap_evt_connected_t& evt);
266276
void on_advertising_packet(const ble_gap_evt_adv_report_t &evt);
267277

278+
void allocate_connection_role(ble::connection_handle_t, Role_t);
279+
void release_connection_role(ble::connection_handle_t);
280+
void release_all_connections_role();
281+
268282
uint16_t m_connectionHandle;
269283

270284
ConnectionEventMonitor::EventHandler* _connection_event_handler;
@@ -275,6 +289,23 @@ class nRF5xGap : public ::Gap, public ble::pal::ConnectionEventMonitor {
275289
AddressType_t _non_private_address_type;
276290
Address_t _non_private_address;
277291

292+
struct connection_role_t {
293+
connection_role_t() :
294+
connection(),
295+
is_peripheral(false),
296+
is_allocated(false)
297+
{ }
298+
299+
ble::connection_handle_t connection;
300+
uint8_t is_peripheral:1;
301+
uint8_t is_allocated:1;
302+
};
303+
304+
static const size_t max_connections_count =
305+
NRF_SDH_BLE_PERIPHERAL_LINK_COUNT + NRF_SDH_BLE_CENTRAL_LINK_COUNT;
306+
307+
connection_role_t _connections_role[max_connections_count];
308+
278309
/*
279310
* Allow instantiation from nRF5xn when required.
280311
*/

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF52/source/nRF5xGap.cpp

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ nRF5xGap::nRF5xGap() : Gap(),
133133
_privacy_enabled(false),
134134
_peripheral_privacy_configuration(default_peripheral_privacy_configuration),
135135
_central_privacy_configuration(default_central_privacy_configuration),
136-
_non_private_address_type(LegacyAddressType::RANDOM_STATIC)
136+
_non_private_address_type(LegacyAddressType::RANDOM_STATIC),
137+
_connections_role()
137138
{
138139
m_connectionHandle = BLE_CONN_HANDLE_INVALID;
139140
}
@@ -743,6 +744,9 @@ ble_error_t nRF5xGap::reset(void)
743744
/* Clear the internal whitelist */
744745
whitelistAddressesSize = 0;
745746

747+
/* Reset existing mapping between a connection and its role */
748+
release_all_connections_role();
749+
746750
return BLE_ERROR_NONE;
747751
}
748752

@@ -1278,6 +1282,8 @@ void nRF5xGap::processDisconnectionEvent(
12781282
Handle_t handle,
12791283
DisconnectionReason_t reason
12801284
) {
1285+
release_connection_role(handle);
1286+
12811287
if (_connection_event_handler) {
12821288
_connection_event_handler->on_disconnected(
12831289
handle,
@@ -1326,6 +1332,9 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t
13261332
// set the new connection handle as the _default_ handle in gap
13271333
setConnectionHandle(handle);
13281334

1335+
// add the connection and the role of the device in the local table
1336+
allocate_connection_role(handle, static_cast<Role_t>(evt.role));
1337+
13291338
// deal with own address
13301339
LegacyAddressType_t own_addr_type;
13311340
ble::address_t own_address;
@@ -1457,3 +1466,48 @@ void nRF5xGap::on_advertising_packet(const ble_gap_evt_adv_report_t &evt) {
14571466
);
14581467
}
14591468

1469+
ble_error_t nRF5xGap::get_role(ble::connection_handle_t connection, Role_t& role) {
1470+
for (size_t i = 0; i < max_connections_count; ++i) {
1471+
connection_role_t& c = _connections_role[i];
1472+
if (c.is_allocated && c.connection == connection) {
1473+
role = c.is_peripheral ? PERIPHERAL : CENTRAL;
1474+
return BLE_ERROR_NONE;
1475+
1476+
}
1477+
}
1478+
1479+
return BLE_ERROR_INVALID_PARAM;
1480+
}
1481+
1482+
void nRF5xGap::allocate_connection_role(
1483+
ble::connection_handle_t connection,
1484+
Role_t role
1485+
) {
1486+
for (size_t i = 0; i < max_connections_count; ++i) {
1487+
connection_role_t& c = _connections_role[i];
1488+
if (c.is_allocated == false) {
1489+
c.connection = connection;
1490+
c.is_peripheral = (role == Gap::PERIPHERAL);
1491+
c.is_allocated = true;
1492+
return;
1493+
}
1494+
}
1495+
}
1496+
void nRF5xGap::release_connection_role(ble::connection_handle_t connection) {
1497+
for (size_t i = 0; i < max_connections_count; ++i) {
1498+
connection_role_t& c = _connections_role[i];
1499+
if (c.is_allocated && c.connection == connection) {
1500+
c.is_allocated = false;
1501+
return;
1502+
}
1503+
}
1504+
}
1505+
1506+
void nRF5xGap::release_all_connections_role() {
1507+
for (size_t i = 0; i < max_connections_count; ++i) {
1508+
_connections_role[i].is_allocated = false;
1509+
}
1510+
}
1511+
1512+
1513+

features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF52/source/nRF5xGap.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,13 +265,28 @@ class nRF5xGap : public ::Gap, public ble::pal::ConnectionEventMonitor {
265265
DisconnectionReason_t reason
266266
);
267267

268+
/**
269+
* Return the role of the local peripheral for a given connection.
270+
*
271+
* @param[in] connection The connection queried.
272+
* @param[out] role The role of the local device in the connection.
273+
*
274+
* @return BLE_ERROR_NONE in case of success or an appropriate error code.
275+
*/
276+
ble_error_t get_role(ble::connection_handle_t connection, Role_t& role);
277+
268278
private:
269279
friend void btle_handler(const ble_evt_t *p_ble_evt);
270280
friend void btle_handler(const ble_evt_t *p_ble_evt, void *p_context);
271281

272282
ble_error_t update_identities_list(bool resolution_enabled);
273283
void on_connection(Handle_t handle, const ble_gap_evt_connected_t& evt);
274284
void on_advertising_packet(const ble_gap_evt_adv_report_t &evt);
285+
286+
void allocate_connection_role(ble::connection_handle_t, Role_t);
287+
void release_connection_role(ble::connection_handle_t);
288+
void release_all_connections_role();
289+
275290
uint16_t m_connectionHandle;
276291
ConnectionEventMonitor::EventHandler* _connection_event_handler;
277292

@@ -281,6 +296,23 @@ class nRF5xGap : public ::Gap, public ble::pal::ConnectionEventMonitor {
281296
AddressType_t _non_private_address_type;
282297
Address_t _non_private_address;
283298

299+
struct connection_role_t {
300+
connection_role_t() :
301+
connection(),
302+
is_peripheral(false),
303+
is_allocated(false)
304+
{ }
305+
306+
ble::connection_handle_t connection;
307+
uint8_t is_peripheral:1;
308+
uint8_t is_allocated:1;
309+
};
310+
311+
static const size_t max_connections_count =
312+
NRF_SDH_BLE_PERIPHERAL_LINK_COUNT + NRF_SDH_BLE_CENTRAL_LINK_COUNT;
313+
314+
connection_role_t _connections_role[max_connections_count];
315+
284316
/*
285317
* Allow instantiation from nRF5xn when required.
286318
*/

0 commit comments

Comments
 (0)