Nordic stack and drivers for the mbed BLE API

Dependents:   idd_hw5_bleFanProto

Fork of nRF51822 by Nordic Semiconductor

Committer:
Rohit Grover
Date:
Wed Jun 04 09:19:57 2014 +0100
Revision:
17:c3e11bb6cb72
Parent:
3:791d672cbbec
Child:
22:c6ee8136847e
white space diffs; uncrustify

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 0:eff01767de02 1 /* mbed Microcontroller Library
bogdanm 0:eff01767de02 2 * Copyright (c) 2006-2013 ARM Limited
bogdanm 0:eff01767de02 3 *
bogdanm 0:eff01767de02 4 * Licensed under the Apache License, Version 2.0 (the "License");
bogdanm 0:eff01767de02 5 * you may not use this file except in compliance with the License.
bogdanm 0:eff01767de02 6 * You may obtain a copy of the License at
bogdanm 0:eff01767de02 7 *
bogdanm 0:eff01767de02 8 * http://www.apache.org/licenses/LICENSE-2.0
bogdanm 0:eff01767de02 9 *
bogdanm 0:eff01767de02 10 * Unless required by applicable law or agreed to in writing, software
bogdanm 0:eff01767de02 11 * distributed under the License is distributed on an "AS IS" BASIS,
bogdanm 0:eff01767de02 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bogdanm 0:eff01767de02 13 * See the License for the specific language governing permissions and
bogdanm 0:eff01767de02 14 * limitations under the License.
bogdanm 0:eff01767de02 15 */
Rohit Grover 17:c3e11bb6cb72 16
bogdanm 0:eff01767de02 17 #include "nRF51Gap.h"
bogdanm 0:eff01767de02 18 #include "mbed.h"
bogdanm 0:eff01767de02 19
bogdanm 0:eff01767de02 20 #include "common/common.h"
bogdanm 0:eff01767de02 21 #include "ble_advdata.h"
mbed_official 1:f84abedbf4fb 22 #include "ble_hci.h"
bogdanm 0:eff01767de02 23
bogdanm 0:eff01767de02 24 /**************************************************************************/
bogdanm 0:eff01767de02 25 /*!
bogdanm 0:eff01767de02 26 @brief Sets the advertising parameters and payload for the device
bogdanm 0:eff01767de02 27
bogdanm 0:eff01767de02 28 @param[in] params
bogdanm 0:eff01767de02 29 Basic advertising details, including the advertising
bogdanm 0:eff01767de02 30 delay, timeout and how the device should be advertised
bogdanm 0:eff01767de02 31 @params[in] advData
bogdanm 0:eff01767de02 32 The primary advertising data payload
bogdanm 0:eff01767de02 33 @params[in] scanResponse
bogdanm 0:eff01767de02 34 The optional Scan Response payload if the advertising
bogdanm 0:eff01767de02 35 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
bogdanm 0:eff01767de02 36 in \ref GapAdveritinngParams
Rohit Grover 17:c3e11bb6cb72 37
bogdanm 0:eff01767de02 38 @returns \ref ble_error_t
Rohit Grover 17:c3e11bb6cb72 39
bogdanm 0:eff01767de02 40 @retval BLE_ERROR_NONE
bogdanm 0:eff01767de02 41 Everything executed properly
bogdanm 0:eff01767de02 42
bogdanm 0:eff01767de02 43 @retval BLE_ERROR_BUFFER_OVERFLOW
bogdanm 0:eff01767de02 44 The proposed action would cause a buffer overflow. All
bogdanm 0:eff01767de02 45 advertising payloads must be <= 31 bytes, for example.
Rohit Grover 17:c3e11bb6cb72 46
bogdanm 0:eff01767de02 47 @retval BLE_ERROR_NOT_IMPLEMENTED
bogdanm 0:eff01767de02 48 A feature was requested that is not yet supported in the
bogdanm 0:eff01767de02 49 nRF51 firmware or hardware.
bogdanm 0:eff01767de02 50
bogdanm 0:eff01767de02 51 @retval BLE_ERROR_PARAM_OUT_OF_RANGE
bogdanm 0:eff01767de02 52 One of the proposed values is outside the valid range.
bogdanm 0:eff01767de02 53
bogdanm 0:eff01767de02 54 @section EXAMPLE
bogdanm 0:eff01767de02 55
bogdanm 0:eff01767de02 56 @code
bogdanm 0:eff01767de02 57
bogdanm 0:eff01767de02 58 @endcode
bogdanm 0:eff01767de02 59 */
bogdanm 0:eff01767de02 60 /**************************************************************************/
Rohit Grover 17:c3e11bb6cb72 61 ble_error_t nRF51Gap::setAdvertisingData(const GapAdvertisingData &advData,
Rohit Grover 17:c3e11bb6cb72 62 const GapAdvertisingData &scanResponse)
bogdanm 0:eff01767de02 63 {
bogdanm 0:eff01767de02 64 /* Make sure we don't exceed the advertising payload length */
Rohit Grover 17:c3e11bb6cb72 65 if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
bogdanm 0:eff01767de02 66 return BLE_ERROR_BUFFER_OVERFLOW;
bogdanm 0:eff01767de02 67 }
Rohit Grover 17:c3e11bb6cb72 68
bogdanm 0:eff01767de02 69 /* Make sure we have a payload! */
Rohit Grover 17:c3e11bb6cb72 70 if (advData.getPayloadLen() == 0) {
Rohit Grover 17:c3e11bb6cb72 71 return BLE_ERROR_PARAM_OUT_OF_RANGE;
bogdanm 0:eff01767de02 72 }
bogdanm 0:eff01767de02 73
bogdanm 0:eff01767de02 74 /* Check the scan response payload limits */
bogdanm 0:eff01767de02 75 //if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED))
bogdanm 0:eff01767de02 76 //{
bogdanm 0:eff01767de02 77 // /* Check if we're within the upper limit */
bogdanm 0:eff01767de02 78 // if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD)
bogdanm 0:eff01767de02 79 // {
bogdanm 0:eff01767de02 80 // return BLE_ERROR_BUFFER_OVERFLOW;
bogdanm 0:eff01767de02 81 // }
bogdanm 0:eff01767de02 82 // /* Make sure we have a payload! */
bogdanm 0:eff01767de02 83 // if (advData.getPayloadLen() == 0)
bogdanm 0:eff01767de02 84 // {
bogdanm 0:eff01767de02 85 // return BLE_ERROR_PARAM_OUT_OF_RANGE;
bogdanm 0:eff01767de02 86 // }
bogdanm 0:eff01767de02 87 //}
Rohit Grover 17:c3e11bb6cb72 88
bogdanm 0:eff01767de02 89 /* Send advertising data! */
Rohit Grover 17:c3e11bb6cb72 90 ASSERT(ERROR_NONE ==
Rohit Grover 17:c3e11bb6cb72 91 sd_ble_gap_adv_data_set(advData.getPayload(),
Rohit Grover 17:c3e11bb6cb72 92 advData.getPayloadLen(),
Rohit Grover 17:c3e11bb6cb72 93 scanResponse.getPayload(),
Rohit Grover 17:c3e11bb6cb72 94 scanResponse.getPayloadLen()),
Rohit Grover 17:c3e11bb6cb72 95 BLE_ERROR_PARAM_OUT_OF_RANGE);
bogdanm 0:eff01767de02 96
Rohit Grover 17:c3e11bb6cb72 97 /* Make sure the GAP Service appearance value is aligned with the
Rohit Grover 17:c3e11bb6cb72 98 *appearance from GapAdvertisingData */
Rohit Grover 17:c3e11bb6cb72 99 ASSERT(ERROR_NONE == sd_ble_gap_appearance_set(advData.getAppearance()),
Rohit Grover 17:c3e11bb6cb72 100 BLE_ERROR_PARAM_OUT_OF_RANGE);
bogdanm 0:eff01767de02 101
bogdanm 0:eff01767de02 102 /* ToDo: Perform some checks on the payload, for example the Scan Response can't */
bogdanm 0:eff01767de02 103 /* contains a flags AD type, etc. */
bogdanm 0:eff01767de02 104
bogdanm 0:eff01767de02 105 return BLE_ERROR_NONE;
bogdanm 0:eff01767de02 106 }
bogdanm 0:eff01767de02 107
bogdanm 0:eff01767de02 108 /**************************************************************************/
bogdanm 0:eff01767de02 109 /*!
bogdanm 0:eff01767de02 110 @brief Starts the BLE HW, initialising any services that were
bogdanm 0:eff01767de02 111 added before this function was called.
Rohit Grover 17:c3e11bb6cb72 112
bogdanm 0:eff01767de02 113 @note All services must be added before calling this function!
Rohit Grover 17:c3e11bb6cb72 114
bogdanm 0:eff01767de02 115 @returns ble_error_t
Rohit Grover 17:c3e11bb6cb72 116
bogdanm 0:eff01767de02 117 @retval BLE_ERROR_NONE
bogdanm 0:eff01767de02 118 Everything executed properly
Rohit Grover 17:c3e11bb6cb72 119
bogdanm 0:eff01767de02 120 @section EXAMPLE
bogdanm 0:eff01767de02 121
bogdanm 0:eff01767de02 122 @code
bogdanm 0:eff01767de02 123
bogdanm 0:eff01767de02 124 @endcode
bogdanm 0:eff01767de02 125 */
bogdanm 0:eff01767de02 126 /**************************************************************************/
Rohit Grover 17:c3e11bb6cb72 127 ble_error_t nRF51Gap::startAdvertising(const GapAdvertisingParams &params)
bogdanm 0:eff01767de02 128 {
Rohit Grover 17:c3e11bb6cb72 129 /* Make sure we support the advertising type */
Rohit Grover 17:c3e11bb6cb72 130 if (params.getAdvertisingType() ==
Rohit Grover 17:c3e11bb6cb72 131 GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
bogdanm 0:eff01767de02 132 /* ToDo: This requires a propery security implementation, etc. */
bogdanm 0:eff01767de02 133 return BLE_ERROR_NOT_IMPLEMENTED;
bogdanm 0:eff01767de02 134 }
bogdanm 0:eff01767de02 135
bogdanm 0:eff01767de02 136 /* Check interval range */
Rohit Grover 17:c3e11bb6cb72 137 if (params.getAdvertisingType() ==
Rohit Grover 17:c3e11bb6cb72 138 GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
bogdanm 0:eff01767de02 139 /* Min delay is slightly longer for unconnectable devices */
bogdanm 0:eff01767de02 140 if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
Rohit Grover 17:c3e11bb6cb72 141 (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX)) {
bogdanm 0:eff01767de02 142 return BLE_ERROR_PARAM_OUT_OF_RANGE;
bogdanm 0:eff01767de02 143 }
Rohit Grover 17:c3e11bb6cb72 144 } else {
bogdanm 0:eff01767de02 145 if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN) ||
Rohit Grover 17:c3e11bb6cb72 146 (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX)) {
bogdanm 0:eff01767de02 147 return BLE_ERROR_PARAM_OUT_OF_RANGE;
bogdanm 0:eff01767de02 148 }
bogdanm 0:eff01767de02 149 }
bogdanm 0:eff01767de02 150
bogdanm 0:eff01767de02 151 /* Check timeout is zero for Connectable Directed */
Rohit Grover 17:c3e11bb6cb72 152 if ((params.getAdvertisingType() ==
Rohit Grover 17:c3e11bb6cb72 153 GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
Rohit Grover 17:c3e11bb6cb72 154 (params.getTimeout() != 0)) {
bogdanm 0:eff01767de02 155 /* Timeout must be 0 with this type, although we'll never get here */
bogdanm 0:eff01767de02 156 /* since this isn't implemented yet anyway */
bogdanm 0:eff01767de02 157 return BLE_ERROR_PARAM_OUT_OF_RANGE;
bogdanm 0:eff01767de02 158 }
bogdanm 0:eff01767de02 159
bogdanm 0:eff01767de02 160 /* Check timeout for other advertising types */
Rohit Grover 17:c3e11bb6cb72 161 if ((params.getAdvertisingType() !=
Rohit Grover 17:c3e11bb6cb72 162 GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
Rohit Grover 17:c3e11bb6cb72 163 (params.getTimeout() > GAP_ADV_PARAMS_TIMEOUT_MAX)) {
bogdanm 0:eff01767de02 164 return BLE_ERROR_PARAM_OUT_OF_RANGE;
bogdanm 0:eff01767de02 165 }
bogdanm 0:eff01767de02 166
bogdanm 0:eff01767de02 167 /* Start Advertising */
Rohit Grover 17:c3e11bb6cb72 168 ble_gap_adv_params_t adv_para = {0};
bogdanm 0:eff01767de02 169
Rohit Grover 17:c3e11bb6cb72 170 adv_para.type = params.getAdvertisingType();
Rohit Grover 17:c3e11bb6cb72 171 adv_para.p_peer_addr = NULL; // Undirected
Rohit Grover 17:c3e11bb6cb72 172 // advertisement
Rohit Grover 17:c3e11bb6cb72 173 adv_para.fp = BLE_GAP_ADV_FP_ANY;
Rohit Grover 17:c3e11bb6cb72 174 adv_para.p_whitelist = NULL;
Rohit Grover 17:c3e11bb6cb72 175 adv_para.interval = params.getInterval(); // advertising
Rohit Grover 17:c3e11bb6cb72 176 // interval (in units
Rohit Grover 17:c3e11bb6cb72 177 // of 0.625 ms)
Rohit Grover 17:c3e11bb6cb72 178 adv_para.timeout = params.getTimeout();
bogdanm 0:eff01767de02 179
Rohit Grover 17:c3e11bb6cb72 180 ASSERT(ERROR_NONE == sd_ble_gap_adv_start(&adv_para),
Rohit Grover 17:c3e11bb6cb72 181 BLE_ERROR_PARAM_OUT_OF_RANGE);
Rohit Grover 17:c3e11bb6cb72 182
Rohit Grover 17:c3e11bb6cb72 183 state.advertising = 1;
bogdanm 0:eff01767de02 184
bogdanm 0:eff01767de02 185 return BLE_ERROR_NONE;
bogdanm 0:eff01767de02 186 }
bogdanm 0:eff01767de02 187
bogdanm 0:eff01767de02 188 /**************************************************************************/
bogdanm 0:eff01767de02 189 /*!
bogdanm 0:eff01767de02 190 @brief Stops the BLE HW and disconnects from any devices
Rohit Grover 17:c3e11bb6cb72 191
bogdanm 0:eff01767de02 192 @returns ble_error_t
Rohit Grover 17:c3e11bb6cb72 193
bogdanm 0:eff01767de02 194 @retval BLE_ERROR_NONE
bogdanm 0:eff01767de02 195 Everything executed properly
Rohit Grover 17:c3e11bb6cb72 196
bogdanm 0:eff01767de02 197 @section EXAMPLE
bogdanm 0:eff01767de02 198
bogdanm 0:eff01767de02 199 @code
bogdanm 0:eff01767de02 200
bogdanm 0:eff01767de02 201 @endcode
bogdanm 0:eff01767de02 202 */
bogdanm 0:eff01767de02 203 /**************************************************************************/
bogdanm 0:eff01767de02 204 ble_error_t nRF51Gap::stopAdvertising(void)
bogdanm 0:eff01767de02 205 {
Rohit Grover 17:c3e11bb6cb72 206 /* Stop Advertising */
Rohit Grover 17:c3e11bb6cb72 207 ASSERT(ERROR_NONE == sd_ble_gap_adv_stop(), BLE_ERROR_PARAM_OUT_OF_RANGE);
bogdanm 0:eff01767de02 208
Rohit Grover 17:c3e11bb6cb72 209 state.advertising = 0;
bogdanm 0:eff01767de02 210
Rohit Grover 17:c3e11bb6cb72 211 return BLE_ERROR_NONE;
bogdanm 0:eff01767de02 212 }
bogdanm 0:eff01767de02 213
bogdanm 0:eff01767de02 214 /**************************************************************************/
bogdanm 0:eff01767de02 215 /*!
bogdanm 0:eff01767de02 216 @brief Disconnects if we are connected to a central device
Rohit Grover 17:c3e11bb6cb72 217
bogdanm 0:eff01767de02 218 @returns ble_error_t
Rohit Grover 17:c3e11bb6cb72 219
bogdanm 0:eff01767de02 220 @retval BLE_ERROR_NONE
bogdanm 0:eff01767de02 221 Everything executed properly
Rohit Grover 17:c3e11bb6cb72 222
bogdanm 0:eff01767de02 223 @section EXAMPLE
bogdanm 0:eff01767de02 224
bogdanm 0:eff01767de02 225 @code
bogdanm 0:eff01767de02 226
bogdanm 0:eff01767de02 227 @endcode
bogdanm 0:eff01767de02 228 */
bogdanm 0:eff01767de02 229 /**************************************************************************/
bogdanm 0:eff01767de02 230 ble_error_t nRF51Gap::disconnect(void)
bogdanm 0:eff01767de02 231 {
Rohit Grover 17:c3e11bb6cb72 232 state.advertising = 0;
Rohit Grover 17:c3e11bb6cb72 233 state.connected = 0;
Rohit Grover 17:c3e11bb6cb72 234
Rohit Grover 17:c3e11bb6cb72 235 /* Disconnect if we are connected to a central device */
Rohit Grover 17:c3e11bb6cb72 236 ASSERT_INT(ERROR_NONE,
Rohit Grover 17:c3e11bb6cb72 237 sd_ble_gap_disconnect(m_connectionHandle,
Rohit Grover 17:c3e11bb6cb72 238 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION),
Rohit Grover 17:c3e11bb6cb72 239 BLE_ERROR_PARAM_OUT_OF_RANGE);
Rohit Grover 17:c3e11bb6cb72 240
Rohit Grover 17:c3e11bb6cb72 241 return BLE_ERROR_NONE;
mbed_official 1:f84abedbf4fb 242 }
bogdanm 0:eff01767de02 243
mbed_official 1:f84abedbf4fb 244 /**************************************************************************/
mbed_official 1:f84abedbf4fb 245 /*!
mbed_official 1:f84abedbf4fb 246 @brief Sets the 16-bit connection handle
mbed_official 1:f84abedbf4fb 247 */
mbed_official 1:f84abedbf4fb 248 /**************************************************************************/
mbed_official 1:f84abedbf4fb 249 void nRF51Gap::setConnectionHandle(uint16_t con_handle)
mbed_official 1:f84abedbf4fb 250 {
Rohit Grover 17:c3e11bb6cb72 251 m_connectionHandle = con_handle;
mbed_official 1:f84abedbf4fb 252 }
Rohit Grover 17:c3e11bb6cb72 253
mbed_official 1:f84abedbf4fb 254 /**************************************************************************/
mbed_official 1:f84abedbf4fb 255 /*!
mbed_official 1:f84abedbf4fb 256 @brief Gets the 16-bit connection handle
mbed_official 1:f84abedbf4fb 257 */
mbed_official 1:f84abedbf4fb 258 /**************************************************************************/
mbed_official 1:f84abedbf4fb 259 uint16_t nRF51Gap::getConnectionHandle(void)
mbed_official 1:f84abedbf4fb 260 {
Rohit Grover 17:c3e11bb6cb72 261 return m_connectionHandle;
bogdanm 0:eff01767de02 262 }
Rohit Grover 17:c3e11bb6cb72 263
mbed_official 1:f84abedbf4fb 264 /**************************************************************************/
mbed_official 1:f84abedbf4fb 265 /*!
mbed_official 1:f84abedbf4fb 266 @brief Sets the BLE device address
Rohit Grover 17:c3e11bb6cb72 267
mbed_official 1:f84abedbf4fb 268 @returns ble_error_t
mbed_official 1:f84abedbf4fb 269
mbed_official 1:f84abedbf4fb 270 @section EXAMPLE
mbed_official 1:f84abedbf4fb 271
mbed_official 1:f84abedbf4fb 272 @code
mbed_official 1:f84abedbf4fb 273
mbed_official 1:f84abedbf4fb 274 uint8_t device_address[6] = { 0xca, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0 };
mbed_official 1:f84abedbf4fb 275 nrf.getGap().setAddress(Gap::ADDR_TYPE_RANDOM_STATIC, device_address);
mbed_official 1:f84abedbf4fb 276
mbed_official 1:f84abedbf4fb 277 @endcode
mbed_official 1:f84abedbf4fb 278 */
mbed_official 1:f84abedbf4fb 279 /**************************************************************************/
Rohit Grover 3:791d672cbbec 280 ble_error_t nRF51Gap::setAddress(addr_type_t type, const uint8_t address[6])
mbed_official 1:f84abedbf4fb 281 {
Rohit Grover 17:c3e11bb6cb72 282 if (type > ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) {
Rohit Grover 17:c3e11bb6cb72 283 return BLE_ERROR_PARAM_OUT_OF_RANGE;
Rohit Grover 17:c3e11bb6cb72 284 }
Rohit Grover 17:c3e11bb6cb72 285
Rohit Grover 17:c3e11bb6cb72 286 ble_gap_addr_t dev_addr;
Rohit Grover 17:c3e11bb6cb72 287 dev_addr.addr_type = type;
Rohit Grover 17:c3e11bb6cb72 288 memcpy(dev_addr.addr, address, 6);
Rohit Grover 17:c3e11bb6cb72 289
Rohit Grover 17:c3e11bb6cb72 290 ASSERT_INT(ERROR_NONE,
Rohit Grover 17:c3e11bb6cb72 291 sd_ble_gap_address_set(&dev_addr),
Rohit Grover 17:c3e11bb6cb72 292 BLE_ERROR_PARAM_OUT_OF_RANGE);
Rohit Grover 17:c3e11bb6cb72 293
Rohit Grover 17:c3e11bb6cb72 294 return BLE_ERROR_NONE;
mbed_official 1:f84abedbf4fb 295 }