Skip to content

Commit c3bcd10

Browse files
committed
BLE NRF52: Implement features related to peer_address_t
The overload of Gap::connect that accept peer_address_t has been added and gap connection and advertising report process have been updated to exploit peer_address_t in a backward compatible fashion.
1 parent d361960 commit c3bcd10

File tree

2 files changed

+143
-79
lines changed

2 files changed

+143
-79
lines changed

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

Lines changed: 142 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,15 @@
2626
#include "headers/ble_hci.h"
2727
#include "ble/pal/ConnectionEventMonitor.h"
2828
#include "nRF5xPalSecurityManager.h"
29+
#include <algorithm>
2930

3031
using ble::pal::vendor::nordic::nRF5xSecurityManager;
3132
using ble::ArrayView;
3233
using ble::pal::advertising_peer_address_type_t;
34+
using ble::peer_address_type_t;
35+
36+
typedef BLEProtocol::AddressType LegacyAddressType;
37+
typedef BLEProtocol::AddressType_t LegacyAddressType_t;
3338

3439
namespace {
3540

@@ -85,29 +90,32 @@ bool is_advertising_non_connectable(const GapAdvertisingParams &params) {
8590
}
8691
}
8792

88-
bool is_identity_address(BLEProtocol::AddressType_t address_type) {
89-
switch (address_type) {
90-
case BLEProtocol::AddressType::PUBLIC_IDENTITY:
91-
case BLEProtocol::AddressType::RANDOM_STATIC_IDENTITY:
92-
return true;
93-
default:
94-
return false;
95-
}
93+
bool is_identity_address(peer_address_type_t address_type) {
94+
return address_type == peer_address_type_t::PUBLIC_IDENTITY ||
95+
address_type == peer_address_type_t::RANDOM_STATIC_IDENTITY;
9696
}
9797

98-
BLEProtocol::AddressType_t convert_nordic_address(uint8_t address) {
99-
if (address == BLE_GAP_ADDR_TYPE_PUBLIC) {
100-
return BLEProtocol::AddressType::PUBLIC;
98+
peer_address_type_t convert_nordic_address(bool identity, uint8_t address) {
99+
if (identity) {
100+
if (address == BLE_GAP_ADDR_TYPE_PUBLIC) {
101+
return peer_address_type_t::PUBLIC_IDENTITY;
102+
} else {
103+
return peer_address_type_t::RANDOM_STATIC_IDENTITY;
104+
}
101105
} else {
102-
return BLEProtocol::AddressType::RANDOM;
106+
if (address == BLE_GAP_ADDR_TYPE_PUBLIC) {
107+
return peer_address_type_t::PUBLIC;
108+
} else {
109+
return peer_address_type_t::RANDOM;
110+
}
103111
}
104112
}
105113

106-
BLEProtocol::AddressType_t convert_identity_address(advertising_peer_address_type_t address) {
114+
peer_address_type_t convert_identity_address(advertising_peer_address_type_t address) {
107115
if (address == advertising_peer_address_type_t::PUBLIC_ADDRESS) {
108-
return BLEProtocol::AddressType::PUBLIC_IDENTITY;
116+
return peer_address_type_t::PUBLIC_IDENTITY;
109117
} else {
110-
return BLEProtocol::AddressType::RANDOM_STATIC_IDENTITY;
118+
return peer_address_type_t::RANDOM_STATIC_IDENTITY;
111119
}
112120
}
113121

@@ -129,7 +137,7 @@ nRF5xGap::nRF5xGap() : Gap(),
129137
_privacy_enabled(false),
130138
_peripheral_privacy_configuration(default_peripheral_privacy_configuration),
131139
_central_privacy_configuration(default_central_privacy_configuration),
132-
_non_private_address_type(BLEProtocol::AddressType::RANDOM)
140+
_non_private_address_type(LegacyAddressType::RANDOM_STATIC)
133141
{
134142
m_connectionHandle = BLE_CONN_HANDLE_INVALID;
135143
}
@@ -453,11 +461,60 @@ ble_error_t nRF5xGap::stopAdvertising(void)
453461
return BLE_ERROR_NONE;
454462
}
455463

456-
ble_error_t nRF5xGap::connect(const Address_t peerAddr,
457-
BLEProtocol::AddressType_t peerAddrType,
458-
const ConnectionParams_t *connectionParams,
459-
const GapScanningParams *scanParamsIn)
460-
{
464+
ble_error_t nRF5xGap::connect(
465+
const Address_t peerAddr,
466+
peer_address_type_t peerAddrType,
467+
const ConnectionParams_t *connectionParams,
468+
const GapScanningParams *scanParamsIn
469+
) {
470+
// NOTE: Nordic address type is an closer to LegacyAddressType: resolved
471+
// address are treaded either as PUBLIC or RANDOM STATIC adresses.
472+
// The idea is to get the conversion done here and call the legacy function.
473+
474+
LegacyAddressType_t legacy_address;
475+
476+
switch (peerAddrType.value()) {
477+
case peer_address_type_t::PUBLIC:
478+
case peer_address_type_t::PUBLIC_IDENTITY:
479+
legacy_address = LegacyAddressType::PUBLIC;
480+
break;
481+
case peer_address_type_t::RANDOM_STATIC_IDENTITY:
482+
legacy_address = LegacyAddressType::RANDOM_STATIC;
483+
break;
484+
case peer_address_type_t::RANDOM: {
485+
RandomAddressType_t random_address_type(RandomAddressType_t::STATIC);
486+
ble_error_t err = getRandomAddressType(peerAddr, &random_address_type);
487+
if (err) {
488+
return err;
489+
}
490+
switch (random_address_type.value()) {
491+
case RandomAddressType_t::STATIC:
492+
legacy_address = LegacyAddressType::RANDOM_STATIC;
493+
break;
494+
case RandomAddressType_t::NON_RESOLVABLE_PRIVATE:
495+
legacy_address = LegacyAddressType::RANDOM_PRIVATE_NON_RESOLVABLE;
496+
break;
497+
case RandomAddressType_t::RESOLVABLE_PRIVATE:
498+
legacy_address = LegacyAddressType::RANDOM_PRIVATE_RESOLVABLE;
499+
break;
500+
default:
501+
return BLE_ERROR_UNSPECIFIED;
502+
}
503+
} break;
504+
default:
505+
return BLE_ERROR_INVALID_PARAM;
506+
}
507+
508+
return connect(peerAddr, legacy_address, connectionParams, scanParamsIn);
509+
}
510+
511+
512+
ble_error_t nRF5xGap::connect(
513+
const Address_t peerAddr,
514+
LegacyAddressType_t peerAddrType,
515+
const ConnectionParams_t *connectionParams,
516+
const GapScanningParams *scanParamsIn
517+
) {
461518
ble_gap_addr_t addr;
462519
ble_gap_addr_t* addr_ptr = &addr;
463520
addr.addr_type = peerAddrType;
@@ -722,11 +779,11 @@ uint16_t nRF5xGap::getConnectionHandle(void)
722779
@endcode
723780
*/
724781
/**************************************************************************/
725-
ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
782+
ble_error_t nRF5xGap::setAddress(LegacyAddressType_t type, const Address_t address)
726783
{
727-
using BLEProtocol::AddressType;
728-
729-
if (type != AddressType::PUBLIC || type != AddressType::RANDOM_STATIC) {
784+
if (type != LegacyAddressType::PUBLIC &&
785+
type != LegacyAddressType::RANDOM_STATIC
786+
) {
730787
return BLE_ERROR_INVALID_PARAM;
731788
}
732789

@@ -736,7 +793,7 @@ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
736793

737794
ble_gap_addr_t dev_addr;
738795
memcpy(dev_addr.addr, address, ADDR_LEN);
739-
if (type == AddressType::PUBLIC) {
796+
if (type == LegacyAddressType::PUBLIC) {
740797
dev_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
741798
} else {
742799
dev_addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC;
@@ -752,8 +809,9 @@ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
752809
case NRF_SUCCESS:
753810
return BLE_ERROR_NONE;
754811
case NRF_ERROR_INVALID_ADDR:
755-
case BLE_ERROR_GAP_INVALID_BLE_ADDR:
756812
return BLE_ERROR_INVALID_PARAM;
813+
case BLE_ERROR_GAP_INVALID_BLE_ADDR:
814+
return BLE_ERROR_PARAM_OUT_OF_RANGE;
757815
case NRF_ERROR_BUSY:
758816
return BLE_STACK_BUSY;
759817
case NRF_ERROR_INVALID_STATE:
@@ -781,11 +839,11 @@ ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address)
781839

782840
switch (dev_addr.addr_type) {
783841
case BLE_GAP_ADDR_TYPE_PUBLIC:
784-
*typeP = BLEProtocol::AddressType::PUBLIC;
842+
*typeP = LegacyAddressType::PUBLIC;
785843
break;
786844

787845
case BLE_GAP_ADDR_TYPE_RANDOM_STATIC:
788-
*typeP = BLEProtocol::AddressType::RANDOM_STATIC;
846+
*typeP = LegacyAddressType::RANDOM_STATIC;
789847
break;
790848

791849
default:
@@ -924,7 +982,7 @@ ble_error_t nRF5xGap::getWhitelist(Gap::Whitelist_t &whitelistOut) const
924982
uint32_t i;
925983
for (i = 0; i < whitelistAddressesSize && i < whitelistOut.capacity; ++i) {
926984
memcpy( &whitelistOut.addresses[i].address, &whitelistAddresses[i].addr, sizeof(whitelistOut.addresses[0].address));
927-
whitelistOut.addresses[i].type = static_cast<BLEProtocol::AddressType_t> (whitelistAddresses[i].addr_type);
985+
whitelistOut.addresses[i].type = static_cast<LegacyAddressType_t> (whitelistAddresses[i].addr_type);
928986

929987

930988
}
@@ -971,7 +1029,9 @@ ble_error_t nRF5xGap::setWhitelist(const Gap::Whitelist_t &whitelistIn)
9711029

9721030
/* Test for invalid parameters before we change the internal state */
9731031
for (uint32_t i = 0; i < whitelistIn.size; ++i) {
974-
if (whitelistIn.addresses[i].type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
1032+
if (whitelistIn.addresses[i].type == LegacyAddressType::RANDOM_PRIVATE_NON_RESOLVABLE ||
1033+
whitelistIn.addresses[i].type == LegacyAddressType::RANDOM_PRIVATE_RESOLVABLE
1034+
) {
9751035
/* This is not allowed because it is completely meaningless */
9761036
return BLE_ERROR_INVALID_PARAM;
9771037
}
@@ -1260,15 +1320,13 @@ ble_error_t nRF5xGap::update_identities_list(bool resolution_enabled)
12601320
}
12611321

12621322
void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t& evt) {
1263-
using BLEProtocol::AddressType;
1264-
12651323
// set the new connection handle as the _default_ handle in gap
12661324
setConnectionHandle(handle);
12671325

12681326
// deal with own address
1269-
AddressType_t own_addr_type;
1270-
Address_t own_address;
1271-
const uint8_t* own_resolvable_address = NULL;
1327+
LegacyAddressType_t own_addr_type;
1328+
ble::address_t own_address;
1329+
ble::address_t own_resolvable_address;
12721330

12731331
#if (NRF_SD_BLE_API_VERSION <= 2)
12741332
if (evt.own_addr.addr_type == BLE_GAP_ADDR_TYPE_PUBLIC) {
@@ -1278,53 +1336,54 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t
12781336
}
12791337
memcpy(own_address, evt.own_addr.addr, sizeof(own_address));
12801338
#else
1281-
// FIXME: handle privacy ???
1282-
getAddress(&own_addr_type, own_address);
1339+
getAddress(&own_addr_type, own_address.data());
12831340
#endif
12841341

12851342
if (_privacy_enabled) {
1286-
own_resolvable_address = own_address;
1343+
// swap own address with own resolvable address as when privacy is
1344+
// enabled own_address is invalid and the address returned by getAddress
1345+
// is the resolvable one.
1346+
std::swap(own_address, own_resolvable_address);
1347+
own_addr_type = LegacyAddressType::RANDOM_PRIVATE_RESOLVABLE;
12871348
}
12881349

1289-
// deal with the peer address: If privacy is enabled then the softdevice
1290-
// indicates if the address has been resolved or not. If the address has
1291-
// been resolved then the identity address should be passed to the application.
1292-
// Depending on the privacy chosen by the application, connection request
1293-
// from privacy enabled peers may trigger a disconnection, the pairing procedure
1294-
// or the authentication procedure.
1295-
AddressType_t peer_addr_type;
1296-
const uint8_t* peer_address;
1297-
const uint8_t* peer_resolvable_address;
1298-
12991350
#if (NRF_SD_BLE_API_VERSION <= 2)
13001351
bool private_peer_known = evt.irk_match;
13011352
#else
13021353
bool private_peer_known = evt.peer_addr.addr_id_peer;
13031354
#endif
13041355

1305-
1306-
if (private_peer_known) {
1307-
peer_addr_type = convert_nordic_address(evt.peer_addr.addr_type);;
1308-
peer_address = evt.peer_addr.addr;
1309-
peer_resolvable_address = evt.peer_addr.addr;
1310-
} else {
1311-
if (_privacy_enabled &&
1312-
evt.role == BLE_GAP_ROLE_PERIPH &&
1313-
_peripheral_privacy_configuration.resolution_strategy == PeripheralPrivacyConfiguration_t::REJECT_NON_RESOLVED_ADDRESS &&
1314-
evt.peer_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE &&
1315-
get_sm().get_resolving_list().size() > 0
1316-
) {
1317-
// FIXME: should use BLE_HCI_AUTHENTICATION_FAILURE; not possible
1318-
// with the softdevice ...
1319-
sd_ble_gap_disconnect(handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
1320-
return;
1321-
}
1322-
1323-
peer_addr_type = convert_nordic_address(evt.peer_addr.addr_type);
1324-
peer_address = evt.peer_addr.addr;
1325-
peer_resolvable_address = NULL;
1356+
// Filter out private address non resolved if the its required by the
1357+
// resolution policy
1358+
if (_privacy_enabled &&
1359+
evt.role == BLE_GAP_ROLE_PERIPH &&
1360+
_peripheral_privacy_configuration.resolution_strategy == PeripheralPrivacyConfiguration_t::REJECT_NON_RESOLVED_ADDRESS &&
1361+
evt.peer_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE &&
1362+
private_peer_known == false &&
1363+
get_sm().get_resolving_list().size() > 0
1364+
) {
1365+
// FIXME: should use BLE_HCI_AUTHENTICATION_FAILURE; not possible
1366+
// with the softdevice ...
1367+
sd_ble_gap_disconnect(handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
1368+
return;
13261369
}
13271370

1371+
// deal with the peer address: If privacy is enabled then the softdevice
1372+
// indicates if the address has been resolved or not. If the address has
1373+
// been resolved then the identity address should be passed to the application.
1374+
// Depending on the privacy chosen by the application, connection request
1375+
// from privacy enabled peers may trigger a disconnection, the pairing procedure
1376+
// or the authentication procedure.
1377+
peer_address_type_t peer_addr_type = convert_nordic_address(
1378+
private_peer_known,
1379+
evt.peer_addr.addr_type
1380+
);
1381+
// NOTE: when privacy is enabled, the only address returned is the resolved
1382+
// address; set peer and resolved address to the same value in such case.
1383+
const uint8_t* peer_address = evt.peer_addr.addr;
1384+
const uint8_t* peer_resolvable_address =
1385+
private_peer_known ? peer_address : NULL;
1386+
13281387
// notify internal event handler before applying the resolution strategy
13291388
if (_connection_event_handler) {
13301389
_connection_event_handler->on_connected(
@@ -1333,14 +1392,15 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t
13331392
peer_addr_type,
13341393
peer_address,
13351394
own_addr_type,
1336-
own_address,
1337-
reinterpret_cast<const ConnectionParams_t *>(&(evt.conn_params))
1395+
own_address.data(),
1396+
reinterpret_cast<const ConnectionParams_t *>(&(evt.conn_params)),
1397+
peer_resolvable_address
13381398
);
13391399
}
13401400

13411401
// Apply authentication strategy before application notification
1342-
if (!private_peer_known &&
1343-
_privacy_enabled &&
1402+
if (_privacy_enabled &&
1403+
!private_peer_known &&
13441404
evt.role == BLE_GAP_ROLE_PERIPH &&
13451405
evt.peer_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE
13461406
) {
@@ -1364,24 +1424,27 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t
13641424
peer_addr_type,
13651425
peer_address,
13661426
own_addr_type,
1367-
own_address,
1427+
own_address.data(),
13681428
reinterpret_cast<const ConnectionParams_t *>(&(evt.conn_params)),
13691429
peer_resolvable_address,
1370-
own_resolvable_address
1430+
own_resolvable_address.data()
13711431
);
13721432
}
13731433

13741434
void nRF5xGap::on_advertising_packet(const ble_gap_evt_adv_report_t &evt) {
1375-
using BLEProtocol::AddressType;
1435+
bool peer_address_resolved = evt.peer_addr.addr_id_peer;
13761436

13771437
if (_privacy_enabled &&
1378-
evt.peer_addr.addr_id_peer == 0 &&
1438+
peer_address_resolved == false &&
13791439
_central_privacy_configuration.resolution_strategy == CentralPrivacyConfiguration_t::RESOLVE_AND_FILTER
13801440
) {
13811441
return;
13821442
}
13831443

1384-
AddressType_t peer_addr_type = convert_nordic_address(evt.peer_addr.addr_type);
1444+
peer_address_type_t peer_addr_type = convert_nordic_address(
1445+
evt.peer_addr.addr_id_peer,
1446+
evt.peer_addr.addr_type
1447+
);
13851448
const uint8_t* peer_address = evt.peer_addr.addr;
13861449

13871450
processAdvertisementReport(

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class nRF5xGap : public ::Gap, public ble::pal::ConnectionEventMonitor {
8686

8787
virtual ble_error_t startAdvertising(const GapAdvertisingParams &);
8888
virtual ble_error_t stopAdvertising(void);
89+
virtual ble_error_t connect(const Address_t, ble::peer_address_type_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams);
8990
virtual ble_error_t connect(const Address_t, BLEProtocol::AddressType_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams);
9091
virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason);
9192
virtual ble_error_t disconnect(DisconnectionReason_t reason);

0 commit comments

Comments
 (0)