Make NRF5 BLE implementation compatible with SoftDevice API 2.x.x,3.x.x,5.0.0-1.alpha by

Copy of changes from
features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5_SDK13/source
to
features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source
pull/4245/head
Andrzej Puzdrowski 2017-04-27 09:46:38 +02:00
parent 2ff5726827
commit b2080ab6d9
19 changed files with 394 additions and 122 deletions

View File

@ -24,7 +24,6 @@
#include "ble_conn_params.h"
#include "btle_gap.h"
#include "btle_advertising.h"
#include "custom/custom_helper.h"
#include "ble/GapEvents.h"
@ -51,7 +50,7 @@ extern "C" {
#include "ble_stack_handler_types.h"
}
#include "nrf_ble_hci.h"
#include "ble_hci.h"
#include "btle_discovery.h"
#include "nRF5xGattClient.h"
@ -165,6 +164,10 @@ error_t btle_init(void)
return ERROR_INVALID_PARAM;
}
// Peer Manger must been initialised prior any other call to its API (this file and btle_security_pm.cpp)
pm_init();
#if (NRF_SD_BLE_API_VERSION <= 2)
ble_gap_addr_t addr;
if (sd_ble_gap_address_get(&addr) != NRF_SUCCESS) {
return ERROR_INVALID_PARAM;
@ -172,6 +175,11 @@ error_t btle_init(void)
if (sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr) != NRF_SUCCESS) {
return ERROR_INVALID_PARAM;
}
#else
ble_gap_privacy_params_t privacy_params = {0};
privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_OFF;
pm_privacy_set(&privacy_params);
#endif
ASSERT_STATUS( softdevice_ble_evt_handler_set(btle_handler));
ASSERT_STATUS( softdevice_sys_evt_handler_set(sys_evt_dispatch));
@ -219,12 +227,25 @@ static void btle_handler(ble_evt_t *p_ble_evt)
gap.setConnectionHandle(handle);
const Gap::ConnectionParams_t *params = reinterpret_cast<Gap::ConnectionParams_t *>(&(p_ble_evt->evt.gap_evt.params.connected.conn_params));
const ble_gap_addr_t *peer = &p_ble_evt->evt.gap_evt.params.connected.peer_addr;
#if (NRF_SD_BLE_API_VERSION <= 2)
const ble_gap_addr_t *own = &p_ble_evt->evt.gap_evt.params.connected.own_addr;
gap.processConnectionEvent(handle,
role,
static_cast<BLEProtocol::AddressType_t>(peer->addr_type), peer->addr,
static_cast<BLEProtocol::AddressType_t>(own->addr_type), own->addr,
params);
role,
static_cast<BLEProtocol::AddressType_t>(peer->addr_type), peer->addr,
static_cast<BLEProtocol::AddressType_t>(own->addr_type), own->addr,
params);
#else
Gap::AddressType_t addr_type;
Gap::Address_t own_address;
gap.getAddress(&addr_type, own_address);
gap.processConnectionEvent(handle,
role,
static_cast<BLEProtocol::AddressType_t>(peer->addr_type), peer->addr,
addr_type, own_address,
params);
#endif
break;
}

View File

