hr with 30102

Dependencies:   BLE_API mbed X_NUCLEO_IDB0XA1

Fork of BLE_HeartRate by Bluetooth Low Energy

Committer:
mssarwar
Date:
Sun Jul 30 05:52:57 2017 +0000
Revision:
80:808f6f367f45
with 30102;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mssarwar 80:808f6f367f45 1 /* mbed Microcontroller Library
mssarwar 80:808f6f367f45 2 * Copyright (c) 2006-2013 ARM Limited
mssarwar 80:808f6f367f45 3 *
mssarwar 80:808f6f367f45 4 * Licensed under the Apache License, Version 2.0 (the "License");
mssarwar 80:808f6f367f45 5 * you may not use this file except in compliance with the License.
mssarwar 80:808f6f367f45 6 * You may obtain a copy of the License at
mssarwar 80:808f6f367f45 7 *
mssarwar 80:808f6f367f45 8 * http://www.apache.org/licenses/LICENSE-2.0
mssarwar 80:808f6f367f45 9 *
mssarwar 80:808f6f367f45 10 * Unless required by applicable law or agreed to in writing, software
mssarwar 80:808f6f367f45 11 * distributed under the License is distributed on an "AS IS" BASIS,
mssarwar 80:808f6f367f45 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mssarwar 80:808f6f367f45 13 * See the License for the specific language governing permissions and
mssarwar 80:808f6f367f45 14 * limitations under the License.
mssarwar 80:808f6f367f45 15 */
mssarwar 80:808f6f367f45 16
mssarwar 80:808f6f367f45 17 #include "nRF5xn.h"
mssarwar 80:808f6f367f45 18 #ifdef YOTTA_CFG_MBED_OS
mssarwar 80:808f6f367f45 19 #include "mbed-drivers/mbed.h"
mssarwar 80:808f6f367f45 20 #else
mssarwar 80:808f6f367f45 21 #include "mbed.h"
mssarwar 80:808f6f367f45 22 #endif
mssarwar 80:808f6f367f45 23 #include "ble/BLE.h"
mssarwar 80:808f6f367f45 24
mssarwar 80:808f6f367f45 25 #include "common/common.h"
mssarwar 80:808f6f367f45 26 #include "ble_advdata.h"
mssarwar 80:808f6f367f45 27 #include "nrf_ble_hci.h"
mssarwar 80:808f6f367f45 28
mssarwar 80:808f6f367f45 29 void radioNotificationStaticCallback(bool param) {
mssarwar 80:808f6f367f45 30 nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap();
mssarwar 80:808f6f367f45 31 gap.processRadioNotificationEvent(param);
mssarwar 80:808f6f367f45 32 }
mssarwar 80:808f6f367f45 33
mssarwar 80:808f6f367f45 34 /**************************************************************************/
mssarwar 80:808f6f367f45 35 /*!
mssarwar 80:808f6f367f45 36 @brief Sets the advertising parameters and payload for the device
mssarwar 80:808f6f367f45 37
mssarwar 80:808f6f367f45 38 @param[in] params
mssarwar 80:808f6f367f45 39 Basic advertising details, including the advertising
mssarwar 80:808f6f367f45 40 delay, timeout and how the device should be advertised
mssarwar 80:808f6f367f45 41 @params[in] advData
mssarwar 80:808f6f367f45 42 The primary advertising data payload
mssarwar 80:808f6f367f45 43 @params[in] scanResponse
mssarwar 80:808f6f367f45 44 The optional Scan Response payload if the advertising
mssarwar 80:808f6f367f45 45 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
mssarwar 80:808f6f367f45 46 in \ref GapAdveritinngParams
mssarwar 80:808f6f367f45 47
mssarwar 80:808f6f367f45 48 @returns \ref ble_error_t
mssarwar 80:808f6f367f45 49
mssarwar 80:808f6f367f45 50 @retval BLE_ERROR_NONE
mssarwar 80:808f6f367f45 51 Everything executed properly
mssarwar 80:808f6f367f45 52
mssarwar 80:808f6f367f45 53 @retval BLE_ERROR_BUFFER_OVERFLOW
mssarwar 80:808f6f367f45 54 The proposed action would cause a buffer overflow. All
mssarwar 80:808f6f367f45 55 advertising payloads must be <= 31 bytes, for example.
mssarwar 80:808f6f367f45 56
mssarwar 80:808f6f367f45 57 @retval BLE_ERROR_NOT_IMPLEMENTED
mssarwar 80:808f6f367f45 58 A feature was requested that is not yet supported in the
mssarwar 80:808f6f367f45 59 nRF51 firmware or hardware.
mssarwar 80:808f6f367f45 60
mssarwar 80:808f6f367f45 61 @retval BLE_ERROR_PARAM_OUT_OF_RANGE
mssarwar 80:808f6f367f45 62 One of the proposed values is outside the valid range.
mssarwar 80:808f6f367f45 63
mssarwar 80:808f6f367f45 64 @section EXAMPLE
mssarwar 80:808f6f367f45 65
mssarwar 80:808f6f367f45 66 @code
mssarwar 80:808f6f367f45 67
mssarwar 80:808f6f367f45 68 @endcode
mssarwar 80:808f6f367f45 69 */
mssarwar 80:808f6f367f45 70 /**************************************************************************/
mssarwar 80:808f6f367f45 71 ble_error_t nRF5xGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
mssarwar 80:808f6f367f45 72 {
mssarwar 80:808f6f367f45 73 /* Make sure we don't exceed the advertising payload length */
mssarwar 80:808f6f367f45 74 if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
mssarwar 80:808f6f367f45 75 return BLE_ERROR_BUFFER_OVERFLOW;
mssarwar 80:808f6f367f45 76 }
mssarwar 80:808f6f367f45 77
mssarwar 80:808f6f367f45 78 /* Make sure we have a payload! */
mssarwar 80:808f6f367f45 79 if (advData.getPayloadLen() == 0) {
mssarwar 80:808f6f367f45 80 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 81 }
mssarwar 80:808f6f367f45 82
mssarwar 80:808f6f367f45 83 /* Check the scan response payload limits */
mssarwar 80:808f6f367f45 84 //if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED))
mssarwar 80:808f6f367f45 85 //{
mssarwar 80:808f6f367f45 86 // /* Check if we're within the upper limit */
mssarwar 80:808f6f367f45 87 // if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD)
mssarwar 80:808f6f367f45 88 // {
mssarwar 80:808f6f367f45 89 // return BLE_ERROR_BUFFER_OVERFLOW;
mssarwar 80:808f6f367f45 90 // }
mssarwar 80:808f6f367f45 91 // /* Make sure we have a payload! */
mssarwar 80:808f6f367f45 92 // if (advData.getPayloadLen() == 0)
mssarwar 80:808f6f367f45 93 // {
mssarwar 80:808f6f367f45 94 // return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 95 // }
mssarwar 80:808f6f367f45 96 //}
mssarwar 80:808f6f367f45 97
mssarwar 80:808f6f367f45 98 /* Send advertising data! */
mssarwar 80:808f6f367f45 99 ASSERT(ERROR_NONE ==
mssarwar 80:808f6f367f45 100 sd_ble_gap_adv_data_set(advData.getPayload(),
mssarwar 80:808f6f367f45 101 advData.getPayloadLen(),
mssarwar 80:808f6f367f45 102 scanResponse.getPayload(),
mssarwar 80:808f6f367f45 103 scanResponse.getPayloadLen()),
mssarwar 80:808f6f367f45 104 BLE_ERROR_PARAM_OUT_OF_RANGE);
mssarwar 80:808f6f367f45 105
mssarwar 80:808f6f367f45 106 /* Make sure the GAP Service appearance value is aligned with the
mssarwar 80:808f6f367f45 107 *appearance from GapAdvertisingData */
mssarwar 80:808f6f367f45 108 ASSERT(ERROR_NONE == sd_ble_gap_appearance_set(advData.getAppearance()),
mssarwar 80:808f6f367f45 109 BLE_ERROR_PARAM_OUT_OF_RANGE);
mssarwar 80:808f6f367f45 110
mssarwar 80:808f6f367f45 111 /* ToDo: Perform some checks on the payload, for example the Scan Response can't */
mssarwar 80:808f6f367f45 112 /* contains a flags AD type, etc. */
mssarwar 80:808f6f367f45 113
mssarwar 80:808f6f367f45 114 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 115 }
mssarwar 80:808f6f367f45 116
mssarwar 80:808f6f367f45 117 /**************************************************************************/
mssarwar 80:808f6f367f45 118 /*!
mssarwar 80:808f6f367f45 119 @brief Starts the BLE HW, initialising any services that were
mssarwar 80:808f6f367f45 120 added before this function was called.
mssarwar 80:808f6f367f45 121
mssarwar 80:808f6f367f45 122 @note All services must be added before calling this function!
mssarwar 80:808f6f367f45 123
mssarwar 80:808f6f367f45 124 @returns ble_error_t
mssarwar 80:808f6f367f45 125
mssarwar 80:808f6f367f45 126 @retval BLE_ERROR_NONE
mssarwar 80:808f6f367f45 127 Everything executed properly
mssarwar 80:808f6f367f45 128
mssarwar 80:808f6f367f45 129 @section EXAMPLE
mssarwar 80:808f6f367f45 130
mssarwar 80:808f6f367f45 131 @code
mssarwar 80:808f6f367f45 132
mssarwar 80:808f6f367f45 133 @endcode
mssarwar 80:808f6f367f45 134 */
mssarwar 80:808f6f367f45 135 /**************************************************************************/
mssarwar 80:808f6f367f45 136 ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams &params)
mssarwar 80:808f6f367f45 137 {
mssarwar 80:808f6f367f45 138 /* Make sure we support the advertising type */
mssarwar 80:808f6f367f45 139 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
mssarwar 80:808f6f367f45 140 /* ToDo: This requires a propery security implementation, etc. */
mssarwar 80:808f6f367f45 141 return BLE_ERROR_NOT_IMPLEMENTED;
mssarwar 80:808f6f367f45 142 }
mssarwar 80:808f6f367f45 143
mssarwar 80:808f6f367f45 144 /* Check interval range */
mssarwar 80:808f6f367f45 145 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
mssarwar 80:808f6f367f45 146 /* Min delay is slightly longer for unconnectable devices */
mssarwar 80:808f6f367f45 147 if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
mssarwar 80:808f6f367f45 148 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
mssarwar 80:808f6f367f45 149 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 150 }
mssarwar 80:808f6f367f45 151 } else {
mssarwar 80:808f6f367f45 152 if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) ||
mssarwar 80:808f6f367f45 153 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
mssarwar 80:808f6f367f45 154 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 155 }
mssarwar 80:808f6f367f45 156 }
mssarwar 80:808f6f367f45 157
mssarwar 80:808f6f367f45 158 /* Check timeout is zero for Connectable Directed */
mssarwar 80:808f6f367f45 159 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
mssarwar 80:808f6f367f45 160 /* Timeout must be 0 with this type, although we'll never get here */
mssarwar 80:808f6f367f45 161 /* since this isn't implemented yet anyway */
mssarwar 80:808f6f367f45 162 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 163 }
mssarwar 80:808f6f367f45 164
mssarwar 80:808f6f367f45 165 /* Check timeout for other advertising types */
mssarwar 80:808f6f367f45 166 if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
mssarwar 80:808f6f367f45 167 (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
mssarwar 80:808f6f367f45 168 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 169 }
mssarwar 80:808f6f367f45 170
mssarwar 80:808f6f367f45 171 /* Allocate the stack's whitelist statically */
mssarwar 80:808f6f367f45 172 ble_gap_whitelist_t whitelist;
mssarwar 80:808f6f367f45 173 ble_gap_addr_t *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE];
mssarwar 80:808f6f367f45 174 ble_gap_irk_t *whitelistIrkPtrs[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
mssarwar 80:808f6f367f45 175 /* Initialize the whitelist */
mssarwar 80:808f6f367f45 176 whitelist.pp_addrs = whitelistAddressPtrs;
mssarwar 80:808f6f367f45 177 whitelist.pp_irks = whitelistIrkPtrs;
mssarwar 80:808f6f367f45 178 whitelist.addr_count = 0;
mssarwar 80:808f6f367f45 179 whitelist.irk_count = 0;
mssarwar 80:808f6f367f45 180
mssarwar 80:808f6f367f45 181 /* Add missing IRKs to whitelist from the bond table held by the SoftDevice */
mssarwar 80:808f6f367f45 182 if (advertisingPolicyMode != Gap::ADV_POLICY_IGNORE_WHITELIST) {
mssarwar 80:808f6f367f45 183 ble_error_t error = generateStackWhitelist(whitelist);
mssarwar 80:808f6f367f45 184 if (error != BLE_ERROR_NONE) {
mssarwar 80:808f6f367f45 185 return error;
mssarwar 80:808f6f367f45 186 }
mssarwar 80:808f6f367f45 187 }
mssarwar 80:808f6f367f45 188
mssarwar 80:808f6f367f45 189 /* Start Advertising */
mssarwar 80:808f6f367f45 190 ble_gap_adv_params_t adv_para = {0};
mssarwar 80:808f6f367f45 191
mssarwar 80:808f6f367f45 192 adv_para.type = params.getAdvertisingType();
mssarwar 80:808f6f367f45 193 adv_para.p_peer_addr = NULL; // Undirected advertisement
mssarwar 80:808f6f367f45 194 adv_para.fp = advertisingPolicyMode;
mssarwar 80:808f6f367f45 195 adv_para.p_whitelist = &whitelist;
mssarwar 80:808f6f367f45 196 adv_para.interval = params.getIntervalInADVUnits(); // advertising interval (in units of 0.625 ms)
mssarwar 80:808f6f367f45 197 adv_para.timeout = params.getTimeout();
mssarwar 80:808f6f367f45 198
mssarwar 80:808f6f367f45 199 uint32_t err = sd_ble_gap_adv_start(&adv_para);
mssarwar 80:808f6f367f45 200 switch(err) {
mssarwar 80:808f6f367f45 201 case ERROR_NONE:
mssarwar 80:808f6f367f45 202 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 203 case NRF_ERROR_NO_MEM:
mssarwar 80:808f6f367f45 204 return BLE_ERROR_NO_MEM;
mssarwar 80:808f6f367f45 205 default:
mssarwar 80:808f6f367f45 206 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 207 }
mssarwar 80:808f6f367f45 208 }
mssarwar 80:808f6f367f45 209
mssarwar 80:808f6f367f45 210 /* Observer role is not supported by S110, return BLE_ERROR_NOT_IMPLEMENTED */
mssarwar 80:808f6f367f45 211 #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
mssarwar 80:808f6f367f45 212 ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams)
mssarwar 80:808f6f367f45 213 {
mssarwar 80:808f6f367f45 214 /* Allocate the stack's whitelist statically */
mssarwar 80:808f6f367f45 215 ble_gap_whitelist_t whitelist;
mssarwar 80:808f6f367f45 216 ble_gap_addr_t *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE];
mssarwar 80:808f6f367f45 217 ble_gap_irk_t *whitelistIrkPtrs[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
mssarwar 80:808f6f367f45 218 /* Initialize the whitelist */
mssarwar 80:808f6f367f45 219 whitelist.pp_addrs = whitelistAddressPtrs;
mssarwar 80:808f6f367f45 220 whitelist.pp_irks = whitelistIrkPtrs;
mssarwar 80:808f6f367f45 221 whitelist.addr_count = 0;
mssarwar 80:808f6f367f45 222 whitelist.irk_count = 0;
mssarwar 80:808f6f367f45 223
mssarwar 80:808f6f367f45 224 /* Add missing IRKs to whitelist from the bond table held by the SoftDevice */
mssarwar 80:808f6f367f45 225 if (scanningPolicyMode != Gap::SCAN_POLICY_IGNORE_WHITELIST) {
mssarwar 80:808f6f367f45 226 ble_error_t error = generateStackWhitelist(whitelist);
mssarwar 80:808f6f367f45 227 if (error != BLE_ERROR_NONE) {
mssarwar 80:808f6f367f45 228 return error;
mssarwar 80:808f6f367f45 229 }
mssarwar 80:808f6f367f45 230 }
mssarwar 80:808f6f367f45 231
mssarwar 80:808f6f367f45 232 ble_gap_scan_params_t scanParams;
mssarwar 80:808f6f367f45 233
mssarwar 80:808f6f367f45 234 scanParams.active = scanningParams.getActiveScanning(); /**< If 1, perform active scanning (scan requests). */
mssarwar 80:808f6f367f45 235 scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */
mssarwar 80:808f6f367f45 236 scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */
mssarwar 80:808f6f367f45 237 scanParams.interval = scanningParams.getInterval(); /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
mssarwar 80:808f6f367f45 238 scanParams.window = scanningParams.getWindow(); /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
mssarwar 80:808f6f367f45 239 scanParams.timeout = scanningParams.getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
mssarwar 80:808f6f367f45 240
mssarwar 80:808f6f367f45 241 if (sd_ble_gap_scan_start(&scanParams) != NRF_SUCCESS) {
mssarwar 80:808f6f367f45 242 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 243 }
mssarwar 80:808f6f367f45 244
mssarwar 80:808f6f367f45 245 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 246 }
mssarwar 80:808f6f367f45 247
mssarwar 80:808f6f367f45 248 ble_error_t nRF5xGap::stopScan(void) {
mssarwar 80:808f6f367f45 249 if (sd_ble_gap_scan_stop() == NRF_SUCCESS) {
mssarwar 80:808f6f367f45 250 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 251 }
mssarwar 80:808f6f367f45 252
mssarwar 80:808f6f367f45 253 return BLE_STACK_BUSY;
mssarwar 80:808f6f367f45 254 }
mssarwar 80:808f6f367f45 255 #endif
mssarwar 80:808f6f367f45 256
mssarwar 80:808f6f367f45 257 /**************************************************************************/
mssarwar 80:808f6f367f45 258 /*!
mssarwar 80:808f6f367f45 259 @brief Stops the BLE HW and disconnects from any devices
mssarwar 80:808f6f367f45 260
mssarwar 80:808f6f367f45 261 @returns ble_error_t
mssarwar 80:808f6f367f45 262
mssarwar 80:808f6f367f45 263 @retval BLE_ERROR_NONE
mssarwar 80:808f6f367f45 264 Everything executed properly
mssarwar 80:808f6f367f45 265
mssarwar 80:808f6f367f45 266 @section EXAMPLE
mssarwar 80:808f6f367f45 267
mssarwar 80:808f6f367f45 268 @code
mssarwar 80:808f6f367f45 269
mssarwar 80:808f6f367f45 270 @endcode
mssarwar 80:808f6f367f45 271 */
mssarwar 80:808f6f367f45 272 /**************************************************************************/
mssarwar 80:808f6f367f45 273 ble_error_t nRF5xGap::stopAdvertising(void)
mssarwar 80:808f6f367f45 274 {
mssarwar 80:808f6f367f45 275 /* Stop Advertising */
mssarwar 80:808f6f367f45 276 ASSERT(ERROR_NONE == sd_ble_gap_adv_stop(), BLE_ERROR_PARAM_OUT_OF_RANGE);
mssarwar 80:808f6f367f45 277
mssarwar 80:808f6f367f45 278 state.advertising = 0;
mssarwar 80:808f6f367f45 279
mssarwar 80:808f6f367f45 280 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 281 }
mssarwar 80:808f6f367f45 282
mssarwar 80:808f6f367f45 283 ble_error_t nRF5xGap::connect(const Address_t peerAddr,
mssarwar 80:808f6f367f45 284 BLEProtocol::AddressType_t peerAddrType,
mssarwar 80:808f6f367f45 285 const ConnectionParams_t *connectionParams,
mssarwar 80:808f6f367f45 286 const GapScanningParams *scanParamsIn)
mssarwar 80:808f6f367f45 287 {
mssarwar 80:808f6f367f45 288 ble_gap_addr_t addr;
mssarwar 80:808f6f367f45 289 addr.addr_type = peerAddrType;
mssarwar 80:808f6f367f45 290 memcpy(addr.addr, peerAddr, Gap::ADDR_LEN);
mssarwar 80:808f6f367f45 291
mssarwar 80:808f6f367f45 292 ble_gap_conn_params_t connParams;
mssarwar 80:808f6f367f45 293 if (connectionParams != NULL) {
mssarwar 80:808f6f367f45 294 connParams.min_conn_interval = connectionParams->minConnectionInterval;
mssarwar 80:808f6f367f45 295 connParams.max_conn_interval = connectionParams->maxConnectionInterval;
mssarwar 80:808f6f367f45 296 connParams.slave_latency = connectionParams->slaveLatency;
mssarwar 80:808f6f367f45 297 connParams.conn_sup_timeout = connectionParams->connectionSupervisionTimeout;
mssarwar 80:808f6f367f45 298 } else {
mssarwar 80:808f6f367f45 299 connParams.min_conn_interval = 50;
mssarwar 80:808f6f367f45 300 connParams.max_conn_interval = 100;
mssarwar 80:808f6f367f45 301 connParams.slave_latency = 0;
mssarwar 80:808f6f367f45 302 connParams.conn_sup_timeout = 600;
mssarwar 80:808f6f367f45 303 }
mssarwar 80:808f6f367f45 304
mssarwar 80:808f6f367f45 305 /* Allocate the stack's whitelist statically */
mssarwar 80:808f6f367f45 306 ble_gap_whitelist_t whitelist;
mssarwar 80:808f6f367f45 307 ble_gap_addr_t *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE];
mssarwar 80:808f6f367f45 308 ble_gap_irk_t *whitelistIrkPtrs[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
mssarwar 80:808f6f367f45 309 /* Initialize the whitelist */
mssarwar 80:808f6f367f45 310 whitelist.pp_addrs = whitelistAddressPtrs;
mssarwar 80:808f6f367f45 311 whitelist.pp_irks = whitelistIrkPtrs;
mssarwar 80:808f6f367f45 312 whitelist.addr_count = 0;
mssarwar 80:808f6f367f45 313 whitelist.irk_count = 0;
mssarwar 80:808f6f367f45 314
mssarwar 80:808f6f367f45 315 /* Add missing IRKs to whitelist from the bond table held by the SoftDevice */
mssarwar 80:808f6f367f45 316 if (scanningPolicyMode != Gap::SCAN_POLICY_IGNORE_WHITELIST) {
mssarwar 80:808f6f367f45 317 ble_error_t error = generateStackWhitelist(whitelist);
mssarwar 80:808f6f367f45 318 if (error != BLE_ERROR_NONE) {
mssarwar 80:808f6f367f45 319 return error;
mssarwar 80:808f6f367f45 320 }
mssarwar 80:808f6f367f45 321 }
mssarwar 80:808f6f367f45 322
mssarwar 80:808f6f367f45 323 ble_gap_scan_params_t scanParams;
mssarwar 80:808f6f367f45 324 scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */
mssarwar 80:808f6f367f45 325 scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */
mssarwar 80:808f6f367f45 326 if (scanParamsIn != NULL) {
mssarwar 80:808f6f367f45 327 scanParams.active = scanParamsIn->getActiveScanning(); /**< If 1, perform active scanning (scan requests). */
mssarwar 80:808f6f367f45 328 scanParams.interval = scanParamsIn->getInterval(); /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
mssarwar 80:808f6f367f45 329 scanParams.window = scanParamsIn->getWindow(); /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
mssarwar 80:808f6f367f45 330 scanParams.timeout = scanParamsIn->getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
mssarwar 80:808f6f367f45 331 } else {
mssarwar 80:808f6f367f45 332 scanParams.active = _scanningParams.getActiveScanning(); /**< If 1, perform active scanning (scan requests). */
mssarwar 80:808f6f367f45 333 scanParams.interval = _scanningParams.getInterval(); /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
mssarwar 80:808f6f367f45 334 scanParams.window = _scanningParams.getWindow(); /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
mssarwar 80:808f6f367f45 335 scanParams.timeout = _scanningParams.getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
mssarwar 80:808f6f367f45 336 }
mssarwar 80:808f6f367f45 337
mssarwar 80:808f6f367f45 338 uint32_t rc = sd_ble_gap_connect(&addr, &scanParams, &connParams);
mssarwar 80:808f6f367f45 339 if (rc == NRF_SUCCESS) {
mssarwar 80:808f6f367f45 340 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 341 }
mssarwar 80:808f6f367f45 342 switch (rc) {
mssarwar 80:808f6f367f45 343 case NRF_ERROR_INVALID_ADDR:
mssarwar 80:808f6f367f45 344 return BLE_ERROR_INVALID_PARAM;
mssarwar 80:808f6f367f45 345 case NRF_ERROR_INVALID_PARAM:
mssarwar 80:808f6f367f45 346 return BLE_ERROR_INVALID_PARAM;
mssarwar 80:808f6f367f45 347 case NRF_ERROR_INVALID_STATE:
mssarwar 80:808f6f367f45 348 return BLE_ERROR_INVALID_STATE;
mssarwar 80:808f6f367f45 349 case BLE_ERROR_GAP_INVALID_BLE_ADDR:
mssarwar 80:808f6f367f45 350 return BLE_ERROR_INVALID_PARAM;
mssarwar 80:808f6f367f45 351 case NRF_ERROR_NO_MEM:
mssarwar 80:808f6f367f45 352 return BLE_ERROR_NO_MEM;
mssarwar 80:808f6f367f45 353 case NRF_ERROR_BUSY:
mssarwar 80:808f6f367f45 354 return BLE_STACK_BUSY;
mssarwar 80:808f6f367f45 355 default:
mssarwar 80:808f6f367f45 356 case BLE_ERROR_GAP_WHITELIST_IN_USE:
mssarwar 80:808f6f367f45 357 return BLE_ERROR_UNSPECIFIED;
mssarwar 80:808f6f367f45 358 }
mssarwar 80:808f6f367f45 359 }
mssarwar 80:808f6f367f45 360
mssarwar 80:808f6f367f45 361 ble_error_t nRF5xGap::disconnect(Handle_t connectionHandle, DisconnectionReason_t reason)
mssarwar 80:808f6f367f45 362 {
mssarwar 80:808f6f367f45 363 uint8_t code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION;
mssarwar 80:808f6f367f45 364 switch (reason) {
mssarwar 80:808f6f367f45 365 case REMOTE_USER_TERMINATED_CONNECTION:
mssarwar 80:808f6f367f45 366 code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION;
mssarwar 80:808f6f367f45 367 break;
mssarwar 80:808f6f367f45 368 case CONN_INTERVAL_UNACCEPTABLE:
mssarwar 80:808f6f367f45 369 code = BLE_HCI_CONN_INTERVAL_UNACCEPTABLE;
mssarwar 80:808f6f367f45 370 break;
mssarwar 80:808f6f367f45 371 default:
mssarwar 80:808f6f367f45 372 break;
mssarwar 80:808f6f367f45 373 }
mssarwar 80:808f6f367f45 374
mssarwar 80:808f6f367f45 375 /* Disconnect if we are connected to a central device */
mssarwar 80:808f6f367f45 376 ASSERT_INT(ERROR_NONE, sd_ble_gap_disconnect(connectionHandle, code), BLE_ERROR_PARAM_OUT_OF_RANGE);
mssarwar 80:808f6f367f45 377
mssarwar 80:808f6f367f45 378 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 379 }
mssarwar 80:808f6f367f45 380
mssarwar 80:808f6f367f45 381 /*!
mssarwar 80:808f6f367f45 382 @brief Disconnects if we are connected to a central device
mssarwar 80:808f6f367f45 383
mssarwar 80:808f6f367f45 384 @returns ble_error_t
mssarwar 80:808f6f367f45 385
mssarwar 80:808f6f367f45 386 @retval BLE_ERROR_NONE
mssarwar 80:808f6f367f45 387 Everything executed properly
mssarwar 80:808f6f367f45 388 */
mssarwar 80:808f6f367f45 389 ble_error_t nRF5xGap::disconnect(DisconnectionReason_t reason)
mssarwar 80:808f6f367f45 390 {
mssarwar 80:808f6f367f45 391 return disconnect(m_connectionHandle, reason);
mssarwar 80:808f6f367f45 392 }
mssarwar 80:808f6f367f45 393
mssarwar 80:808f6f367f45 394 ble_error_t nRF5xGap::getPreferredConnectionParams(ConnectionParams_t *params)
mssarwar 80:808f6f367f45 395 {
mssarwar 80:808f6f367f45 396 ASSERT_INT(NRF_SUCCESS,
mssarwar 80:808f6f367f45 397 sd_ble_gap_ppcp_get(reinterpret_cast<ble_gap_conn_params_t *>(params)),
mssarwar 80:808f6f367f45 398 BLE_ERROR_PARAM_OUT_OF_RANGE);
mssarwar 80:808f6f367f45 399
mssarwar 80:808f6f367f45 400 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 401 }
mssarwar 80:808f6f367f45 402
mssarwar 80:808f6f367f45 403 ble_error_t nRF5xGap::setPreferredConnectionParams(const ConnectionParams_t *params)
mssarwar 80:808f6f367f45 404 {
mssarwar 80:808f6f367f45 405 ASSERT_INT(NRF_SUCCESS,
mssarwar 80:808f6f367f45 406 sd_ble_gap_ppcp_set(reinterpret_cast<const ble_gap_conn_params_t *>(params)),
mssarwar 80:808f6f367f45 407 BLE_ERROR_PARAM_OUT_OF_RANGE);
mssarwar 80:808f6f367f45 408
mssarwar 80:808f6f367f45 409 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 410 }
mssarwar 80:808f6f367f45 411
mssarwar 80:808f6f367f45 412 ble_error_t nRF5xGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *newParams)
mssarwar 80:808f6f367f45 413 {
mssarwar 80:808f6f367f45 414 uint32_t rc;
mssarwar 80:808f6f367f45 415
mssarwar 80:808f6f367f45 416 rc = sd_ble_gap_conn_param_update(handle, reinterpret_cast<ble_gap_conn_params_t *>(const_cast<ConnectionParams_t*>(newParams)));
mssarwar 80:808f6f367f45 417 if (rc == NRF_SUCCESS) {
mssarwar 80:808f6f367f45 418 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 419 } else {
mssarwar 80:808f6f367f45 420 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 421 }
mssarwar 80:808f6f367f45 422 }
mssarwar 80:808f6f367f45 423
mssarwar 80:808f6f367f45 424 /**************************************************************************/
mssarwar 80:808f6f367f45 425 /*!
mssarwar 80:808f6f367f45 426 @brief Clear nRF5xGap's state.
mssarwar 80:808f6f367f45 427
mssarwar 80:808f6f367f45 428 @returns ble_error_t
mssarwar 80:808f6f367f45 429
mssarwar 80:808f6f367f45 430 @retval BLE_ERROR_NONE
mssarwar 80:808f6f367f45 431 Everything executed properly
mssarwar 80:808f6f367f45 432 */
mssarwar 80:808f6f367f45 433 /**************************************************************************/
mssarwar 80:808f6f367f45 434 ble_error_t nRF5xGap::reset(void)
mssarwar 80:808f6f367f45 435 {
mssarwar 80:808f6f367f45 436 /* Clear all state that is from the parent, including private members */
mssarwar 80:808f6f367f45 437 if (Gap::reset() != BLE_ERROR_NONE) {
mssarwar 80:808f6f367f45 438 return BLE_ERROR_INVALID_STATE;
mssarwar 80:808f6f367f45 439 }
mssarwar 80:808f6f367f45 440
mssarwar 80:808f6f367f45 441 /* Clear derived class members */
mssarwar 80:808f6f367f45 442 m_connectionHandle = BLE_CONN_HANDLE_INVALID;
mssarwar 80:808f6f367f45 443
mssarwar 80:808f6f367f45 444 /* Set the whitelist policy filter modes to IGNORE_WHITELIST */
mssarwar 80:808f6f367f45 445 advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST;
mssarwar 80:808f6f367f45 446 scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST;
mssarwar 80:808f6f367f45 447
mssarwar 80:808f6f367f45 448 /* Clear the internal whitelist */
mssarwar 80:808f6f367f45 449 whitelistAddressesSize = 0;
mssarwar 80:808f6f367f45 450
mssarwar 80:808f6f367f45 451 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 452 }
mssarwar 80:808f6f367f45 453
mssarwar 80:808f6f367f45 454 /**************************************************************************/
mssarwar 80:808f6f367f45 455 /*!
mssarwar 80:808f6f367f45 456 @brief Sets the 16-bit connection handle
mssarwar 80:808f6f367f45 457 */
mssarwar 80:808f6f367f45 458 /**************************************************************************/
mssarwar 80:808f6f367f45 459 void nRF5xGap::setConnectionHandle(uint16_t con_handle)
mssarwar 80:808f6f367f45 460 {
mssarwar 80:808f6f367f45 461 m_connectionHandle = con_handle;
mssarwar 80:808f6f367f45 462 }
mssarwar 80:808f6f367f45 463
mssarwar 80:808f6f367f45 464 /**************************************************************************/
mssarwar 80:808f6f367f45 465 /*!
mssarwar 80:808f6f367f45 466 @brief Gets the 16-bit connection handle
mssarwar 80:808f6f367f45 467 */
mssarwar 80:808f6f367f45 468 /**************************************************************************/
mssarwar 80:808f6f367f45 469 uint16_t nRF5xGap::getConnectionHandle(void)
mssarwar 80:808f6f367f45 470 {
mssarwar 80:808f6f367f45 471 return m_connectionHandle;
mssarwar 80:808f6f367f45 472 }
mssarwar 80:808f6f367f45 473
mssarwar 80:808f6f367f45 474 /**************************************************************************/
mssarwar 80:808f6f367f45 475 /*!
mssarwar 80:808f6f367f45 476 @brief Sets the BLE device address
mssarwar 80:808f6f367f45 477
mssarwar 80:808f6f367f45 478 @returns ble_error_t
mssarwar 80:808f6f367f45 479
mssarwar 80:808f6f367f45 480 @section EXAMPLE
mssarwar 80:808f6f367f45 481
mssarwar 80:808f6f367f45 482 @code
mssarwar 80:808f6f367f45 483
mssarwar 80:808f6f367f45 484 uint8_t device_address[6] = { 0xca, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0 };
mssarwar 80:808f6f367f45 485 nrf.getGap().setAddress(Gap::BLEProtocol::AddressType::RANDOM_STATIC, device_address);
mssarwar 80:808f6f367f45 486
mssarwar 80:808f6f367f45 487 @endcode
mssarwar 80:808f6f367f45 488 */
mssarwar 80:808f6f367f45 489 /**************************************************************************/
mssarwar 80:808f6f367f45 490 ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
mssarwar 80:808f6f367f45 491 {
mssarwar 80:808f6f367f45 492 uint8_t cycle_mode;
mssarwar 80:808f6f367f45 493 ble_gap_addr_t dev_addr;
mssarwar 80:808f6f367f45 494
mssarwar 80:808f6f367f45 495 /* When using Public or Static addresses, the cycle mode must be None.
mssarwar 80:808f6f367f45 496 When using Random Private addresses, the cycle mode must be Auto.
mssarwar 80:808f6f367f45 497 In auto mode, the given address is ignored.
mssarwar 80:808f6f367f45 498 */
mssarwar 80:808f6f367f45 499 if ((type == BLEProtocol::AddressType::PUBLIC) || (type == BLEProtocol::AddressType::RANDOM_STATIC))
mssarwar 80:808f6f367f45 500 {
mssarwar 80:808f6f367f45 501 cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_NONE;
mssarwar 80:808f6f367f45 502 memcpy(dev_addr.addr, address, ADDR_LEN);
mssarwar 80:808f6f367f45 503 }
mssarwar 80:808f6f367f45 504 else if ((type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE) || (type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE))
mssarwar 80:808f6f367f45 505 {
mssarwar 80:808f6f367f45 506 cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_AUTO;
mssarwar 80:808f6f367f45 507 // address is ignored when in auto mode
mssarwar 80:808f6f367f45 508 }
mssarwar 80:808f6f367f45 509 else
mssarwar 80:808f6f367f45 510 {
mssarwar 80:808f6f367f45 511 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 512 }
mssarwar 80:808f6f367f45 513
mssarwar 80:808f6f367f45 514 dev_addr.addr_type = type;
mssarwar 80:808f6f367f45 515 ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(cycle_mode, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE);
mssarwar 80:808f6f367f45 516
mssarwar 80:808f6f367f45 517 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 518 }
mssarwar 80:808f6f367f45 519
mssarwar 80:808f6f367f45 520 ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address)
mssarwar 80:808f6f367f45 521 {
mssarwar 80:808f6f367f45 522 ble_gap_addr_t dev_addr;
mssarwar 80:808f6f367f45 523 if (sd_ble_gap_address_get(&dev_addr) != NRF_SUCCESS) {
mssarwar 80:808f6f367f45 524 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 525 }
mssarwar 80:808f6f367f45 526
mssarwar 80:808f6f367f45 527 if (typeP != NULL) {
mssarwar 80:808f6f367f45 528 *typeP = static_cast<AddressType_t>(dev_addr.addr_type);
mssarwar 80:808f6f367f45 529 }
mssarwar 80:808f6f367f45 530 if (address != NULL) {
mssarwar 80:808f6f367f45 531 memcpy(address, dev_addr.addr, ADDR_LEN);
mssarwar 80:808f6f367f45 532 }
mssarwar 80:808f6f367f45 533 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 534 }
mssarwar 80:808f6f367f45 535
mssarwar 80:808f6f367f45 536 ble_error_t nRF5xGap::setDeviceName(const uint8_t *deviceName)
mssarwar 80:808f6f367f45 537 {
mssarwar 80:808f6f367f45 538 ble_gap_conn_sec_mode_t sec_mode;
mssarwar 80:808f6f367f45 539 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); // no security is needed
mssarwar 80:808f6f367f45 540
mssarwar 80:808f6f367f45 541 if (sd_ble_gap_device_name_set(&sec_mode, deviceName, strlen((const char *)deviceName)) == NRF_SUCCESS) {
mssarwar 80:808f6f367f45 542 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 543 } else {
mssarwar 80:808f6f367f45 544 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 545 }
mssarwar 80:808f6f367f45 546 }
mssarwar 80:808f6f367f45 547
mssarwar 80:808f6f367f45 548 ble_error_t nRF5xGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
mssarwar 80:808f6f367f45 549 {
mssarwar 80:808f6f367f45 550 if (sd_ble_gap_device_name_get(deviceName, (uint16_t *)lengthP) == NRF_SUCCESS) {
mssarwar 80:808f6f367f45 551 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 552 } else {
mssarwar 80:808f6f367f45 553 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 554 }
mssarwar 80:808f6f367f45 555 }
mssarwar 80:808f6f367f45 556
mssarwar 80:808f6f367f45 557 ble_error_t nRF5xGap::setAppearance(GapAdvertisingData::Appearance appearance)
mssarwar 80:808f6f367f45 558 {
mssarwar 80:808f6f367f45 559 if (sd_ble_gap_appearance_set(appearance) == NRF_SUCCESS) {
mssarwar 80:808f6f367f45 560 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 561 } else {
mssarwar 80:808f6f367f45 562 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 563 }
mssarwar 80:808f6f367f45 564 }
mssarwar 80:808f6f367f45 565
mssarwar 80:808f6f367f45 566 ble_error_t nRF5xGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
mssarwar 80:808f6f367f45 567 {
mssarwar 80:808f6f367f45 568 if ((sd_ble_gap_appearance_get(reinterpret_cast<uint16_t *>(appearanceP)) == NRF_SUCCESS)) {
mssarwar 80:808f6f367f45 569 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 570 } else {
mssarwar 80:808f6f367f45 571 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 572 }
mssarwar 80:808f6f367f45 573 }
mssarwar 80:808f6f367f45 574
mssarwar 80:808f6f367f45 575 /* (Valid values are -40, -20, -16, -12, -8, -4, 0, 4) */
mssarwar 80:808f6f367f45 576 ble_error_t nRF5xGap::setTxPower(int8_t txPower)
mssarwar 80:808f6f367f45 577 {
mssarwar 80:808f6f367f45 578 unsigned rc;
mssarwar 80:808f6f367f45 579 if ((rc = sd_ble_gap_tx_power_set(txPower)) != NRF_SUCCESS) {
mssarwar 80:808f6f367f45 580 switch (rc) {
mssarwar 80:808f6f367f45 581 case NRF_ERROR_BUSY:
mssarwar 80:808f6f367f45 582 return BLE_STACK_BUSY;
mssarwar 80:808f6f367f45 583 case NRF_ERROR_INVALID_PARAM:
mssarwar 80:808f6f367f45 584 default:
mssarwar 80:808f6f367f45 585 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 586 }
mssarwar 80:808f6f367f45 587 }
mssarwar 80:808f6f367f45 588
mssarwar 80:808f6f367f45 589 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 590 }
mssarwar 80:808f6f367f45 591
mssarwar 80:808f6f367f45 592 void nRF5xGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP)
mssarwar 80:808f6f367f45 593 {
mssarwar 80:808f6f367f45 594 #if defined(NRF51)
mssarwar 80:808f6f367f45 595 static const int8_t permittedTxValues[] = {
mssarwar 80:808f6f367f45 596 -30, -20, -16, -12, -8, -4, 0, 4
mssarwar 80:808f6f367f45 597 };
mssarwar 80:808f6f367f45 598 #elif defined(NRF52)
mssarwar 80:808f6f367f45 599 static const int8_t permittedTxValues[] = {
mssarwar 80:808f6f367f45 600 -40, -20, -16, -12, -8, -4, 0, 4
mssarwar 80:808f6f367f45 601 };
mssarwar 80:808f6f367f45 602 #else
mssarwar 80:808f6f367f45 603 #error permitted TX power values unknown for this SOC
mssarwar 80:808f6f367f45 604 #endif
mssarwar 80:808f6f367f45 605
mssarwar 80:808f6f367f45 606 *valueArrayPP = permittedTxValues;
mssarwar 80:808f6f367f45 607 *countP = sizeof(permittedTxValues) / sizeof(int8_t);
mssarwar 80:808f6f367f45 608 }
mssarwar 80:808f6f367f45 609
mssarwar 80:808f6f367f45 610 /**************************************************************************/
mssarwar 80:808f6f367f45 611 /*!
mssarwar 80:808f6f367f45 612 @brief Get the capacity of the internal whitelist maintained by this
mssarwar 80:808f6f367f45 613 implementation.
mssarwar 80:808f6f367f45 614
mssarwar 80:808f6f367f45 615 @returns The capacity of the internal whitelist.
mssarwar 80:808f6f367f45 616
mssarwar 80:808f6f367f45 617 @section EXAMPLE
mssarwar 80:808f6f367f45 618
mssarwar 80:808f6f367f45 619 @code
mssarwar 80:808f6f367f45 620
mssarwar 80:808f6f367f45 621 @endcode
mssarwar 80:808f6f367f45 622 */
mssarwar 80:808f6f367f45 623 /**************************************************************************/
mssarwar 80:808f6f367f45 624 uint8_t nRF5xGap::getMaxWhitelistSize(void) const
mssarwar 80:808f6f367f45 625 {
mssarwar 80:808f6f367f45 626 return YOTTA_CFG_WHITELIST_MAX_SIZE;
mssarwar 80:808f6f367f45 627 }
mssarwar 80:808f6f367f45 628
mssarwar 80:808f6f367f45 629 /**************************************************************************/
mssarwar 80:808f6f367f45 630 /*!
mssarwar 80:808f6f367f45 631 @brief Get a copy of the implementation's internal whitelist.
mssarwar 80:808f6f367f45 632
mssarwar 80:808f6f367f45 633 @param[out] whitelistOut
mssarwar 80:808f6f367f45 634 A \ref Gap::Whitelist_t structure containing a copy of the
mssarwar 80:808f6f367f45 635 addresses in the implemenetation's internal whitelist.
mssarwar 80:808f6f367f45 636
mssarwar 80:808f6f367f45 637 @returns \ref ble_errror_t
mssarwar 80:808f6f367f45 638
mssarwar 80:808f6f367f45 639 @retval BLE_ERROR_NONE
mssarwar 80:808f6f367f45 640 Everything executed properly.
mssarwar 80:808f6f367f45 641
mssarwar 80:808f6f367f45 642 @section EXAMPLE
mssarwar 80:808f6f367f45 643
mssarwar 80:808f6f367f45 644 @code
mssarwar 80:808f6f367f45 645
mssarwar 80:808f6f367f45 646 @endcode
mssarwar 80:808f6f367f45 647 */
mssarwar 80:808f6f367f45 648 /**************************************************************************/
mssarwar 80:808f6f367f45 649 ble_error_t nRF5xGap::getWhitelist(Gap::Whitelist_t &whitelistOut) const
mssarwar 80:808f6f367f45 650 {
mssarwar 80:808f6f367f45 651 uint8_t i;
mssarwar 80:808f6f367f45 652 for (i = 0; i < whitelistAddressesSize && i < whitelistOut.capacity; ++i) {
mssarwar 80:808f6f367f45 653 memcpy(&whitelistOut.addresses[i], &whitelistAddresses[i], sizeof(BLEProtocol::Address_t));
mssarwar 80:808f6f367f45 654 }
mssarwar 80:808f6f367f45 655 whitelistOut.size = i;
mssarwar 80:808f6f367f45 656
mssarwar 80:808f6f367f45 657 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 658 }
mssarwar 80:808f6f367f45 659
mssarwar 80:808f6f367f45 660 /**************************************************************************/
mssarwar 80:808f6f367f45 661 /*!
mssarwar 80:808f6f367f45 662 @brief Set the whitelist that will be used in the next call to
mssarwar 80:808f6f367f45 663 startAdvertising().
mssarwar 80:808f6f367f45 664
mssarwar 80:808f6f367f45 665 @param[in] whitelistIn
mssarwar 80:808f6f367f45 666 A reference to a \ref Gap::Whitelist_t structure
mssarwar 80:808f6f367f45 667 representing a whitelist containing all the white listed
mssarwar 80:808f6f367f45 668 BLE addresses.
mssarwar 80:808f6f367f45 669
mssarwar 80:808f6f367f45 670 @returns \ref ble_errror_t
mssarwar 80:808f6f367f45 671
mssarwar 80:808f6f367f45 672 @retval BLE_ERROR_NONE
mssarwar 80:808f6f367f45 673 Everything executed properly.
mssarwar 80:808f6f367f45 674
mssarwar 80:808f6f367f45 675 BLE_ERROR_INVALID_PARAM
mssarwar 80:808f6f367f45 676 The supplied whitelist contains a private non-resolvable
mssarwar 80:808f6f367f45 677 address
mssarwar 80:808f6f367f45 678
mssarwar 80:808f6f367f45 679 BLE_ERROR_PARAM_OUT_OF_RANGE
mssarwar 80:808f6f367f45 680 The size of the supplied whitelist exceeds the maximum
mssarwar 80:808f6f367f45 681 capacity of the implementation's internal whitelist.
mssarwar 80:808f6f367f45 682
mssarwar 80:808f6f367f45 683 @section EXAMPLE
mssarwar 80:808f6f367f45 684
mssarwar 80:808f6f367f45 685 @code
mssarwar 80:808f6f367f45 686
mssarwar 80:808f6f367f45 687 @endcode
mssarwar 80:808f6f367f45 688 */
mssarwar 80:808f6f367f45 689 /**************************************************************************/
mssarwar 80:808f6f367f45 690 ble_error_t nRF5xGap::setWhitelist(const Gap::Whitelist_t &whitelistIn)
mssarwar 80:808f6f367f45 691 {
mssarwar 80:808f6f367f45 692 if (whitelistIn.size > getMaxWhitelistSize()) {
mssarwar 80:808f6f367f45 693 return BLE_ERROR_PARAM_OUT_OF_RANGE;
mssarwar 80:808f6f367f45 694 }
mssarwar 80:808f6f367f45 695
mssarwar 80:808f6f367f45 696 /* Test for invalid parameters before we change the internal state */
mssarwar 80:808f6f367f45 697 for (uint8_t i = 0; i < whitelistIn.size; ++i) {
mssarwar 80:808f6f367f45 698 if (whitelistIn.addresses[i].type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
mssarwar 80:808f6f367f45 699 /* This is not allowed because it is completely meaningless */
mssarwar 80:808f6f367f45 700 return BLE_ERROR_INVALID_PARAM;
mssarwar 80:808f6f367f45 701 }
mssarwar 80:808f6f367f45 702 }
mssarwar 80:808f6f367f45 703
mssarwar 80:808f6f367f45 704 whitelistAddressesSize = 0;
mssarwar 80:808f6f367f45 705 for (uint8_t i = 0; i < whitelistIn.size; ++i) {
mssarwar 80:808f6f367f45 706 memcpy(&whitelistAddresses[whitelistAddressesSize], &whitelistIn.addresses[i], sizeof(BLEProtocol::Address_t));
mssarwar 80:808f6f367f45 707 whitelistAddressesSize++;
mssarwar 80:808f6f367f45 708 }
mssarwar 80:808f6f367f45 709
mssarwar 80:808f6f367f45 710 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 711 }
mssarwar 80:808f6f367f45 712
mssarwar 80:808f6f367f45 713 /**************************************************************************/
mssarwar 80:808f6f367f45 714 /*!
mssarwar 80:808f6f367f45 715 @brief Set the advertising policy filter mode that will be used in
mssarwar 80:808f6f367f45 716 the next call to startAdvertising().
mssarwar 80:808f6f367f45 717
mssarwar 80:808f6f367f45 718 @returns \ref ble_errror_t
mssarwar 80:808f6f367f45 719
mssarwar 80:808f6f367f45 720 @retval BLE_ERROR_NONE
mssarwar 80:808f6f367f45 721 Everything executed properly.
mssarwar 80:808f6f367f45 722
mssarwar 80:808f6f367f45 723 BLE_ERROR_NOT_IMPLEMENTED
mssarwar 80:808f6f367f45 724 This feature is currently note implemented.
mssarwar 80:808f6f367f45 725
mssarwar 80:808f6f367f45 726 @section EXAMPLE
mssarwar 80:808f6f367f45 727
mssarwar 80:808f6f367f45 728 @code
mssarwar 80:808f6f367f45 729
mssarwar 80:808f6f367f45 730 @endcode
mssarwar 80:808f6f367f45 731 */
mssarwar 80:808f6f367f45 732 /**************************************************************************/
mssarwar 80:808f6f367f45 733 ble_error_t nRF5xGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode)
mssarwar 80:808f6f367f45 734 {
mssarwar 80:808f6f367f45 735 advertisingPolicyMode = mode;
mssarwar 80:808f6f367f45 736
mssarwar 80:808f6f367f45 737 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 738 }
mssarwar 80:808f6f367f45 739
mssarwar 80:808f6f367f45 740 /**************************************************************************/
mssarwar 80:808f6f367f45 741 /*!
mssarwar 80:808f6f367f45 742 @brief Set the scanning policy filter mode that will be used in
mssarwar 80:808f6f367f45 743 the next call to startAdvertising().
mssarwar 80:808f6f367f45 744
mssarwar 80:808f6f367f45 745 @returns \ref ble_errror_t
mssarwar 80:808f6f367f45 746
mssarwar 80:808f6f367f45 747 @retval BLE_ERROR_NONE
mssarwar 80:808f6f367f45 748 Everything executed properly.
mssarwar 80:808f6f367f45 749
mssarwar 80:808f6f367f45 750 BLE_ERROR_NOT_IMPLEMENTED
mssarwar 80:808f6f367f45 751 This feature is currently note implemented.
mssarwar 80:808f6f367f45 752
mssarwar 80:808f6f367f45 753 @section EXAMPLE
mssarwar 80:808f6f367f45 754
mssarwar 80:808f6f367f45 755 @code
mssarwar 80:808f6f367f45 756
mssarwar 80:808f6f367f45 757 @endcode
mssarwar 80:808f6f367f45 758 */
mssarwar 80:808f6f367f45 759 /**************************************************************************/
mssarwar 80:808f6f367f45 760 ble_error_t nRF5xGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode)
mssarwar 80:808f6f367f45 761 {
mssarwar 80:808f6f367f45 762 scanningPolicyMode = mode;
mssarwar 80:808f6f367f45 763
mssarwar 80:808f6f367f45 764 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 765 }
mssarwar 80:808f6f367f45 766
mssarwar 80:808f6f367f45 767 /**************************************************************************/
mssarwar 80:808f6f367f45 768 /*!
mssarwar 80:808f6f367f45 769 @brief Set the initiator policy filter mode that will be used in
mssarwar 80:808f6f367f45 770 the next call to startAdvertising()
mssarwar 80:808f6f367f45 771
mssarwar 80:808f6f367f45 772 @returns \ref ble_errror_t
mssarwar 80:808f6f367f45 773
mssarwar 80:808f6f367f45 774 @retval BLE_ERROR_NONE
mssarwar 80:808f6f367f45 775 Everything executed properly.
mssarwar 80:808f6f367f45 776
mssarwar 80:808f6f367f45 777 BLE_ERROR_NOT_IMPLEMENTED
mssarwar 80:808f6f367f45 778 This feature is currently note implemented.
mssarwar 80:808f6f367f45 779
mssarwar 80:808f6f367f45 780 @section EXAMPLE
mssarwar 80:808f6f367f45 781
mssarwar 80:808f6f367f45 782 @code
mssarwar 80:808f6f367f45 783
mssarwar 80:808f6f367f45 784 @endcode
mssarwar 80:808f6f367f45 785 */
mssarwar 80:808f6f367f45 786 /**************************************************************************/
mssarwar 80:808f6f367f45 787 ble_error_t nRF5xGap::setInitiatorPolicyMode(Gap::InitiatorPolicyMode_t mode)
mssarwar 80:808f6f367f45 788 {
mssarwar 80:808f6f367f45 789 return BLE_ERROR_NOT_IMPLEMENTED;
mssarwar 80:808f6f367f45 790 }
mssarwar 80:808f6f367f45 791
mssarwar 80:808f6f367f45 792 /**************************************************************************/
mssarwar 80:808f6f367f45 793 /*!
mssarwar 80:808f6f367f45 794 @brief Get the current advertising policy filter mode.
mssarwar 80:808f6f367f45 795
mssarwar 80:808f6f367f45 796 @returns The advertising policy filter mode.
mssarwar 80:808f6f367f45 797
mssarwar 80:808f6f367f45 798 @section EXAMPLE
mssarwar 80:808f6f367f45 799
mssarwar 80:808f6f367f45 800 @code
mssarwar 80:808f6f367f45 801
mssarwar 80:808f6f367f45 802 @endcode
mssarwar 80:808f6f367f45 803 */
mssarwar 80:808f6f367f45 804 /**************************************************************************/
mssarwar 80:808f6f367f45 805 Gap::AdvertisingPolicyMode_t nRF5xGap::getAdvertisingPolicyMode(void) const
mssarwar 80:808f6f367f45 806 {
mssarwar 80:808f6f367f45 807 return advertisingPolicyMode;
mssarwar 80:808f6f367f45 808 }
mssarwar 80:808f6f367f45 809
mssarwar 80:808f6f367f45 810 /**************************************************************************/
mssarwar 80:808f6f367f45 811 /*!
mssarwar 80:808f6f367f45 812 @brief Get the current scanning policy filter mode.
mssarwar 80:808f6f367f45 813
mssarwar 80:808f6f367f45 814 @returns The scanning policy filter mode.
mssarwar 80:808f6f367f45 815
mssarwar 80:808f6f367f45 816 @section EXAMPLE
mssarwar 80:808f6f367f45 817
mssarwar 80:808f6f367f45 818 @code
mssarwar 80:808f6f367f45 819
mssarwar 80:808f6f367f45 820 @endcode
mssarwar 80:808f6f367f45 821 */
mssarwar 80:808f6f367f45 822 /**************************************************************************/
mssarwar 80:808f6f367f45 823 Gap::ScanningPolicyMode_t nRF5xGap::getScanningPolicyMode(void) const
mssarwar 80:808f6f367f45 824 {
mssarwar 80:808f6f367f45 825 return scanningPolicyMode;
mssarwar 80:808f6f367f45 826 }
mssarwar 80:808f6f367f45 827
mssarwar 80:808f6f367f45 828 /**************************************************************************/
mssarwar 80:808f6f367f45 829 /*!
mssarwar 80:808f6f367f45 830 @brief Get the current initiator policy filter mode.
mssarwar 80:808f6f367f45 831
mssarwar 80:808f6f367f45 832 @returns The initiator policy filter mode.
mssarwar 80:808f6f367f45 833
mssarwar 80:808f6f367f45 834 @note Currently initiator filtering using the whitelist is not
mssarwar 80:808f6f367f45 835 implemented in this module.
mssarwar 80:808f6f367f45 836
mssarwar 80:808f6f367f45 837 @section EXAMPLE
mssarwar 80:808f6f367f45 838
mssarwar 80:808f6f367f45 839 @code
mssarwar 80:808f6f367f45 840
mssarwar 80:808f6f367f45 841 @endcode
mssarwar 80:808f6f367f45 842 */
mssarwar 80:808f6f367f45 843 /**************************************************************************/
mssarwar 80:808f6f367f45 844 Gap::InitiatorPolicyMode_t nRF5xGap::getInitiatorPolicyMode(void) const
mssarwar 80:808f6f367f45 845 {
mssarwar 80:808f6f367f45 846 return Gap::INIT_POLICY_IGNORE_WHITELIST;
mssarwar 80:808f6f367f45 847 }
mssarwar 80:808f6f367f45 848
mssarwar 80:808f6f367f45 849 /**************************************************************************/
mssarwar 80:808f6f367f45 850 /*!
mssarwar 80:808f6f367f45 851 @brief Helper function used to populate the ble_gap_whitelist_t that
mssarwar 80:808f6f367f45 852 will be used by the SoftDevice for filtering requests.
mssarwar 80:808f6f367f45 853
mssarwar 80:808f6f367f45 854 @returns \ref ble_error_t
mssarwar 80:808f6f367f45 855
mssarwar 80:808f6f367f45 856 @retval BLE_ERROR_NONE
mssarwar 80:808f6f367f45 857 Everything executed properly
mssarwar 80:808f6f367f45 858
mssarwar 80:808f6f367f45 859 @retval BLE_ERROR_INVALID_STATE
mssarwar 80:808f6f367f45 860 The internal stack was not initialized correctly.
mssarwar 80:808f6f367f45 861
mssarwar 80:808f6f367f45 862 @note Both the SecurityManager and Gap must initialize correctly for
mssarwar 80:808f6f367f45 863 this function to succeed.
mssarwar 80:808f6f367f45 864
mssarwar 80:808f6f367f45 865 @note This function is needed because for the BLE API the whitelist
mssarwar 80:808f6f367f45 866 is just a collection of keys, but for the stack it also includes
mssarwar 80:808f6f367f45 867 the IRK table.
mssarwar 80:808f6f367f45 868
mssarwar 80:808f6f367f45 869 @section EXAMPLE
mssarwar 80:808f6f367f45 870
mssarwar 80:808f6f367f45 871 @code
mssarwar 80:808f6f367f45 872
mssarwar 80:808f6f367f45 873 @endcode
mssarwar 80:808f6f367f45 874 */
mssarwar 80:808f6f367f45 875 /**************************************************************************/
mssarwar 80:808f6f367f45 876 ble_error_t nRF5xGap::generateStackWhitelist(ble_gap_whitelist_t &whitelist)
mssarwar 80:808f6f367f45 877 {
mssarwar 80:808f6f367f45 878 ble_gap_whitelist_t whitelistFromBondTable;
mssarwar 80:808f6f367f45 879 ble_gap_addr_t *addressPtr[1];
mssarwar 80:808f6f367f45 880 ble_gap_irk_t *irkPtr[YOTTA_CFG_IRK_TABLE_MAX_SIZE];
mssarwar 80:808f6f367f45 881
mssarwar 80:808f6f367f45 882 nRF5xSecurityManager& securityManager = (nRF5xSecurityManager&) nRF5xn::Instance(0).getSecurityManager();
mssarwar 80:808f6f367f45 883
mssarwar 80:808f6f367f45 884 if (securityManager.hasInitialized()) {
mssarwar 80:808f6f367f45 885 /* We do not care about the addresses, set the count to 0 */
mssarwar 80:808f6f367f45 886 whitelistFromBondTable.addr_count = 0;
mssarwar 80:808f6f367f45 887 /* The Nordic SDK will return a failure if we set pp_addr to NULL */
mssarwar 80:808f6f367f45 888 whitelistFromBondTable.pp_addrs = addressPtr;
mssarwar 80:808f6f367f45 889 /* We want all the IRKs we can get because we do not know which ones match the addresses */
mssarwar 80:808f6f367f45 890 whitelistFromBondTable.irk_count = YOTTA_CFG_IRK_TABLE_MAX_SIZE;
mssarwar 80:808f6f367f45 891 whitelistFromBondTable.pp_irks = irkPtr;
mssarwar 80:808f6f367f45 892
mssarwar 80:808f6f367f45 893 /* Use the security manager to get the IRKs from the bond table */
mssarwar 80:808f6f367f45 894 ble_error_t error = securityManager.createWhitelistFromBondTable(whitelistFromBondTable);
mssarwar 80:808f6f367f45 895 if (error != BLE_ERROR_NONE) {
mssarwar 80:808f6f367f45 896 return error;
mssarwar 80:808f6f367f45 897 }
mssarwar 80:808f6f367f45 898 } else {
mssarwar 80:808f6f367f45 899 /**
mssarwar 80:808f6f367f45 900 * If there is no security manager then we cannot access the bond table,
mssarwar 80:808f6f367f45 901 * so disable IRK matching
mssarwar 80:808f6f367f45 902 */
mssarwar 80:808f6f367f45 903 whitelistFromBondTable.addr_count = 0;
mssarwar 80:808f6f367f45 904 whitelistFromBondTable.irk_count = 0;
mssarwar 80:808f6f367f45 905 }
mssarwar 80:808f6f367f45 906
mssarwar 80:808f6f367f45 907 /**
mssarwar 80:808f6f367f45 908 * For every private resolvable address in the local whitelist check if
mssarwar 80:808f6f367f45 909 * there is an IRK for said address in the bond table and add it to the
mssarwar 80:808f6f367f45 910 * local IRK list.
mssarwar 80:808f6f367f45 911 */
mssarwar 80:808f6f367f45 912 whitelist.irk_count = 0;
mssarwar 80:808f6f367f45 913 whitelist.addr_count = 0;
mssarwar 80:808f6f367f45 914 for (uint8_t i = 0; i < whitelistAddressesSize; ++i) {
mssarwar 80:808f6f367f45 915 if (whitelistAddresses[i].addr_type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE) {
mssarwar 80:808f6f367f45 916 /* Test if there is a matching IRK for this private resolvable address */
mssarwar 80:808f6f367f45 917 for (uint8_t j = 0; j < whitelistFromBondTable.irk_count; ++j) {
mssarwar 80:808f6f367f45 918 if (securityManager.matchAddressAndIrk(&whitelistAddresses[i], whitelistFromBondTable.pp_irks[j])) {
mssarwar 80:808f6f367f45 919 /* Found the corresponding IRK, add it to our local whitelist */
mssarwar 80:808f6f367f45 920 whitelist.pp_irks[whitelist.irk_count] = whitelistFromBondTable.pp_irks[j];
mssarwar 80:808f6f367f45 921 whitelist.irk_count++;
mssarwar 80:808f6f367f45 922 /* Make sure we do not look at this IRK again */
mssarwar 80:808f6f367f45 923 if (j != whitelistFromBondTable.irk_count - 1) {
mssarwar 80:808f6f367f45 924 /**
mssarwar 80:808f6f367f45 925 * This is not the last IRK, so replace the pointer
mssarwar 80:808f6f367f45 926 * with the last pointer in the array
mssarwar 80:808f6f367f45 927 */
mssarwar 80:808f6f367f45 928 whitelistFromBondTable.pp_irks[j] =
mssarwar 80:808f6f367f45 929 whitelistFromBondTable.pp_irks[whitelistFromBondTable.irk_count - 1];
mssarwar 80:808f6f367f45 930 }
mssarwar 80:808f6f367f45 931 /**
mssarwar 80:808f6f367f45 932 * If the IRK is the last pointer in the array simply
mssarwar 80:808f6f367f45 933 * decrement the total IRK count
mssarwar 80:808f6f367f45 934 */
mssarwar 80:808f6f367f45 935 whitelistFromBondTable.irk_count--;
mssarwar 80:808f6f367f45 936 break;
mssarwar 80:808f6f367f45 937 }
mssarwar 80:808f6f367f45 938 }
mssarwar 80:808f6f367f45 939 } else {
mssarwar 80:808f6f367f45 940 /* Include the address into the whitelist */
mssarwar 80:808f6f367f45 941 whitelist.pp_addrs[whitelist.addr_count] = &whitelistAddresses[i];
mssarwar 80:808f6f367f45 942 whitelist.addr_count++;
mssarwar 80:808f6f367f45 943 }
mssarwar 80:808f6f367f45 944 }
mssarwar 80:808f6f367f45 945
mssarwar 80:808f6f367f45 946 return BLE_ERROR_NONE;
mssarwar 80:808f6f367f45 947 }