BLE_API

Committer:
vcoubard
Date:
Wed Apr 06 19:15:30 2016 +0100
Revision:
1179:4ab722f8dca0
Parent:
1172:4aad76f757e6
Child:
1183:1589830dbdb7
Synchronized with git rev ca632aaf
Author: Andres Amaya Garcia
Update Gap state after advertising times out

The BLE API was not updating the Gap internal state when the advertising stops
because of a user timeout. This commit fixes the issue by updating the internal
state structure in Gap just before the registered callbacks are notified of the
advertising timeout.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vcoubard 1131:692ddf04fc42 1 /* mbed Microcontroller Library
vcoubard 1131:692ddf04fc42 2 * Copyright (c) 2006-2013 ARM Limited
vcoubard 1131:692ddf04fc42 3 *
vcoubard 1131:692ddf04fc42 4 * Licensed under the Apache License, Version 2.0 (the "License");
vcoubard 1131:692ddf04fc42 5 * you may not use this file except in compliance with the License.
vcoubard 1131:692ddf04fc42 6 * You may obtain a copy of the License at
vcoubard 1131:692ddf04fc42 7 *
vcoubard 1131:692ddf04fc42 8 * http://www.apache.org/licenses/LICENSE-2.0
vcoubard 1131:692ddf04fc42 9 *
vcoubard 1131:692ddf04fc42 10 * Unless required by applicable law or agreed to in writing, software
vcoubard 1131:692ddf04fc42 11 * distributed under the License is distributed on an "AS IS" BASIS,
vcoubard 1131:692ddf04fc42 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
vcoubard 1131:692ddf04fc42 13 * See the License for the specific language governing permissions and
vcoubard 1131:692ddf04fc42 14 * limitations under the License.
vcoubard 1131:692ddf04fc42 15 */
vcoubard 1131:692ddf04fc42 16
vcoubard 1131:692ddf04fc42 17 #ifndef __GAP_ADVERTISING_DATA_H__
vcoubard 1131:692ddf04fc42 18 #define __GAP_ADVERTISING_DATA_H__
vcoubard 1131:692ddf04fc42 19
vcoubard 1131:692ddf04fc42 20 #include <stdint.h>
vcoubard 1131:692ddf04fc42 21 #include <string.h>
vcoubard 1131:692ddf04fc42 22
vcoubard 1131:692ddf04fc42 23 #include "blecommon.h"
vcoubard 1131:692ddf04fc42 24
vcoubard 1131:692ddf04fc42 25 #define GAP_ADVERTISING_DATA_MAX_PAYLOAD (31)
vcoubard 1131:692ddf04fc42 26
vcoubard 1179:4ab722f8dca0 27 /**************************************************************************/
vcoubard 1179:4ab722f8dca0 28 /*!
vcoubard 1179:4ab722f8dca0 29 \brief
vcoubard 1179:4ab722f8dca0 30 This class provides several helper functions to generate properly
vcoubard 1179:4ab722f8dca0 31 formatted GAP Advertising and Scan Response data payloads.
vcoubard 1179:4ab722f8dca0 32
vcoubard 1179:4ab722f8dca0 33 \note
vcoubard 1179:4ab722f8dca0 34 See Bluetooth Specification 4.0 (Vol. 3), Part C, Sections 11 and 18
vcoubard 1179:4ab722f8dca0 35 for further information on Advertising and Scan Response data.
vcoubard 1179:4ab722f8dca0 36
vcoubard 1179:4ab722f8dca0 37 \par Advertising and Scan Response Payloads
vcoubard 1179:4ab722f8dca0 38 Advertising data and Scan Response data are organized around a set of
vcoubard 1179:4ab722f8dca0 39 data types called 'AD types' in Bluetooth 4.0 (see the Bluetooth Core
vcoubard 1179:4ab722f8dca0 40 Specification v4.0, Vol. 3, Part C, Sections 11 and 18).
vcoubard 1179:4ab722f8dca0 41
vcoubard 1179:4ab722f8dca0 42 \par
vcoubard 1179:4ab722f8dca0 43 Each AD type has its own standardized assigned number, as defined
vcoubard 1179:4ab722f8dca0 44 by the Bluetooth SIG:
vcoubard 1179:4ab722f8dca0 45 https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile
vcoubard 1179:4ab722f8dca0 46
vcoubard 1179:4ab722f8dca0 47 \par
vcoubard 1179:4ab722f8dca0 48 For convenience, all appropriate AD types are encapsulated
vcoubard 1179:4ab722f8dca0 49 in GapAdvertisingData::DataType.
vcoubard 1179:4ab722f8dca0 50
vcoubard 1179:4ab722f8dca0 51 \par
vcoubard 1179:4ab722f8dca0 52 Before the AD Types and their payload (if any) can be inserted into
vcoubard 1179:4ab722f8dca0 53 the Advertising or Scan Response frames, they need to be formatted as
vcoubard 1179:4ab722f8dca0 54 follows:
vcoubard 1179:4ab722f8dca0 55
vcoubard 1179:4ab722f8dca0 56 \li \c Record length (1 byte).
vcoubard 1179:4ab722f8dca0 57 \li \c AD Type (1 byte).
vcoubard 1179:4ab722f8dca0 58 \li \c AD payload (optional; only present if record length > 1).
vcoubard 1179:4ab722f8dca0 59
vcoubard 1179:4ab722f8dca0 60 \par
vcoubard 1179:4ab722f8dca0 61 This class takes care of properly formatting the payload, performs
vcoubard 1179:4ab722f8dca0 62 some basic checks on the payload length, and tries to avoid common
vcoubard 1179:4ab722f8dca0 63 errors like adding an exclusive AD field twice in the Advertising
vcoubard 1179:4ab722f8dca0 64 or Scan Response payload.
vcoubard 1179:4ab722f8dca0 65
vcoubard 1179:4ab722f8dca0 66 \par EXAMPLE
vcoubard 1179:4ab722f8dca0 67
vcoubard 1179:4ab722f8dca0 68 \code
vcoubard 1179:4ab722f8dca0 69
vcoubard 1179:4ab722f8dca0 70 // ToDo
vcoubard 1179:4ab722f8dca0 71
vcoubard 1179:4ab722f8dca0 72 \endcode
vcoubard 1179:4ab722f8dca0 73 */
vcoubard 1179:4ab722f8dca0 74 /**************************************************************************/
vcoubard 1131:692ddf04fc42 75 class GapAdvertisingData
vcoubard 1131:692ddf04fc42 76 {
vcoubard 1131:692ddf04fc42 77 public:
vcoubard 1179:4ab722f8dca0 78 /**********************************************************************/
vcoubard 1131:692ddf04fc42 79 /*!
vcoubard 1179:4ab722f8dca0 80 \brief
vcoubard 1179:4ab722f8dca0 81 A list of Advertising Data types commonly used by peripherals.
vcoubard 1179:4ab722f8dca0 82 These AD types are used to describe the capabilities of the
vcoubard 1179:4ab722f8dca0 83 peripheral, and are inserted inside the advertising or scan
vcoubard 1179:4ab722f8dca0 84 response payloads.
vcoubard 1179:4ab722f8dca0 85
vcoubard 1179:4ab722f8dca0 86 \par Source
vcoubard 1179:4ab722f8dca0 87 \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 11, 18
vcoubard 1179:4ab722f8dca0 88 \li \c https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile
vcoubard 1179:4ab722f8dca0 89 */
vcoubard 1179:4ab722f8dca0 90 /**********************************************************************/
vcoubard 1131:692ddf04fc42 91 enum DataType_t {
vcoubard 1179:4ab722f8dca0 92 FLAGS = 0x01, /**< \ref *Flags */
vcoubard 1179:4ab722f8dca0 93 INCOMPLETE_LIST_16BIT_SERVICE_IDS = 0x02, /**< Incomplete list of 16-bit Service IDs */
vcoubard 1179:4ab722f8dca0 94 COMPLETE_LIST_16BIT_SERVICE_IDS = 0x03, /**< Complete list of 16-bit Service IDs */
vcoubard 1179:4ab722f8dca0 95 INCOMPLETE_LIST_32BIT_SERVICE_IDS = 0x04, /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
vcoubard 1179:4ab722f8dca0 96 COMPLETE_LIST_32BIT_SERVICE_IDS = 0x05, /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
vcoubard 1179:4ab722f8dca0 97 INCOMPLETE_LIST_128BIT_SERVICE_IDS = 0x06, /**< Incomplete list of 128-bit Service IDs */
vcoubard 1179:4ab722f8dca0 98 COMPLETE_LIST_128BIT_SERVICE_IDS = 0x07, /**< Complete list of 128-bit Service IDs */
vcoubard 1179:4ab722f8dca0 99 SHORTENED_LOCAL_NAME = 0x08, /**< Shortened Local Name */
vcoubard 1179:4ab722f8dca0 100 COMPLETE_LOCAL_NAME = 0x09, /**< Complete Local Name */
vcoubard 1179:4ab722f8dca0 101 TX_POWER_LEVEL = 0x0A, /**< TX Power Level (in dBm) */
vcoubard 1179:4ab722f8dca0 102 DEVICE_ID = 0x10, /**< Device ID */
vcoubard 1179:4ab722f8dca0 103 SLAVE_CONNECTION_INTERVAL_RANGE = 0x12, /**< Slave Connection Interval Range */
vcoubard 1179:4ab722f8dca0 104 LIST_128BIT_SOLICITATION_IDS = 0x15, /**< List of 128 bit service UUIDs the device is looking for */
vcoubard 1179:4ab722f8dca0 105 SERVICE_DATA = 0x16, /**< Service Data */
vcoubard 1179:4ab722f8dca0 106 APPEARANCE = 0x19, /**< \ref Appearance */
vcoubard 1179:4ab722f8dca0 107 ADVERTISING_INTERVAL = 0x1A, /**< Advertising Interval */
vcoubard 1179:4ab722f8dca0 108 MANUFACTURER_SPECIFIC_DATA = 0xFF /**< Manufacturer Specific Data */
vcoubard 1131:692ddf04fc42 109 };
vcoubard 1179:4ab722f8dca0 110 typedef enum DataType_t DataType; /* Deprecated type alias. This may be dropped in a future release. */
vcoubard 1179:4ab722f8dca0 111
vcoubard 1179:4ab722f8dca0 112 /**********************************************************************/
vcoubard 1179:4ab722f8dca0 113 /*!
vcoubard 1179:4ab722f8dca0 114 \brief
vcoubard 1179:4ab722f8dca0 115 A list of values for the FLAGS AD Type.
vcoubard 1131:692ddf04fc42 116
vcoubard 1179:4ab722f8dca0 117 \note
vcoubard 1179:4ab722f8dca0 118 You can use more than one value in the FLAGS AD Type (ex.
vcoubard 1179:4ab722f8dca0 119 LE_GENERAL_DISCOVERABLE and BREDR_NOT_SUPPORTED).
vcoubard 1179:4ab722f8dca0 120
vcoubard 1179:4ab722f8dca0 121 \par Source
vcoubard 1179:4ab722f8dca0 122 \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 18.1
vcoubard 1179:4ab722f8dca0 123 */
vcoubard 1179:4ab722f8dca0 124 /**********************************************************************/
vcoubard 1131:692ddf04fc42 125 enum Flags_t {
vcoubard 1179:4ab722f8dca0 126 LE_LIMITED_DISCOVERABLE = 0x01, /**< *Peripheral device is discoverable for a limited period of time. */
vcoubard 1131:692ddf04fc42 127 LE_GENERAL_DISCOVERABLE = 0x02, /**< Peripheral device is discoverable at any moment. */
vcoubard 1131:692ddf04fc42 128 BREDR_NOT_SUPPORTED = 0x04, /**< Peripheral device is LE only. */
vcoubard 1131:692ddf04fc42 129 SIMULTANEOUS_LE_BREDR_C = 0x08, /**< Not relevant - central mode only. */
vcoubard 1131:692ddf04fc42 130 SIMULTANEOUS_LE_BREDR_H = 0x10 /**< Not relevant - central mode only. */
vcoubard 1131:692ddf04fc42 131 };
vcoubard 1179:4ab722f8dca0 132 typedef enum Flags_t Flags; /* Deprecated type alias. This may be dropped in a future release. */
vcoubard 1131:692ddf04fc42 133
vcoubard 1179:4ab722f8dca0 134 /**********************************************************************/
vcoubard 1179:4ab722f8dca0 135 /*!
vcoubard 1179:4ab722f8dca0 136 \brief
vcoubard 1179:4ab722f8dca0 137 A list of values for the APPEARANCE AD Type, which describes the
vcoubard 1179:4ab722f8dca0 138 physical shape or appearance of the device.
vcoubard 1179:4ab722f8dca0 139
vcoubard 1179:4ab722f8dca0 140 \par Source
vcoubard 1179:4ab722f8dca0 141 \li \c Bluetooth Core Specification Supplement, Part A, Section 1.12
vcoubard 1179:4ab722f8dca0 142 \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 12.2
vcoubard 1179:4ab722f8dca0 143 \li \c https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
vcoubard 1179:4ab722f8dca0 144 */
vcoubard 1179:4ab722f8dca0 145 /**********************************************************************/
vcoubard 1131:692ddf04fc42 146 enum Appearance_t {
vcoubard 1131:692ddf04fc42 147 UNKNOWN = 0, /**< Unknown or unspecified appearance type. */
vcoubard 1131:692ddf04fc42 148 GENERIC_PHONE = 64, /**< Generic Phone. */
vcoubard 1131:692ddf04fc42 149 GENERIC_COMPUTER = 128, /**< Generic Computer. */
vcoubard 1131:692ddf04fc42 150 GENERIC_WATCH = 192, /**< Generic Watch. */
vcoubard 1131:692ddf04fc42 151 WATCH_SPORTS_WATCH = 193, /**< Sports Watch. */
vcoubard 1131:692ddf04fc42 152 GENERIC_CLOCK = 256, /**< Generic Clock. */
vcoubard 1131:692ddf04fc42 153 GENERIC_DISPLAY = 320, /**< Generic Display. */
vcoubard 1131:692ddf04fc42 154 GENERIC_REMOTE_CONTROL = 384, /**< Generic Remote Control. */
vcoubard 1131:692ddf04fc42 155 GENERIC_EYE_GLASSES = 448, /**< Generic Eye Glasses. */
vcoubard 1131:692ddf04fc42 156 GENERIC_TAG = 512, /**< Generic Tag. */
vcoubard 1131:692ddf04fc42 157 GENERIC_KEYRING = 576, /**< Generic Keyring. */
vcoubard 1131:692ddf04fc42 158 GENERIC_MEDIA_PLAYER = 640, /**< Generic Media Player. */
vcoubard 1131:692ddf04fc42 159 GENERIC_BARCODE_SCANNER = 704, /**< Generic Barcode Scanner. */
vcoubard 1131:692ddf04fc42 160 GENERIC_THERMOMETER = 768, /**< Generic Thermometer. */
vcoubard 1131:692ddf04fc42 161 THERMOMETER_EAR = 769, /**< Ear Thermometer. */
vcoubard 1131:692ddf04fc42 162 GENERIC_HEART_RATE_SENSOR = 832, /**< Generic Heart Rate Sensor. */
vcoubard 1131:692ddf04fc42 163 HEART_RATE_SENSOR_HEART_RATE_BELT = 833, /**< Belt Heart Rate Sensor. */
vcoubard 1131:692ddf04fc42 164 GENERIC_BLOOD_PRESSURE = 896, /**< Generic Blood Pressure. */
vcoubard 1131:692ddf04fc42 165 BLOOD_PRESSURE_ARM = 897, /**< Arm Blood Pressure. */
vcoubard 1131:692ddf04fc42 166 BLOOD_PRESSURE_WRIST = 898, /**< Wrist Blood Pressure. */
vcoubard 1131:692ddf04fc42 167 HUMAN_INTERFACE_DEVICE_HID = 960, /**< Human Interface Device (HID). */
vcoubard 1131:692ddf04fc42 168 KEYBOARD = 961, /**< Keyboard. */
vcoubard 1131:692ddf04fc42 169 MOUSE = 962, /**< Mouse. */
vcoubard 1131:692ddf04fc42 170 JOYSTICK = 963, /**< Joystick. */
vcoubard 1131:692ddf04fc42 171 GAMEPAD = 964, /**< Gamepad. */
vcoubard 1131:692ddf04fc42 172 DIGITIZER_TABLET = 965, /**< Digitizer Tablet. */
vcoubard 1131:692ddf04fc42 173 CARD_READER = 966, /**< Card Reader. */
vcoubard 1131:692ddf04fc42 174 DIGITAL_PEN = 967, /**< Digital Pen. */
vcoubard 1131:692ddf04fc42 175 BARCODE_SCANNER = 968, /**< Barcode Scanner. */
vcoubard 1131:692ddf04fc42 176 GENERIC_GLUCOSE_METER = 1024, /**< Generic Glucose Meter. */
vcoubard 1131:692ddf04fc42 177 GENERIC_RUNNING_WALKING_SENSOR = 1088, /**< Generic Running/Walking Sensor. */
vcoubard 1131:692ddf04fc42 178 RUNNING_WALKING_SENSOR_IN_SHOE = 1089, /**< In Shoe Running/Walking Sensor. */
vcoubard 1131:692ddf04fc42 179 RUNNING_WALKING_SENSOR_ON_SHOE = 1090, /**< On Shoe Running/Walking Sensor. */
vcoubard 1131:692ddf04fc42 180 RUNNING_WALKING_SENSOR_ON_HIP = 1091, /**< On Hip Running/Walking Sensor. */
vcoubard 1131:692ddf04fc42 181 GENERIC_CYCLING = 1152, /**< Generic Cycling. */
vcoubard 1131:692ddf04fc42 182 CYCLING_CYCLING_COMPUTER = 1153, /**< Cycling Computer. */
vcoubard 1131:692ddf04fc42 183 CYCLING_SPEED_SENSOR = 1154, /**< Cycling Speed Sensor. */
vcoubard 1131:692ddf04fc42 184 CYCLING_CADENCE_SENSOR = 1155, /**< Cycling Cadence Sensor. */
vcoubard 1131:692ddf04fc42 185 CYCLING_POWER_SENSOR = 1156, /**< Cycling Power Sensor. */
vcoubard 1131:692ddf04fc42 186 CYCLING_SPEED_AND_CADENCE_SENSOR = 1157, /**< Cycling Speed and Cadence Sensor. */
vcoubard 1131:692ddf04fc42 187 PULSE_OXIMETER_GENERIC = 3136, /**< Generic Pulse Oximeter. */
vcoubard 1131:692ddf04fc42 188 PULSE_OXIMETER_FINGERTIP = 3137, /**< Fingertip Pulse Oximeter. */
vcoubard 1131:692ddf04fc42 189 PULSE_OXIMETER_WRIST_WORN = 3138, /**< Wrist Worn Pulse Oximeter. */
vcoubard 1135:22aada733dbd 190 GENERIC_WEIGHT_SCALE = 3200, /**< Generic Weight Scale. */
vcoubard 1131:692ddf04fc42 191 OUTDOOR_GENERIC = 5184, /**< Generic Outdoor. */
vcoubard 1131:692ddf04fc42 192 OUTDOOR_LOCATION_DISPLAY_DEVICE = 5185, /**< Outdoor Location Display Device. */
vcoubard 1131:692ddf04fc42 193 OUTDOOR_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE = 5186, /**< Outdoor Location and Navigation Display Device. */
vcoubard 1131:692ddf04fc42 194 OUTDOOR_LOCATION_POD = 5187, /**< Outdoor Location Pod. */
vcoubard 1131:692ddf04fc42 195 OUTDOOR_LOCATION_AND_NAVIGATION_POD = 5188 /**< Outdoor Location and Navigation Pod. */
vcoubard 1131:692ddf04fc42 196 };
vcoubard 1179:4ab722f8dca0 197 typedef enum Appearance_t Appearance; /* Deprecated type alias. This may be dropped in a future release. */
vcoubard 1131:692ddf04fc42 198
vcoubard 1131:692ddf04fc42 199 GapAdvertisingData(void) : _payload(), _payloadLen(0), _appearance(GENERIC_TAG) {
vcoubard 1131:692ddf04fc42 200 /* empty */
vcoubard 1131:692ddf04fc42 201 }
vcoubard 1131:692ddf04fc42 202
vcoubard 1131:692ddf04fc42 203 /**
vcoubard 1179:4ab722f8dca0 204 * Adds advertising data based on the specified AD type (see DataType).
vcoubard 1135:22aada733dbd 205 * If the supplied AD type is already present in the advertising
vcoubard 1135:22aada733dbd 206 * payload, then the value is updated.
vcoubard 1131:692ddf04fc42 207 *
vcoubard 1131:692ddf04fc42 208 * @param[in] advDataType The Advertising 'DataType' to add.
vcoubard 1131:692ddf04fc42 209 * @param[in] payload Pointer to the payload contents.
vcoubard 1131:692ddf04fc42 210 * @param[in] len Size of the payload in bytes.
vcoubard 1131:692ddf04fc42 211 *
vcoubard 1135:22aada733dbd 212 * @return BLE_ERROR_BUFFER_OVERFLOW if the new value causes the
vcoubard 1135:22aada733dbd 213 * advertising buffer to overflow. BLE_ERROR_NONE is returned
vcoubard 1135:22aada733dbd 214 * on success.
vcoubard 1135:22aada733dbd 215 *
vcoubard 1135:22aada733dbd 216 * @note When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS,
vcoubard 1135:22aada733dbd 217 * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS,
vcoubard 1135:22aada733dbd 218 * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS,
vcoubard 1135:22aada733dbd 219 * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the
vcoubard 1135:22aada733dbd 220 * supplied value is appended to the values previously added to the
vcoubard 1135:22aada733dbd 221 * payload.
vcoubard 1135:22aada733dbd 222 */
vcoubard 1135:22aada733dbd 223 ble_error_t addData(DataType_t advDataType, const uint8_t *payload, uint8_t len)
vcoubard 1135:22aada733dbd 224 {
vcoubard 1179:4ab722f8dca0 225 // find field
vcoubard 1135:22aada733dbd 226 uint8_t* field = findField(advDataType);
vcoubard 1135:22aada733dbd 227
vcoubard 1135:22aada733dbd 228 if (field) {
vcoubard 1179:4ab722f8dca0 229 // Field type already exist, either add to field or replace
vcoubard 1135:22aada733dbd 230 return addField(advDataType, payload, len, field);
vcoubard 1135:22aada733dbd 231 } else {
vcoubard 1179:4ab722f8dca0 232 // field doesn't exists, insert new
vcoubard 1135:22aada733dbd 233 return appendField(advDataType, payload, len);
vcoubard 1135:22aada733dbd 234 }
vcoubard 1135:22aada733dbd 235 }
vcoubard 1135:22aada733dbd 236
vcoubard 1135:22aada733dbd 237 /**
vcoubard 1135:22aada733dbd 238 * Update a particular ADV field in the advertising payload (based on
vcoubard 1135:22aada733dbd 239 * matching type).
vcoubard 1135:22aada733dbd 240 *
vcoubard 1135:22aada733dbd 241 * @param[in] advDataType The Advertising 'DataType' to add.
vcoubard 1135:22aada733dbd 242 * @param[in] payload Pointer to the payload contents.
vcoubard 1135:22aada733dbd 243 * @param[in] len Size of the payload in bytes.
vcoubard 1135:22aada733dbd 244 *
vcoubard 1135:22aada733dbd 245 * @return BLE_ERROR_UNSPECIFIED if the specified field is not found,
vcoubard 1135:22aada733dbd 246 * BLE_ERROR_BUFFER_OVERFLOW if the new value causes the
vcoubard 1135:22aada733dbd 247 * advertising buffer to overflow. BLE_ERROR_NONE is returned
vcoubard 1135:22aada733dbd 248 * on success.
vcoubard 1131:692ddf04fc42 249 */
vcoubard 1131:692ddf04fc42 250 ble_error_t updateData(DataType_t advDataType, const uint8_t *payload, uint8_t len)
vcoubard 1131:692ddf04fc42 251 {
vcoubard 1179:4ab722f8dca0 252 // find field
vcoubard 1135:22aada733dbd 253 uint8_t* field = findField(advDataType);
vcoubard 1131:692ddf04fc42 254
vcoubard 1135:22aada733dbd 255 if (field) {
vcoubard 1179:4ab722f8dca0 256 // Field type already exist, replace field contents
vcoubard 1135:22aada733dbd 257 return updateField(advDataType, payload, len, field);
vcoubard 1135:22aada733dbd 258 } else {
vcoubard 1179:4ab722f8dca0 259 // field doesn't exists, return an error
vcoubard 1135:22aada733dbd 260 return BLE_ERROR_UNSPECIFIED;
vcoubard 1131:692ddf04fc42 261 }
vcoubard 1131:692ddf04fc42 262 }
vcoubard 1131:692ddf04fc42 263
vcoubard 1131:692ddf04fc42 264 /**
vcoubard 1131:692ddf04fc42 265 * Helper function to add APPEARANCE data to the advertising payload.
vcoubard 1131:692ddf04fc42 266 *
vcoubard 1131:692ddf04fc42 267 * @param appearance
vcoubard 1131:692ddf04fc42 268 * The APPEARANCE value to add.
vcoubard 1131:692ddf04fc42 269 *
vcoubard 1131:692ddf04fc42 270 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
vcoubard 1179:4ab722f8dca0 271 * advertising buffer to overflow, else BLE_ERROR_NONE.
vcoubard 1131:692ddf04fc42 272 */
vcoubard 1131:692ddf04fc42 273 ble_error_t addAppearance(Appearance appearance = GENERIC_TAG) {
vcoubard 1131:692ddf04fc42 274 _appearance = appearance;
vcoubard 1131:692ddf04fc42 275 return addData(GapAdvertisingData::APPEARANCE, (uint8_t *)&appearance, 2);
vcoubard 1131:692ddf04fc42 276 }
vcoubard 1131:692ddf04fc42 277
vcoubard 1131:692ddf04fc42 278 /**
vcoubard 1131:692ddf04fc42 279 * Helper function to add FLAGS data to the advertising payload.
vcoubard 1179:4ab722f8dca0 280 * @param flags
vcoubard 1179:4ab722f8dca0 281 * LE_LIMITED_DISCOVERABLE
vcoubard 1179:4ab722f8dca0 282 * The peripheral is discoverable for a limited period of time.
vcoubard 1179:4ab722f8dca0 283 * LE_GENERAL_DISCOVERABLE
vcoubard 1179:4ab722f8dca0 284 * The peripheral is permanently discoverable.
vcoubard 1179:4ab722f8dca0 285 * BREDR_NOT_SUPPORTED
vcoubard 1179:4ab722f8dca0 286 * This peripheral is a Bluetooth Low Energy only device (no EDR support).
vcoubard 1131:692ddf04fc42 287 *
vcoubard 1131:692ddf04fc42 288 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
vcoubard 1179:4ab722f8dca0 289 * advertising buffer to overflow, else BLE_ERROR_NONE.
vcoubard 1131:692ddf04fc42 290 */
vcoubard 1131:692ddf04fc42 291 ble_error_t addFlags(uint8_t flags = LE_GENERAL_DISCOVERABLE) {
vcoubard 1131:692ddf04fc42 292 return addData(GapAdvertisingData::FLAGS, &flags, 1);
vcoubard 1131:692ddf04fc42 293 }
vcoubard 1131:692ddf04fc42 294
vcoubard 1131:692ddf04fc42 295 /**
vcoubard 1131:692ddf04fc42 296 * Helper function to add TX_POWER_LEVEL data to the advertising payload.
vcoubard 1131:692ddf04fc42 297 *
vcoubard 1131:692ddf04fc42 298 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
vcoubard 1179:4ab722f8dca0 299 * advertising buffer to overflow, else BLE_ERROR_NONE.
vcoubard 1131:692ddf04fc42 300 */
vcoubard 1131:692ddf04fc42 301 ble_error_t addTxPower(int8_t txPower) {
vcoubard 1131:692ddf04fc42 302 /* To Do: Basic error checking to make sure txPower is in range. */
vcoubard 1131:692ddf04fc42 303 return addData(GapAdvertisingData::TX_POWER_LEVEL, (uint8_t *)&txPower, 1);
vcoubard 1131:692ddf04fc42 304 }
vcoubard 1131:692ddf04fc42 305
vcoubard 1131:692ddf04fc42 306 /**
vcoubard 1131:692ddf04fc42 307 * Clears the payload and resets the payload length counter.
vcoubard 1131:692ddf04fc42 308 */
vcoubard 1131:692ddf04fc42 309 void clear(void) {
vcoubard 1131:692ddf04fc42 310 memset(&_payload, 0, GAP_ADVERTISING_DATA_MAX_PAYLOAD);
vcoubard 1131:692ddf04fc42 311 _payloadLen = 0;
vcoubard 1131:692ddf04fc42 312 }
vcoubard 1131:692ddf04fc42 313
vcoubard 1131:692ddf04fc42 314 /**
vcoubard 1179:4ab722f8dca0 315 * Returns a pointer to the current payload.
vcoubard 1131:692ddf04fc42 316 */
vcoubard 1131:692ddf04fc42 317 const uint8_t *getPayload(void) const {
vcoubard 1131:692ddf04fc42 318 return _payload;
vcoubard 1131:692ddf04fc42 319 }
vcoubard 1131:692ddf04fc42 320
vcoubard 1131:692ddf04fc42 321 /**
vcoubard 1179:4ab722f8dca0 322 * Returns the current payload length (0..31 bytes).
vcoubard 1131:692ddf04fc42 323 */
vcoubard 1131:692ddf04fc42 324 uint8_t getPayloadLen(void) const {
vcoubard 1131:692ddf04fc42 325 return _payloadLen;
vcoubard 1131:692ddf04fc42 326 }
vcoubard 1131:692ddf04fc42 327
vcoubard 1131:692ddf04fc42 328 /**
vcoubard 1179:4ab722f8dca0 329 * Returns the 16-bit appearance value for this device.
vcoubard 1131:692ddf04fc42 330 */
vcoubard 1131:692ddf04fc42 331 uint16_t getAppearance(void) const {
vcoubard 1131:692ddf04fc42 332 return (uint16_t)_appearance;
vcoubard 1131:692ddf04fc42 333 }
vcoubard 1131:692ddf04fc42 334
vcoubard 1131:692ddf04fc42 335 /**
vcoubard 1179:4ab722f8dca0 336 * Search advertisement data for field.
vcoubard 1179:4ab722f8dca0 337 * Returns pointer to the first element in the field if found, NULL otherwise.
vcoubard 1179:4ab722f8dca0 338 * Where the first element is the length of the field.
vcoubard 1131:692ddf04fc42 339 */
vcoubard 1131:692ddf04fc42 340 const uint8_t* findField(DataType_t type) const {
vcoubard 1131:692ddf04fc42 341 return findField(type);
vcoubard 1131:692ddf04fc42 342 }
vcoubard 1131:692ddf04fc42 343
vcoubard 1131:692ddf04fc42 344 private:
vcoubard 1131:692ddf04fc42 345 /**
vcoubard 1179:4ab722f8dca0 346 * Append advertising data based on the specified AD type (see DataType)
vcoubard 1131:692ddf04fc42 347 */
vcoubard 1131:692ddf04fc42 348 ble_error_t appendField(DataType advDataType, const uint8_t *payload, uint8_t len)
vcoubard 1131:692ddf04fc42 349 {
vcoubard 1131:692ddf04fc42 350 /* Make sure we don't exceed the 31 byte payload limit */
vcoubard 1131:692ddf04fc42 351 if (_payloadLen + len + 2 > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
vcoubard 1131:692ddf04fc42 352 return BLE_ERROR_BUFFER_OVERFLOW;
vcoubard 1131:692ddf04fc42 353 }
vcoubard 1131:692ddf04fc42 354
vcoubard 1131:692ddf04fc42 355 /* Field length. */
vcoubard 1131:692ddf04fc42 356 memset(&_payload[_payloadLen], len + 1, 1);
vcoubard 1131:692ddf04fc42 357 _payloadLen++;
vcoubard 1131:692ddf04fc42 358
vcoubard 1131:692ddf04fc42 359 /* Field ID. */
vcoubard 1131:692ddf04fc42 360 memset(&_payload[_payloadLen], (uint8_t)advDataType, 1);
vcoubard 1131:692ddf04fc42 361 _payloadLen++;
vcoubard 1131:692ddf04fc42 362
vcoubard 1131:692ddf04fc42 363 /* Payload. */
vcoubard 1131:692ddf04fc42 364 memcpy(&_payload[_payloadLen], payload, len);
vcoubard 1131:692ddf04fc42 365 _payloadLen += len;
vcoubard 1131:692ddf04fc42 366
vcoubard 1131:692ddf04fc42 367 return BLE_ERROR_NONE;
vcoubard 1131:692ddf04fc42 368 }
vcoubard 1131:692ddf04fc42 369
vcoubard 1131:692ddf04fc42 370 /**
vcoubard 1131:692ddf04fc42 371 * Search advertisement data for field.
vcoubard 1179:4ab722f8dca0 372 * Returns pointer to the first element in the field if found, NULL otherwise.
vcoubard 1179:4ab722f8dca0 373 * Where the first element is the length of the field.
vcoubard 1131:692ddf04fc42 374 */
vcoubard 1131:692ddf04fc42 375 uint8_t* findField(DataType_t type) {
vcoubard 1179:4ab722f8dca0 376 // scan through advertisement data
vcoubard 1131:692ddf04fc42 377 for (uint8_t idx = 0; idx < _payloadLen; ) {
vcoubard 1131:692ddf04fc42 378 uint8_t fieldType = _payload[idx + 1];
vcoubard 1131:692ddf04fc42 379
vcoubard 1131:692ddf04fc42 380 if (fieldType == type) {
vcoubard 1131:692ddf04fc42 381 return &_payload[idx];
vcoubard 1131:692ddf04fc42 382 }
vcoubard 1131:692ddf04fc42 383
vcoubard 1179:4ab722f8dca0 384 // advance to next field
vcoubard 1131:692ddf04fc42 385 idx += _payload[idx] + 1;
vcoubard 1131:692ddf04fc42 386 }
vcoubard 1131:692ddf04fc42 387
vcoubard 1179:4ab722f8dca0 388 // field not found
vcoubard 1131:692ddf04fc42 389 return NULL;
vcoubard 1131:692ddf04fc42 390 }
vcoubard 1131:692ddf04fc42 391
vcoubard 1135:22aada733dbd 392 /**
vcoubard 1135:22aada733dbd 393 * Given the a pointer to a field in the advertising payload it replaces
vcoubard 1135:22aada733dbd 394 * the existing data in the field with the supplied data.
vcoubard 1135:22aada733dbd 395 *
vcoubard 1135:22aada733dbd 396 * When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS,
vcoubard 1135:22aada733dbd 397 * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS,
vcoubard 1135:22aada733dbd 398 * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS,
vcoubard 1135:22aada733dbd 399 * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the
vcoubard 1135:22aada733dbd 400 * supplied value is appended to the values previously added to the
vcoubard 1135:22aada733dbd 401 * payload.
vcoubard 1135:22aada733dbd 402 *
vcoubard 1179:4ab722f8dca0 403 * Returns BLE_ERROR_NONE on success.
vcoubard 1135:22aada733dbd 404 */
vcoubard 1135:22aada733dbd 405 ble_error_t addField(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field)
vcoubard 1135:22aada733dbd 406 {
vcoubard 1135:22aada733dbd 407 ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW;
vcoubard 1135:22aada733dbd 408
vcoubard 1135:22aada733dbd 409 switch(advDataType) {
vcoubard 1179:4ab722f8dca0 410 // These fields will have the new data appended if there is sufficient space
vcoubard 1135:22aada733dbd 411 case INCOMPLETE_LIST_16BIT_SERVICE_IDS:
vcoubard 1135:22aada733dbd 412 case COMPLETE_LIST_16BIT_SERVICE_IDS:
vcoubard 1135:22aada733dbd 413 case INCOMPLETE_LIST_32BIT_SERVICE_IDS:
vcoubard 1135:22aada733dbd 414 case COMPLETE_LIST_32BIT_SERVICE_IDS:
vcoubard 1135:22aada733dbd 415 case INCOMPLETE_LIST_128BIT_SERVICE_IDS:
vcoubard 1135:22aada733dbd 416 case COMPLETE_LIST_128BIT_SERVICE_IDS:
vcoubard 1135:22aada733dbd 417 case LIST_128BIT_SOLICITATION_IDS: {
vcoubard 1179:4ab722f8dca0 418 // check if data fits
vcoubard 1135:22aada733dbd 419 if ((_payloadLen + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
vcoubard 1179:4ab722f8dca0 420 // make room for new field by moving the remainder of the
vcoubard 1179:4ab722f8dca0 421 // advertisement payload "to the right" starting after the
vcoubard 1179:4ab722f8dca0 422 // TYPE field.
vcoubard 1135:22aada733dbd 423 uint8_t* end = &_payload[_payloadLen];
vcoubard 1135:22aada733dbd 424
vcoubard 1135:22aada733dbd 425 while (&field[1] < end) {
vcoubard 1135:22aada733dbd 426 end[len] = *end;
vcoubard 1135:22aada733dbd 427 end--;
vcoubard 1135:22aada733dbd 428 }
vcoubard 1135:22aada733dbd 429
vcoubard 1179:4ab722f8dca0 430 // insert new data
vcoubard 1135:22aada733dbd 431 for (uint8_t idx = 0; idx < len; idx++) {
vcoubard 1135:22aada733dbd 432 field[2 + idx] = payload[idx];
vcoubard 1135:22aada733dbd 433 }
vcoubard 1135:22aada733dbd 434
vcoubard 1179:4ab722f8dca0 435 // increment lengths
vcoubard 1135:22aada733dbd 436 field[0] += len;
vcoubard 1135:22aada733dbd 437 _payloadLen += len;
vcoubard 1135:22aada733dbd 438
vcoubard 1135:22aada733dbd 439 result = BLE_ERROR_NONE;
vcoubard 1135:22aada733dbd 440 }
vcoubard 1135:22aada733dbd 441
vcoubard 1135:22aada733dbd 442 break;
vcoubard 1135:22aada733dbd 443 }
vcoubard 1179:4ab722f8dca0 444 // These fields will be overwritten with the new value
vcoubard 1135:22aada733dbd 445 default: {
vcoubard 1135:22aada733dbd 446 result = updateField(advDataType, payload, len, field);
vcoubard 1135:22aada733dbd 447
vcoubard 1135:22aada733dbd 448 break;
vcoubard 1135:22aada733dbd 449 }
vcoubard 1135:22aada733dbd 450 }
vcoubard 1135:22aada733dbd 451
vcoubard 1135:22aada733dbd 452 return result;
vcoubard 1135:22aada733dbd 453 }
vcoubard 1135:22aada733dbd 454
vcoubard 1135:22aada733dbd 455 /**
vcoubard 1135:22aada733dbd 456 * Given the a pointer to a field in the advertising payload it replaces
vcoubard 1135:22aada733dbd 457 * the existing data in the field with the supplied data.
vcoubard 1179:4ab722f8dca0 458 * Returns BLE_ERROR_NONE on success.
vcoubard 1135:22aada733dbd 459 */
vcoubard 1135:22aada733dbd 460 ble_error_t updateField(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field)
vcoubard 1135:22aada733dbd 461 {
vcoubard 1135:22aada733dbd 462 ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW;
vcoubard 1135:22aada733dbd 463 uint8_t dataLength = field[0] - 1;
vcoubard 1135:22aada733dbd 464
vcoubard 1179:4ab722f8dca0 465 // new data has same length, do in-order replacement
vcoubard 1135:22aada733dbd 466 if (len == dataLength) {
vcoubard 1135:22aada733dbd 467 for (uint8_t idx = 0; idx < dataLength; idx++) {
vcoubard 1135:22aada733dbd 468 field[2 + idx] = payload[idx];
vcoubard 1135:22aada733dbd 469 }
vcoubard 1135:22aada733dbd 470
vcoubard 1135:22aada733dbd 471 result = BLE_ERROR_NONE;
vcoubard 1135:22aada733dbd 472 } else {
vcoubard 1179:4ab722f8dca0 473 // check if data fits
vcoubard 1135:22aada733dbd 474 if ((_payloadLen - dataLength + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
vcoubard 1135:22aada733dbd 475
vcoubard 1179:4ab722f8dca0 476 // remove old field
vcoubard 1135:22aada733dbd 477 while ((field + dataLength + 2) < &_payload[_payloadLen]) {
vcoubard 1135:22aada733dbd 478 *field = field[dataLength + 2];
vcoubard 1135:22aada733dbd 479 field++;
vcoubard 1135:22aada733dbd 480 }
vcoubard 1135:22aada733dbd 481
vcoubard 1179:4ab722f8dca0 482 // reduce length
vcoubard 1135:22aada733dbd 483 _payloadLen -= dataLength + 2;
vcoubard 1135:22aada733dbd 484
vcoubard 1179:4ab722f8dca0 485 // add new field
vcoubard 1135:22aada733dbd 486 result = appendField(advDataType, payload, len);
vcoubard 1135:22aada733dbd 487 }
vcoubard 1135:22aada733dbd 488 }
vcoubard 1135:22aada733dbd 489
vcoubard 1135:22aada733dbd 490 return result;
vcoubard 1135:22aada733dbd 491 }
vcoubard 1135:22aada733dbd 492
vcoubard 1131:692ddf04fc42 493 uint8_t _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD];
vcoubard 1131:692ddf04fc42 494 uint8_t _payloadLen;
vcoubard 1131:692ddf04fc42 495 uint16_t _appearance;
vcoubard 1131:692ddf04fc42 496 };
vcoubard 1131:692ddf04fc42 497
vcoubard 1179:4ab722f8dca0 498 #endif // ifndef __GAP_ADVERTISING_DATA_H__