IOTIO

Fork of Nucleo_BLE_API by ST Americas mbed Team

Committer:
sjallouli
Date:
Fri Dec 19 18:54:46 2014 +0000
Revision:
0:289fd2dae405
BLE_API for Nucleo Bluetoothe Low Energy Shield

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sjallouli 0:289fd2dae405 1 /* mbed Microcontroller Library
sjallouli 0:289fd2dae405 2 * Copyright (c) 2006-2013 ARM Limited
sjallouli 0:289fd2dae405 3 *
sjallouli 0:289fd2dae405 4 * Licensed under the Apache License, Version 2.0 (the "License");
sjallouli 0:289fd2dae405 5 * you may not use this file except in compliance with the License.
sjallouli 0:289fd2dae405 6 * You may obtain a copy of the License at
sjallouli 0:289fd2dae405 7 *
sjallouli 0:289fd2dae405 8 * http://www.apache.org/licenses/LICENSE-2.0
sjallouli 0:289fd2dae405 9 *
sjallouli 0:289fd2dae405 10 * Unless required by applicable law or agreed to in writing, software
sjallouli 0:289fd2dae405 11 * distributed under the License is distributed on an "AS IS" BASIS,
sjallouli 0:289fd2dae405 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
sjallouli 0:289fd2dae405 13 * See the License for the specific language governing permissions and
sjallouli 0:289fd2dae405 14 * limitations under the License.
sjallouli 0:289fd2dae405 15 */
sjallouli 0:289fd2dae405 16
sjallouli 0:289fd2dae405 17 #ifndef __BLE_DEVICE__
sjallouli 0:289fd2dae405 18 #define __BLE_DEVICE__
sjallouli 0:289fd2dae405 19
sjallouli 0:289fd2dae405 20 #include "mbed.h"
sjallouli 0:289fd2dae405 21 #include "blecommon.h"
sjallouli 0:289fd2dae405 22 #include "Gap.h"
sjallouli 0:289fd2dae405 23 #include "GattServer.h"
sjallouli 0:289fd2dae405 24 #include "BLEDeviceInstanceBase.h"
sjallouli 0:289fd2dae405 25
sjallouli 0:289fd2dae405 26 /**
sjallouli 0:289fd2dae405 27 * The base class used to abstract away BLE capable radio transceivers or SOCs,
sjallouli 0:289fd2dae405 28 * to enable this BLE API to work with any radio transparently.
sjallouli 0:289fd2dae405 29 */
sjallouli 0:289fd2dae405 30 class BLEDevice
sjallouli 0:289fd2dae405 31 {
sjallouli 0:289fd2dae405 32 public:
sjallouli 0:289fd2dae405 33 /**
sjallouli 0:289fd2dae405 34 * Initialize the BLE controller. This should be called before using
sjallouli 0:289fd2dae405 35 * anything else in the BLE_API.
sjallouli 0:289fd2dae405 36 */
sjallouli 0:289fd2dae405 37 ble_error_t init();
sjallouli 0:289fd2dae405 38 ble_error_t reset(void);
sjallouli 0:289fd2dae405 39
sjallouli 0:289fd2dae405 40 /* GAP specific APIs */
sjallouli 0:289fd2dae405 41 public:
sjallouli 0:289fd2dae405 42 /**
sjallouli 0:289fd2dae405 43 * Set the BTLE MAC address and type.
sjallouli 0:289fd2dae405 44 * @return
sjallouli 0:289fd2dae405 45 */
sjallouli 0:289fd2dae405 46 ble_error_t setAddress(Gap::addr_type_t type, const uint8_t address[6]);
sjallouli 0:289fd2dae405 47
sjallouli 0:289fd2dae405 48 /**
sjallouli 0:289fd2dae405 49 * @param[in] advType
sjallouli 0:289fd2dae405 50 * The GAP advertising mode to use for this device. Valid
sjallouli 0:289fd2dae405 51 * values are defined in AdvertisingType:
sjallouli 0:289fd2dae405 52 *
sjallouli 0:289fd2dae405 53 * \par ADV_NON_CONNECTABLE_UNDIRECTED
sjallouli 0:289fd2dae405 54 * All connections to the peripheral device will be refused.
sjallouli 0:289fd2dae405 55 *
sjallouli 0:289fd2dae405 56 * \par ADV_CONNECTABLE_DIRECTED
sjallouli 0:289fd2dae405 57 * Only connections from a pre-defined central device will be
sjallouli 0:289fd2dae405 58 * accepted.
sjallouli 0:289fd2dae405 59 *
sjallouli 0:289fd2dae405 60 * \par ADV_CONNECTABLE_UNDIRECTED
sjallouli 0:289fd2dae405 61 * Any central device can connect to this peripheral.
sjallouli 0:289fd2dae405 62 *
sjallouli 0:289fd2dae405 63 * \par ADV_SCANNABLE_UNDIRECTED
sjallouli 0:289fd2dae405 64 * Any central device can connect to this peripheral, and
sjallouli 0:289fd2dae405 65 * the secondary Scan Response payload will be included or
sjallouli 0:289fd2dae405 66 * available to central devices.
sjallouli 0:289fd2dae405 67 *
sjallouli 0:289fd2dae405 68 * \par
sjallouli 0:289fd2dae405 69 * See Bluetooth Core Specification 4.0 (Vol. 3), Part C,
sjallouli 0:289fd2dae405 70 * Section 9.3 and Core Specification 4.0 (Vol. 6), Part B,
sjallouli 0:289fd2dae405 71 * Section 2.3.1 for further information on GAP connection
sjallouli 0:289fd2dae405 72 * modes
sjallouli 0:289fd2dae405 73 */
sjallouli 0:289fd2dae405 74 void setAdvertisingType(GapAdvertisingParams::AdvertisingType);
sjallouli 0:289fd2dae405 75
sjallouli 0:289fd2dae405 76 /**
sjallouli 0:289fd2dae405 77 * @param[in] interval
sjallouli 0:289fd2dae405 78 * Advertising interval between 0x0020 and 0x4000 in 0.625ms
sjallouli 0:289fd2dae405 79 * units (20ms to 10.24s). If using non-connectable mode
sjallouli 0:289fd2dae405 80 * (ADV_NON_CONNECTABLE_UNDIRECTED) this min value is
sjallouli 0:289fd2dae405 81 * 0x00A0 (100ms). To reduce the likelihood of collisions, the
sjallouli 0:289fd2dae405 82 * link layer perturbs this interval by a pseudo-random delay
sjallouli 0:289fd2dae405 83 * with a range of 0 ms to 10 ms for each advertising event.
sjallouli 0:289fd2dae405 84 *
sjallouli 0:289fd2dae405 85 * \par
sjallouli 0:289fd2dae405 86 * Decreasing this value will allow central devices to detect
sjallouli 0:289fd2dae405 87 * your peripheral faster at the expense of more power being
sjallouli 0:289fd2dae405 88 * used by the radio due to the higher data transmit rate.
sjallouli 0:289fd2dae405 89 *
sjallouli 0:289fd2dae405 90 * \par
sjallouli 0:289fd2dae405 91 * This field must be set to 0 if connectionMode is equal
sjallouli 0:289fd2dae405 92 * to ADV_CONNECTABLE_DIRECTED
sjallouli 0:289fd2dae405 93 *
sjallouli 0:289fd2dae405 94 * \par
sjallouli 0:289fd2dae405 95 * See Bluetooth Core Specification, Vol 3., Part C,
sjallouli 0:289fd2dae405 96 * Appendix A for suggested advertising intervals.
sjallouli 0:289fd2dae405 97 */
sjallouli 0:289fd2dae405 98 void setAdvertisingInterval(uint16_t interval);
sjallouli 0:289fd2dae405 99
sjallouli 0:289fd2dae405 100 /**
sjallouli 0:289fd2dae405 101 * @param[in] timeout
sjallouli 0:289fd2dae405 102 * Advertising timeout between 0x1 and 0x3FFF (1 and 16383)
sjallouli 0:289fd2dae405 103 * in seconds. Enter 0 to disable the advertising timeout.
sjallouli 0:289fd2dae405 104 */
sjallouli 0:289fd2dae405 105 void setAdvertisingTimeout(uint16_t timeout);
sjallouli 0:289fd2dae405 106
sjallouli 0:289fd2dae405 107 /**
sjallouli 0:289fd2dae405 108 * Please refer to the APIs above.
sjallouli 0:289fd2dae405 109 */
sjallouli 0:289fd2dae405 110 void setAdvertisingParams(const GapAdvertisingParams &advParams);
sjallouli 0:289fd2dae405 111
sjallouli 0:289fd2dae405 112 /**
sjallouli 0:289fd2dae405 113 * This API is typically used as an internal helper to udpate the transport
sjallouli 0:289fd2dae405 114 * backend with advertising data before starting to advertise. It may also
sjallouli 0:289fd2dae405 115 * be explicity used to dynamically reset the accumulated advertising
sjallouli 0:289fd2dae405 116 * payload and scanResponse; to do this, the application can clear and re-
sjallouli 0:289fd2dae405 117 * accumulate a new advertising payload (and scanResponse) before using this
sjallouli 0:289fd2dae405 118 * API.
sjallouli 0:289fd2dae405 119 */
sjallouli 0:289fd2dae405 120 ble_error_t setAdvertisingPayload(void);
sjallouli 0:289fd2dae405 121
sjallouli 0:289fd2dae405 122 /**
sjallouli 0:289fd2dae405 123 * Reset any advertising payload prepared from prior calls to
sjallouli 0:289fd2dae405 124 * accumulateAdvertisingPayload().
sjallouli 0:289fd2dae405 125 */
sjallouli 0:289fd2dae405 126 void clearAdvertisingPayload(void);
sjallouli 0:289fd2dae405 127
sjallouli 0:289fd2dae405 128 /**
sjallouli 0:289fd2dae405 129 * Accumulate an AD structure in the advertising payload. Please note that
sjallouli 0:289fd2dae405 130 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
sjallouli 0:289fd2dae405 131 * as an additional 31 bytes if the advertising payload proves to be too
sjallouli 0:289fd2dae405 132 * small.
sjallouli 0:289fd2dae405 133 *
sjallouli 0:289fd2dae405 134 * @param flags
sjallouli 0:289fd2dae405 135 * The flags to be added. Multiple flags may be specified in
sjallouli 0:289fd2dae405 136 * combination.
sjallouli 0:289fd2dae405 137 */
sjallouli 0:289fd2dae405 138 ble_error_t accumulateAdvertisingPayload(uint8_t flags);
sjallouli 0:289fd2dae405 139
sjallouli 0:289fd2dae405 140 /**
sjallouli 0:289fd2dae405 141 * Accumulate an AD structure in the advertising payload. Please note that
sjallouli 0:289fd2dae405 142 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
sjallouli 0:289fd2dae405 143 * as an additional 31 bytes if the advertising payload proves to be too
sjallouli 0:289fd2dae405 144 * small.
sjallouli 0:289fd2dae405 145 *
sjallouli 0:289fd2dae405 146 * @param app
sjallouli 0:289fd2dae405 147 * The appearance of the peripheral.
sjallouli 0:289fd2dae405 148 */
sjallouli 0:289fd2dae405 149 ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app);
sjallouli 0:289fd2dae405 150
sjallouli 0:289fd2dae405 151 /**
sjallouli 0:289fd2dae405 152 * Accumulate an AD structure in the advertising payload. Please note that
sjallouli 0:289fd2dae405 153 * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
sjallouli 0:289fd2dae405 154 * as an additional 31 bytes if the advertising payload proves to be too
sjallouli 0:289fd2dae405 155 * small.
sjallouli 0:289fd2dae405 156 *
sjallouli 0:289fd2dae405 157 * @param app
sjallouli 0:289fd2dae405 158 * The max transmit power to be used by the controller. This is
sjallouli 0:289fd2dae405 159 * only a hint.
sjallouli 0:289fd2dae405 160 */
sjallouli 0:289fd2dae405 161 ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power);
sjallouli 0:289fd2dae405 162
sjallouli 0:289fd2dae405 163 /**
sjallouli 0:289fd2dae405 164 * Accumulate a variable length byte-stream as an AD structure in the
sjallouli 0:289fd2dae405 165 * advertising payload. Please note that the payload is limited to 31 bytes.
sjallouli 0:289fd2dae405 166 * The SCAN_RESPONSE message may be used as an additional 31 bytes if the
sjallouli 0:289fd2dae405 167 * advertising payload proves to be too small.
sjallouli 0:289fd2dae405 168 *
sjallouli 0:289fd2dae405 169 * @param type The type which describes the variable length data.
sjallouli 0:289fd2dae405 170 * @param data data bytes.
sjallouli 0:289fd2dae405 171 * @param len length of data.
sjallouli 0:289fd2dae405 172 */
sjallouli 0:289fd2dae405 173 ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len);
sjallouli 0:289fd2dae405 174
sjallouli 0:289fd2dae405 175 /**
sjallouli 0:289fd2dae405 176 * Accumulate a variable length byte-stream as an AD structure in the
sjallouli 0:289fd2dae405 177 * scanResponse payload.
sjallouli 0:289fd2dae405 178 *
sjallouli 0:289fd2dae405 179 * @param type The type which describes the variable length data.
sjallouli 0:289fd2dae405 180 * @param data data bytes.
sjallouli 0:289fd2dae405 181 * @param len length of data.
sjallouli 0:289fd2dae405 182 */
sjallouli 0:289fd2dae405 183 ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len);
sjallouli 0:289fd2dae405 184
sjallouli 0:289fd2dae405 185 /**
sjallouli 0:289fd2dae405 186 * Start advertising (GAP Discoverable, Connectable modes, Broadcast
sjallouli 0:289fd2dae405 187 * Procedure).
sjallouli 0:289fd2dae405 188 */
sjallouli 0:289fd2dae405 189 ble_error_t startAdvertising(void);
sjallouli 0:289fd2dae405 190
sjallouli 0:289fd2dae405 191 /**
sjallouli 0:289fd2dae405 192 * Stop advertising (GAP Discoverable, Connectable modes, Broadcast
sjallouli 0:289fd2dae405 193 * Procedure).
sjallouli 0:289fd2dae405 194 */
sjallouli 0:289fd2dae405 195 ble_error_t stopAdvertising(void);
sjallouli 0:289fd2dae405 196
sjallouli 0:289fd2dae405 197 ble_error_t disconnect(Gap::DisconnectionReason_t reason);
sjallouli 0:289fd2dae405 198
sjallouli 0:289fd2dae405 199 /* APIs to set GAP callbacks. */
sjallouli 0:289fd2dae405 200 void onTimeout(Gap::EventCallback_t timeoutCallback);
sjallouli 0:289fd2dae405 201
sjallouli 0:289fd2dae405 202 void onConnection(Gap::ConnectionEventCallback_t connectionCallback);
sjallouli 0:289fd2dae405 203 /**
sjallouli 0:289fd2dae405 204 * Used to setup a callback for GAP disconnection.
sjallouli 0:289fd2dae405 205 */
sjallouli 0:289fd2dae405 206 void onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback);
sjallouli 0:289fd2dae405 207
sjallouli 0:289fd2dae405 208 /**
sjallouli 0:289fd2dae405 209 * Setup a callback for the GATT event DATA_SENT.
sjallouli 0:289fd2dae405 210 */
sjallouli 0:289fd2dae405 211 void onDataSent(GattServer::ServerEventCallbackWithCount_t callback);
sjallouli 0:289fd2dae405 212
sjallouli 0:289fd2dae405 213 /**
sjallouli 0:289fd2dae405 214 * Setup a callback for when a characteristic has its value updated by a
sjallouli 0:289fd2dae405 215 * client.
sjallouli 0:289fd2dae405 216 *
sjallouli 0:289fd2dae405 217 * @Note: it is possible to chain together multiple onDataWritten callbacks
sjallouli 0:289fd2dae405 218 * (potentially from different modules of an application) to receive updates
sjallouli 0:289fd2dae405 219 * to characteristics. Many services, such as DFU and UART add their own
sjallouli 0:289fd2dae405 220 * onDataWritten callbacks behind the scenes to trap interesting events.
sjallouli 0:289fd2dae405 221 *
sjallouli 0:289fd2dae405 222 * @Note: it is also possible to setup a callback into a member function of
sjallouli 0:289fd2dae405 223 * some object.
sjallouli 0:289fd2dae405 224 */
sjallouli 0:289fd2dae405 225 void onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP));
sjallouli 0:289fd2dae405 226 template <typename T> void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context));
sjallouli 0:289fd2dae405 227
sjallouli 0:289fd2dae405 228 void onUpdatesEnabled(GattServer::EventCallback_t callback);
sjallouli 0:289fd2dae405 229 void onUpdatesDisabled(GattServer::EventCallback_t callback);
sjallouli 0:289fd2dae405 230 void onConfirmationReceived(GattServer::EventCallback_t callback);
sjallouli 0:289fd2dae405 231
sjallouli 0:289fd2dae405 232 /**
sjallouli 0:289fd2dae405 233 * Add a service declaration to the local server ATT table. Also add the
sjallouli 0:289fd2dae405 234 * characteristics contained within.
sjallouli 0:289fd2dae405 235 */
sjallouli 0:289fd2dae405 236 ble_error_t addService(GattService &service);
sjallouli 0:289fd2dae405 237
sjallouli 0:289fd2dae405 238 Gap::GapState_t getGapState(void) const;
sjallouli 0:289fd2dae405 239
sjallouli 0:289fd2dae405 240 /**
sjallouli 0:289fd2dae405 241 * @param[in/out] lengthP
sjallouli 0:289fd2dae405 242 * input: Length in bytes to be read,
sjallouli 0:289fd2dae405 243 * output: Total length of attribute value upon successful return.
sjallouli 0:289fd2dae405 244 */
sjallouli 0:289fd2dae405 245 ble_error_t readCharacteristicValue(uint16_t handle, uint8_t *const buffer, uint16_t *const lengthP);
sjallouli 0:289fd2dae405 246
sjallouli 0:289fd2dae405 247 /**
sjallouli 0:289fd2dae405 248 * @param localOnly
sjallouli 0:289fd2dae405 249 * Only update the characteristic locally regardless of notify/indicate flags in the CCCD.
sjallouli 0:289fd2dae405 250 */
sjallouli 0:289fd2dae405 251 ble_error_t updateCharacteristicValue(uint16_t handle, const uint8_t* value, uint16_t size, bool localOnly = false);
sjallouli 0:289fd2dae405 252
sjallouli 0:289fd2dae405 253 /**
sjallouli 0:289fd2dae405 254 * Yield control to the BLE stack or to other tasks waiting for events. This
sjallouli 0:289fd2dae405 255 * is a sleep function which will return when there is an application
sjallouli 0:289fd2dae405 256 * specific interrupt, but the MCU might wake up several times before
sjallouli 0:289fd2dae405 257 * returning (to service the stack). This is not always interchangeable with
sjallouli 0:289fd2dae405 258 * WFE().
sjallouli 0:289fd2dae405 259 */
sjallouli 0:289fd2dae405 260 void waitForEvent(void);
sjallouli 0:289fd2dae405 261
sjallouli 0:289fd2dae405 262 ble_error_t getPreferredConnectionParams(Gap::ConnectionParams_t *params);
sjallouli 0:289fd2dae405 263 ble_error_t setPreferredConnectionParams(const Gap::ConnectionParams_t *params);
sjallouli 0:289fd2dae405 264 ble_error_t updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params);
sjallouli 0:289fd2dae405 265
sjallouli 0:289fd2dae405 266 /**
sjallouli 0:289fd2dae405 267 * This call allows the application to get the BLE stack version information.
sjallouli 0:289fd2dae405 268 *
sjallouli 0:289fd2dae405 269 * @return A pointer to a const string representing the version.
sjallouli 0:289fd2dae405 270 * Note: The string is owned by the BLE_API.
sjallouli 0:289fd2dae405 271 */
sjallouli 0:289fd2dae405 272 const char *getVersion(void);
sjallouli 0:289fd2dae405 273
sjallouli 0:289fd2dae405 274 /**
sjallouli 0:289fd2dae405 275 * Set the device name characteristic in the GAP service.
sjallouli 0:289fd2dae405 276 * @param deviceName The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string.
sjallouli 0:289fd2dae405 277 */
sjallouli 0:289fd2dae405 278 ble_error_t setDeviceName(const uint8_t *deviceName);
sjallouli 0:289fd2dae405 279
sjallouli 0:289fd2dae405 280 /**
sjallouli 0:289fd2dae405 281 * Get the value of the device name characteristic in the GAP service.
sjallouli 0:289fd2dae405 282 * @param[out] deviceName Pointer to an empty buffer where the UTF-8 *non NULL-
sjallouli 0:289fd2dae405 283 * terminated* string will be placed. Set this
sjallouli 0:289fd2dae405 284 * value to NULL in order to obtain the deviceName-length
sjallouli 0:289fd2dae405 285 * from the 'length' parameter.
sjallouli 0:289fd2dae405 286 *
sjallouli 0:289fd2dae405 287 * @param[in/out] lengthP (on input) Length of the buffer pointed to by deviceName;
sjallouli 0:289fd2dae405 288 * (on output) the complete device name length (without the
sjallouli 0:289fd2dae405 289 * null terminator).
sjallouli 0:289fd2dae405 290 *
sjallouli 0:289fd2dae405 291 * @note If the device name is longer than the size of the supplied buffer,
sjallouli 0:289fd2dae405 292 * length will return the complete device name length,
sjallouli 0:289fd2dae405 293 * and not the number of bytes actually returned in deviceName.
sjallouli 0:289fd2dae405 294 * The application may use this information to retry with a suitable buffer size.
sjallouli 0:289fd2dae405 295 *
sjallouli 0:289fd2dae405 296 * Sample use:
sjallouli 0:289fd2dae405 297 * uint8_t deviceName[20];
sjallouli 0:289fd2dae405 298 * unsigned length = sizeof(deviceName);
sjallouli 0:289fd2dae405 299 * ble.getDeviceName(deviceName, &length);
sjallouli 0:289fd2dae405 300 * if (length < sizeof(deviceName)) {
sjallouli 0:289fd2dae405 301 * deviceName[length] = 0;
sjallouli 0:289fd2dae405 302 * }
sjallouli 0:289fd2dae405 303 * DEBUG("length: %u, deviceName: %s\r\n", length, deviceName);
sjallouli 0:289fd2dae405 304 */
sjallouli 0:289fd2dae405 305 ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP);
sjallouli 0:289fd2dae405 306
sjallouli 0:289fd2dae405 307 /**
sjallouli 0:289fd2dae405 308 * Set the appearance characteristic in the GAP service.
sjallouli 0:289fd2dae405 309 * @param[in] appearance The new value for the device-appearance.
sjallouli 0:289fd2dae405 310 */
sjallouli 0:289fd2dae405 311 ble_error_t setAppearance(uint16_t appearance);
sjallouli 0:289fd2dae405 312
sjallouli 0:289fd2dae405 313 /**
sjallouli 0:289fd2dae405 314 * Set the appearance characteristic in the GAP service.
sjallouli 0:289fd2dae405 315 * @param[out] appearance The new value for the device-appearance.
sjallouli 0:289fd2dae405 316 */
sjallouli 0:289fd2dae405 317 ble_error_t getAppearance(uint16_t *appearanceP);
sjallouli 0:289fd2dae405 318
sjallouli 0:289fd2dae405 319 /**
sjallouli 0:289fd2dae405 320 * Set the radio's transmit power.
sjallouli 0:289fd2dae405 321 * @param[in] txPower Radio transmit power in dBm.
sjallouli 0:289fd2dae405 322 */
sjallouli 0:289fd2dae405 323 ble_error_t setTxPower(int8_t txPower);
sjallouli 0:289fd2dae405 324
sjallouli 0:289fd2dae405 325 public:
sjallouli 0:289fd2dae405 326 BLEDevice() : transport(createBLEDeviceInstance()), advParams(), advPayload(), scanResponse(), needToSetAdvPayload(true) {
sjallouli 0:289fd2dae405 327 advPayload.clear();
sjallouli 0:289fd2dae405 328 scanResponse.clear();
sjallouli 0:289fd2dae405 329 }
sjallouli 0:289fd2dae405 330
sjallouli 0:289fd2dae405 331 private:
sjallouli 0:289fd2dae405 332 BLEDeviceInstanceBase *const transport; /* the device specific backend */
sjallouli 0:289fd2dae405 333
sjallouli 0:289fd2dae405 334 GapAdvertisingParams advParams;
sjallouli 0:289fd2dae405 335 GapAdvertisingData advPayload;
sjallouli 0:289fd2dae405 336 GapAdvertisingData scanResponse;
sjallouli 0:289fd2dae405 337
sjallouli 0:289fd2dae405 338 /* Accumulation of AD structures in the advertisement payload should
sjallouli 0:289fd2dae405 339 * eventually result in a call to the target's setAdvertisingData() before
sjallouli 0:289fd2dae405 340 * the server begins advertising. This flag marks the status of the pending update.*/
sjallouli 0:289fd2dae405 341 bool needToSetAdvPayload;
sjallouli 0:289fd2dae405 342
sjallouli 0:289fd2dae405 343 /**
sjallouli 0:289fd2dae405 344 * DEPRECATED
sjallouli 0:289fd2dae405 345 */
sjallouli 0:289fd2dae405 346 public:
sjallouli 0:289fd2dae405 347 ble_error_t setAdvertisingData(const GapAdvertisingData &ADStructures, const GapAdvertisingData &scanResponse);
sjallouli 0:289fd2dae405 348 ble_error_t setAdvertisingData(const GapAdvertisingData &ADStructures);
sjallouli 0:289fd2dae405 349
sjallouli 0:289fd2dae405 350 ble_error_t startAdvertising(const GapAdvertisingParams &advParams);
sjallouli 0:289fd2dae405 351 };
sjallouli 0:289fd2dae405 352
sjallouli 0:289fd2dae405 353 /* BLEDevice methods. Most of these simply forward the calls to the underlying
sjallouli 0:289fd2dae405 354 * transport.*/
sjallouli 0:289fd2dae405 355
sjallouli 0:289fd2dae405 356 inline ble_error_t
sjallouli 0:289fd2dae405 357 BLEDevice::reset(void)
sjallouli 0:289fd2dae405 358 {
sjallouli 0:289fd2dae405 359 return transport->reset();
sjallouli 0:289fd2dae405 360 }
sjallouli 0:289fd2dae405 361
sjallouli 0:289fd2dae405 362 inline ble_error_t
sjallouli 0:289fd2dae405 363 BLEDevice::setAddress(Gap::addr_type_t type, const uint8_t address[6])
sjallouli 0:289fd2dae405 364 {
sjallouli 0:289fd2dae405 365 return transport->getGap().setAddress(type, address);
sjallouli 0:289fd2dae405 366 }
sjallouli 0:289fd2dae405 367
sjallouli 0:289fd2dae405 368 inline void
sjallouli 0:289fd2dae405 369 BLEDevice::setAdvertisingType(GapAdvertisingParams::AdvertisingType advType)
sjallouli 0:289fd2dae405 370 {
sjallouli 0:289fd2dae405 371 advParams.setAdvertisingType(advType);
sjallouli 0:289fd2dae405 372 }
sjallouli 0:289fd2dae405 373
sjallouli 0:289fd2dae405 374 inline void
sjallouli 0:289fd2dae405 375 BLEDevice::setAdvertisingInterval(uint16_t interval)
sjallouli 0:289fd2dae405 376 {
sjallouli 0:289fd2dae405 377 advParams.setInterval(interval);
sjallouli 0:289fd2dae405 378 }
sjallouli 0:289fd2dae405 379
sjallouli 0:289fd2dae405 380 inline void
sjallouli 0:289fd2dae405 381 BLEDevice::setAdvertisingTimeout(uint16_t timeout)
sjallouli 0:289fd2dae405 382 {
sjallouli 0:289fd2dae405 383 advParams.setTimeout(timeout);
sjallouli 0:289fd2dae405 384 }
sjallouli 0:289fd2dae405 385
sjallouli 0:289fd2dae405 386 inline void
sjallouli 0:289fd2dae405 387 BLEDevice::setAdvertisingParams(const GapAdvertisingParams &newAdvParams)
sjallouli 0:289fd2dae405 388 {
sjallouli 0:289fd2dae405 389 advParams = newAdvParams;
sjallouli 0:289fd2dae405 390 }
sjallouli 0:289fd2dae405 391
sjallouli 0:289fd2dae405 392 inline void
sjallouli 0:289fd2dae405 393 BLEDevice::clearAdvertisingPayload(void)
sjallouli 0:289fd2dae405 394 {
sjallouli 0:289fd2dae405 395 needToSetAdvPayload = true;
sjallouli 0:289fd2dae405 396 advPayload.clear();
sjallouli 0:289fd2dae405 397 }
sjallouli 0:289fd2dae405 398
sjallouli 0:289fd2dae405 399 inline ble_error_t
sjallouli 0:289fd2dae405 400 BLEDevice::accumulateAdvertisingPayload(uint8_t flags)
sjallouli 0:289fd2dae405 401 {
sjallouli 0:289fd2dae405 402 needToSetAdvPayload = true;
sjallouli 0:289fd2dae405 403 return advPayload.addFlags(flags);
sjallouli 0:289fd2dae405 404 }
sjallouli 0:289fd2dae405 405
sjallouli 0:289fd2dae405 406 inline ble_error_t
sjallouli 0:289fd2dae405 407 BLEDevice::accumulateAdvertisingPayload(GapAdvertisingData::Appearance app)
sjallouli 0:289fd2dae405 408 {
sjallouli 0:289fd2dae405 409 needToSetAdvPayload = true;
sjallouli 0:289fd2dae405 410 return advPayload.addAppearance(app);
sjallouli 0:289fd2dae405 411 }
sjallouli 0:289fd2dae405 412
sjallouli 0:289fd2dae405 413 inline ble_error_t
sjallouli 0:289fd2dae405 414 BLEDevice::accumulateAdvertisingPayloadTxPower(int8_t txPower)
sjallouli 0:289fd2dae405 415 {
sjallouli 0:289fd2dae405 416 needToSetAdvPayload = true;
sjallouli 0:289fd2dae405 417 return advPayload.addTxPower(txPower);
sjallouli 0:289fd2dae405 418 }
sjallouli 0:289fd2dae405 419
sjallouli 0:289fd2dae405 420 inline ble_error_t
sjallouli 0:289fd2dae405 421 BLEDevice::accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len)
sjallouli 0:289fd2dae405 422 {
sjallouli 0:289fd2dae405 423 needToSetAdvPayload = true;
sjallouli 0:289fd2dae405 424 return advPayload.addData(type, data, len);
sjallouli 0:289fd2dae405 425 }
sjallouli 0:289fd2dae405 426
sjallouli 0:289fd2dae405 427 inline ble_error_t
sjallouli 0:289fd2dae405 428 BLEDevice::accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len)
sjallouli 0:289fd2dae405 429 {
sjallouli 0:289fd2dae405 430 needToSetAdvPayload = true;
sjallouli 0:289fd2dae405 431 return scanResponse.addData(type, data, len);
sjallouli 0:289fd2dae405 432 }
sjallouli 0:289fd2dae405 433
sjallouli 0:289fd2dae405 434 inline ble_error_t
sjallouli 0:289fd2dae405 435 BLEDevice::setAdvertisingPayload(void) {
sjallouli 0:289fd2dae405 436 needToSetAdvPayload = false;
sjallouli 0:289fd2dae405 437 return transport->getGap().setAdvertisingData(advPayload, scanResponse);
sjallouli 0:289fd2dae405 438 }
sjallouli 0:289fd2dae405 439
sjallouli 0:289fd2dae405 440 inline ble_error_t
sjallouli 0:289fd2dae405 441 BLEDevice::startAdvertising(void)
sjallouli 0:289fd2dae405 442 {
sjallouli 0:289fd2dae405 443 if (needToSetAdvPayload) {
sjallouli 0:289fd2dae405 444 ble_error_t rc;
sjallouli 0:289fd2dae405 445 if ((rc = setAdvertisingPayload()) != BLE_ERROR_NONE) {
sjallouli 0:289fd2dae405 446 return rc;
sjallouli 0:289fd2dae405 447 }
sjallouli 0:289fd2dae405 448 }
sjallouli 0:289fd2dae405 449
sjallouli 0:289fd2dae405 450 return transport->getGap().startAdvertising(advParams);
sjallouli 0:289fd2dae405 451 }
sjallouli 0:289fd2dae405 452
sjallouli 0:289fd2dae405 453 inline ble_error_t
sjallouli 0:289fd2dae405 454 BLEDevice::stopAdvertising(void)
sjallouli 0:289fd2dae405 455 {
sjallouli 0:289fd2dae405 456 return transport->getGap().stopAdvertising();
sjallouli 0:289fd2dae405 457 }
sjallouli 0:289fd2dae405 458
sjallouli 0:289fd2dae405 459 inline ble_error_t
sjallouli 0:289fd2dae405 460 BLEDevice::disconnect(Gap::DisconnectionReason_t reason)
sjallouli 0:289fd2dae405 461 {
sjallouli 0:289fd2dae405 462 return transport->getGap().disconnect(reason);
sjallouli 0:289fd2dae405 463 }
sjallouli 0:289fd2dae405 464
sjallouli 0:289fd2dae405 465 inline void
sjallouli 0:289fd2dae405 466 BLEDevice::onTimeout(Gap::EventCallback_t timeoutCallback)
sjallouli 0:289fd2dae405 467 {
sjallouli 0:289fd2dae405 468 transport->getGap().setOnTimeout(timeoutCallback);
sjallouli 0:289fd2dae405 469 }
sjallouli 0:289fd2dae405 470
sjallouli 0:289fd2dae405 471 inline void
sjallouli 0:289fd2dae405 472 BLEDevice::onConnection(Gap::ConnectionEventCallback_t connectionCallback)
sjallouli 0:289fd2dae405 473 {
sjallouli 0:289fd2dae405 474 transport->getGap().setOnConnection(connectionCallback);
sjallouli 0:289fd2dae405 475 }
sjallouli 0:289fd2dae405 476
sjallouli 0:289fd2dae405 477 inline void
sjallouli 0:289fd2dae405 478 BLEDevice::onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback)
sjallouli 0:289fd2dae405 479 {
sjallouli 0:289fd2dae405 480 transport->getGap().setOnDisconnection(disconnectionCallback);
sjallouli 0:289fd2dae405 481 }
sjallouli 0:289fd2dae405 482
sjallouli 0:289fd2dae405 483 inline void
sjallouli 0:289fd2dae405 484 BLEDevice::onDataSent(GattServer::ServerEventCallbackWithCount_t callback)
sjallouli 0:289fd2dae405 485 {
sjallouli 0:289fd2dae405 486 transport->getGattServer().setOnDataSent(callback);
sjallouli 0:289fd2dae405 487 }
sjallouli 0:289fd2dae405 488
sjallouli 0:289fd2dae405 489 inline void
sjallouli 0:289fd2dae405 490 BLEDevice::onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)) {
sjallouli 0:289fd2dae405 491 transport->getGattServer().setOnDataWritten(callback);
sjallouli 0:289fd2dae405 492 }
sjallouli 0:289fd2dae405 493
sjallouli 0:289fd2dae405 494 template <typename T> inline void
sjallouli 0:289fd2dae405 495 BLEDevice::onDataWritten(T *objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)) {
sjallouli 0:289fd2dae405 496 transport->getGattServer().setOnDataWritten(objPtr, memberPtr);
sjallouli 0:289fd2dae405 497 }
sjallouli 0:289fd2dae405 498
sjallouli 0:289fd2dae405 499
sjallouli 0:289fd2dae405 500 inline void
sjallouli 0:289fd2dae405 501 BLEDevice::onUpdatesEnabled(GattServer::EventCallback_t callback)
sjallouli 0:289fd2dae405 502 {
sjallouli 0:289fd2dae405 503 transport->getGattServer().setOnUpdatesEnabled(callback);
sjallouli 0:289fd2dae405 504 }
sjallouli 0:289fd2dae405 505
sjallouli 0:289fd2dae405 506 inline void
sjallouli 0:289fd2dae405 507 BLEDevice::onUpdatesDisabled(GattServer::EventCallback_t callback)
sjallouli 0:289fd2dae405 508 {
sjallouli 0:289fd2dae405 509 transport->getGattServer().setOnUpdatesDisabled(callback);
sjallouli 0:289fd2dae405 510 }
sjallouli 0:289fd2dae405 511
sjallouli 0:289fd2dae405 512 inline void
sjallouli 0:289fd2dae405 513 BLEDevice::onConfirmationReceived(GattServer::EventCallback_t callback)
sjallouli 0:289fd2dae405 514 {
sjallouli 0:289fd2dae405 515 transport->getGattServer().setOnConfirmationReceived(callback);
sjallouli 0:289fd2dae405 516 }
sjallouli 0:289fd2dae405 517
sjallouli 0:289fd2dae405 518 inline ble_error_t
sjallouli 0:289fd2dae405 519 BLEDevice::addService(GattService &service)
sjallouli 0:289fd2dae405 520 {
sjallouli 0:289fd2dae405 521 return transport->getGattServer().addService(service);
sjallouli 0:289fd2dae405 522 }
sjallouli 0:289fd2dae405 523
sjallouli 0:289fd2dae405 524 inline Gap::GapState_t
sjallouli 0:289fd2dae405 525 BLEDevice::getGapState(void) const
sjallouli 0:289fd2dae405 526 {
sjallouli 0:289fd2dae405 527 return transport->getGap().getState();
sjallouli 0:289fd2dae405 528 }
sjallouli 0:289fd2dae405 529
sjallouli 0:289fd2dae405 530 inline ble_error_t BLEDevice::readCharacteristicValue(uint16_t handle, uint8_t *const buffer, uint16_t *const lengthP)
sjallouli 0:289fd2dae405 531 {
sjallouli 0:289fd2dae405 532 return transport->getGattServer().readValue(handle, buffer, lengthP);
sjallouli 0:289fd2dae405 533 }
sjallouli 0:289fd2dae405 534
sjallouli 0:289fd2dae405 535 inline ble_error_t
sjallouli 0:289fd2dae405 536 BLEDevice::updateCharacteristicValue(uint16_t handle, const uint8_t* value, uint16_t size, bool localOnly)
sjallouli 0:289fd2dae405 537 {
sjallouli 0:289fd2dae405 538 return transport->getGattServer().updateValue(handle, const_cast<uint8_t *>(value), size, localOnly);
sjallouli 0:289fd2dae405 539 }
sjallouli 0:289fd2dae405 540
sjallouli 0:289fd2dae405 541 inline void
sjallouli 0:289fd2dae405 542 BLEDevice::waitForEvent(void)
sjallouli 0:289fd2dae405 543 {
sjallouli 0:289fd2dae405 544 transport->waitForEvent();
sjallouli 0:289fd2dae405 545 }
sjallouli 0:289fd2dae405 546
sjallouli 0:289fd2dae405 547 inline ble_error_t
sjallouli 0:289fd2dae405 548 BLEDevice::getPreferredConnectionParams(Gap::ConnectionParams_t *params)
sjallouli 0:289fd2dae405 549 {
sjallouli 0:289fd2dae405 550 return transport->getGap().getPreferredConnectionParams(params);
sjallouli 0:289fd2dae405 551 }
sjallouli 0:289fd2dae405 552
sjallouli 0:289fd2dae405 553 inline ble_error_t
sjallouli 0:289fd2dae405 554 BLEDevice::setPreferredConnectionParams(const Gap::ConnectionParams_t *params)
sjallouli 0:289fd2dae405 555 {
sjallouli 0:289fd2dae405 556 return transport->getGap().setPreferredConnectionParams(params);
sjallouli 0:289fd2dae405 557 }
sjallouli 0:289fd2dae405 558
sjallouli 0:289fd2dae405 559 inline ble_error_t
sjallouli 0:289fd2dae405 560 BLEDevice::updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params) {
sjallouli 0:289fd2dae405 561 return transport->getGap().updateConnectionParams(handle, params);
sjallouli 0:289fd2dae405 562 }
sjallouli 0:289fd2dae405 563
sjallouli 0:289fd2dae405 564 inline const char *
sjallouli 0:289fd2dae405 565 BLEDevice::getVersion(void)
sjallouli 0:289fd2dae405 566 {
sjallouli 0:289fd2dae405 567 return transport->getVersion();
sjallouli 0:289fd2dae405 568 }
sjallouli 0:289fd2dae405 569
sjallouli 0:289fd2dae405 570 inline ble_error_t
sjallouli 0:289fd2dae405 571 BLEDevice::setDeviceName(const uint8_t *deviceName)
sjallouli 0:289fd2dae405 572 {
sjallouli 0:289fd2dae405 573 return transport->getGap().setDeviceName(deviceName);
sjallouli 0:289fd2dae405 574 }
sjallouli 0:289fd2dae405 575
sjallouli 0:289fd2dae405 576 inline ble_error_t
sjallouli 0:289fd2dae405 577 BLEDevice::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
sjallouli 0:289fd2dae405 578 {
sjallouli 0:289fd2dae405 579 return transport->getGap().getDeviceName(deviceName, lengthP);
sjallouli 0:289fd2dae405 580 }
sjallouli 0:289fd2dae405 581
sjallouli 0:289fd2dae405 582 inline ble_error_t
sjallouli 0:289fd2dae405 583 BLEDevice::setAppearance(uint16_t appearance)
sjallouli 0:289fd2dae405 584 {
sjallouli 0:289fd2dae405 585 return transport->getGap().setAppearance(appearance);
sjallouli 0:289fd2dae405 586 }
sjallouli 0:289fd2dae405 587
sjallouli 0:289fd2dae405 588 inline ble_error_t
sjallouli 0:289fd2dae405 589 BLEDevice::getAppearance(uint16_t *appearanceP)
sjallouli 0:289fd2dae405 590 {
sjallouli 0:289fd2dae405 591 return transport->getGap().getAppearance(appearanceP);
sjallouli 0:289fd2dae405 592 }
sjallouli 0:289fd2dae405 593
sjallouli 0:289fd2dae405 594 inline ble_error_t
sjallouli 0:289fd2dae405 595 BLEDevice::setTxPower(int8_t txPower)
sjallouli 0:289fd2dae405 596 {
sjallouli 0:289fd2dae405 597 return transport->setTxPower(txPower);
sjallouli 0:289fd2dae405 598 }
sjallouli 0:289fd2dae405 599
sjallouli 0:289fd2dae405 600 /*
sjallouli 0:289fd2dae405 601 * ALL OF THE FOLLOWING METHODS ARE DEPRECATED
sjallouli 0:289fd2dae405 602 */
sjallouli 0:289fd2dae405 603
sjallouli 0:289fd2dae405 604 inline ble_error_t
sjallouli 0:289fd2dae405 605 BLEDevice::setAdvertisingData(const GapAdvertisingData &ADStructures, const GapAdvertisingData &scanResponse)
sjallouli 0:289fd2dae405 606 {
sjallouli 0:289fd2dae405 607 needToSetAdvPayload = false;
sjallouli 0:289fd2dae405 608 return transport->getGap().setAdvertisingData(ADStructures, scanResponse);
sjallouli 0:289fd2dae405 609 }
sjallouli 0:289fd2dae405 610
sjallouli 0:289fd2dae405 611 inline ble_error_t
sjallouli 0:289fd2dae405 612 BLEDevice::setAdvertisingData(const GapAdvertisingData &ADStructures)
sjallouli 0:289fd2dae405 613 {
sjallouli 0:289fd2dae405 614 GapAdvertisingData scanResponse;
sjallouli 0:289fd2dae405 615
sjallouli 0:289fd2dae405 616 needToSetAdvPayload = false;
sjallouli 0:289fd2dae405 617 return transport->getGap().setAdvertisingData(ADStructures, scanResponse);
sjallouli 0:289fd2dae405 618 }
sjallouli 0:289fd2dae405 619
sjallouli 0:289fd2dae405 620 inline ble_error_t
sjallouli 0:289fd2dae405 621 BLEDevice::startAdvertising(const GapAdvertisingParams &_advParams)
sjallouli 0:289fd2dae405 622 {
sjallouli 0:289fd2dae405 623 return transport->getGap().startAdvertising(_advParams);
sjallouli 0:289fd2dae405 624 }
sjallouli 0:289fd2dae405 625
sjallouli 0:289fd2dae405 626 #endif // ifndef __BLE_DEVICE__