Microbug / BLE_API

Fork of BLE_API by Bluetooth Low Energy

Committer:
ktownsend
Date:
Thu Jan 16 22:29:53 2014 +0000
Revision:
29:011e95ce78b8
Child:
30:9614522cf932
Added better radio abstraction layer, moved Gatt enums from blecommon.h to GattCharacteristic.h

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ktownsend 29:011e95ce78b8 1 /* mbed Microcontroller Library
ktownsend 29:011e95ce78b8 2 * Copyright (c) 2006-2013 ARM Limited
ktownsend 29:011e95ce78b8 3 *
ktownsend 29:011e95ce78b8 4 * Licensed under the Apache License, Version 2.0 (the "License");
ktownsend 29:011e95ce78b8 5 * you may not use this file except in compliance with the License.
ktownsend 29:011e95ce78b8 6 * You may obtain a copy of the License at
ktownsend 29:011e95ce78b8 7 *
ktownsend 29:011e95ce78b8 8 * http://www.apache.org/licenses/LICENSE-2.0
ktownsend 29:011e95ce78b8 9 *
ktownsend 29:011e95ce78b8 10 * Unless required by applicable law or agreed to in writing, software
ktownsend 29:011e95ce78b8 11 * distributed under the License is distributed on an "AS IS" BASIS,
ktownsend 29:011e95ce78b8 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ktownsend 29:011e95ce78b8 13 * See the License for the specific language governing permissions and
ktownsend 29:011e95ce78b8 14 * limitations under the License.
ktownsend 29:011e95ce78b8 15 */
ktownsend 29:011e95ce78b8 16
ktownsend 29:011e95ce78b8 17 #include "nRF51Gap.h"
ktownsend 29:011e95ce78b8 18 #include "mbed.h"
ktownsend 29:011e95ce78b8 19
ktownsend 29:011e95ce78b8 20 /**************************************************************************/
ktownsend 29:011e95ce78b8 21 /*!
ktownsend 29:011e95ce78b8 22 @brief Constructor
ktownsend 29:011e95ce78b8 23 */
ktownsend 29:011e95ce78b8 24 /**************************************************************************/
ktownsend 29:011e95ce78b8 25 nRF51Gap::nRF51Gap(RawSerial &serial) : Gap(), uart(serial)
ktownsend 29:011e95ce78b8 26 {
ktownsend 29:011e95ce78b8 27 /* Reset the service and characteristic counters */
ktownsend 29:011e95ce78b8 28 connected = 0;
ktownsend 29:011e95ce78b8 29 }
ktownsend 29:011e95ce78b8 30
ktownsend 29:011e95ce78b8 31 /**************************************************************************/
ktownsend 29:011e95ce78b8 32 /*!
ktownsend 29:011e95ce78b8 33 @brief Destructor
ktownsend 29:011e95ce78b8 34 */
ktownsend 29:011e95ce78b8 35 /**************************************************************************/
ktownsend 29:011e95ce78b8 36 nRF51Gap::~nRF51Gap(void)
ktownsend 29:011e95ce78b8 37 {
ktownsend 29:011e95ce78b8 38 }
ktownsend 29:011e95ce78b8 39
ktownsend 29:011e95ce78b8 40 /**************************************************************************/
ktownsend 29:011e95ce78b8 41 /*!
ktownsend 29:011e95ce78b8 42 @brief Sets the advertising parameters and payload for the device
ktownsend 29:011e95ce78b8 43
ktownsend 29:011e95ce78b8 44 @param[in] params
ktownsend 29:011e95ce78b8 45 Basic advertising details, including the advertising
ktownsend 29:011e95ce78b8 46 delay, timeout and how the device should be advertised
ktownsend 29:011e95ce78b8 47 @params[in] advData
ktownsend 29:011e95ce78b8 48 The primary advertising data payload
ktownsend 29:011e95ce78b8 49 @params[in] scanResponse
ktownsend 29:011e95ce78b8 50 The optional Scan Response payload if the advertising
ktownsend 29:011e95ce78b8 51 type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
ktownsend 29:011e95ce78b8 52 in \ref GapAdveritinngParams
ktownsend 29:011e95ce78b8 53
ktownsend 29:011e95ce78b8 54 @returns \ref ble_error_t
ktownsend 29:011e95ce78b8 55
ktownsend 29:011e95ce78b8 56 @retval BLE_ERROR_NONE
ktownsend 29:011e95ce78b8 57 Everything executed properly
ktownsend 29:011e95ce78b8 58
ktownsend 29:011e95ce78b8 59 @retval BLE_ERROR_BUFFER_OVERFLOW
ktownsend 29:011e95ce78b8 60 The proposed action would cause a buffer overflow. All
ktownsend 29:011e95ce78b8 61 advertising payloads must be <= 31 bytes, for example.
ktownsend 29:011e95ce78b8 62
ktownsend 29:011e95ce78b8 63 @retval BLE_ERROR_NOT_IMPLEMENTED
ktownsend 29:011e95ce78b8 64 A feature was requested that is not yet supported in the
ktownsend 29:011e95ce78b8 65 nRF51 firmware or hardware.
ktownsend 29:011e95ce78b8 66
ktownsend 29:011e95ce78b8 67 @retval BLE_ERROR_PARAM_OUT_OF_RANGE
ktownsend 29:011e95ce78b8 68 One of the proposed values is outside the valid range.
ktownsend 29:011e95ce78b8 69
ktownsend 29:011e95ce78b8 70 @section EXAMPLE
ktownsend 29:011e95ce78b8 71
ktownsend 29:011e95ce78b8 72 @code
ktownsend 29:011e95ce78b8 73
ktownsend 29:011e95ce78b8 74 @endcode
ktownsend 29:011e95ce78b8 75 */
ktownsend 29:011e95ce78b8 76 /**************************************************************************/
ktownsend 29:011e95ce78b8 77 ble_error_t nRF51Gap::setAdvertising(GapAdvertisingParams & params, GapAdvertisingData & advData, GapAdvertisingData & scanResponse)
ktownsend 29:011e95ce78b8 78 {
ktownsend 29:011e95ce78b8 79 uint8_t len = 0;
ktownsend 29:011e95ce78b8 80 uint8_t *buffer;
ktownsend 29:011e95ce78b8 81
ktownsend 29:011e95ce78b8 82 /* Make sure we support the advertising type */
ktownsend 29:011e95ce78b8 83 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED)
ktownsend 29:011e95ce78b8 84 {
ktownsend 29:011e95ce78b8 85 /* ToDo: This requires a propery security implementation, etc. */
ktownsend 29:011e95ce78b8 86 return BLE_ERROR_NOT_IMPLEMENTED;
ktownsend 29:011e95ce78b8 87 }
ktownsend 29:011e95ce78b8 88
ktownsend 29:011e95ce78b8 89 /* Check interval range */
ktownsend 29:011e95ce78b8 90 if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED)
ktownsend 29:011e95ce78b8 91 {
ktownsend 29:011e95ce78b8 92 /* Min delay is slightly longer for unconnectable devices */
ktownsend 29:011e95ce78b8 93 if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
ktownsend 29:011e95ce78b8 94 (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX))
ktownsend 29:011e95ce78b8 95 {
ktownsend 29:011e95ce78b8 96 return BLE_ERROR_PARAM_OUT_OF_RANGE;
ktownsend 29:011e95ce78b8 97 }
ktownsend 29:011e95ce78b8 98 }
ktownsend 29:011e95ce78b8 99 else
ktownsend 29:011e95ce78b8 100 {
ktownsend 29:011e95ce78b8 101 if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN) ||
ktownsend 29:011e95ce78b8 102 (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX))
ktownsend 29:011e95ce78b8 103 {
ktownsend 29:011e95ce78b8 104 return BLE_ERROR_PARAM_OUT_OF_RANGE;
ktownsend 29:011e95ce78b8 105 }
ktownsend 29:011e95ce78b8 106 }
ktownsend 29:011e95ce78b8 107
ktownsend 29:011e95ce78b8 108 /* Check timeout is zero for Connectable Directed */
ktownsend 29:011e95ce78b8 109 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
ktownsend 29:011e95ce78b8 110 (params.getTimeout() != 0))
ktownsend 29:011e95ce78b8 111 {
ktownsend 29:011e95ce78b8 112 /* Timeout must be 0 with this type, although we'll never get here */
ktownsend 29:011e95ce78b8 113 /* since this isn't implemented yet anyway */
ktownsend 29:011e95ce78b8 114 return BLE_ERROR_PARAM_OUT_OF_RANGE;
ktownsend 29:011e95ce78b8 115 }
ktownsend 29:011e95ce78b8 116
ktownsend 29:011e95ce78b8 117 /* Check timeout for other advertising types */
ktownsend 29:011e95ce78b8 118 if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
ktownsend 29:011e95ce78b8 119 (params.getTimeout() > GAP_ADV_PARAMS_TIMEOUT_MAX))
ktownsend 29:011e95ce78b8 120 {
ktownsend 29:011e95ce78b8 121 return BLE_ERROR_PARAM_OUT_OF_RANGE;
ktownsend 29:011e95ce78b8 122 }
ktownsend 29:011e95ce78b8 123
ktownsend 29:011e95ce78b8 124 /* Make sure we don't exceed the advertising payload length */
ktownsend 29:011e95ce78b8 125 if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD)
ktownsend 29:011e95ce78b8 126 {
ktownsend 29:011e95ce78b8 127 return BLE_ERROR_BUFFER_OVERFLOW;
ktownsend 29:011e95ce78b8 128 }
ktownsend 29:011e95ce78b8 129
ktownsend 29:011e95ce78b8 130 /* Check the scan response payload limits */
ktownsend 29:011e95ce78b8 131 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED))
ktownsend 29:011e95ce78b8 132 {
ktownsend 29:011e95ce78b8 133 /* Check if we're within the upper limit */
ktownsend 29:011e95ce78b8 134 if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD)
ktownsend 29:011e95ce78b8 135 {
ktownsend 29:011e95ce78b8 136 return BLE_ERROR_BUFFER_OVERFLOW;
ktownsend 29:011e95ce78b8 137 }
ktownsend 29:011e95ce78b8 138 /* Make sure we have a payload! */
ktownsend 29:011e95ce78b8 139 if (advData.getPayloadLen() == 0)
ktownsend 29:011e95ce78b8 140 {
ktownsend 29:011e95ce78b8 141 return BLE_ERROR_PARAM_OUT_OF_RANGE;
ktownsend 29:011e95ce78b8 142 }
ktownsend 29:011e95ce78b8 143 }
ktownsend 29:011e95ce78b8 144
ktownsend 29:011e95ce78b8 145 /* ToDo: Perform some checks on the payload, for example the Scan Response can't */
ktownsend 29:011e95ce78b8 146 /* contains a flags AD type, etc. */
ktownsend 29:011e95ce78b8 147
ktownsend 29:011e95ce78b8 148 /* ToDo: Refactor these actions into separate private functions */
ktownsend 29:011e95ce78b8 149
ktownsend 29:011e95ce78b8 150 /* 1.) Send advertising params, Command IDs = 0x000C, 0x000D, 0x000E */
ktownsend 29:011e95ce78b8 151 /* A.) Command ID = 0x000C, Advertising Interval, uint16_t */
ktownsend 29:011e95ce78b8 152 uart.printf("10 0C 00 02 %02X %02X\r\n", (uint8_t)(params.getInterval() & 0xFF),
ktownsend 29:011e95ce78b8 153 (uint8_t)(params.getInterval() >> 8));
ktownsend 29:011e95ce78b8 154 /* ToDo: Check response */
ktownsend 29:011e95ce78b8 155 wait(0.5);
ktownsend 29:011e95ce78b8 156
ktownsend 29:011e95ce78b8 157 /* B.) Command ID = 0x000D, Advertising Timeout, uint16_t */
ktownsend 29:011e95ce78b8 158 uart.printf("10 0D 00 02 %02X %02X\r\n", (uint8_t)(params.getTimeout() & 0xFF),
ktownsend 29:011e95ce78b8 159 (uint8_t)(params.getTimeout() >> 8));
ktownsend 29:011e95ce78b8 160 /* ToDo: Check response */
ktownsend 29:011e95ce78b8 161 wait(0.5);
ktownsend 29:011e95ce78b8 162
ktownsend 29:011e95ce78b8 163 /* C.) Command ID = 0x000E, Advertising Type, uint8_t */
ktownsend 29:011e95ce78b8 164 uart.printf("10 0E 00 01 %02X\r\n", (uint8_t)(params.getAdvertisingType()));
ktownsend 29:011e95ce78b8 165 /* ToDo: Check response */
ktownsend 29:011e95ce78b8 166 wait(0.5);
ktownsend 29:011e95ce78b8 167
ktownsend 29:011e95ce78b8 168 /* 2.) Send advertising data, Command ID = 0x000A */
ktownsend 29:011e95ce78b8 169 len = advData.getPayloadLen();
ktownsend 29:011e95ce78b8 170 buffer = advData.getPayload();
ktownsend 29:011e95ce78b8 171 uart.printf("10 0A 00 %02X", len);
ktownsend 29:011e95ce78b8 172 for (uint16_t i = 0; i < len; i++)
ktownsend 29:011e95ce78b8 173 {
ktownsend 29:011e95ce78b8 174 uart.printf(" %02X", buffer[i]);
ktownsend 29:011e95ce78b8 175 }
ktownsend 29:011e95ce78b8 176 uart.printf("\r\n");
ktownsend 29:011e95ce78b8 177
ktownsend 29:011e95ce78b8 178 /* ToDo: Check response */
ktownsend 29:011e95ce78b8 179 wait(0.1);
ktownsend 29:011e95ce78b8 180
ktownsend 29:011e95ce78b8 181 /* 3.) Send scan response data, Command ID = 0x000B */
ktownsend 29:011e95ce78b8 182 if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED))
ktownsend 29:011e95ce78b8 183 {
ktownsend 29:011e95ce78b8 184 len = scanResponse.getPayloadLen();
ktownsend 29:011e95ce78b8 185 buffer = scanResponse.getPayload();
ktownsend 29:011e95ce78b8 186 uart.printf("10 0B 00 %02X", len);
ktownsend 29:011e95ce78b8 187 for (uint16_t i = 0; i < len; i++)
ktownsend 29:011e95ce78b8 188 {
ktownsend 29:011e95ce78b8 189 uart.printf(" %02X", buffer[i]);
ktownsend 29:011e95ce78b8 190 }
ktownsend 29:011e95ce78b8 191 uart.printf("\r\n");
ktownsend 29:011e95ce78b8 192
ktownsend 29:011e95ce78b8 193 /* ToDo: Check response */
ktownsend 29:011e95ce78b8 194 wait(0.1);
ktownsend 29:011e95ce78b8 195 }
ktownsend 29:011e95ce78b8 196
ktownsend 29:011e95ce78b8 197 return BLE_ERROR_NONE;
ktownsend 29:011e95ce78b8 198 }
ktownsend 29:011e95ce78b8 199
ktownsend 29:011e95ce78b8 200 /**************************************************************************/
ktownsend 29:011e95ce78b8 201 /*!
ktownsend 29:011e95ce78b8 202 @brief Starts the BLE HW, initialising any services that were
ktownsend 29:011e95ce78b8 203 added before this function was called.
ktownsend 29:011e95ce78b8 204
ktownsend 29:011e95ce78b8 205 @note All services must be added before calling this function!
ktownsend 29:011e95ce78b8 206
ktownsend 29:011e95ce78b8 207 @returns ble_error_t
ktownsend 29:011e95ce78b8 208
ktownsend 29:011e95ce78b8 209 @retval BLE_ERROR_NONE
ktownsend 29:011e95ce78b8 210 Everything executed properly
ktownsend 29:011e95ce78b8 211
ktownsend 29:011e95ce78b8 212 @section EXAMPLE
ktownsend 29:011e95ce78b8 213
ktownsend 29:011e95ce78b8 214 @code
ktownsend 29:011e95ce78b8 215
ktownsend 29:011e95ce78b8 216 @endcode
ktownsend 29:011e95ce78b8 217 */
ktownsend 29:011e95ce78b8 218 /**************************************************************************/
ktownsend 29:011e95ce78b8 219 ble_error_t nRF51Gap::startAdvertising(void)
ktownsend 29:011e95ce78b8 220 {
ktownsend 29:011e95ce78b8 221 /* Command ID = 0x0003, No payload */
ktownsend 29:011e95ce78b8 222 uart.printf("10 03 00 00\r\n");
ktownsend 29:011e95ce78b8 223
ktownsend 29:011e95ce78b8 224 /* ToDo: Check response */
ktownsend 29:011e95ce78b8 225 wait(0.5);
ktownsend 29:011e95ce78b8 226
ktownsend 29:011e95ce78b8 227 return BLE_ERROR_NONE;
ktownsend 29:011e95ce78b8 228 }
ktownsend 29:011e95ce78b8 229
ktownsend 29:011e95ce78b8 230 /**************************************************************************/
ktownsend 29:011e95ce78b8 231 /*!
ktownsend 29:011e95ce78b8 232 @brief Stops the BLE HW and disconnects from any devices
ktownsend 29:011e95ce78b8 233
ktownsend 29:011e95ce78b8 234 @returns ble_error_t
ktownsend 29:011e95ce78b8 235
ktownsend 29:011e95ce78b8 236 @retval BLE_ERROR_NONE
ktownsend 29:011e95ce78b8 237 Everything executed properly
ktownsend 29:011e95ce78b8 238
ktownsend 29:011e95ce78b8 239 @section EXAMPLE
ktownsend 29:011e95ce78b8 240
ktownsend 29:011e95ce78b8 241 @code
ktownsend 29:011e95ce78b8 242
ktownsend 29:011e95ce78b8 243 @endcode
ktownsend 29:011e95ce78b8 244 */
ktownsend 29:011e95ce78b8 245 /**************************************************************************/
ktownsend 29:011e95ce78b8 246 ble_error_t nRF51Gap::stopAdvertising(void)
ktownsend 29:011e95ce78b8 247 {
ktownsend 29:011e95ce78b8 248 /* Command ID = 0x0004, No payload */
ktownsend 29:011e95ce78b8 249 uart.printf("10 04 00 00\r\n");
ktownsend 29:011e95ce78b8 250
ktownsend 29:011e95ce78b8 251 /* ToDo: Check response */
ktownsend 29:011e95ce78b8 252 wait(0.1);
ktownsend 29:011e95ce78b8 253
ktownsend 29:011e95ce78b8 254 return BLE_ERROR_NONE;
ktownsend 29:011e95ce78b8 255 }