Nordic BLE: Store locally role for a given connection.

pull/7375/head
Vincent Coubard 2018-06-13 15:03:43 +01:00 committed by adbridge
parent a6eefdfdcf
commit e8b783b702
4 changed files with 168 additions and 2 deletions

View File

@ -104,7 +104,8 @@ nRF5xGap::nRF5xGap() : Gap(),
_privacy_enabled(false),
_peripheral_privacy_configuration(default_peripheral_privacy_configuration),
_central_privacy_configuration(default_central_privacy_configuration),
_non_private_address_type(LegacyAddressType::RANDOM_STATIC)
_non_private_address_type(LegacyAddressType::RANDOM_STATIC),
_connections_role()
{
m_connectionHandle = BLE_CONN_HANDLE_INVALID;
}
@ -682,6 +683,8 @@ ble_error_t nRF5xGap::reset(void)
/* Clear the internal whitelist */
whitelistAddressesSize = 0;
/* Reset existing mapping between a connection and its role */
release_all_connections_role();
return BLE_ERROR_NONE;
}
@ -1195,6 +1198,8 @@ void nRF5xGap::processDisconnectionEvent(
Handle_t handle,
DisconnectionReason_t reason
) {
release_connection_role(handle);
if (_connection_event_handler) {
_connection_event_handler->on_disconnected(
handle,
@ -1214,6 +1219,9 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t
// set the new connection handle as the _default_ handle in gap
setConnectionHandle(handle);
// add the connection and the role of the device in the local table
allocate_connection_role(handle, static_cast<Role_t>(evt.role));
// deal with own address
LegacyAddressType_t own_addr_type;
Address_t own_address;
@ -1375,5 +1383,46 @@ void nRF5xGap::on_advertising_packet(const ble_gap_evt_adv_report_t &evt) {
);
}
ble_error_t nRF5xGap::get_role(ble::connection_handle_t connection, Role_t& role) {
for (size_t i = 0; i < max_connections_count; ++i) {
connection_role_t& c = _connections_role[i];
if (c.is_allocated && c.connection == connection) {
role = c.is_peripheral ? PERIPHERAL : CENTRAL;
return BLE_ERROR_NONE;
}
}
return BLE_ERROR_INVALID_PARAM;
}
void nRF5xGap::allocate_connection_role(
ble::connection_handle_t connection,
Role_t role
) {
for (size_t i = 0; i < max_connections_count; ++i) {
connection_role_t& c = _connections_role[i];
if (c.is_allocated == false) {
c.connection = connection;
c.is_peripheral = (role == Gap::PERIPHERAL);
c.is_allocated = true;
return;
}
}
}
void nRF5xGap::release_connection_role(ble::connection_handle_t connection) {
for (size_t i = 0; i < max_connections_count; ++i) {
connection_role_t& c = _connections_role[i];
if (c.is_allocated && c.connection == connection) {
c.is_allocated = false;
return;
}
}
}
void nRF5xGap::release_all_connections_role() {
for (size_t i = 0; i < max_connections_count; ++i) {
_connections_role[i].is_allocated = false;
}
}

View File

@ -259,12 +259,26 @@ public:
DisconnectionReason_t reason
);
/**
* Return the role of the local peripheral for a given connection.
*
* @param[in] connection The connection queried.
* @param[out] role The role of the local device in the connection.
*
* @return BLE_ERROR_NONE in case of success or an appropriate error code.
*/
ble_error_t get_role(ble::connection_handle_t connection, Role_t& role);
private:
friend void btle_handler(ble_evt_t *p_ble_evt);
void on_connection(Handle_t handle, const ble_gap_evt_connected_t& evt);
void on_advertising_packet(const ble_gap_evt_adv_report_t &evt);
void allocate_connection_role(ble::connection_handle_t, Role_t);
void release_connection_role(ble::connection_handle_t);
void release_all_connections_role();
uint16_t m_connectionHandle;
ConnectionEventMonitor::EventHandler* _connection_event_handler;
@ -275,6 +289,23 @@ private:
AddressType_t _non_private_address_type;
Address_t _non_private_address;
struct connection_role_t {
connection_role_t() :
connection(),
is_peripheral(false),
is_allocated(false)
{ }
ble::connection_handle_t connection;
uint8_t is_peripheral:1;
uint8_t is_allocated:1;
};
static const size_t max_connections_count =
NRF_SDH_BLE_PERIPHERAL_LINK_COUNT + NRF_SDH_BLE_CENTRAL_LINK_COUNT;
connection_role_t _connections_role[max_connections_count];
/*
* Allow instantiation from nRF5xn when required.
*/

View File

@ -133,7 +133,8 @@ nRF5xGap::nRF5xGap() : Gap(),
_privacy_enabled(false),
_peripheral_privacy_configuration(default_peripheral_privacy_configuration),
_central_privacy_configuration(default_central_privacy_configuration),
_non_private_address_type(LegacyAddressType::RANDOM_STATIC)
_non_private_address_type(LegacyAddressType::RANDOM_STATIC),
_connections_role()
{
m_connectionHandle = BLE_CONN_HANDLE_INVALID;
}
@ -743,6 +744,9 @@ ble_error_t nRF5xGap::reset(void)
/* Clear the internal whitelist */
whitelistAddressesSize = 0;
/* Reset existing mapping between a connection and its role */
release_all_connections_role();
return BLE_ERROR_NONE;
}
@ -1278,6 +1282,8 @@ void nRF5xGap::processDisconnectionEvent(
Handle_t handle,
DisconnectionReason_t reason
) {
release_connection_role(handle);
if (_connection_event_handler) {
_connection_event_handler->on_disconnected(
handle,
@ -1326,6 +1332,9 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t
// set the new connection handle as the _default_ handle in gap
setConnectionHandle(handle);
// add the connection and the role of the device in the local table
allocate_connection_role(handle, static_cast<Role_t>(evt.role));
// deal with own address
LegacyAddressType_t own_addr_type;
ble::address_t own_address;
@ -1457,3 +1466,48 @@ void nRF5xGap::on_advertising_packet(const ble_gap_evt_adv_report_t &evt) {
);
}
ble_error_t nRF5xGap::get_role(ble::connection_handle_t connection, Role_t& role) {
for (size_t i = 0; i < max_connections_count; ++i) {
connection_role_t& c = _connections_role[i];
if (c.is_allocated && c.connection == connection) {
role = c.is_peripheral ? PERIPHERAL : CENTRAL;
return BLE_ERROR_NONE;
}
}
return BLE_ERROR_INVALID_PARAM;
}
void nRF5xGap::allocate_connection_role(
ble::connection_handle_t connection,
Role_t role
) {
for (size_t i = 0; i < max_connections_count; ++i) {
connection_role_t& c = _connections_role[i];
if (c.is_allocated == false) {
c.connection = connection;
c.is_peripheral = (role == Gap::PERIPHERAL);
c.is_allocated = true;
return;
}
}
}
void nRF5xGap::release_connection_role(ble::connection_handle_t connection) {
for (size_t i = 0; i < max_connections_count; ++i) {
connection_role_t& c = _connections_role[i];
if (c.is_allocated && c.connection == connection) {
c.is_allocated = false;
return;
}
}
}
void nRF5xGap::release_all_connections_role() {
for (size_t i = 0; i < max_connections_count; ++i) {
_connections_role[i].is_allocated = false;
}
}

View File

@ -265,6 +265,16 @@ public:
DisconnectionReason_t reason
);
/**
* Return the role of the local peripheral for a given connection.
*
* @param[in] connection The connection queried.
* @param[out] role The role of the local device in the connection.
*
* @return BLE_ERROR_NONE in case of success or an appropriate error code.
*/
ble_error_t get_role(ble::connection_handle_t connection, Role_t& role);
private:
friend void btle_handler(const ble_evt_t *p_ble_evt);
friend void btle_handler(const ble_evt_t *p_ble_evt, void *p_context);
@ -272,6 +282,11 @@ private:
ble_error_t update_identities_list(bool resolution_enabled);
void on_connection(Handle_t handle, const ble_gap_evt_connected_t& evt);
void on_advertising_packet(const ble_gap_evt_adv_report_t &evt);
void allocate_connection_role(ble::connection_handle_t, Role_t);
void release_connection_role(ble::connection_handle_t);
void release_all_connections_role();
uint16_t m_connectionHandle;
ConnectionEventMonitor::EventHandler* _connection_event_handler;
@ -281,6 +296,23 @@ private:
AddressType_t _non_private_address_type;
Address_t _non_private_address;
struct connection_role_t {
connection_role_t() :
connection(),
is_peripheral(false),
is_allocated(false)
{ }
ble::connection_handle_t connection;
uint8_t is_peripheral:1;
uint8_t is_allocated:1;
};
static const size_t max_connections_count =
NRF_SDH_BLE_PERIPHERAL_LINK_COUNT + NRF_SDH_BLE_CENTRAL_LINK_COUNT;
connection_role_t _connections_role[max_connections_count];
/*
* Allow instantiation from nRF5xn when required.
*/