@ -24,7 +24,7 @@ extern "C" {
#include "common/common.h"
#include "ble_srv_common.h"
#include "nrf_ble.h"
#include "headers/ble.h"
error_t btle_init(void);

View File

@ -1,46 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "common/common.h"
#include "ble_advdata.h"
#include "btle.h"
/**************************************************************************/
/*!
@brief Starts the advertising process
@returns
*/
/**************************************************************************/
error_t btle_advertising_start(void)
{
ble_gap_adv_params_t adv_para = {0};
/* Set the default advertising parameters */
adv_para.type = BLE_GAP_ADV_TYPE_ADV_IND;
adv_para.p_peer_addr = NULL; /* Undirected advertising */
adv_para.fp = BLE_GAP_ADV_FP_ANY;
adv_para.p_whitelist = NULL;
adv_para.interval = (CFG_GAP_ADV_INTERVAL_MS * 8) / 5; /* Advertising
* interval in
* units of 0.625
* ms */
adv_para.timeout = CFG_GAP_ADV_TIMEOUT_S;
ASSERT_STATUS( sd_ble_gap_adv_start(&adv_para));
return ERROR_NONE;
}

View File

@ -1,24 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _BTLE_ADVERTISING_H_
#define _BTLE_ADVERTISING_H_
#include "common/common.h"
error_t btle_advertising_start(void);
#endif // ifndef _BTLE_ADVERTISING_H_

View File

@ -57,7 +57,7 @@ void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
if (sdSingleton.isActive()) {
sdSingleton.processDiscoverUUIDResponse(&p_ble_evt->evt.gattc_evt.params.char_val_by_uuid_read_rsp);
sdSingleton.processDiscoverUUIDResponse(&p_ble_evt->evt.gattc_evt);
}
break;

View File

@ -15,7 +15,7 @@
*/
#include "common/common.h"
#include "nrf_ble_gap.h"
#include "ble_gap.h"
#include "ble_conn_params.h"
static inline uint32_t msec_to_1_25msec(uint32_t interval_ms) ATTR_ALWAYS_INLINE ATTR_CONST;

View File

@ -84,6 +84,7 @@ ble_error_t btle_setLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager
*/
ble_error_t btle_purgeAllBondingState(void);
#if (NRF_SD_BLE_API_VERSION <= 2)
/**
* Query the SoftDevice bond table to extract a whitelist containing the BLE
* addresses and IRKs of bonded devices.
@ -98,6 +99,7 @@ ble_error_t btle_purgeAllBondingState(void);
* @return BLE_ERROR_NONE Or appropriate error code indicating reason for failure.
*/
ble_error_t btle_createWhitelistFromBondTable(ble_gap_whitelist_t *p_whitelist);
#endif
/**
* Function to test whether a BLE address is generated using an IRK.

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
#if defined(S130) || defined(S132)
#if defined(S130) || defined(S132) || defined(S140)
#include "btle.h"
#include "nRF5xn.h"
@ -94,10 +94,6 @@ btle_initializeSecurity(bool enableBonding,
}
}
if (pm_init() != NRF_SUCCESS) {
return BLE_ERROR_UNSPECIFIED;
}
// update default security parameters with function call parameters
securityParameters.bond = enableBonding;
securityParameters.mitm = requireMITM;
@ -393,6 +389,7 @@ void pm_handler(pm_evt_t const *p_event)
}
}
#if (NRF_SD_BLE_API_VERSION <= 2)
ble_error_t
btle_createWhitelistFromBondTable(ble_gap_whitelist_t *p_whitelist)
{
@ -408,7 +405,7 @@ btle_createWhitelistFromBondTable(ble_gap_whitelist_t *p_whitelist)
return BLE_ERROR_INVALID_STATE;
}
}
#endif
bool
btle_matchAddressAndIrk(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk)

View File

@ -18,7 +18,7 @@
#define _CUSTOM_HELPER_H_
#include "common/common.h"
#include "nrf_ble.h"
#include "headers/ble.h"
#include "ble/UUID.h"
#include "ble/GattCharacteristic.h"

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "nRF5xCharacteristicDescriptorDiscoverer.h"
#include "nrf_ble_err.h"
#include "ble_err.h"
#include "ble/DiscoveredCharacteristicDescriptor.h"
nRF5xCharacteristicDescriptorDiscoverer::nRF5xCharacteristicDescriptorDiscoverer() :
@ -136,6 +136,7 @@ void nRF5xCharacteristicDescriptorDiscoverer::processAttributeInformation(
return;
}
#if (NRF_SD_BLE_API_VERSION <= 2)
// for all UUIDS found, process the discovery
for (uint16_t i = 0; i < infos.count; ++i) {
bool use_16bits_uuids = infos.format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT;
@ -146,6 +147,27 @@ void nRF5xCharacteristicDescriptorDiscoverer::processAttributeInformation(
// prepare the next round of descriptors discovery
uint16_t startHandle = infos.attr_info[infos.count - 1].handle + 1;
#else
uint16_t startHandle;
// for all UUIDS found, process the discovery
if (infos.format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) {
for (uint16_t i = 0; i < infos.count; ++i) {
UUID uuid = UUID(infos.info.attr_info16[i].uuid.uuid);
discovery->process(infos.info.attr_info16[i].handle, uuid);
}
// prepare the next round of descriptors discovery
startHandle = infos.info.attr_info16[infos.count - 1].handle + 1;
} else {
for (uint16_t i = 0; i < infos.count; ++i) {
UUID uuid = UUID(infos.info.attr_info128[i].uuid.uuid128, UUID::LSB);
discovery->process(infos.info.attr_info128[i].handle, uuid);
}
// prepare the next round of descriptors discovery
startHandle = infos.info.attr_info128[infos.count - 1].handle + 1;
}
#endif
uint16_t endHandle = discovery->getCharacteristic().getLastHandle();
if(startHandle > endHandle) {

View File

@ -21,7 +21,7 @@
#include "ble/DiscoveredCharacteristic.h"
#include "ble/CharacteristicDescriptorDiscovery.h"
#include "ble/GattClient.h"
#include "nrf_ble_gattc.h"
#include "ble_gattc.h"
/**
* @brief Manage the discovery of Characteristic descriptors

View File

@ -16,7 +16,7 @@
#include "nRF5xDiscoveredCharacteristic.h"
#include "nRF5xGattClient.h"
#include "nrf_ble_gatt.h"
#include "ble_gatt.h"
void
nRF5xDiscoveredCharacteristic::setup(nRF5xGattClient *gattcIn,

View File

@ -18,7 +18,7 @@
#define __NRF_DISCOVERED_CHARACTERISTIC_H__
#include "ble/DiscoveredCharacteristic.h"
#include "nrf_ble_gatt.h"
#include "ble_gatt.h"
class nRF5xGattClient; /* forward declaration */

View File

@ -24,7 +24,13 @@
#include "common/common.h"
#include "ble_advdata.h"
#include "nrf_ble_hci.h"
#include "ble_hci.h"
#if (NRF_SD_BLE_API_VERSION >= 3)
#include "peer_manager.h"
#include "peer_data_storage.h"
#endif
void radioNotificationStaticCallback(bool param) {
nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap();
@ -167,7 +173,11 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams &params)
(params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
uint32_t err;
ble_gap_adv_params_t adv_para = {0};
#if (NRF_SD_BLE_API_VERSION <= 2)
/* Allocate the stack's whitelist statically */
ble_gap_whitelist_t whitelist;
ble_gap_addr_t *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE];
@ -185,18 +195,22 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams &params)
return error;
}
}
adv_para.p_whitelist = &whitelist;
#endif
/* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */
/* Start Advertising */
ble_gap_adv_params_t adv_para = {0};
adv_para.type = params.getAdvertisingType();
adv_para.p_peer_addr = NULL; // Undirected advertisement
adv_para.fp = advertisingPolicyMode;
adv_para.p_whitelist = &whitelist;
adv_para.interval = params.getIntervalInADVUnits(); // advertising interval (in units of 0.625 ms)
adv_para.timeout = params.getTimeout();
uint32_t err = sd_ble_gap_adv_start(&adv_para);
err = sd_ble_gap_adv_start(&adv_para);
switch(err) {
case ERROR_NONE:
return BLE_ERROR_NONE;
@ -211,6 +225,10 @@ ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams &params)
#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)
/* Allocate the stack's whitelist statically */
ble_gap_whitelist_t whitelist;
ble_gap_addr_t *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE];
@ -229,11 +247,17 @@ ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams)
}
}
ble_gap_scan_params_t scanParams;
scanParams.active = scanningParams.getActiveScanning(); /**< If 1, perform active scanning (scan requests). */
scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */
scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */
#else
/* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */
scanParams.use_whitelist = scanningPolicyMode;
scanParams.adv_dir_report = 0;
#endif
scanParams.active = scanningParams.getActiveScanning(); /**< If 1, perform active scanning (scan requests). */
scanParams.interval = scanningParams.getInterval(); /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
scanParams.window = scanningParams.getWindow(); /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
scanParams.timeout = scanningParams.getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
@ -302,6 +326,9 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr,
connParams.conn_sup_timeout = 600;
}
ble_gap_scan_params_t scanParams ={0};
#if (NRF_SD_BLE_API_VERSION <= 2)
/* Allocate the stack's whitelist statically */
ble_gap_whitelist_t whitelist;
ble_gap_addr_t *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE];
@ -319,10 +346,28 @@ ble_error_t nRF5xGap::connect(const Address_t peerAddr,
return error;
}
}
ble_gap_scan_params_t scanParams;
scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */
scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */
#else
/* For NRF_SD_BLE_API_VERSION >= 3 nRF5xGap::setWhitelist setups the whitelist. */
scanParams.use_whitelist = (whitelistAddressesSize) ? 1 : 0;
if ((addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
|| (addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE)) {
/* If a device is using Resolvable Private Addresses Section 1.3.2.2 (Core spec v4.2 volume 6 part B),
it shall also have an Identity Address that is either a Public or Random Static address type.
To establish a connection, a static address must be provided by the application to the SoftDevice.
The SoftDevice resolves the address and connects to the right device if it is available. */
addr.addr_id_peer = 1;
addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
} else {
addr.addr_id_peer = 0;
}
#endif
if (scanParamsIn != NULL) {
scanParams.active = scanParamsIn->getActiveScanning(); /**< If 1, perform active scanning (scan requests). */
scanParams.interval = scanParamsIn->getInterval(); /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
@ -447,6 +492,7 @@ ble_error_t nRF5xGap::reset(void)
/* Clear the internal whitelist */
whitelistAddressesSize = 0;
return BLE_ERROR_NONE;
}
@ -489,7 +535,13 @@ uint16_t nRF5xGap::getConnectionHandle(void)
/**************************************************************************/
ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
{
#if (NRF_SD_BLE_API_VERSION <= 2)
uint8_t cycle_mode;
#else
ble_gap_privacy_params_t privacy_params = {0};
#endif
ble_gap_addr_t dev_addr;
/* When using Public or Static addresses, the cycle mode must be None.
@ -498,12 +550,27 @@ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
*/
if ((type == BLEProtocol::AddressType::PUBLIC) || (type == BLEProtocol::AddressType::RANDOM_STATIC))
{
memcpy(dev_addr.addr, address, ADDR_LEN);
#if (NRF_SD_BLE_API_VERSION <= 2)
cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_NONE;
memcpy(dev_addr.addr, address, ADDR_LEN);
#else
privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_OFF;
dev_addr.addr_type = type;
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);
#endif
}
else if ((type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE) || (type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE))
{
#if (NRF_SD_BLE_API_VERSION <= 2)
cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_AUTO;
#else
privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY;
privacy_params.private_addr_type = type;
ASSERT_INT(ERROR_NONE, pm_privacy_set(&privacy_params), BLE_ERROR_PARAM_OUT_OF_RANGE);
#endif
// address is ignored when in auto mode
}
else
@ -511,8 +578,10 @@ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
#if (NRF_SD_BLE_API_VERSION <= 2)
dev_addr.addr_type = type;
ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(cycle_mode, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE);
#endif
return BLE_ERROR_NONE;
}
@ -520,7 +589,11 @@ ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address)
{
ble_gap_addr_t dev_addr;
#if (NRF_SD_BLE_API_VERSION <= 2)
if (sd_ble_gap_address_get(&dev_addr) != NRF_SUCCESS) {
#else
if (sd_ble_gap_addr_get(&dev_addr) != NRF_SUCCESS) {
#endif
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
@ -599,6 +672,10 @@ void nRF5xGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *co
static const int8_t permittedTxValues[] = {
-40, -20, -16, -12, -8, -4, 0, 4
};
#elif defined(NRF52840_XXAA)
static const int8_t permittedTxValues[] = {
-40, -20, -16, -12, -8, -4, 0, 2, 3, 4, 5, 6, 7, 8, 9
};
#else
#error permitted TX power values unknown for this SOC
#endif
@ -648,9 +725,12 @@ uint8_t nRF5xGap::getMaxWhitelistSize(void) const
/**************************************************************************/
ble_error_t nRF5xGap::getWhitelist(Gap::Whitelist_t &whitelistOut) const
{
uint8_t i;
uint32_t i;
for (i = 0; i < whitelistAddressesSize && i < whitelistOut.capacity; ++i) {
memcpy(&whitelistOut.addresses[i], &whitelistAddresses[i], sizeof(BLEProtocol::Address_t));
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.size = i;
@ -694,19 +774,24 @@ ble_error_t nRF5xGap::setWhitelist(const Gap::Whitelist_t &whitelistIn)
}
/* Test for invalid parameters before we change the internal state */
for (uint8_t i = 0; i < whitelistIn.size; ++i) {
for (uint32_t i = 0; i < whitelistIn.size; ++i) {
if (whitelistIn.addresses[i].type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
/* This is not allowed because it is completely meaningless */
return BLE_ERROR_INVALID_PARAM;
}
}
whitelistAddressesSize = 0;
for (uint8_t i = 0; i < whitelistIn.size; ++i) {
memcpy(&whitelistAddresses[whitelistAddressesSize], &whitelistIn.addresses[i], sizeof(BLEProtocol::Address_t));
whitelistAddressesSize++;
whitelistAddressesSize = whitelistIn.size;
for (uint32_t i = 0; i < whitelistIn.size; ++i) {
memcpy(&whitelistAddresses[i].addr , &whitelistIn.addresses[i].address , sizeof(whitelistAddresses[0].addr));
whitelistAddresses[i].addr_type = static_cast<uint8_t> (whitelistIn.addresses[i].type);
}
#if (NRF_SD_BLE_API_VERSION >= 3)
updateWhiteAndIdentityListInStack();
#endif
return BLE_ERROR_NONE;
}
@ -846,6 +931,7 @@ Gap::InitiatorPolicyMode_t nRF5xGap::getInitiatorPolicyMode(void) const
return Gap::INIT_POLICY_IGNORE_WHITELIST;
}
#if (NRF_SD_BLE_API_VERSION <= 2)
/**************************************************************************/
/*!
@brief Helper function used to populate the ble_gap_whitelist_t that
@ -945,3 +1031,167 @@ ble_error_t nRF5xGap::generateStackWhitelist(ble_gap_whitelist_t &whitelist)
return BLE_ERROR_NONE;
}
#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)
{
pm_peer_id_t peer_id;
ret_code_t ret;
pm_peer_data_bonding_t bond_data;
uint8_t irk_found[YOTTA_CFG_WHITELIST_MAX_SIZE];
memset(irk_found, 0x00, sizeof(irk_found));
gapAdrHelper.identities_cnt = 0;
peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
nRF5xSecurityManager& securityManager = (nRF5xSecurityManager&) nRF5xn::Instance(0).getSecurityManager();
/**
* Build identities list:
* For every private resolvable address in the bond table check if
* there is maching address in th provided whitelist.
*/
while (peer_id != PM_PEER_ID_INVALID)
{
memset(&bond_data, 0x00, sizeof(bond_data));
// Read peer data from flash.
ret = pm_peer_data_bonding_load(peer_id, &bond_data);
if ((ret == NRF_ERROR_NOT_FOUND) || (ret == NRF_ERROR_INVALID_PARAM))
{
// Peer data could not be found in flash or peer ID is not valid.
return BLE_ERROR_UNSPECIFIED;
}
if ( bond_data.peer_ble_id.id_addr_info.addr_type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE)
{
for (uint8_t i = 0; i < whitelistAddressesSize; ++i)
{
if (!irk_found[i])
{
if (whitelistAddresses[i].addr_type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE)
{
//ble_gap_irk_t *p_dfg = &bond_data.peer_ble_id.id_info;
if (securityManager.matchAddressAndIrk(&whitelistAddresses[i], &bond_data.peer_ble_id.id_info))
{
// Copy data to the buffer.
memcpy(&gapAdrHelper.identities[i], &bond_data.peer_ble_id, sizeof(ble_gap_id_key_t));
gapAdrHelper.identities_cnt++;
irk_found[i] = 1; // don't look at this address again
}
}
}
}
}
// get next peer id
peer_id = pm_next_peer_id_get(peer_id);
}
gapAdrHelper.addrs_cnt = 0;
/**
* Build whitelist from the rest of addresses (explicit addresses)
*/
for (uint8_t i = 0; i < whitelistAddressesSize; ++i)
{
if (!irk_found[i])
{
memcpy(&gapAdrHelper.addrs[i], &whitelistAddresses[i], sizeof(ble_gap_addr_t));
gapAdrHelper.addrs[i].addr_id_peer = 0;
gapAdrHelper.addrs_cnt++;
}
}
return BLE_ERROR_NONE;
}
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

View File

@ -29,13 +29,17 @@
#define YOTTA_CFG_WHITELIST_MAX_SIZE BLE_GAP_WHITELIST_ADDR_MAX_COUNT
#endif
#ifndef YOTTA_CFG_IRK_TABLE_MAX_SIZE
#define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_WHITELIST_IRK_MAX_COUNT
#if (NRF_SD_BLE_API_VERSION >= 3)
#define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT
#else
#define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_WHITELIST_IRK_MAX_COUNT
#endif
#elif YOTTA_CFG_IRK_TABLE_MAX_SIZE > BLE_GAP_WHITELIST_IRK_MAX_COUNT
#undef YOTTA_CFG_IRK_TABLE_MAX_SIZE
#define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_WHITELIST_IRK_MAX_COUNT
#endif
#include "ble/blecommon.h"
#include "nrf_ble.h"
#include "headers/ble.h"
#include "ble/GapAdvertisingParams.h"
#include "ble/GapAdvertisingData.h"
#include "ble/Gap.h"
@ -135,6 +139,7 @@ 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
@ -142,6 +147,30 @@ private:
* 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. */

View File

@ -20,7 +20,7 @@
#include <stddef.h>
#include "ble/blecommon.h"
#include "nrf_ble.h" /* nordic ble */
#include "headers/ble.h" /* nordic ble */
#include "ble/Gap.h"
#include "ble/GattServer.h"

View File

@ -45,7 +45,7 @@ public:
virtual ble_error_t purgeAllBondingState(void) {
return btle_purgeAllBondingState();
}
#if (NRF_SD_BLE_API_VERSION <= 2)
/**
* @brief Returns a list of addresses from peers in the stacks bond table.
*
@ -57,6 +57,8 @@ public:
*
* @return
* BLE_ERROR_NONE if successful.
*
* @todo check whether remove this function (because it is never called)
*/
virtual ble_error_t getAddressesFromBondTable(Gap::Whitelist_t &addresses) const {
uint8_t i;
@ -112,7 +114,7 @@ public:
return BLE_ERROR_NONE;
}
#endif
/**
* @brief Clear nRF5xSecurityManager's state.
*
@ -146,6 +148,7 @@ private:
nRF5xSecurityManager(const nRF5xSecurityManager &);
const nRF5xSecurityManager& operator=(const nRF5xSecurityManager &);
#if (NRF_SD_BLE_API_VERSION <= 2)
/*
* Expose an interface that allows us to query the SoftDevice bond table
* and extract a whitelist.
@ -153,7 +156,7 @@ private:
ble_error_t createWhitelistFromBondTable(ble_gap_whitelist_t &whitelistFromBondTable) const {
return btle_createWhitelistFromBondTable(&whitelistFromBondTable);
}
#endif
/*
* Given a BLE address and a IRK this function check whether the address
* can be generated from the IRK. To do so, this function uses the hash

View File

@ -281,12 +281,23 @@ nRF5xServiceDiscovery::CharUUIDDiscoveryQueue::triggerFirst(void)
}
void
nRF5xServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response)
nRF5xServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_t *p_gattc_evt)
{
const ble_gattc_evt_char_val_by_uuid_read_rsp_t * response = &p_gattc_evt->params.char_val_by_uuid_read_rsp;
if (state == DISCOVER_SERVICE_UUIDS) {
if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID)) {
UUID::LongUUIDBytes_t uuid;
memcpy(uuid, response->handle_value[0].p_value, UUID::LENGTH_OF_LONG_UUID);
#if (NRF_SD_BLE_API_VERSION >= 3)
/* SoftDevice API since 3.0.0 (e.g. sd 140 5.0.0-1.alpha) provide sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter() helper function,
* but it's not reliable for c++ build.
* Instead of it memcpy gets proper response's value field by offset from handle-value pair: [2 B handle|16 B value=uuid_128b] */
memcpy(uuid, (&response->handle_value + 2), UUID::LENGTH_OF_LONG_UUID);
#else
memcpy(uuid, &(response->handle_value[0].p_value[0]), UUID::LENGTH_OF_LONG_UUID);
#endif
unsigned serviceIndex = serviceUUIDDiscoveryQueue.dequeue();
services[serviceIndex].setupLongUUID(uuid, UUID::LSB);
@ -298,9 +309,16 @@ nRF5xServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_char_val_
} else if (state == DISCOVER_CHARACTERISTIC_UUIDS) {
if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID + 1 /* props */ + 2 /* value handle */)) {
UUID::LongUUIDBytes_t uuid;
#if (NRF_SD_BLE_API_VERSION >= 3)
/* SoftDevice API since 3.0.0 (e.g. sd 140 5.0.0-1.alpha) provide sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter() helper function,
* but it's not reliable for c++ build.
* Instead of it memcpy gets proper response's value by offset: [2 B type| 1B prop |2 B value handle| 16 B value=uuid_128b] */
memcpy(uuid, (&response->handle_value + 5), UUID::LENGTH_OF_LONG_UUID);
#else
memcpy(uuid, &(response->handle_value[0].p_value[3]), UUID::LENGTH_OF_LONG_UUID);
#endif
unsigned charIndex = charUUIDDiscoveryQueue.dequeue();
characteristics[charIndex].setupLongUUID(uuid, UUID::LSB);

View File

@ -21,8 +21,8 @@
#include "ble/DiscoveredService.h"
#include "nRF5xDiscoveredCharacteristic.h"
#include "nrf_ble.h"
#include "nrf_ble_gattc.h"
#include "headers/ble.h"
#include "ble_gattc.h"
class nRF5xGattClient; /* forward declaration */
@ -139,7 +139,7 @@ private:
void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response);
void triggerServiceUUIDDiscovery(void);
void processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response);
void processDiscoverUUIDResponse(const ble_gattc_evt_t *p_gattc_evt);
void removeFirstServiceNeedingUUIDDiscovery(void);
void terminateServiceDiscovery(void) {