Nordic stack and drivers for the mbed BLE API. Version to work around build bug.

Dependents:   microbit_rubber_ducky microbit_mouse_BLE microbit_mouse_BLE_daybreak_version microbit_presenter

Fork of nRF51822 by Nordic Semiconductor

Committer:
vcoubard
Date:
Mon Jan 11 10:19:15 2016 +0000
Revision:
561:613dbbdeed27
Parent:
552:20b282c26f96
Child:
562:0d32ae12429e
Synchronized with git rev 7bf81e7e
Author: Andres Amaya Garcia
Improve shutdown to clear BLE API and not just SD

Improve the shutdown functionality, such that a call to ble.shutdown() from
the user application clears the API and nRF5x state and NOT only the
SoftDevice. To achieve this the following changes are introduced:

* Add a protected member cleanup() to nRF5xGap, nRF5xGattClient,
nRF5xGattServer, nRF5xSecurityManager and nRF5xServiceDiscovery.
* Modify the shutdown() implementation in nRF5xn such that it also calls the
static member shutdown() exposed by the BLE API in Gap.h, SecurityManager.h,
GattClient.h and GattServer.h.
* Modify nRF5xGattClient, nRF5xGattServer and nRF5xSecurityManager
classes so that they dynamically create their respective objects only if
needed. Previously the GattClient, GattServer and SecurityManager objects were
declared as static, which means that they were always present even though they
were not always needed. This increases memory consumption unnecessarily.
Furthermore, pointers to the object instances are stored in static members of
the classes as specified by the BLE API base classes. This ensures that
calls to shutdown do not require calls to getInstance() functions that would
otherwise result in undesired memory allocations.
* nRF5xGap object is always needed, so this remains allocated statically. But
the reference in Gap is pointed to this object.

The shutdown procedure is as follows:

1. The user calls ble.shutdown() which executes the code in nRF5xn::shutdown()
1. The SoftDevice is shutdown
1. The static members of Gap.h, SecurityManager.h, GattClient.h and
GattServer.h are called to clean up their own state.

