Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of nRF51822 by
nRF51Gap.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 "nRF51Gap.h" 00018 #include "mbed.h" 00019 00020 #include "common/common.h" 00021 #include "ble_advdata.h " 00022 #include "ble_hci.h" 00023 00024 nRF51Gap &nRF51Gap::getInstance() { 00025 static nRF51Gap m_instance; 00026 return m_instance; 00027 } 00028 00029 /**************************************************************************/ 00030 /*! 00031 @brief Sets the advertising parameters and payload for the device 00032 00033 @param[in] params 00034 Basic advertising details, including the advertising 00035 delay, timeout and how the device should be advertised 00036 @params[in] advData 00037 The primary advertising data payload 00038 @params[in] scanResponse 00039 The optional Scan Response payload if the advertising 00040 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED 00041 in \ref GapAdveritinngParams 00042 00043 @returns \ref ble_error_t 00044 00045 @retval BLE_ERROR_NONE 00046 Everything executed properly 00047 00048 @retval BLE_ERROR_BUFFER_OVERFLOW 00049 The proposed action would cause a buffer overflow. All 00050 advertising payloads must be <= 31 bytes, for example. 00051 00052 @retval BLE_ERROR_NOT_IMPLEMENTED 00053 A feature was requested that is not yet supported in the 00054 nRF51 firmware or hardware. 00055 00056 @retval BLE_ERROR_PARAM_OUT_OF_RANGE 00057 One of the proposed values is outside the valid range. 00058 00059 @section EXAMPLE 00060 00061 @code 00062 00063 @endcode 00064 */ 00065 /**************************************************************************/ 00066 ble_error_t nRF51Gap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) 00067 { 00068 /* Make sure we don't exceed the advertising payload length */ 00069 if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { 00070 return BLE_ERROR_BUFFER_OVERFLOW; 00071 } 00072 00073 /* Make sure we have a payload! */ 00074 if (advData.getPayloadLen() == 0) { 00075 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00076 } 00077 00078 /* Check the scan response payload limits */ 00079 //if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED)) 00080 //{ 00081 // /* Check if we're within the upper limit */ 00082 // if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) 00083 // { 00084 // return BLE_ERROR_BUFFER_OVERFLOW; 00085 // } 00086 // /* Make sure we have a payload! */ 00087 // if (advData.getPayloadLen() == 0) 00088 // { 00089 // return BLE_ERROR_PARAM_OUT_OF_RANGE; 00090 // } 00091 //} 00092 00093 /* Send advertising data! */ 00094 ASSERT(ERROR_NONE == 00095 sd_ble_gap_adv_data_set(advData.getPayload(), 00096 advData.getPayloadLen(), 00097 scanResponse.getPayload(), 00098 scanResponse.getPayloadLen()), 00099 BLE_ERROR_PARAM_OUT_OF_RANGE); 00100 00101 /* Make sure the GAP Service appearance value is aligned with the 00102 *appearance from GapAdvertisingData */ 00103 ASSERT(ERROR_NONE == sd_ble_gap_appearance_set(advData.getAppearance()), 00104 BLE_ERROR_PARAM_OUT_OF_RANGE); 00105 00106 /* ToDo: Perform some checks on the payload, for example the Scan Response can't */ 00107 /* contains a flags AD type, etc. */ 00108 00109 return BLE_ERROR_NONE; 00110 } 00111 00112 /**************************************************************************/ 00113 /*! 00114 @brief Starts the BLE HW, initialising any services that were 00115 added before this function was called. 00116 00117 @note All services must be added before calling this function! 00118 00119 @returns ble_error_t 00120 00121 @retval BLE_ERROR_NONE 00122 Everything executed properly 00123 00124 @section EXAMPLE 00125 00126 @code 00127 00128 @endcode 00129 */ 00130 /**************************************************************************/ 00131 ble_error_t nRF51Gap::startAdvertising(const GapAdvertisingParams ¶ms) 00132 { 00133 /* Make sure we support the advertising type */ 00134 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { 00135 /* ToDo: This requires a propery security implementation, etc. */ 00136 return BLE_ERROR_NOT_IMPLEMENTED; 00137 } 00138 00139 /* Check interval range */ 00140 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { 00141 /* Min delay is slightly longer for unconnectable devices */ 00142 if ((params.getInterval() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || 00143 (params.getInterval() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { 00144 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00145 } 00146 } else { 00147 if ((params.getInterval() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) || 00148 (params.getInterval() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) { 00149 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00150 } 00151 } 00152 00153 /* Check timeout is zero for Connectable Directed */ 00154 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { 00155 /* Timeout must be 0 with this type, although we'll never get here */ 00156 /* since this isn't implemented yet anyway */ 00157 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00158 } 00159 00160 /* Check timeout for other advertising types */ 00161 if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && 00162 (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) { 00163 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00164 } 00165 00166 /* Start Advertising */ 00167 ble_gap_adv_params_t adv_para = {0}; 00168 00169 adv_para.type = params.getAdvertisingType(); 00170 adv_para.p_peer_addr = NULL; // Undirected advertisement 00171 adv_para.fp = BLE_GAP_ADV_FP_ANY; 00172 adv_para.p_whitelist = NULL; 00173 adv_para.interval = params.getInterval(); // advertising interval (in units of 0.625 ms) 00174 adv_para.timeout = params.getTimeout(); 00175 00176 ASSERT(ERROR_NONE == sd_ble_gap_adv_start(&adv_para), BLE_ERROR_PARAM_OUT_OF_RANGE); 00177 00178 state.advertising = 1; 00179 00180 return BLE_ERROR_NONE; 00181 } 00182 00183 /**************************************************************************/ 00184 /*! 00185 @brief Stops the BLE HW and disconnects from any devices 00186 00187 @returns ble_error_t 00188 00189 @retval BLE_ERROR_NONE 00190 Everything executed properly 00191 00192 @section EXAMPLE 00193 00194 @code 00195 00196 @endcode 00197 */ 00198 /**************************************************************************/ 00199 ble_error_t nRF51Gap::stopAdvertising(void) 00200 { 00201 /* Stop Advertising */ 00202 ASSERT(ERROR_NONE == sd_ble_gap_adv_stop(), BLE_ERROR_PARAM_OUT_OF_RANGE); 00203 00204 state.advertising = 0; 00205 00206 return BLE_ERROR_NONE; 00207 } 00208 00209 ble_error_t nRF51Gap::connect(const Address_t peerAddr, 00210 Gap::AddressType_t peerAddrType, 00211 const ConnectionParams_t *connectionParams, 00212 const GapScanningParams *scanParamsIn) 00213 { 00214 ble_gap_addr_t addr; 00215 addr.addr_type = peerAddrType; 00216 memcpy(addr.addr, peerAddr, Gap::ADDR_LEN); 00217 00218 ble_gap_conn_params_t connParams; 00219 if (connectionParams != NULL) { 00220 connParams.min_conn_interval = connectionParams->minConnectionInterval; 00221 connParams.max_conn_interval = connectionParams->maxConnectionInterval; 00222 connParams.slave_latency = connectionParams->slaveLatency; 00223 connParams.conn_sup_timeout = connectionParams->connectionSupervisionTimeout; 00224 } else { 00225 connParams.min_conn_interval = 50; 00226 connParams.max_conn_interval = 100; 00227 connParams.slave_latency = 0; 00228 connParams.conn_sup_timeout = 600; 00229 } 00230 00231 ble_gap_scan_params_t scanParams; 00232 scanParams.active = 0; /**< If 1, perform active scanning (scan requests). */ 00233 scanParams.selective = 0; /**< If 1, ignore unknown devices (non whitelisted). */ 00234 scanParams.p_whitelist = NULL; /**< Pointer to whitelist, NULL if none is given. */ 00235 if (scanParamsIn != NULL) { 00236 scanParams.interval = scanParamsIn->getInterval(); /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ 00237 scanParams.window = scanParamsIn->getWindow(); /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ 00238 scanParams.timeout = scanParamsIn->getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ 00239 } else { 00240 scanParams.interval = 500; /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ 00241 scanParams.window = 200; /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ 00242 scanParams.timeout = 0; /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ 00243 } 00244 00245 uint32_t rc = sd_ble_gap_connect(&addr, &scanParams, &connParams); 00246 if (rc == NRF_SUCCESS) { 00247 return BLE_ERROR_NONE; 00248 } 00249 switch (rc) { 00250 case NRF_ERROR_INVALID_ADDR: 00251 return BLE_ERROR_INVALID_PARAM; 00252 case NRF_ERROR_INVALID_PARAM: 00253 return BLE_ERROR_INVALID_PARAM; 00254 case NRF_ERROR_INVALID_STATE: 00255 return BLE_ERROR_INVALID_STATE; 00256 case BLE_ERROR_GAP_INVALID_BLE_ADDR: 00257 return BLE_ERROR_INVALID_PARAM; 00258 case NRF_ERROR_NO_MEM: 00259 return BLE_ERROR_NO_MEM; 00260 case NRF_ERROR_BUSY: 00261 return BLE_STACK_BUSY; 00262 default: 00263 case BLE_ERROR_GAP_WHITELIST_IN_USE: 00264 return BLE_ERROR_UNSPECIFIED; 00265 } 00266 } 00267 00268 ble_error_t nRF51Gap::disconnect(Handle_t connectionHandle, DisconnectionReason_t reason) 00269 { 00270 state.advertising = 0; 00271 state.connected = 0; 00272 00273 uint8_t code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION; 00274 switch (reason) { 00275 case REMOTE_USER_TERMINATED_CONNECTION: 00276 code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION; 00277 break; 00278 case CONN_INTERVAL_UNACCEPTABLE: 00279 code = BLE_HCI_CONN_INTERVAL_UNACCEPTABLE; 00280 break; 00281 default: 00282 break; 00283 } 00284 00285 /* Disconnect if we are connected to a central device */ 00286 ASSERT_INT(ERROR_NONE, sd_ble_gap_disconnect(connectionHandle, code), BLE_ERROR_PARAM_OUT_OF_RANGE); 00287 00288 return BLE_ERROR_NONE; 00289 } 00290 00291 /*! 00292 @brief Disconnects if we are connected to a central device 00293 00294 @returns ble_error_t 00295 00296 @retval BLE_ERROR_NONE 00297 Everything executed properly 00298 */ 00299 ble_error_t nRF51Gap::disconnect(DisconnectionReason_t reason) 00300 { 00301 return disconnect(m_connectionHandle, reason); 00302 } 00303 00304 ble_error_t nRF51Gap::getPreferredConnectionParams(ConnectionParams_t *params) 00305 { 00306 ASSERT_INT(NRF_SUCCESS, 00307 sd_ble_gap_ppcp_get(reinterpret_cast<ble_gap_conn_params_t *>(params)), 00308 BLE_ERROR_PARAM_OUT_OF_RANGE); 00309 00310 return BLE_ERROR_NONE; 00311 } 00312 00313 ble_error_t nRF51Gap::setPreferredConnectionParams(const ConnectionParams_t *params) 00314 { 00315 ASSERT_INT(NRF_SUCCESS, 00316 sd_ble_gap_ppcp_set(reinterpret_cast<const ble_gap_conn_params_t *>(params)), 00317 BLE_ERROR_PARAM_OUT_OF_RANGE); 00318 00319 return BLE_ERROR_NONE; 00320 } 00321 00322 ble_error_t nRF51Gap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *newParams) 00323 { 00324 uint32_t rc; 00325 00326 rc = sd_ble_gap_conn_param_update(handle, reinterpret_cast<ble_gap_conn_params_t *>(const_cast<ConnectionParams_t*>(newParams))); 00327 if (rc == NRF_SUCCESS) { 00328 return BLE_ERROR_NONE; 00329 } else { 00330 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00331 } 00332 } 00333 00334 /**************************************************************************/ 00335 /*! 00336 @brief Sets the 16-bit connection handle 00337 */ 00338 /**************************************************************************/ 00339 void nRF51Gap::setConnectionHandle(uint16_t con_handle) 00340 { 00341 m_connectionHandle = con_handle; 00342 } 00343 00344 /**************************************************************************/ 00345 /*! 00346 @brief Gets the 16-bit connection handle 00347 */ 00348 /**************************************************************************/ 00349 uint16_t nRF51Gap::getConnectionHandle(void) 00350 { 00351 return m_connectionHandle; 00352 } 00353 00354 /**************************************************************************/ 00355 /*! 00356 @brief Sets the BLE device address 00357 00358 @returns ble_error_t 00359 00360 @section EXAMPLE 00361 00362 @code 00363 00364 uint8_t device_address[6] = { 0xca, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0 }; 00365 nrf.getGap().setAddress(Gap::ADDR_TYPE_RANDOM_STATIC, device_address); 00366 00367 @endcode 00368 */ 00369 /**************************************************************************/ 00370 ble_error_t nRF51Gap::setAddress(AddressType_t type, const Address_t address) 00371 { 00372 if (type > ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) { 00373 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00374 } 00375 00376 ble_gap_addr_t dev_addr; 00377 dev_addr.addr_type = type; 00378 memcpy(dev_addr.addr, address, ADDR_LEN); 00379 00380 ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE); 00381 00382 return BLE_ERROR_NONE; 00383 } 00384 00385 ble_error_t nRF51Gap::getAddress(AddressType_t *typeP, Address_t address) 00386 { 00387 ble_gap_addr_t dev_addr; 00388 if (sd_ble_gap_address_get(&dev_addr) != NRF_SUCCESS) { 00389 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00390 } 00391 00392 if (typeP != NULL) { 00393 *typeP = static_cast<AddressType_t>(dev_addr.addr_type); 00394 } 00395 if (address != NULL) { 00396 memcpy(address, dev_addr.addr, ADDR_LEN); 00397 } 00398 return BLE_ERROR_NONE; 00399 } 00400 00401 ble_error_t nRF51Gap::setDeviceName(const uint8_t *deviceName) 00402 { 00403 ble_gap_conn_sec_mode_t sec_mode; 00404 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); // no security is needed 00405 00406 if (sd_ble_gap_device_name_set(&sec_mode, deviceName, strlen((const char *)deviceName)) == NRF_SUCCESS) { 00407 return BLE_ERROR_NONE; 00408 } else { 00409 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00410 } 00411 } 00412 00413 ble_error_t nRF51Gap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) 00414 { 00415 if (sd_ble_gap_device_name_get(deviceName, (uint16_t *)lengthP) == NRF_SUCCESS) { 00416 return BLE_ERROR_NONE; 00417 } else { 00418 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00419 } 00420 } 00421 00422 ble_error_t nRF51Gap::setAppearance(GapAdvertisingData::Appearance appearance) 00423 { 00424 if (sd_ble_gap_appearance_set(appearance) == NRF_SUCCESS) { 00425 return BLE_ERROR_NONE; 00426 } else { 00427 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00428 } 00429 } 00430 00431 ble_error_t nRF51Gap::getAppearance(GapAdvertisingData::Appearance *appearanceP) 00432 { 00433 if (sd_ble_gap_appearance_get(reinterpret_cast<uint16_t *>(appearanceP))) { 00434 return BLE_ERROR_NONE; 00435 } else { 00436 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00437 } 00438 } 00439 00440 /* (Valid values are -40, -20, -16, -12, -8, -4, 0, 4) */ 00441 ble_error_t nRF51Gap::setTxPower(int8_t txPower) 00442 { 00443 unsigned rc; 00444 if ((rc = sd_ble_gap_tx_power_set(txPower)) != NRF_SUCCESS) { 00445 switch (rc) { 00446 case NRF_ERROR_BUSY: 00447 return BLE_STACK_BUSY; 00448 case NRF_ERROR_INVALID_PARAM: 00449 default: 00450 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00451 } 00452 } 00453 00454 return BLE_ERROR_NONE; 00455 } 00456 00457 void nRF51Gap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) 00458 { 00459 static const int8_t permittedTxValues[] = { 00460 -40, -30, -20, -16, -12, -8, -4, 0, 4 00461 }; 00462 00463 *valueArrayPP = permittedTxValues; 00464 *countP = sizeof(permittedTxValues) / sizeof(int8_t); 00465 }
Generated on Tue Jul 12 2022 15:45:40 by
