library for BLE_GAP_backpack
Dependencies: nrf51-sdk
Fork of nRF51822 by
nRF5xGap.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "nRF5xn.h" 00018 #ifdef YOTTA_CFG_MBED_OS 00019 #include "mbed-drivers/mbed.h" 00020 #else 00021 #include "mbed.h" 00022 #endif 00023 #include "ble/BLE.h" 00024 00025 #include "common/common.h " 00026 #include "ble_advdata.h" 00027 #include "ble_hci.h" 00028 00029 void radioNotificationStaticCallback(bool param) { 00030 nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap(); 00031 gap.processRadioNotificationEvent(param); 00032 } 00033 00034 /**************************************************************************/ 00035 /*! 00036 @brief Sets the advertising parameters and payload for the device 00037 00038 @param[in] params 00039 Basic advertising details, including the advertising 00040 delay, timeout and how the device should be advertised 00041 @params[in] advData 00042 The primary advertising data payload 00043 @params[in] scanResponse 00044 The optional Scan Response payload if the advertising 00045 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED 00046 in \ref GapAdveritinngParams 00047 00048 @returns \ref ble_error_t 00049 00050 @retval BLE_ERROR_NONE 00051 Everything executed properly 00052 00053 @retval BLE_ERROR_BUFFER_OVERFLOW 00054 The proposed action would cause a buffer overflow. All 00055 advertising payloads must be <= 31 bytes, for example. 00056 00057 @retval BLE_ERROR_NOT_IMPLEMENTED 00058 A feature was requested that is not yet supported in the 00059 nRF51 firmware or hardware. 00060 00061 @retval BLE_ERROR_PARAM_OUT_OF_RANGE 00062 One of the proposed values is outside the valid range. 00063 00064 @section EXAMPLE 00065 00066 @code 00067 00068 @endcode 00069 */ 00070 /**************************************************************************/ 00071 ble_error_t nRF5xGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) 00072 { 00073 /* Make sure we don't exceed the advertising payload length */ 00074 if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { 00075 return BLE_ERROR_BUFFER_OVERFLOW; 00076 } 00077 00078 /* Make sure we have a payload! */ 00079 if (advData.getPayloadLen() == 0) { 00080 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00081 } 00082 00083 /* Check the scan response payload limits */ 00084 //if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED)) 00085 //{ 00086 // /* Check if we're within the upper limit */ 00087 // if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) 00088 // { 00089 // return BLE_ERROR_BUFFER_OVERFLOW; 00090 // } 00091 // /* Make sure we have a payload! */ 00092 // if (advData.getPayloadLen() == 0) 00093 // { 00094 // return BLE_ERROR_PARAM_OUT_OF_RANGE; 00095 // } 00096 //} 00097 00098 /* Send advertising data! */ 00099 ASSERT(ERROR_NONE == 00100 sd_ble_gap_adv_data_set(advData.getPayload(), 00101 advData.getPayloadLen(), 00102 scanResponse.getPayload(), 00103 scanResponse.getPayloadLen()), 00104 BLE_ERROR_PARAM_OUT_OF_RANGE); 00105 00106 /* Make sure the GAP Service appearance value is aligned with the 00107 *appearance from GapAdvertisingData */ 00108 ASSERT(ERROR_NONE == sd_ble_gap_appearance_set(advData.getAppearance()), 00109 BLE_ERROR_PARAM_OUT_OF_RANGE); 00110 00111 /* ToDo: Perform some checks on the payload, for example the Scan Response can't */ 00112 /* contains a flags AD type, etc. */ 00113 00114 return BLE_ERROR_NONE; 00115 } 00116 00117 /**************************************************************************/ 00118 /*! 00119 @brief Starts the BLE HW, initialising any services that were 00120 added before this function was called. 00121 00122 @note All services must be added before calling this function! 00123 00124 @returns ble_error_t 00125 00126 @retval BLE_ERROR_NONE 00127 Everything executed properly 00128 00129 @section EXAMPLE 00130 00131 @code 00132 00133 @endcode 00134 */ 00135 /**************************************************************************/ 00136 ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams ¶ms) 00137 { 00138 /* Make sure we support the advertising type */ 00139 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { 00140 /* ToDo: This requires a propery security implementation, etc. */ 00141 return BLE_ERROR_NOT_IMPLEMENTED; 00142 } 00143 00144 /* Check interval range */ 00145 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { 00146 /* Min delay is slightly longer for unconnectable devices */ 00147 if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || 00148 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { 00149 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00150 } 00151 } else { 00152 if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) || 00153 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { 00154 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00155 } 00156 } 00157 00158 /* Check timeout is zero for Connectable Directed */ 00159 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { 00160 /* Timeout must be 0 with this type, although we'll never get here */ 00161 /* since this isn't implemented yet anyway */ 00162 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00163 } 00164 00165 /* Check timeout for other advertising types */ 00166 if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && 00167 (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) { 00168 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00169 } 00170 00171 /* Allocate the stack's whitelist statically */ 00172 ble_gap_whitelist_t whitelist; 00173 ble_gap_addr_t *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE]; 00174 ble_gap_irk_t *whitelistIrkPtrs[YOTTA_CFG_IRK_TABLE_MAX_SIZE]; 00175 /* Initialize the whitelist */ 00176 whitelist.pp_addrs = whitelistAddressPtrs; 00177 whitelist.pp_irks = whitelistIrkPtrs; 00178 whitelist.addr_count = 0; 00179 whitelist.irk_count = 0; 00180 00181 /* Add missing IRKs to whitelist from the bond table held by the SoftDevice */ 00182 if (advertisingPolicyMode != Gap::ADV_POLICY_IGNORE_WHITELIST) { 00183 ble_error_t error = generateStackWhitelist(whitelist); 00184 if (error != BLE_ERROR_NONE) { 00185 return error; 00186 } 00187 } 00188 00189 /* Start Advertising */ 00190 ble_gap_adv_params_t adv_para = {0}; 00191 00192 adv_para.type = params.getAdvertisingType(); 00193 adv_para.p_peer_addr = NULL; // Undirected advertisement 00194 adv_para.fp = advertisingPolicyMode; 00195 adv_para.p_whitelist = &whitelist; 00196 adv_para.interval = params.getIntervalInADVUnits(); // advertising interval (in units of 0.625 ms) 00197 adv_para.timeout = params.getTimeout(); 00198 00199 ASSERT(ERROR_NONE == sd_ble_gap_adv_start(&adv_para), BLE_ERROR_PARAM_OUT_OF_RANGE); 00200 00201 return BLE_ERROR_NONE; 00202 } 00203 00204 /* Observer role is not supported by S110, return BLE_ERROR_NOT_IMPLEMENTED */ 00205 #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) 00206 ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams) 00207 { 00208 /* Allocate the stack's whitelist statically */ 00209 ble_gap_whitelist_t whitelist; 00210 ble_gap_addr_t *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE]; 00211 ble_gap_irk_t *whitelistIrkPtrs[YOTTA_CFG_IRK_TABLE_MAX_SIZE]; 00212 /* Initialize the whitelist */ 00213 whitelist.pp_addrs = whitelistAddressPtrs; 00214 whitelist.pp_irks = whitelistIrkPtrs; 00215 whitelist.addr_count = 0; 00216 whitelist.irk_count = 0; 00217 00218 /* Add missing IRKs to whitelist from the bond table held by the SoftDevice */ 00219 if (scanningPolicyMode != Gap::SCAN_POLICY_IGNORE_WHITELIST) { 00220 ble_error_t error = generateStackWhitelist(whitelist); 00221 if (error != BLE_ERROR_NONE) { 00222 return error; 00223 } 00224 } 00225 00226 ble_gap_scan_params_t scanParams = { 00227 .active = scanningParams.getActiveScanning(), /**< If 1, perform active scanning (scan requests). */ 00228 .selective = scanningPolicyMode, /**< If 1, ignore unknown devices (non whitelisted). */ 00229 .p_whitelist = &whitelist, /**< Pointer to whitelist, NULL if none is given. */ 00230 .interval = scanningParams.getInterval(), /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ 00231 .window = scanningParams.getWindow(), /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ 00232 .timeout = scanningParams.getTimeout(), /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ 00233 }; 00234 00235 if (sd_ble_gap_scan_start(&scanParams) != NRF_SUCCESS) { 00236 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00237 } 00238 00239 return BLE_ERROR_NONE; 00240 } 00241 00242 ble_error_t nRF5xGap::stopScan(void) { 00243 if (sd_ble_gap_scan_stop() == NRF_SUCCESS) { 00244 return BLE_ERROR_NONE; 00245 } 00246 00247 return BLE_STACK_BUSY; 00248 } 00249 #endif 00250 00251 /**************************************************************************/ 00252 /*! 00253 @brief Stops the BLE HW and disconnects from any devices 00254 00255 @returns ble_error_t 00256 00257 @retval BLE_ERROR_NONE 00258 Everything executed properly 00259 00260 @section EXAMPLE 00261 00262 @code 00263 00264 @endcode 00265 */ 00266 /**************************************************************************/ 00267 ble_error_t nRF5xGap::stopAdvertising(void) 00268 { 00269 /* Stop Advertising */ 00270 ASSERT(ERROR_NONE == sd_ble_gap_adv_stop(), BLE_ERROR_PARAM_OUT_OF_RANGE); 00271 00272 state.advertising = 0; 00273 00274 return BLE_ERROR_NONE; 00275 } 00276 00277 ble_error_t nRF5xGap::connect(const Address_t peerAddr, 00278 BLEProtocol::AddressType_t peerAddrType, 00279 const ConnectionParams_t *connectionParams, 00280 const GapScanningParams *scanParamsIn) 00281 { 00282 ble_gap_addr_t addr; 00283 addr.addr_type = peerAddrType; 00284 memcpy(addr.addr, peerAddr, Gap::ADDR_LEN); 00285 00286 ble_gap_conn_params_t connParams; 00287 if (connectionParams != NULL) { 00288 connParams.min_conn_interval = connectionParams->minConnectionInterval; 00289 connParams.max_conn_interval = connectionParams->maxConnectionInterval; 00290 connParams.slave_latency = connectionParams->slaveLatency; 00291 connParams.conn_sup_timeout = connectionParams->connectionSupervisionTimeout; 00292 } else { 00293 connParams.min_conn_interval = 50; 00294 connParams.max_conn_interval = 100; 00295 connParams.slave_latency = 0; 00296 connParams.conn_sup_timeout = 600; 00297 } 00298 00299 /* Allocate the stack's whitelist statically */ 00300 ble_gap_whitelist_t whitelist; 00301 ble_gap_addr_t *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE]; 00302 ble_gap_irk_t *whitelistIrkPtrs[YOTTA_CFG_IRK_TABLE_MAX_SIZE]; 00303 /* Initialize the whitelist */ 00304 whitelist.pp_addrs = whitelistAddressPtrs; 00305 whitelist.pp_irks = whitelistIrkPtrs; 00306 whitelist.addr_count = 0; 00307 whitelist.irk_count = 0; 00308 00309 /* Add missing IRKs to whitelist from the bond table held by the SoftDevice */ 00310 if (scanningPolicyMode != Gap::SCAN_POLICY_IGNORE_WHITELIST) { 00311 ble_error_t error = generateStackWhitelist(whitelist); 00312 if (error != BLE_ERROR_NONE) { 00313 return error; 00314 } 00315 } 00316 00317 ble_gap_scan_params_t scanParams; 00318 scanParams.selective = scanningPolicyMode; /**< If 1, ignore unknown devices (non whitelisted). */ 00319 scanParams.p_whitelist = &whitelist; /**< Pointer to whitelist, NULL if none is given. */ 00320 if (scanParamsIn != NULL) { 00321 scanParams.active = scanParamsIn->getActiveScanning(); /**< If 1, perform active scanning (scan requests). */ 00322 scanParams.interval = scanParamsIn->getInterval(); /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ 00323 scanParams.window = scanParamsIn->getWindow(); /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ 00324 scanParams.timeout = scanParamsIn->getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ 00325 } else { 00326 scanParams.active = _scanningParams.getActiveScanning(); /**< If 1, perform active scanning (scan requests). */ 00327 scanParams.interval = _scanningParams.getInterval(); /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ 00328 scanParams.window = _scanningParams.getWindow(); /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ 00329 scanParams.timeout = _scanningParams.getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ 00330 } 00331 00332 uint32_t rc = sd_ble_gap_connect(&addr, &scanParams, &connParams); 00333 if (rc == NRF_SUCCESS) { 00334 return BLE_ERROR_NONE; 00335 } 00336 switch (rc) { 00337 case NRF_ERROR_INVALID_ADDR: 00338 return BLE_ERROR_INVALID_PARAM; 00339 case NRF_ERROR_INVALID_PARAM: 00340 return BLE_ERROR_INVALID_PARAM; 00341 case NRF_ERROR_INVALID_STATE: 00342 return BLE_ERROR_INVALID_STATE; 00343 case BLE_ERROR_GAP_INVALID_BLE_ADDR: 00344 return BLE_ERROR_INVALID_PARAM; 00345 case NRF_ERROR_NO_MEM: 00346 return BLE_ERROR_NO_MEM; 00347 case NRF_ERROR_BUSY: 00348 return BLE_STACK_BUSY; 00349 default: 00350 case BLE_ERROR_GAP_WHITELIST_IN_USE: 00351 return BLE_ERROR_UNSPECIFIED; 00352 } 00353 } 00354 00355 ble_error_t nRF5xGap::disconnect(Handle_t connectionHandle, DisconnectionReason_t reason) 00356 { 00357 uint8_t code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION; 00358 switch (reason) { 00359 case REMOTE_USER_TERMINATED_CONNECTION: 00360 code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION; 00361 break; 00362 case CONN_INTERVAL_UNACCEPTABLE: 00363 code = BLE_HCI_CONN_INTERVAL_UNACCEPTABLE; 00364 break; 00365 default: 00366 break; 00367 } 00368 00369 /* Disconnect if we are connected to a central device */ 00370 ASSERT_INT(ERROR_NONE, sd_ble_gap_disconnect(connectionHandle, code), BLE_ERROR_PARAM_OUT_OF_RANGE); 00371 00372 return BLE_ERROR_NONE; 00373 } 00374 00375 /*! 00376 @brief Disconnects if we are connected to a central device 00377 00378 @returns ble_error_t 00379 00380 @retval BLE_ERROR_NONE 00381 Everything executed properly 00382 */ 00383 ble_error_t nRF5xGap::disconnect(DisconnectionReason_t reason) 00384 { 00385 return disconnect(m_connectionHandle, reason); 00386 } 00387 00388 ble_error_t nRF5xGap::getPreferredConnectionParams(ConnectionParams_t *params) 00389 { 00390 ASSERT_INT(NRF_SUCCESS, 00391 sd_ble_gap_ppcp_get(reinterpret_cast<ble_gap_conn_params_t *>(params)), 00392 BLE_ERROR_PARAM_OUT_OF_RANGE); 00393 00394 return BLE_ERROR_NONE; 00395 } 00396 00397 ble_error_t nRF5xGap::setPreferredConnectionParams(const ConnectionParams_t *params) 00398 { 00399 ASSERT_INT(NRF_SUCCESS, 00400 sd_ble_gap_ppcp_set(reinterpret_cast<const ble_gap_conn_params_t *>(params)), 00401 BLE_ERROR_PARAM_OUT_OF_RANGE); 00402 00403 return BLE_ERROR_NONE; 00404 } 00405 00406 ble_error_t nRF5xGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *newParams) 00407 { 00408 uint32_t rc; 00409 00410 rc = sd_ble_gap_conn_param_update(handle, reinterpret_cast<ble_gap_conn_params_t *>(const_cast<ConnectionParams_t*>(newParams))); 00411 if (rc == NRF_SUCCESS) { 00412 return BLE_ERROR_NONE; 00413 } else { 00414 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00415 } 00416 } 00417 00418 /**************************************************************************/ 00419 /*! 00420 @brief Clear nRF5xGap's state. 00421 00422 @returns ble_error_t 00423 00424 @retval BLE_ERROR_NONE 00425 Everything executed properly 00426 */ 00427 /**************************************************************************/ 00428 ble_error_t nRF5xGap::reset(void) 00429 { 00430 /* Clear all state that is from the parent, including private members */ 00431 if (Gap::reset() != BLE_ERROR_NONE) { 00432 return BLE_ERROR_INVALID_STATE; 00433 } 00434 00435 /* Clear derived class members */ 00436 m_connectionHandle = BLE_CONN_HANDLE_INVALID; 00437 00438 /* Set the whitelist policy filter modes to IGNORE_WHITELIST */ 00439 advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST; 00440 scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST; 00441 00442 /* Clear the internal whitelist */ 00443 whitelistAddressesSize = 0; 00444 00445 return BLE_ERROR_NONE; 00446 } 00447 00448 /**************************************************************************/ 00449 /*! 00450 @brief Sets the 16-bit connection handle 00451 */ 00452 /**************************************************************************/ 00453 void nRF5xGap::setConnectionHandle(uint16_t con_handle) 00454 { 00455 m_connectionHandle = con_handle; 00456 } 00457 00458 /**************************************************************************/ 00459 /*! 00460 @brief Gets the 16-bit connection handle 00461 */ 00462 /**************************************************************************/ 00463 uint16_t nRF5xGap::getConnectionHandle(void) 00464 { 00465 return m_connectionHandle; 00466 } 00467 00468 /**************************************************************************/ 00469 /*! 00470 @brief Sets the BLE device address 00471 00472 @returns ble_error_t 00473 00474 @section EXAMPLE 00475 00476 @code 00477 00478 uint8_t device_address[6] = { 0xca, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0 }; 00479 nrf.getGap().setAddress(Gap::BLEProtocol::AddressType::RANDOM_STATIC, device_address); 00480 00481 @endcode 00482 */ 00483 /**************************************************************************/ 00484 ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address) 00485 { 00486 uint8_t cycle_mode; 00487 ble_gap_addr_t dev_addr; 00488 00489 /* When using Public or Static addresses, the cycle mode must be None. 00490 When using Random Private addresses, the cycle mode must be Auto. 00491 In auto mode, the given address is ignored. 00492 */ 00493 if ((type == BLEProtocol::AddressType::PUBLIC) || (type == BLEProtocol::AddressType::RANDOM_STATIC)) 00494 { 00495 cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_NONE; 00496 memcpy(dev_addr.addr, address, ADDR_LEN); 00497 } 00498 else if ((type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE) || (type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE)) 00499 { 00500 cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_AUTO; 00501 // address is ignored when in auto mode 00502 } 00503 else 00504 { 00505 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00506 } 00507 00508 dev_addr.addr_type = type; 00509 ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(cycle_mode, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE); 00510 00511 return BLE_ERROR_NONE; 00512 } 00513 00514 ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address) 00515 { 00516 ble_gap_addr_t dev_addr; 00517 if (sd_ble_gap_address_get(&dev_addr) != NRF_SUCCESS) { 00518 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00519 } 00520 00521 if (typeP != NULL) { 00522 *typeP = static_cast<AddressType_t>(dev_addr.addr_type); 00523 } 00524 if (address != NULL) { 00525 memcpy(address, dev_addr.addr, ADDR_LEN); 00526 } 00527 return BLE_ERROR_NONE; 00528 } 00529 00530 ble_error_t nRF5xGap::setDeviceName(const uint8_t *deviceName) 00531 { 00532 ble_gap_conn_sec_mode_t sec_mode; 00533 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); // no security is needed 00534 00535 if (sd_ble_gap_device_name_set(&sec_mode, deviceName, strlen((const char *)deviceName)) == NRF_SUCCESS) { 00536 return BLE_ERROR_NONE; 00537 } else { 00538 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00539 } 00540 } 00541 00542 ble_error_t nRF5xGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) 00543 { 00544 if (sd_ble_gap_device_name_get(deviceName, (uint16_t *)lengthP) == NRF_SUCCESS) { 00545 return BLE_ERROR_NONE; 00546 } else { 00547 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00548 } 00549 } 00550 00551 ble_error_t nRF5xGap::setAppearance(GapAdvertisingData::Appearance appearance) 00552 { 00553 if (sd_ble_gap_appearance_set(appearance) == NRF_SUCCESS) { 00554 return BLE_ERROR_NONE; 00555 } else { 00556 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00557 } 00558 } 00559 00560 ble_error_t nRF5xGap::getAppearance(GapAdvertisingData::Appearance *appearanceP) 00561 { 00562 if ((sd_ble_gap_appearance_get(reinterpret_cast<uint16_t *>(appearanceP)) == NRF_SUCCESS)) { 00563 return BLE_ERROR_NONE; 00564 } else { 00565 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00566 } 00567 } 00568 00569 /* (Valid values are -40, -20, -16, -12, -8, -4, 0, 4) */ 00570 ble_error_t nRF5xGap::setTxPower(int8_t txPower) 00571 { 00572 unsigned rc; 00573 if ((rc = sd_ble_gap_tx_power_set(txPower)) != NRF_SUCCESS) { 00574 switch (rc) { 00575 case NRF_ERROR_BUSY: 00576 return BLE_STACK_BUSY; 00577 case NRF_ERROR_INVALID_PARAM: 00578 default: 00579 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00580 } 00581 } 00582 00583 return BLE_ERROR_NONE; 00584 } 00585 00586 void nRF5xGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) 00587 { 00588 static const int8_t permittedTxValues[] = { 00589 -40, -30, -20, -16, -12, -8, -4, 0, 4 00590 }; 00591 00592 *valueArrayPP = permittedTxValues; 00593 *countP = sizeof(permittedTxValues) / sizeof(int8_t); 00594 } 00595 00596 /**************************************************************************/ 00597 /*! 00598 @brief Get the capacity of the internal whitelist maintained by this 00599 implementation. 00600 00601 @returns The capacity of the internal whitelist. 00602 00603 @section EXAMPLE 00604 00605 @code 00606 00607 @endcode 00608 */ 00609 /**************************************************************************/ 00610 uint8_t nRF5xGap::getMaxWhitelistSize(void) const 00611 { 00612 return YOTTA_CFG_WHITELIST_MAX_SIZE; 00613 } 00614 00615 /**************************************************************************/ 00616 /*! 00617 @brief Get a copy of the implementation's internal whitelist. 00618 00619 @param[out] whitelistOut 00620 A \ref Gap::Whitelist_t structure containing a copy of the 00621 addresses in the implemenetation's internal whitelist. 00622 00623 @returns \ref ble_errror_t 00624 00625 @retval BLE_ERROR_NONE 00626 Everything executed properly. 00627 00628 @section EXAMPLE 00629 00630 @code 00631 00632 @endcode 00633 */ 00634 /**************************************************************************/ 00635 ble_error_t nRF5xGap::getWhitelist(Gap::Whitelist_t &whitelistOut) const 00636 { 00637 uint8_t i; 00638 for (i = 0; i < whitelistAddressesSize && i < whitelistOut.capacity; ++i) { 00639 memcpy(&whitelistOut.addresses[i], &whitelistAddresses[i], sizeof(BLEProtocol::Address_t)); 00640 } 00641 whitelistOut.size = i; 00642 00643 return BLE_ERROR_NONE; 00644 } 00645 00646 /**************************************************************************/ 00647 /*! 00648 @brief Set the whitelist that will be used in the next call to 00649 startAdvertising(). 00650 00651 @param[in] whitelistIn 00652 A reference to a \ref Gap::Whitelist_t structure 00653 representing a whitelist containing all the white listed 00654 BLE addresses. 00655 00656 @returns \ref ble_errror_t 00657 00658 @retval BLE_ERROR_NONE 00659 Everything executed properly. 00660 00661 BLE_ERROR_INVALID_PARAM 00662 The supplied whitelist contains a private non-resolvable 00663 address 00664 00665 BLE_ERROR_PARAM_OUT_OF_RANGE 00666 The size of the supplied whitelist exceeds the maximum 00667 capacity of the implementation's internal whitelist. 00668 00669 @section EXAMPLE 00670 00671 @code 00672 00673 @endcode 00674 */ 00675 /**************************************************************************/ 00676 ble_error_t nRF5xGap::setWhitelist(const Gap::Whitelist_t &whitelistIn) 00677 { 00678 if (whitelistIn.size > getMaxWhitelistSize()) { 00679 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00680 } 00681 00682 /* Test for invalid parameters before we change the internal state */ 00683 for (uint8_t i = 0; i < whitelistIn.size; ++i) { 00684 if (whitelistIn.addresses[i].type == BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) { 00685 /* This is not allowed because it is completely meaningless */ 00686 return BLE_ERROR_INVALID_PARAM; 00687 } 00688 } 00689 00690 whitelistAddressesSize = 0; 00691 for (uint8_t i = 0; i < whitelistIn.size; ++i) { 00692 memcpy(&whitelistAddresses[whitelistAddressesSize], &whitelistIn.addresses[i], sizeof(BLEProtocol::Address_t)); 00693 whitelistAddressesSize++; 00694 } 00695 00696 return BLE_ERROR_NONE; 00697 } 00698 00699 /**************************************************************************/ 00700 /*! 00701 @brief Set the advertising policy filter mode that will be used in 00702 the next call to startAdvertising(). 00703 00704 @returns \ref ble_errror_t 00705 00706 @retval BLE_ERROR_NONE 00707 Everything executed properly. 00708 00709 BLE_ERROR_NOT_IMPLEMENTED 00710 This feature is currently note implemented. 00711 00712 @section EXAMPLE 00713 00714 @code 00715 00716 @endcode 00717 */ 00718 /**************************************************************************/ 00719 ble_error_t nRF5xGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode) 00720 { 00721 advertisingPolicyMode = mode; 00722 00723 return BLE_ERROR_NONE; 00724 } 00725 00726 /**************************************************************************/ 00727 /*! 00728 @brief Set the scanning policy filter mode that will be used in 00729 the next call to startAdvertising(). 00730 00731 @returns \ref ble_errror_t 00732 00733 @retval BLE_ERROR_NONE 00734 Everything executed properly. 00735 00736 BLE_ERROR_NOT_IMPLEMENTED 00737 This feature is currently note implemented. 00738 00739 @section EXAMPLE 00740 00741 @code 00742 00743 @endcode 00744 */ 00745 /**************************************************************************/ 00746 ble_error_t nRF5xGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode) 00747 { 00748 scanningPolicyMode = mode; 00749 00750 return BLE_ERROR_NONE; 00751 } 00752 00753 /**************************************************************************/ 00754 /*! 00755 @brief Set the initiator policy filter mode that will be used in 00756 the next call to startAdvertising() 00757 00758 @returns \ref ble_errror_t 00759 00760 @retval BLE_ERROR_NONE 00761 Everything executed properly. 00762 00763 BLE_ERROR_NOT_IMPLEMENTED 00764 This feature is currently note implemented. 00765 00766 @section EXAMPLE 00767 00768 @code 00769 00770 @endcode 00771 */ 00772 /**************************************************************************/ 00773 ble_error_t nRF5xGap::setInitiatorPolicyMode(Gap::InitiatorPolicyMode_t mode) 00774 { 00775 return BLE_ERROR_NOT_IMPLEMENTED; 00776 } 00777 00778 /**************************************************************************/ 00779 /*! 00780 @brief Get the current advertising policy filter mode. 00781 00782 @returns The advertising policy filter mode. 00783 00784 @section EXAMPLE 00785 00786 @code 00787 00788 @endcode 00789 */ 00790 /**************************************************************************/ 00791 Gap::AdvertisingPolicyMode_t nRF5xGap::getAdvertisingPolicyMode(void) const 00792 { 00793 return advertisingPolicyMode; 00794 } 00795 00796 /**************************************************************************/ 00797 /*! 00798 @brief Get the current scanning policy filter mode. 00799 00800 @returns The scanning policy filter mode. 00801 00802 @section EXAMPLE 00803 00804 @code 00805 00806 @endcode 00807 */ 00808 /**************************************************************************/ 00809 Gap::ScanningPolicyMode_t nRF5xGap::getScanningPolicyMode(void) const 00810 { 00811 return scanningPolicyMode; 00812 } 00813 00814 /**************************************************************************/ 00815 /*! 00816 @brief Get the current initiator policy filter mode. 00817 00818 @returns The initiator policy filter mode. 00819 00820 @note Currently initiator filtering using the whitelist is not 00821 implemented in this module. 00822 00823 @section EXAMPLE 00824 00825 @code 00826 00827 @endcode 00828 */ 00829 /**************************************************************************/ 00830 Gap::InitiatorPolicyMode_t nRF5xGap::getInitiatorPolicyMode(void) const 00831 { 00832 return Gap::INIT_POLICY_IGNORE_WHITELIST; 00833 } 00834 00835 /**************************************************************************/ 00836 /*! 00837 @brief Helper function used to populate the ble_gap_whitelist_t that 00838 will be used by the SoftDevice for filtering requests. 00839 00840 @returns \ref ble_error_t 00841 00842 @retval BLE_ERROR_NONE 00843 Everything executed properly 00844 00845 @retval BLE_ERROR_INVALID_STATE 00846 The internal stack was not initialized correctly. 00847 00848 @note Both the SecurityManager and Gap must initialize correctly for 00849 this function to succeed. 00850 00851 @note This function is needed because for the BLE API the whitelist 00852 is just a collection of keys, but for the stack it also includes 00853 the IRK table. 00854 00855 @section EXAMPLE 00856 00857 @code 00858 00859 @endcode 00860 */ 00861 /**************************************************************************/ 00862 ble_error_t nRF5xGap::generateStackWhitelist(ble_gap_whitelist_t &whitelist) 00863 { 00864 ble_gap_whitelist_t whitelistFromBondTable; 00865 ble_gap_addr_t *addressPtr[1]; 00866 ble_gap_irk_t *irkPtr[YOTTA_CFG_IRK_TABLE_MAX_SIZE]; 00867 00868 nRF5xSecurityManager& securityManager = (nRF5xSecurityManager&) nRF5xn::Instance(0).getSecurityManager(); 00869 00870 if (securityManager.hasInitialized()) { 00871 /* We do not care about the addresses, set the count to 0 */ 00872 whitelistFromBondTable.addr_count = 0; 00873 /* The Nordic SDK will return a failure if we set pp_addr to NULL */ 00874 whitelistFromBondTable.pp_addrs = addressPtr; 00875 /* We want all the IRKs we can get because we do not know which ones match the addresses */ 00876 whitelistFromBondTable.irk_count = YOTTA_CFG_IRK_TABLE_MAX_SIZE; 00877 whitelistFromBondTable.pp_irks = irkPtr; 00878 00879 /* Use the security manager to get the IRKs from the bond table */ 00880 ble_error_t error = securityManager.createWhitelistFromBondTable(whitelistFromBondTable); 00881 if (error != BLE_ERROR_NONE) { 00882 return error; 00883 } 00884 } else { 00885 /** 00886 * If there is no security manager then we cannot access the bond table, 00887 * so disable IRK matching 00888 */ 00889 whitelistFromBondTable.addr_count = 0; 00890 whitelistFromBondTable.irk_count = 0; 00891 } 00892 00893 /** 00894 * For every private resolvable address in the local whitelist check if 00895 * there is an IRK for said address in the bond table and add it to the 00896 * local IRK list. 00897 */ 00898 whitelist.irk_count = 0; 00899 whitelist.addr_count = 0; 00900 for (uint8_t i = 0; i < whitelistAddressesSize; ++i) { 00901 if (whitelistAddresses[i].addr_type == BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE) { 00902 /* Test if there is a matching IRK for this private resolvable address */ 00903 for (uint8_t j = 0; j < whitelistFromBondTable.irk_count; ++j) { 00904 if (securityManager.matchAddressAndIrk(&whitelistAddresses[i], whitelistFromBondTable.pp_irks[j])) { 00905 /* Found the corresponding IRK, add it to our local whitelist */ 00906 whitelist.pp_irks[whitelist.irk_count] = whitelistFromBondTable.pp_irks[j]; 00907 whitelist.irk_count++; 00908 /* Make sure we do not look at this IRK again */ 00909 if (j != whitelistFromBondTable.irk_count - 1) { 00910 /** 00911 * This is not the last IRK, so replace the pointer 00912 * with the last pointer in the array 00913 */ 00914 whitelistFromBondTable.pp_irks[j] = 00915 whitelistFromBondTable.pp_irks[whitelistFromBondTable.irk_count - 1]; 00916 } 00917 /** 00918 * If the IRK is the last pointer in the array simply 00919 * decrement the total IRK count 00920 */ 00921 whitelistFromBondTable.irk_count--; 00922 break; 00923 } 00924 } 00925 } else { 00926 /* Include the address into the whitelist */ 00927 whitelist.pp_addrs[whitelist.addr_count] = &whitelistAddresses[i]; 00928 whitelist.addr_count++; 00929 } 00930 } 00931 00932 return BLE_ERROR_NONE; 00933 }
Generated on Wed Jul 13 2022 11:18:00 by 1.7.2