If at any point an error occur during the last step, BLE_ERROR_INVALID_STATE is
returned.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vcoubard 541:884f95bf5351 1 /* mbed Microcontroller Library
vcoubard 541:884f95bf5351 2 * Copyright (c) 2006-2013 ARM Limited
vcoubard 541:884f95bf5351 3 *
vcoubard 541:884f95bf5351 4 * Licensed under the Apache License, Version 2.0 (the "License");
vcoubard 541:884f95bf5351 5 * you may not use this file except in compliance with the License.
vcoubard 541:884f95bf5351 6 * You may obtain a copy of the License at
vcoubard 541:884f95bf5351 7 *
vcoubard 541:884f95bf5351 8 * http://www.apache.org/licenses/LICENSE-2.0
vcoubard 541:884f95bf5351 9 *
vcoubard 541:884f95bf5351 10 * Unless required by applicable law or agreed to in writing, software
vcoubard 541:884f95bf5351 11 * distributed under the License is distributed on an "AS IS" BASIS,
vcoubard 541:884f95bf5351 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
vcoubard 541:884f95bf5351 13 * See the License for the specific language governing permissions and
vcoubard 541:884f95bf5351 14 * limitations under the License.
vcoubard 541:884f95bf5351 15 */
vcoubard 541:884f95bf5351 16
vcoubard 541:884f95bf5351 17 #include "nRF5xGap.h"
vcoubard 541:884f95bf5351 18 #include "mbed.h"
vcoubard 541:884f95bf5351 19
vcoubard 541:884f95bf5351 20 #include "common/common.h"
vcoubard 541:884f95bf5351 21 #include "ble_advdata.h"
vcoubard 541:884f95bf5351 22 #include "ble_hci.h"
vcoubard 541:884f95bf5351 23
vcoubard 541:884f95bf5351 24 nRF5xGap &nRF5xGap::getInstance() {
vcoubard 541:884f95bf5351 25 static nRF5xGap m_instance;
vcoubard 561:613dbbdeed27 26 if (gapInstance == NULL) {
vcoubard 561:613dbbdeed27 27 gapInstance = &m_instance;
vcoubard 561:613dbbdeed27 28 }
vcoubard 541:884f95bf5351 29 return m_instance;
vcoubard 541:884f95bf5351 30 }
vcoubard 541:884f95bf5351 31
vcoubard 541:884f95bf5351 32 void radioNotificationStaticCallback(bool param) {
vcoubard 541:884f95bf5351 33 nRF5xGap::getInstance().processRadioNotificationEvent(param);
vcoubard 541:884f95bf5351 34 }
vcoubard 541:884f95bf5351 35
vcoubard 541:884f95bf5351 36 /**************************************************************************/
vcoubard 541:884f95bf5351 37 /*!
vcoubard 541:884f95bf5351 38 @brief Sets the advertising parameters and payload for the device
vcoubard 541:884f95bf5351 39
vcoubard 541:884f95bf5351 40 @param[in] params
vcoubard 541:884f95bf5351 41 Basic advertising details, including the advertising
vcoubard 541:884f95bf5351 42 delay, timeout and how the device should be advertised
vcoubard 541:884f95bf5351 43 @params[in] advData
vcoubard 541:884f95bf5351 44 The primary advertising data payload
vcoubard 541:884f95bf5351 45 @params[in] scanResponse
vcoubard 541:884f95bf5351 46 The optional Scan Response payload if the advertising
vcoubard 541:884f95bf5351 47 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
vcoubard 541:884f95bf5351 48 in \ref GapAdveritinngParams
vcoubard 541:884f95bf5351 49
vcoubard 541:884f95bf5351 50 @returns \ref ble_error_t
vcoubard 541:884f95bf5351 51
vcoubard 541:884f95bf5351 52 @retval BLE_ERROR_NONE
vcoubard 541:884f95bf5351 53 Everything executed properly
vcoubard 541:884f95bf5351 54
vcoubard 541:884f95bf5351 55 @retval BLE_ERROR_BUFFER_OVERFLOW
vcoubard 541:884f95bf5351 56 The proposed action would cause a buffer overflow. All
vcoubard 541:884f95bf5351 57 advertising payloads must be <= 31 bytes, for example.
vcoubard 541:884f95bf5351 58
vcoubard 541:884f95bf5351 59 @retval BLE_ERROR_NOT_IMPLEMENTED
vcoubard 541:884f95bf5351 60 A feature was requested that is not yet supported in the
vcoubard 541:884f95bf5351 61 nRF51 firmware or hardware.
vcoubard 541:884f95bf5351 62
vcoubard 541:884f95bf5351 63 @retval BLE_ERROR_PARAM_OUT_OF_RANGE
vcoubard 541:884f95bf5351 64 One of the proposed values is outside the valid range.
vcoubard 541:884f95bf5351 65
vcoubard 541:884f95bf5351 66 @section EXAMPLE
vcoubard 541:884f95bf5351 67
vcoubard 541:884f95bf5351 68 @code
vcoubard 541:884f95bf5351 69
vcoubard 541:884f95bf5351 70 @endcode
vcoubard 541:884f95bf5351 71 */
vcoubard 541:884f95bf5351 72 /**************************************************************************/
vcoubard 541:884f95bf5351 73 ble_error_t nRF5xGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
vcoubard 541:884f95bf5351 74 {
vcoubard 541:884f95bf5351 75 /* Make sure we don't exceed the advertising payload length */
vcoubard 541:884f95bf5351 76 if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
vcoubard 541:884f95bf5351 77 return BLE_ERROR_BUFFER_OVERFLOW;
vcoubard 541:884f95bf5351 78 }
vcoubard 541:884f95bf5351 79
vcoubard 541:884f95bf5351 80 /* Make sure we have a payload! */
vcoubard 541:884f95bf5351 81 if (advData.getPayloadLen() == 0) {
vcoubard 541:884f95bf5351 82 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 83 }
vcoubard 541:884f95bf5351 84
vcoubard 541:884f95bf5351 85 /* Check the scan response payload limits */
vcoubard 541:884f95bf5351 86 //if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED))
vcoubard 541:884f95bf5351 87 //{
vcoubard 541:884f95bf5351 88 // /* Check if we're within the upper limit */
vcoubard 541:884f95bf5351 89 // if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD)
vcoubard 541:884f95bf5351 90 // {
vcoubard 541:884f95bf5351 91 // return BLE_ERROR_BUFFER_OVERFLOW;
vcoubard 541:884f95bf5351 92 // }
vcoubard 541:884f95bf5351 93 // /* Make sure we have a payload! */
vcoubard 541:884f95bf5351 94 // if (advData.getPayloadLen() == 0)
vcoubard 541:884f95bf5351 95 // {
vcoubard 541:884f95bf5351 96 // return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 97 // }
vcoubard 541:884f95bf5351 98 //}
vcoubard 541:884f95bf5351 99
vcoubard 541:884f95bf5351 100 /* Send advertising data! */
vcoubard 541:884f95bf5351 101 ASSERT(ERROR_NONE ==
vcoubard 541:884f95bf5351 102 sd_ble_gap_adv_data_set(advData.getPayload(),
vcoubard 541:884f95bf5351 103 advData.getPayloadLen(),
vcoubard 541:884f95bf5351 104 scanResponse.getPayload(),
vcoubard 541:884f95bf5351 105 scanResponse.getPayloadLen()),
vcoubard 541:884f95bf5351 106 BLE_ERROR_PARAM_OUT_OF_RANGE);
vcoubard 541:884f95bf5351 107
vcoubard 541:884f95bf5351 108 /* Make sure the GAP Service appearance value is aligned with the
vcoubard 541:884f95bf5351 109 *appearance from GapAdvertisingData */
vcoubard 541:884f95bf5351 110 ASSERT(ERROR_NONE == sd_ble_gap_appearance_set(advData.getAppearance()),
vcoubard 541:884f95bf5351 111 BLE_ERROR_PARAM_OUT_OF_RANGE);
vcoubard 541:884f95bf5351 112
vcoubard 541:884f95bf5351 113 /* ToDo: Perform some checks on the payload, for example the Scan Response can't */
vcoubard 541:884f95bf5351 114 /* contains a flags AD type, etc. */
vcoubard 541:884f95bf5351 115
vcoubard 541:884f95bf5351 116 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 117 }
vcoubard 541:884f95bf5351 118
vcoubard 541:884f95bf5351 119 /**************************************************************************/
vcoubard 541:884f95bf5351 120 /*!
vcoubard 541:884f95bf5351 121 @brief Starts the BLE HW, initialising any services that were
vcoubard 541:884f95bf5351 122 added before this function was called.
vcoubard 541:884f95bf5351 123
vcoubard 541:884f95bf5351 124 @note All services must be added before calling this function!
vcoubard 541:884f95bf5351 125
vcoubard 541:884f95bf5351 126 @returns ble_error_t
vcoubard 541:884f95bf5351 127
vcoubard 541:884f95bf5351 128 @retval BLE_ERROR_NONE
vcoubard 541:884f95bf5351 129 Everything executed properly
vcoubard 541:884f95bf5351 130
vcoubard 541:884f95bf5351 131 @section EXAMPLE
vcoubard 541:884f95bf5351 132
vcoubard 541:884f95bf5351 133 @code
vcoubard 541:884f95bf5351 134
vcoubard 541:884f95bf5351 135 @endcode
vcoubard 541:884f95bf5351 136 */
vcoubard 541:884f95bf5351 137 /**************************************************************************/
vcoubard 541:884f95bf5351 138 ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams &params)
vcoubard 541:884f95bf5351 139 {
vcoubard 541:884f95bf5351 140 /* Make sure we support the advertising type */
vcoubard 541:884f95bf5351 141 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
vcoubard 541:884f95bf5351 142 /* ToDo: This requires a propery security implementation, etc. */
vcoubard 541:884f95bf5351 143 return BLE_ERROR_NOT_IMPLEMENTED;
vcoubard 541:884f95bf5351 144 }
vcoubard 541:884f95bf5351 145
vcoubard 541:884f95bf5351 146 /* Check interval range */
vcoubard 541:884f95bf5351 147 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
vcoubard 541:884f95bf5351 148 /* Min delay is slightly longer for unconnectable devices */
vcoubard 541:884f95bf5351 149 if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
vcoubard 541:884f95bf5351 150 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
vcoubard 541:884f95bf5351 151 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 152 }
vcoubard 541:884f95bf5351 153 } else {
vcoubard 541:884f95bf5351 154 if ((params.getIntervalInADVUnits() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) ||
vcoubard 541:884f95bf5351 155 (params.getIntervalInADVUnits() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
vcoubard 541:884f95bf5351 156 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 157 }
vcoubard 541:884f95bf5351 158 }
vcoubard 541:884f95bf5351 159
vcoubard 541:884f95bf5351 160 /* Check timeout is zero for Connectable Directed */
vcoubard 541:884f95bf5351 161 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
vcoubard 541:884f95bf5351 162 /* Timeout must be 0 with this type, although we'll never get here */
vcoubard 541:884f95bf5351 163 /* since this isn't implemented yet anyway */
vcoubard 541:884f95bf5351 164 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 165 }
vcoubard 541:884f95bf5351 166
vcoubard 541:884f95bf5351 167 /* Check timeout for other advertising types */
vcoubard 541:884f95bf5351 168 if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
vcoubard 541:884f95bf5351 169 (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
vcoubard 541:884f95bf5351 170 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 171 }
vcoubard 541:884f95bf5351 172
vcoubard 541:884f95bf5351 173 /* Start Advertising */
vcoubard 541:884f95bf5351 174 ble_gap_adv_params_t adv_para = {0};
vcoubard 541:884f95bf5351 175
vcoubard 541:884f95bf5351 176 adv_para.type = params.getAdvertisingType();
vcoubard 541:884f95bf5351 177 adv_para.p_peer_addr = NULL; // Undirected advertisement
vcoubard 541:884f95bf5351 178 adv_para.fp = BLE_GAP_ADV_FP_ANY;
vcoubard 541:884f95bf5351 179 adv_para.p_whitelist = NULL;
vcoubard 541:884f95bf5351 180 adv_para.interval = params.getIntervalInADVUnits(); // advertising interval (in units of 0.625 ms)
vcoubard 541:884f95bf5351 181 adv_para.timeout = params.getTimeout();
vcoubard 541:884f95bf5351 182
vcoubard 541:884f95bf5351 183 ASSERT(ERROR_NONE == sd_ble_gap_adv_start(&adv_para), BLE_ERROR_PARAM_OUT_OF_RANGE);
vcoubard 541:884f95bf5351 184
vcoubard 541:884f95bf5351 185 state.advertising = 1;
vcoubard 541:884f95bf5351 186
vcoubard 541:884f95bf5351 187 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 188 }
vcoubard 541:884f95bf5351 189
vcoubard 541:884f95bf5351 190 /**************************************************************************/
vcoubard 541:884f95bf5351 191 /*!
vcoubard 541:884f95bf5351 192 @brief Stops the BLE HW and disconnects from any devices
vcoubard 541:884f95bf5351 193
vcoubard 541:884f95bf5351 194 @returns ble_error_t
vcoubard 541:884f95bf5351 195
vcoubard 541:884f95bf5351 196 @retval BLE_ERROR_NONE
vcoubard 541:884f95bf5351 197 Everything executed properly
vcoubard 541:884f95bf5351 198
vcoubard 541:884f95bf5351 199 @section EXAMPLE
vcoubard 541:884f95bf5351 200
vcoubard 541:884f95bf5351 201 @code
vcoubard 541:884f95bf5351 202
vcoubard 541:884f95bf5351 203 @endcode
vcoubard 541:884f95bf5351 204 */
vcoubard 541:884f95bf5351 205 /**************************************************************************/
vcoubard 541:884f95bf5351 206 ble_error_t nRF5xGap::stopAdvertising(void)
vcoubard 541:884f95bf5351 207 {
vcoubard 541:884f95bf5351 208 /* Stop Advertising */
vcoubard 541:884f95bf5351 209 ASSERT(ERROR_NONE == sd_ble_gap_adv_stop(), BLE_ERROR_PARAM_OUT_OF_RANGE);
vcoubard 541:884f95bf5351 210
vcoubard 541:884f95bf5351 211 state.advertising = 0;
vcoubard 541:884f95bf5351 212
vcoubard 541:884f95bf5351 213 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 214 }
vcoubard 541:884f95bf5351 215
vcoubard 541:884f95bf5351 216 ble_error_t nRF5xGap::connect(const Address_t peerAddr,
vcoubard 541:884f95bf5351 217 Gap::AddressType_t peerAddrType,
vcoubard 541:884f95bf5351 218 const ConnectionParams_t *connectionParams,
vcoubard 541:884f95bf5351 219 const GapScanningParams *scanParamsIn)
vcoubard 541:884f95bf5351 220 {
vcoubard 541:884f95bf5351 221 ble_gap_addr_t addr;
vcoubard 541:884f95bf5351 222 addr.addr_type = peerAddrType;
vcoubard 541:884f95bf5351 223 memcpy(addr.addr, peerAddr, Gap::ADDR_LEN);
vcoubard 541:884f95bf5351 224
vcoubard 541:884f95bf5351 225 ble_gap_conn_params_t connParams;
vcoubard 541:884f95bf5351 226 if (connectionParams != NULL) {
vcoubard 541:884f95bf5351 227 connParams.min_conn_interval = connectionParams->minConnectionInterval;
vcoubard 541:884f95bf5351 228 connParams.max_conn_interval = connectionParams->maxConnectionInterval;
vcoubard 541:884f95bf5351 229 connParams.slave_latency = connectionParams->slaveLatency;
vcoubard 541:884f95bf5351 230 connParams.conn_sup_timeout = connectionParams->connectionSupervisionTimeout;
vcoubard 541:884f95bf5351 231 } else {
vcoubard 541:884f95bf5351 232 connParams.min_conn_interval = 50;
vcoubard 541:884f95bf5351 233 connParams.max_conn_interval = 100;
vcoubard 541:884f95bf5351 234 connParams.slave_latency = 0;
vcoubard 541:884f95bf5351 235 connParams.conn_sup_timeout = 600;
vcoubard 541:884f95bf5351 236 }
vcoubard 541:884f95bf5351 237
vcoubard 541:884f95bf5351 238 ble_gap_scan_params_t scanParams;
vcoubard 541:884f95bf5351 239 scanParams.selective = 0; /**< If 1, ignore unknown devices (non whitelisted). */
vcoubard 541:884f95bf5351 240 scanParams.p_whitelist = NULL; /**< Pointer to whitelist, NULL if none is given. */
vcoubard 541:884f95bf5351 241 if (scanParamsIn != NULL) {
vcoubard 541:884f95bf5351 242 scanParams.active = scanParamsIn->getActiveScanning(); /**< If 1, perform active scanning (scan requests). */
vcoubard 541:884f95bf5351 243 scanParams.interval = scanParamsIn->getInterval(); /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
vcoubard 541:884f95bf5351 244 scanParams.window = scanParamsIn->getWindow(); /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
vcoubard 541:884f95bf5351 245 scanParams.timeout = scanParamsIn->getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
vcoubard 541:884f95bf5351 246 } else {
vcoubard 541:884f95bf5351 247 scanParams.active = _scanningParams.getActiveScanning(); /**< If 1, perform active scanning (scan requests). */
vcoubard 541:884f95bf5351 248 scanParams.interval = _scanningParams.getInterval(); /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
vcoubard 541:884f95bf5351 249 scanParams.window = _scanningParams.getWindow(); /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
vcoubard 541:884f95bf5351 250 scanParams.timeout = _scanningParams.getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
vcoubard 541:884f95bf5351 251 }
vcoubard 541:884f95bf5351 252
vcoubard 541:884f95bf5351 253 uint32_t rc = sd_ble_gap_connect(&addr, &scanParams, &connParams);
vcoubard 541:884f95bf5351 254 if (rc == NRF_SUCCESS) {
vcoubard 541:884f95bf5351 255 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 256 }
vcoubard 541:884f95bf5351 257 switch (rc) {
vcoubard 541:884f95bf5351 258 case NRF_ERROR_INVALID_ADDR:
vcoubard 541:884f95bf5351 259 return BLE_ERROR_INVALID_PARAM;
vcoubard 541:884f95bf5351 260 case NRF_ERROR_INVALID_PARAM:
vcoubard 541:884f95bf5351 261 return BLE_ERROR_INVALID_PARAM;
vcoubard 541:884f95bf5351 262 case NRF_ERROR_INVALID_STATE:
vcoubard 541:884f95bf5351 263 return BLE_ERROR_INVALID_STATE;
vcoubard 541:884f95bf5351 264 case BLE_ERROR_GAP_INVALID_BLE_ADDR:
vcoubard 541:884f95bf5351 265 return BLE_ERROR_INVALID_PARAM;
vcoubard 541:884f95bf5351 266 case NRF_ERROR_NO_MEM:
vcoubard 541:884f95bf5351 267 return BLE_ERROR_NO_MEM;
vcoubard 541:884f95bf5351 268 case NRF_ERROR_BUSY:
vcoubard 541:884f95bf5351 269 return BLE_STACK_BUSY;
vcoubard 541:884f95bf5351 270 default:
vcoubard 541:884f95bf5351 271 case BLE_ERROR_GAP_WHITELIST_IN_USE:
vcoubard 541:884f95bf5351 272 return BLE_ERROR_UNSPECIFIED;
vcoubard 541:884f95bf5351 273 }
vcoubard 541:884f95bf5351 274 }
vcoubard 541:884f95bf5351 275
vcoubard 541:884f95bf5351 276 ble_error_t nRF5xGap::disconnect(Handle_t connectionHandle, DisconnectionReason_t reason)
vcoubard 541:884f95bf5351 277 {
vcoubard 541:884f95bf5351 278 state.advertising = 0;
vcoubard 541:884f95bf5351 279 state.connected = 0;
vcoubard 541:884f95bf5351 280
vcoubard 541:884f95bf5351 281 uint8_t code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION;
vcoubard 541:884f95bf5351 282 switch (reason) {
vcoubard 541:884f95bf5351 283 case REMOTE_USER_TERMINATED_CONNECTION:
vcoubard 541:884f95bf5351 284 code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION;
vcoubard 541:884f95bf5351 285 break;
vcoubard 541:884f95bf5351 286 case CONN_INTERVAL_UNACCEPTABLE:
vcoubard 541:884f95bf5351 287 code = BLE_HCI_CONN_INTERVAL_UNACCEPTABLE;
vcoubard 541:884f95bf5351 288 break;
vcoubard 541:884f95bf5351 289 default:
vcoubard 541:884f95bf5351 290 break;
vcoubard 541:884f95bf5351 291 }
vcoubard 541:884f95bf5351 292
vcoubard 541:884f95bf5351 293 /* Disconnect if we are connected to a central device */
vcoubard 541:884f95bf5351 294 ASSERT_INT(ERROR_NONE, sd_ble_gap_disconnect(connectionHandle, code), BLE_ERROR_PARAM_OUT_OF_RANGE);
vcoubard 541:884f95bf5351 295
vcoubard 541:884f95bf5351 296 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 297 }
vcoubard 541:884f95bf5351 298
vcoubard 541:884f95bf5351 299 /*!
vcoubard 541:884f95bf5351 300 @brief Disconnects if we are connected to a central device
vcoubard 541:884f95bf5351 301
vcoubard 541:884f95bf5351 302 @returns ble_error_t
vcoubard 541:884f95bf5351 303
vcoubard 541:884f95bf5351 304 @retval BLE_ERROR_NONE
vcoubard 541:884f95bf5351 305 Everything executed properly
vcoubard 541:884f95bf5351 306 */
vcoubard 541:884f95bf5351 307 ble_error_t nRF5xGap::disconnect(DisconnectionReason_t reason)
vcoubard 541:884f95bf5351 308 {
vcoubard 541:884f95bf5351 309 return disconnect(m_connectionHandle, reason);
vcoubard 541:884f95bf5351 310 }
vcoubard 541:884f95bf5351 311
vcoubard 541:884f95bf5351 312 ble_error_t nRF5xGap::getPreferredConnectionParams(ConnectionParams_t *params)
vcoubard 541:884f95bf5351 313 {
vcoubard 541:884f95bf5351 314 ASSERT_INT(NRF_SUCCESS,
vcoubard 541:884f95bf5351 315 sd_ble_gap_ppcp_get(reinterpret_cast<ble_gap_conn_params_t *>(params)),
vcoubard 541:884f95bf5351 316 BLE_ERROR_PARAM_OUT_OF_RANGE);
vcoubard 541:884f95bf5351 317
vcoubard 541:884f95bf5351 318 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 319 }
vcoubard 541:884f95bf5351 320
vcoubard 541:884f95bf5351 321 ble_error_t nRF5xGap::setPreferredConnectionParams(const ConnectionParams_t *params)
vcoubard 541:884f95bf5351 322 {
vcoubard 541:884f95bf5351 323 ASSERT_INT(NRF_SUCCESS,
vcoubard 541:884f95bf5351 324 sd_ble_gap_ppcp_set(reinterpret_cast<const ble_gap_conn_params_t *>(params)),
vcoubard 541:884f95bf5351 325 BLE_ERROR_PARAM_OUT_OF_RANGE);
vcoubard 541:884f95bf5351 326
vcoubard 541:884f95bf5351 327 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 328 }
vcoubard 541:884f95bf5351 329
vcoubard 541:884f95bf5351 330 ble_error_t nRF5xGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *newParams)
vcoubard 541:884f95bf5351 331 {
vcoubard 541:884f95bf5351 332 uint32_t rc;
vcoubard 541:884f95bf5351 333
vcoubard 541:884f95bf5351 334 rc = sd_ble_gap_conn_param_update(handle, reinterpret_cast<ble_gap_conn_params_t *>(const_cast<ConnectionParams_t*>(newParams)));
vcoubard 541:884f95bf5351 335 if (rc == NRF_SUCCESS) {
vcoubard 541:884f95bf5351 336 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 337 } else {
vcoubard 541:884f95bf5351 338 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 339 }
vcoubard 541:884f95bf5351 340 }
vcoubard 541:884f95bf5351 341
vcoubard 541:884f95bf5351 342 /**************************************************************************/
vcoubard 541:884f95bf5351 343 /*!
vcoubard 561:613dbbdeed27 344 @brief Clear nRF5xGap's state.
vcoubard 561:613dbbdeed27 345
vcoubard 561:613dbbdeed27 346 @returns ble_error_t
vcoubard 561:613dbbdeed27 347
vcoubard 561:613dbbdeed27 348 @retval BLE_ERROR_NONE
vcoubard 561:613dbbdeed27 349 Everything executed properly
vcoubard 561:613dbbdeed27 350 */
vcoubard 561:613dbbdeed27 351 /**************************************************************************/
vcoubard 561:613dbbdeed27 352 ble_error_t nRF5xGap::cleanup(void)
vcoubard 561:613dbbdeed27 353 {
vcoubard 561:613dbbdeed27 354 /* Clear all state that is from the parent, including private members */
vcoubard 561:613dbbdeed27 355 if (Gap::cleanup() != BLE_ERROR_NONE) {
vcoubard 561:613dbbdeed27 356 return BLE_ERROR_INVALID_STATE;
vcoubard 561:613dbbdeed27 357 }
vcoubard 561:613dbbdeed27 358
vcoubard 561:613dbbdeed27 359 /* Clear derived class members */
vcoubard 561:613dbbdeed27 360 m_connectionHandle = BLE_CONN_HANDLE_INVALID;
vcoubard 561:613dbbdeed27 361
vcoubard 561:613dbbdeed27 362 return BLE_ERROR_NONE;
vcoubard 561:613dbbdeed27 363 }
vcoubard 561:613dbbdeed27 364
vcoubard 561:613dbbdeed27 365 /**************************************************************************/
vcoubard 561:613dbbdeed27 366 /*!
vcoubard 541:884f95bf5351 367 @brief Sets the 16-bit connection handle
vcoubard 541:884f95bf5351 368 */
vcoubard 541:884f95bf5351 369 /**************************************************************************/
vcoubard 541:884f95bf5351 370 void nRF5xGap::setConnectionHandle(uint16_t con_handle)
vcoubard 541:884f95bf5351 371 {
vcoubard 541:884f95bf5351 372 m_connectionHandle = con_handle;
vcoubard 541:884f95bf5351 373 }
vcoubard 541:884f95bf5351 374
vcoubard 541:884f95bf5351 375 /**************************************************************************/
vcoubard 541:884f95bf5351 376 /*!
vcoubard 541:884f95bf5351 377 @brief Gets the 16-bit connection handle
vcoubard 541:884f95bf5351 378 */
vcoubard 541:884f95bf5351 379 /**************************************************************************/
vcoubard 541:884f95bf5351 380 uint16_t nRF5xGap::getConnectionHandle(void)
vcoubard 541:884f95bf5351 381 {
vcoubard 541:884f95bf5351 382 return m_connectionHandle;
vcoubard 541:884f95bf5351 383 }
vcoubard 541:884f95bf5351 384
vcoubard 561:613dbbdeed27 385 /**************5************************************************************/
vcoubard 541:884f95bf5351 386 /*!
vcoubard 541:884f95bf5351 387 @brief Sets the BLE device address
vcoubard 541:884f95bf5351 388
vcoubard 541:884f95bf5351 389 @returns ble_error_t
vcoubard 541:884f95bf5351 390
vcoubard 541:884f95bf5351 391 @section EXAMPLE
vcoubard 541:884f95bf5351 392
vcoubard 541:884f95bf5351 393 @code
vcoubard 541:884f95bf5351 394
vcoubard 541:884f95bf5351 395 uint8_t device_address[6] = { 0xca, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0 };
vcoubard 541:884f95bf5351 396 nrf.getGap().setAddress(Gap::ADDR_TYPE_RANDOM_STATIC, device_address);
vcoubard 541:884f95bf5351 397
vcoubard 541:884f95bf5351 398 @endcode
vcoubard 541:884f95bf5351 399 */
vcoubard 541:884f95bf5351 400 /**************************************************************************/
vcoubard 541:884f95bf5351 401 ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
vcoubard 541:884f95bf5351 402 {
vcoubard 552:20b282c26f96 403 uint8_t cycle_mode;
vcoubard 552:20b282c26f96 404 ble_gap_addr_t dev_addr;
vcoubard 552:20b282c26f96 405
vcoubard 552:20b282c26f96 406 /* When using Public or Static addresses, the cycle mode must be None.
vcoubard 552:20b282c26f96 407 When using Random Private addresses, the cycle mode must be Auto.
vcoubard 552:20b282c26f96 408 In auto mode, the given address is ignored.
vcoubard 552:20b282c26f96 409 */
vcoubard 552:20b282c26f96 410 if ((type == ADDR_TYPE_PUBLIC) || (type == ADDR_TYPE_RANDOM_STATIC))
vcoubard 552:20b282c26f96 411 {
vcoubard 552:20b282c26f96 412 cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_NONE;
vcoubard 552:20b282c26f96 413 memcpy(dev_addr.addr, address, ADDR_LEN);
vcoubard 552:20b282c26f96 414 }
vcoubard 552:20b282c26f96 415 else if ((type == ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE) || (type == ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE))
vcoubard 552:20b282c26f96 416 {
vcoubard 552:20b282c26f96 417 cycle_mode = BLE_GAP_ADDR_CYCLE_MODE_AUTO;
vcoubard 552:20b282c26f96 418 // address is ignored when in auto mode
vcoubard 552:20b282c26f96 419 }
vcoubard 552:20b282c26f96 420 else
vcoubard 552:20b282c26f96 421 {
vcoubard 541:884f95bf5351 422 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 423 }
vcoubard 541:884f95bf5351 424
vcoubard 541:884f95bf5351 425 dev_addr.addr_type = type;
vcoubard 552:20b282c26f96 426 ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(cycle_mode, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE);
vcoubard 541:884f95bf5351 427
vcoubard 541:884f95bf5351 428 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 429 }
vcoubard 541:884f95bf5351 430
vcoubard 541:884f95bf5351 431 ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address)
vcoubard 541:884f95bf5351 432 {
vcoubard 541:884f95bf5351 433 ble_gap_addr_t dev_addr;
vcoubard 541:884f95bf5351 434 if (sd_ble_gap_address_get(&dev_addr) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 435 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 436 }
vcoubard 541:884f95bf5351 437
vcoubard 541:884f95bf5351 438 if (typeP != NULL) {
vcoubard 541:884f95bf5351 439 *typeP = static_cast<AddressType_t>(dev_addr.addr_type);
vcoubard 541:884f95bf5351 440 }
vcoubard 541:884f95bf5351 441 if (address != NULL) {
vcoubard 541:884f95bf5351 442 memcpy(address, dev_addr.addr, ADDR_LEN);
vcoubard 541:884f95bf5351 443 }
vcoubard 541:884f95bf5351 444 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 445 }
vcoubard 541:884f95bf5351 446
vcoubard 541:884f95bf5351 447 ble_error_t nRF5xGap::setDeviceName(const uint8_t *deviceName)
vcoubard 541:884f95bf5351 448 {
vcoubard 541:884f95bf5351 449 ble_gap_conn_sec_mode_t sec_mode;
vcoubard 541:884f95bf5351 450 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); // no security is needed
vcoubard 541:884f95bf5351 451
vcoubard 541:884f95bf5351 452 if (sd_ble_gap_device_name_set(&sec_mode, deviceName, strlen((const char *)deviceName)) == NRF_SUCCESS) {
vcoubard 541:884f95bf5351 453 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 454 } else {
vcoubard 541:884f95bf5351 455 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 456 }
vcoubard 541:884f95bf5351 457 }
vcoubard 541:884f95bf5351 458
vcoubard 541:884f95bf5351 459 ble_error_t nRF5xGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
vcoubard 541:884f95bf5351 460 {
vcoubard 541:884f95bf5351 461 if (sd_ble_gap_device_name_get(deviceName, (uint16_t *)lengthP) == NRF_SUCCESS) {
vcoubard 541:884f95bf5351 462 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 463 } else {
vcoubard 541:884f95bf5351 464 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 465 }
vcoubard 541:884f95bf5351 466 }
vcoubard 541:884f95bf5351 467
vcoubard 541:884f95bf5351 468 ble_error_t nRF5xGap::setAppearance(GapAdvertisingData::Appearance appearance)
vcoubard 541:884f95bf5351 469 {
vcoubard 541:884f95bf5351 470 if (sd_ble_gap_appearance_set(appearance) == NRF_SUCCESS) {
vcoubard 541:884f95bf5351 471 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 472 } else {
vcoubard 541:884f95bf5351 473 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 474 }
vcoubard 541:884f95bf5351 475 }
vcoubard 541:884f95bf5351 476
vcoubard 541:884f95bf5351 477 ble_error_t nRF5xGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
vcoubard 541:884f95bf5351 478 {
vcoubard 541:884f95bf5351 479 if ((sd_ble_gap_appearance_get(reinterpret_cast<uint16_t *>(appearanceP)) == NRF_SUCCESS)) {
vcoubard 541:884f95bf5351 480 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 481 } else {
vcoubard 541:884f95bf5351 482 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 483 }
vcoubard 541:884f95bf5351 484 }
vcoubard 541:884f95bf5351 485
vcoubard 541:884f95bf5351 486 /* (Valid values are -40, -20, -16, -12, -8, -4, 0, 4) */
vcoubard 541:884f95bf5351 487 ble_error_t nRF5xGap::setTxPower(int8_t txPower)
vcoubard 541:884f95bf5351 488 {
vcoubard 541:884f95bf5351 489 unsigned rc;
vcoubard 541:884f95bf5351 490 if ((rc = sd_ble_gap_tx_power_set(txPower)) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 491 switch (rc) {
vcoubard 541:884f95bf5351 492 case NRF_ERROR_BUSY:
vcoubard 541:884f95bf5351 493 return BLE_STACK_BUSY;
vcoubard 541:884f95bf5351 494 case NRF_ERROR_INVALID_PARAM:
vcoubard 541:884f95bf5351 495 default:
vcoubard 541:884f95bf5351 496 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 541:884f95bf5351 497 }
vcoubard 541:884f95bf5351 498 }
vcoubard 541:884f95bf5351 499
vcoubard 541:884f95bf5351 500 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 501 }
vcoubard 541:884f95bf5351 502
vcoubard 541:884f95bf5351 503 void nRF5xGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP)
vcoubard 541:884f95bf5351 504 {
vcoubard 541:884f95bf5351 505 static const int8_t permittedTxValues[] = {
vcoubard 541:884f95bf5351 506 -40, -30, -20, -16, -12, -8, -4, 0, 4
vcoubard 541:884f95bf5351 507 };
vcoubard 541:884f95bf5351 508
vcoubard 541:884f95bf5351 509 *valueArrayPP = permittedTxValues;
vcoubard 541:884f95bf5351 510 *countP = sizeof(permittedTxValues) / sizeof(int8_t);
rgrover1 388:db85a09c27ef 511 }