mirror of https://github.com/ARMmbed/mbed-os.git
Nordic BLE: Backport privacy backward compatibility to NRF51
parent
14a1095c31
commit
57ffa14b4b
|
|
@ -32,6 +32,10 @@ using ble::pal::vendor::nordic::nRF5xSecurityManager;
|
|||
typedef nRF5xSecurityManager::resolving_list_entry_t resolving_list_entry_t;
|
||||
using ble::ArrayView;
|
||||
using ble::pal::advertising_peer_address_type_t;
|
||||
using ble::peer_address_type_t;
|
||||
|
||||
typedef BLEProtocol::AddressType LegacyAddressType;
|
||||
typedef BLEProtocol::AddressType_t LegacyAddressType_t;
|
||||
|
||||
namespace {
|
||||
|
||||
|
|
@ -39,14 +43,16 @@ nRF5xSecurityManager& get_sm() {
|
|||
return nRF5xSecurityManager::get_security_manager();
|
||||
}
|
||||
|
||||
void set_private_resolvable_address() {
|
||||
ble_error_t set_private_resolvable_address() {
|
||||
ble_gap_addr_t addr = { BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE };
|
||||
sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &addr);
|
||||
uint32_t err = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &addr);
|
||||
return err ? BLE_ERROR_UNSPECIFIED : BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
void set_private_non_resolvable_address() {
|
||||
ble_error_t set_private_non_resolvable_address() {
|
||||
ble_gap_addr_t addr = { BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE };
|
||||
sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &addr);
|
||||
uint32_t err = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &addr);
|
||||
return err ? BLE_ERROR_UNSPECIFIED : BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
bool is_advertising_non_connectable(const GapAdvertisingParams ¶ms) {
|
||||
|
|
@ -59,29 +65,24 @@ bool is_advertising_non_connectable(const GapAdvertisingParams ¶ms) {
|
|||
}
|
||||
}
|
||||
|
||||
bool is_identity_address(BLEProtocol::AddressType_t address_type) {
|
||||
switch (address_type) {
|
||||
case BLEProtocol::AddressType::PUBLIC_IDENTITY:
|
||||
case BLEProtocol::AddressType::RANDOM_STATIC_IDENTITY:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
bool is_identity_address(peer_address_type_t address_type) {
|
||||
return address_type == peer_address_type_t::PUBLIC_IDENTITY ||
|
||||
address_type == peer_address_type_t::RANDOM_STATIC_IDENTITY;
|
||||
}
|
||||
|
||||
BLEProtocol::AddressType_t convert_nordic_address(uint8_t address) {
|
||||
peer_address_type_t convert_nordic_address(uint8_t address) {
|
||||
if (address == BLE_GAP_ADDR_TYPE_PUBLIC) {
|
||||
return BLEProtocol::AddressType::PUBLIC;
|
||||
return peer_address_type_t::PUBLIC;
|
||||
} else {
|
||||
return BLEProtocol::AddressType::RANDOM;
|
||||
return peer_address_type_t::RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
BLEProtocol::AddressType_t convert_identity_address(advertising_peer_address_type_t address) {
|
||||
peer_address_type_t convert_identity_address(advertising_peer_address_type_t address) {
|
||||
if (address == advertising_peer_address_type_t::PUBLIC_ADDRESS) {
|
||||
return BLEProtocol::AddressType::PUBLIC_IDENTITY;
|
||||
return peer_address_type_t::PUBLIC_IDENTITY;
|
||||
} else {
|
||||
return BLEProtocol::AddressType::RANDOM_STATIC_IDENTITY;
|
||||
return peer_address_type_t::RANDOM_STATIC_IDENTITY;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +104,7 @@ nRF5xGap::nRF5xGap() : Gap(),
|
|||
_privacy_enabled(false),
|
||||
_peripheral_privacy_configuration(default_peripheral_privacy_configuration),
|
||||
_central_privacy_configuration(default_central_privacy_configuration),
|
||||
_non_private_type(BLEProtocol::AddressType::RANDOM)
|
||||
_non_private_address_type(LegacyAddressType::RANDOM_STATIC)
|
||||
{
|
||||
m_connectionHandle = BLE_CONN_HANDLE_INVALID;
|
||||
}
|
||||
|
|
@ -259,12 +260,10 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams ¶ms)
|
|||
whitelist.addr_count = 0;
|
||||
whitelist.irk_count = 0;
|
||||
|
||||
/* Add missing IRKs to whitelist from the bond table held by the SoftDevice */
|
||||
if (advertisingPolicyMode != Gap::ADV_POLICY_IGNORE_WHITELIST) {
|
||||
ble_error_t error = generateStackWhitelist(whitelist);
|
||||
if (error != BLE_ERROR_NONE) {
|
||||
return error;
|
||||
}
|
||||
whitelist.addr_count = whitelistAddressesSize;
|
||||
|
||||
for (uint32_t i = 0; i < whitelistAddressesSize; ++i) {
|
||||
whitelistAddressPtrs[i] = &whitelistAddresses[i];
|
||||
}
|
||||
|
||||
if (_privacy_enabled) {
|
||||
|
|
@ -295,15 +294,12 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams ¶ms)
|
|||
/* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */
|
||||
|
||||
/* Start Advertising */
|
||||
|
||||
|
||||
adv_para.type = params.getAdvertisingType();
|
||||
adv_para.p_peer_addr = NULL; // Undirected advertisement
|
||||
adv_para.fp = advertisingPolicyMode;
|
||||
adv_para.interval = params.getIntervalInADVUnits(); // advertising interval (in units of 0.625 ms)
|
||||
adv_para.timeout = params.getTimeout();
|
||||
|
||||
|
||||
err = sd_ble_gap_adv_start(&adv_para);
|
||||
switch(err) {
|
||||
case ERROR_NONE:
|
||||
|
|
@ -319,7 +315,6 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams ¶ms)
|
|||
#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
|
||||
ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams)
|
||||
{
|
||||
|
||||
ble_gap_scan_params_t scanParams;
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
|
|
@ -333,15 +328,26 @@ ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams)
|
|||
whitelist.addr_count = 0;
|
||||
whitelist.irk_count = 0;
|
||||
|
||||
/* Add missing IRKs to whitelist from the bond table held by the SoftDevice */
|
||||
if (scanningPolicyMode != Gap::SCAN_POLICY_IGNORE_WHITELIST) {
|
||||
ble_error_t error = generateStackWhitelist(whitelist);
|
||||
if (error != BLE_ERROR_NONE) {
|
||||
return error;
|
||||
}
|
||||
whitelist.addr_count = whitelistAddressesSize;
|
||||
|
||||
for (uint32_t i = 0; i < whitelistAddressesSize; ++i) {
|
||||
whitelistAddressPtrs[i] = &whitelistAddresses[i];
|
||||
}
|
||||
|
||||
// FIXME: fill the irk list once addresses are resolved by the softdevice.
|
||||
if (_privacy_enabled) {
|
||||
if (_central_privacy_configuration.resolution_strategy != CentralPrivacyConfiguration_t::DO_NOT_RESOLVE) {
|
||||
ArrayView<resolving_list_entry_t> entries = get_sm().get_resolving_list();
|
||||
|
||||
size_t limit = std::min(
|
||||
entries.size(), (size_t) YOTTA_CFG_IRK_TABLE_MAX_SIZE
|
||||
);
|
||||
|
||||
for (size_t i = 0; i < limit; ++i) {
|
||||
whitelistIrkPtrs[i] = (ble_gap_irk_t*) entries[i].peer_irk.data();
|
||||
}
|
||||
whitelist.irk_count = limit;
|
||||
}
|
||||
}
|
||||
|
||||
scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */
|
||||
scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */
|
||||
|
|
@ -408,11 +414,59 @@ ble_error_t nRF5xGap::stopAdvertising(void)
|
|||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
ble_error_t nRF5xGap::connect(const Address_t peerAddr,
|
||||
BLEProtocol::AddressType_t peerAddrType,
|
||||
const ConnectionParams_t *connectionParams,
|
||||
const GapScanningParams *scanParamsIn)
|
||||
{
|
||||
ble_error_t nRF5xGap::connect(
|
||||
const Address_t peerAddr,
|
||||
peer_address_type_t peerAddrType,
|
||||
const ConnectionParams_t *connectionParams,
|
||||
const GapScanningParams *scanParamsIn
|
||||
) {
|
||||
// NOTE: Nordic address type is an closer to LegacyAddressType: resolved
|
||||
// address are treaded either as PUBLIC or RANDOM STATIC adresses.
|
||||
// The idea is to get the conversion done here and call the legacy function.
|
||||
|
||||
LegacyAddressType_t legacy_address;
|
||||
|
||||
switch (peerAddrType.value()) {
|
||||
case peer_address_type_t::PUBLIC:
|
||||
case peer_address_type_t::PUBLIC_IDENTITY:
|
||||
legacy_address = LegacyAddressType::PUBLIC;
|
||||
break;
|
||||
case peer_address_type_t::RANDOM_STATIC_IDENTITY:
|
||||
legacy_address = LegacyAddressType::RANDOM_STATIC;
|
||||
break;
|
||||
case peer_address_type_t::RANDOM: {
|
||||
RandomAddressType_t random_address_type(RandomAddressType_t::STATIC);
|
||||
ble_error_t err = getRandomAddressType(peerAddr, &random_address_type);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
switch (random_address_type.value()) {
|
||||
case RandomAddressType_t::STATIC:
|
||||
legacy_address = LegacyAddressType::RANDOM_STATIC;
|
||||
break;
|
||||
case RandomAddressType_t::NON_RESOLVABLE_PRIVATE:
|
||||
legacy_address = LegacyAddressType::RANDOM_PRIVATE_NON_RESOLVABLE;
|
||||
break;
|
||||
case RandomAddressType_t::RESOLVABLE_PRIVATE:
|
||||
legacy_address = LegacyAddressType::RANDOM_PRIVATE_RESOLVABLE;
|
||||
break;
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return connect(peerAddr, legacy_address, connectionParams, scanParamsIn);
|
||||
}
|
||||
|
||||
ble_error_t nRF5xGap::connect(
|
||||
const Address_t peerAddr,
|
||||
LegacyAddressType_t peerAddrType,
|
||||
const ConnectionParams_t *connectionParams,
|
||||
const GapScanningParams *scanParamsIn
|
||||
) {
|
||||
ble_gap_addr_t addr;
|
||||
ble_gap_addr_t* addr_ptr = &addr;
|
||||
addr.addr_type = peerAddrType;
|
||||
|
|
@ -444,40 +498,21 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr,
|
|||
whitelist.addr_count = 0;
|
||||
whitelist.irk_count = 0;
|
||||
|
||||
/* Add missing IRKs to whitelist from the bond table held by the SoftDevice */
|
||||
if (scanningPolicyMode != Gap::SCAN_POLICY_IGNORE_WHITELIST) {
|
||||
ble_error_t error = generateStackWhitelist(whitelist);
|
||||
if (error != BLE_ERROR_NONE) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */
|
||||
scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */
|
||||
|
||||
if (_privacy_enabled) {
|
||||
// configure the "whitelist" with the IRK associated with the identity
|
||||
// address in input.
|
||||
if (is_identity_address(peerAddrType)) {
|
||||
if (_central_privacy_configuration.resolution_strategy != CentralPrivacyConfiguration_t::DO_NOT_RESOLVE) {
|
||||
ArrayView<resolving_list_entry_t> entries = get_sm().get_resolving_list();
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < entries.size(); ++i) {
|
||||
const ble::address_t& entry_address = entries[i].peer_identity_address;
|
||||
size_t limit = std::min(
|
||||
entries.size(), (size_t) YOTTA_CFG_IRK_TABLE_MAX_SIZE
|
||||
);
|
||||
|
||||
// entry found; fill the whitelist and invalidate addr_ptr
|
||||
if (memcmp(entry_address.data(), peerAddr, entry_address.size_) == 0) {
|
||||
whitelist.pp_irks[0] = (ble_gap_irk_t*) entries[i].peer_irk.data();
|
||||
whitelist.irk_count = 1;
|
||||
scanParams.selective = 1;
|
||||
addr_ptr = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Occur only if the address in input hasn't been resolved.
|
||||
if (i == entries.size()) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
for (size_t i = 0; i < limit; ++i) {
|
||||
whitelistIrkPtrs[i] = (ble_gap_irk_t*) entries[i].peer_irk.data();
|
||||
}
|
||||
whitelist.irk_count = limit;
|
||||
}
|
||||
|
||||
set_private_resolvable_address();
|
||||
|
|
@ -666,11 +701,11 @@ uint16_t nRF5xGap::getConnectionHandle(void)
|
|||
@endcode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
|
||||
ble_error_t nRF5xGap::setAddress(LegacyAddressType_t type, const Address_t address)
|
||||
{
|
||||
using BLEProtocol::AddressType;
|
||||
|
||||
if (type != AddressType::PUBLIC || type != AddressType::RANDOM_STATIC) {
|
||||
if (type != LegacyAddressType::PUBLIC &&
|
||||
type != LegacyAddressType::RANDOM_STATIC
|
||||
) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
|
|
@ -680,30 +715,41 @@ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
|
|||
|
||||
ble_gap_addr_t dev_addr;
|
||||
memcpy(dev_addr.addr, address, ADDR_LEN);
|
||||
if (type == AddressType::PUBLIC) {
|
||||
if (type == LegacyAddressType::PUBLIC) {
|
||||
dev_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
|
||||
} else {
|
||||
dev_addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC;
|
||||
}
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE);
|
||||
uint32_t err = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &dev_addr);
|
||||
#else
|
||||
// FIXME is there any reason to use the pm ?
|
||||
ble_gap_privacy_params_t privacy_params = {0};
|
||||
privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_OFF;
|
||||
|
||||
ASSERT_INT(ERROR_NONE, pm_id_addr_set(&dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE);
|
||||
ASSERT_INT(ERROR_NONE, pm_privacy_set(&privacy_params), BLE_ERROR_PARAM_OUT_OF_RANGE);
|
||||
uint32_t err = sd_ble_gap_addr_set(&dev_addr);
|
||||
#endif
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
switch (err) {
|
||||
case NRF_SUCCESS:
|
||||
return BLE_ERROR_NONE;
|
||||
case NRF_ERROR_INVALID_ADDR:
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
case BLE_ERROR_GAP_INVALID_BLE_ADDR:
|
||||
return BLE_ERROR_PARAM_OUT_OF_RANGE;
|
||||
case NRF_ERROR_BUSY:
|
||||
return BLE_STACK_BUSY;
|
||||
case NRF_ERROR_INVALID_STATE:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address)
|
||||
{
|
||||
ble_gap_addr_t dev_addr;
|
||||
if (typeP == NULL || address == NULL) {
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ble_gap_addr_t dev_addr;
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
if (sd_ble_gap_address_get(&dev_addr) != NRF_SUCCESS) {
|
||||
#else
|
||||
|
|
@ -712,17 +758,20 @@ ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address)
|
|||
return BLE_ERROR_PARAM_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
if (typeP != NULL) {
|
||||
if (dev_addr.addr_type == BLE_GAP_ADDR_TYPE_PUBLIC){
|
||||
*typeP = BLEProtocol::AddressType::PUBLIC;
|
||||
} else {
|
||||
*typeP = BLEProtocol::AddressType::RANDOM;
|
||||
}
|
||||
switch (dev_addr.addr_type) {
|
||||
case BLE_GAP_ADDR_TYPE_PUBLIC:
|
||||
*typeP = LegacyAddressType::PUBLIC;
|
||||
break;
|
||||
|
||||
case BLE_GAP_ADDR_TYPE_RANDOM_STATIC:
|
||||
*typeP = LegacyAddressType::RANDOM_STATIC;
|
||||
break;
|
||||
|
||||
default:
|
||||
return BLE_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (address != NULL) {
|
||||
memcpy(address, dev_addr.addr, ADDR_LEN);
|
||||
}
|
||||
memcpy(address, dev_addr.addr, ADDR_LEN);
|
||||
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
|
@ -849,9 +898,7 @@ ble_error_t nRF5xGap::getWhitelist(Gap::Whitelist_t &whitelistOut) const
|
|||
uint32_t i;
|
||||
for (i = 0; i < whitelistAddressesSize && i < whitelistOut.capacity; ++i) {
|
||||
memcpy( &whitelistOut.addresses[i].address, &whitelistAddresses[i].addr, sizeof(whitelistOut.addresses[0].address));
|
||||
whitelistOut.addresses[i].type = static_cast<BLEProtocol::AddressType_t> (whitelistAddresses[i].addr_type);
|
||||
|
||||
|
||||
whitelistOut.addresses[i].type = static_cast<LegacyAddressType_t> (whitelistAddresses[i].addr_type);
|
||||
}
|
||||
whitelistOut.size = i;
|
||||
|
||||
|
|
@ -896,7 +943,9 @@ ble_error_t nRF5xGap::setWhitelist(const Gap::Whitelist_t &whitelistIn)
|
|||
|
||||
/* Test for invalid parameters before we change the internal state */
|
||||
for (uint32_t i = 0; i < whitelistIn.size; ++i) {
|
||||
if (whitelistIn.addresses[i].type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
|
||||
if (whitelistIn.addresses[i].type == LegacyAddressType::RANDOM_PRIVATE_NON_RESOLVABLE ||
|
||||
whitelistIn.addresses[i].type == LegacyAddressType::RANDOM_PRIVATE_RESOLVABLE
|
||||
) {
|
||||
/* This is not allowed because it is completely meaningless */
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
|
@ -1052,24 +1101,38 @@ Gap::InitiatorPolicyMode_t nRF5xGap::getInitiatorPolicyMode(void) const
|
|||
return Gap::INIT_POLICY_IGNORE_WHITELIST;
|
||||
}
|
||||
|
||||
ble_error_t nRF5xGap::enablePrivacy(bool enable)
|
||||
ble_error_t nRF5xGap::enablePrivacy(bool enable_privacy)
|
||||
{
|
||||
if (enable == _privacy_enabled) {
|
||||
if (enable_privacy == _privacy_enabled) {
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
ble_error_t err = BLE_ERROR_UNSPECIFIED;
|
||||
if (enable == false) {
|
||||
err = setAddress(_non_private_type, _non_private_address);
|
||||
if (enable_privacy == false) {
|
||||
err = setAddress(_non_private_address_type, _non_private_address);
|
||||
} else {
|
||||
err = getAddress(&_non_private_type, _non_private_address);
|
||||
err = getAddress(&_non_private_address_type, _non_private_address);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
_privacy_enabled = enable;
|
||||
#if (NRF_SD_BLE_API_VERSION > 2)
|
||||
ble_gap_privacy_params_t privacy_config = { 0 };
|
||||
if (sd_ble_gap_privacy_get(&privacy_config)) {
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
privacy_config.privacy_mode = enable_privacy ?
|
||||
BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY :
|
||||
BLE_GAP_PRIVACY_MODE_OFF;
|
||||
if (sd_ble_gap_privacy_set(&privacy_config)) {
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
#endif
|
||||
|
||||
_privacy_enabled = enable_privacy;
|
||||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
|
|
@ -1101,116 +1164,6 @@ ble_error_t nRF5xGap::getCentralPrivacyConfiguration(
|
|||
return BLE_ERROR_NONE;
|
||||
}
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Helper function used to populate the ble_gap_whitelist_t that
|
||||
will be used by the SoftDevice for filtering requests.
|
||||
@returns \ref ble_error_t
|
||||
@retval BLE_ERROR_NONE
|
||||
Everything executed properly
|
||||
@retval BLE_ERROR_INVALID_STATE
|
||||
The internal stack was not initialized correctly.
|
||||
@note Both the SecurityManager and Gap must initialize correctly for
|
||||
this function to succeed.
|
||||
@note This function is needed because for the BLE API the whitelist
|
||||
is just a collection of keys, but for the stack it also includes
|
||||
the IRK table.
|
||||
@section EXAMPLE
|
||||
@code
|
||||
@endcode
|
||||
*/
|
||||
/**************************************************************************/
|
||||
ble_error_t nRF5xGap::generateStackWhitelist(ble_gap_whitelist_t &whitelist)
|
||||
{
|
||||
return BLE_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION >= 3)
|
||||
|
||||
/**
|
||||
* Function for preparing settings of the whitelist feature and the identity-resolving feature (privacy) for the SoftDevice.
|
||||
*
|
||||
* Gap::setWhitelist provides the base for preparation of these settings.
|
||||
* This function matches resolvable addresses (passed by Gap::setWhitelist) to IRK data in bonds table.
|
||||
* Therefore resolvable addresses instead of being passed to the whitelist (intended to be passed to the Softdevice)
|
||||
* are passed to the identities list (intended to be passed to the Softdevice).
|
||||
*
|
||||
* @param[out] gapAdrHelper Reference to the struct for storing settings.
|
||||
*/
|
||||
|
||||
ble_error_t nRF5xGap::getStackWhiteIdentityList(GapWhiteAndIdentityList_t &gapAdrHelper)
|
||||
{
|
||||
BLE_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ble_error_t nRF5xGap::applyWhiteIdentityList(GapWhiteAndIdentityList_t &gapAdrHelper)
|
||||
{
|
||||
uint32_t retc;
|
||||
|
||||
if (gapAdrHelper.identities_cnt == 0) {
|
||||
retc = sd_ble_gap_device_identities_set(NULL, NULL, 0);
|
||||
} else {
|
||||
ble_gap_id_key_t * pp_identities[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
|
||||
|
||||
for (uint32_t i = 0; i < gapAdrHelper.identities_cnt; ++i)
|
||||
{
|
||||
pp_identities[i] = &gapAdrHelper.identities[i];
|
||||
}
|
||||
|
||||
retc = sd_ble_gap_device_identities_set(pp_identities, NULL /* Don't use local IRKs*/,gapAdrHelper.identities_cnt);
|
||||
}
|
||||
|
||||
if (retc == NRF_SUCCESS) {
|
||||
if (gapAdrHelper.addrs_cnt == 0) {
|
||||
retc = sd_ble_gap_whitelist_set(NULL, 0);
|
||||
} else {
|
||||
ble_gap_addr_t * pp_addrs[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
|
||||
|
||||
for (uint32_t i = 0; i < gapAdrHelper.addrs_cnt; ++i)
|
||||
{
|
||||
pp_addrs[i] = &gapAdrHelper.addrs[i];
|
||||
}
|
||||
|
||||
retc = sd_ble_gap_whitelist_set(pp_addrs, gapAdrHelper.addrs_cnt);
|
||||
}
|
||||
}
|
||||
|
||||
switch(retc) {
|
||||
case NRF_SUCCESS:
|
||||
return BLE_ERROR_NONE;
|
||||
|
||||
case BLE_ERROR_GAP_WHITELIST_IN_USE: //The whitelist is in use by a BLE role and cannot be set or cleared.
|
||||
case BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE: //The device identity list is in use and cannot be set or cleared.
|
||||
return BLE_ERROR_ALREADY_INITIALIZED;
|
||||
|
||||
case NRF_ERROR_INVALID_ADDR:
|
||||
case BLE_ERROR_GAP_INVALID_BLE_ADDR: //Invalid address type is supplied.
|
||||
case NRF_ERROR_DATA_SIZE:
|
||||
case BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE: //The device identity list contains multiple entries with the same identity address.
|
||||
return BLE_ERROR_INVALID_PARAM;
|
||||
|
||||
default:
|
||||
return BLE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
ble_error_t nRF5xGap::updateWhiteAndIdentityListInStack()
|
||||
{
|
||||
GapWhiteAndIdentityList_t whiteAndIdentityList;
|
||||
uint32_t err;
|
||||
|
||||
err = getStackWhiteIdentityList(whiteAndIdentityList);
|
||||
|
||||
if (err != BLE_ERROR_NONE) {
|
||||
return (ble_error_t)err;
|
||||
}
|
||||
|
||||
return applyWhiteIdentityList(whiteAndIdentityList);
|
||||
}
|
||||
#endif
|
||||
|
||||
void nRF5xGap::set_connection_event_handler(
|
||||
ConnectionEventMonitor::EventHandler* connection_event_handler
|
||||
) {
|
||||
|
|
@ -1241,36 +1194,44 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t
|
|||
setConnectionHandle(handle);
|
||||
|
||||
// deal with own address
|
||||
AddressType_t own_addr_type;
|
||||
LegacyAddressType_t own_addr_type;
|
||||
Address_t own_address;
|
||||
const uint8_t* own_resolvable_address = NULL;
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
if (evt.own_addr.addr_type == BLE_GAP_ADDR_TYPE_PUBLIC) {
|
||||
own_addr_type = AddressType::PUBLIC;
|
||||
if (_privacy_enabled) {
|
||||
own_addr_type = LegacyAddressType::RANDOM_PRIVATE_RESOLVABLE;
|
||||
} else {
|
||||
own_addr_type = AddressType::RANDOM;
|
||||
if (evt.own_addr.addr_type == BLE_GAP_ADDR_TYPE_PUBLIC) {
|
||||
own_addr_type = LegacyAddressType::PUBLIC;
|
||||
} else {
|
||||
own_addr_type = LegacyAddressType::RANDOM_STATIC;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: is it the resolvable address or the identity address ?
|
||||
memcpy(own_address, evt.own_addr.addr, sizeof(own_address));
|
||||
#else
|
||||
gap.getAddress(&addr_type, own_address);
|
||||
#endif
|
||||
|
||||
if (_privacy_enabled) {
|
||||
own_resolvable_address = own_address;
|
||||
}
|
||||
|
||||
// deal with the peer address: If privacy is enabled then the softdevice
|
||||
// indicates if the address has been resolved or not. If the address has
|
||||
// been resolved then the identity address should be passed to the application.
|
||||
// Depending on the privacy chosen by the application, connection request
|
||||
// from privacy enabled peers may trigger a disconnection, the pairing procedure
|
||||
// or the authentication procedure.
|
||||
AddressType_t peer_addr_type;
|
||||
peer_address_type_t peer_addr_type(peer_address_type_t::PUBLIC);
|
||||
const uint8_t* peer_address;
|
||||
const uint8_t* peer_resolvable_address;
|
||||
|
||||
if (evt.irk_match) {
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
bool private_peer_known = evt.irk_match;
|
||||
#else
|
||||
bool private_peer_known = evt.peer_addr.addr_id_peer;
|
||||
#endif
|
||||
|
||||
if (private_peer_known) {
|
||||
const resolving_list_entry_t* entry = get_sm().resolve_address(
|
||||
evt.peer_addr.addr
|
||||
);
|
||||
|
|
@ -1311,14 +1272,14 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t
|
|||
}
|
||||
|
||||
// Apply authentication strategy before application notification
|
||||
if (!evt.irk_match &&
|
||||
if (!private_peer_known &&
|
||||
_privacy_enabled &&
|
||||
evt.role == BLE_GAP_ROLE_PERIPH &&
|
||||
evt.peer_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE
|
||||
) {
|
||||
switch (_peripheral_privacy_configuration.resolution_strategy) {
|
||||
case PeripheralPrivacyConfiguration_t::PERFORM_PAIRING_PROCEDURE:
|
||||
nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getSecurityManager().requestPairing(handle);
|
||||
nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getSecurityManager().requestAuthentication(handle);
|
||||
break;
|
||||
|
||||
case PeripheralPrivacyConfiguration_t::PERFORM_AUTHENTICATION_PROCEDURE:
|
||||
|
|
@ -1344,9 +1305,7 @@ void nRF5xGap::on_connection(Gap::Handle_t handle, const ble_gap_evt_connected_t
|
|||
}
|
||||
|
||||
void nRF5xGap::on_advertising_packet(const ble_gap_evt_adv_report_t &evt) {
|
||||
using BLEProtocol::AddressType;
|
||||
|
||||
AddressType_t peer_addr_type;
|
||||
peer_address_type_t peer_addr_type(peer_address_type_t::PUBLIC);
|
||||
const uint8_t* peer_address = evt.peer_addr.addr;
|
||||
|
||||
if (_privacy_enabled &&
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ public:
|
|||
|
||||
virtual ble_error_t startAdvertising(const GapAdvertisingParams &);
|
||||
virtual ble_error_t stopAdvertising(void);
|
||||
virtual ble_error_t connect(const Address_t, ble::peer_address_type_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams);
|
||||
virtual ble_error_t connect(const Address_t, BLEProtocol::AddressType_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams);
|
||||
virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason);
|
||||
virtual ble_error_t disconnect(DisconnectionReason_t reason);
|
||||
|
|
@ -159,39 +160,6 @@ private:
|
|||
uint8_t whitelistAddressesSize;
|
||||
ble_gap_addr_t whitelistAddresses[YOTTA_CFG_WHITELIST_MAX_SIZE];
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION <= 2)
|
||||
/*
|
||||
* An internal function used to populate the ble_gap_whitelist_t that will be used by
|
||||
* the SoftDevice for filtering requests. This function is needed because for the BLE
|
||||
* API the whitelist is just a collection of keys, but for the stack it also includes
|
||||
* the IRK table.
|
||||
*/
|
||||
ble_error_t generateStackWhitelist(ble_gap_whitelist_t &whitelist);
|
||||
#endif
|
||||
|
||||
#if (NRF_SD_BLE_API_VERSION >= 3)
|
||||
/* internal type for passing a whitelist and a identities list. */
|
||||
typedef struct
|
||||
{
|
||||
ble_gap_addr_t addrs[YOTTA_CFG_WHITELIST_MAX_SIZE];
|
||||
uint32_t addrs_cnt;
|
||||
|
||||
ble_gap_id_key_t identities[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
|
||||
uint32_t identities_cnt;
|
||||
} GapWhiteAndIdentityList_t;
|
||||
|
||||
/* Function for preparing setting of the whitelist feature and the identity-resolving feature (privacy).*/
|
||||
ble_error_t getStackWhiteIdentityList(GapWhiteAndIdentityList_t &whiteAndIdentityList);
|
||||
|
||||
/* Function for applying setting of the whitelist feature and identity-resolving feature (privacy).*/
|
||||
ble_error_t applyWhiteIdentityList(GapWhiteAndIdentityList_t &whiteAndIdentityList);
|
||||
|
||||
/* Function for introducing whitelist feature and the identity-resolving feature setting into SoftDevice.
|
||||
*
|
||||
* This function incorporates getStackWhiteIdentityList and applyWhiteIdentityList together. */
|
||||
ble_error_t updateWhiteAndIdentityListInStack(void);
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool radioNotificationCallbackParam; /* parameter to be passed into the Timeout-generated radio notification callback. */
|
||||
Timeout radioNotificationTimeout;
|
||||
|
|
@ -303,7 +271,7 @@ private:
|
|||
bool _privacy_enabled;
|
||||
PeripheralPrivacyConfiguration_t _peripheral_privacy_configuration;
|
||||
CentralPrivacyConfiguration_t _central_privacy_configuration;
|
||||
AddressType_t _non_private_type;
|
||||
AddressType_t _non_private_address_type;
|
||||
Address_t _non_private_address;
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue