High level Bluetooth Low Energy API and radio abstraction layer

Fork of BLE_API by Bluetooth Low Energy

Committer:
vcoubard
Date:
Wed Apr 06 19:13:54 2016 +0100
Revision:
1135:22aada733dbd
Parent:
1131:692ddf04fc42
Child:
1172:4aad76f757e6
Synchronized with git rev 17e37360
Author: Vincent Coubard
Merge pull request #161 from ARMmbed/develop

merge branch develop (v2.4.0)

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 1131:692ddf04fc42 27 /**************************************************************************/
vcoubard 1131:692ddf04fc42 28 /*!
vcoubard 1131:692ddf04fc42 29 \brief
vcoubard 1131:692ddf04fc42 30 This class provides several helper functions to generate properly
vcoubard 1131:692ddf04fc42 31 formatted GAP Advertising and Scan Response data payloads.
vcoubard 1131:692ddf04fc42 32
vcoubard 1131:692ddf04fc42 33 \note
vcoubard 1131:692ddf04fc42 34 See Bluetooth Specification 4.0 (Vol. 3), Part C, Sections 11 and 18
vcoubard 1131:692ddf04fc42 35 for further information on Advertising and Scan Response data.
vcoubard 1131:692ddf04fc42 36
vcoubard 1131:692ddf04fc42 37 \par Advertising and Scan Response Payloads
vcoubard 1131:692ddf04fc42 38 Advertising data and Scan Response data are organized around a set of
vcoubard 1131:692ddf04fc42 39 data types called 'AD types' in Bluetooth 4.0 (see the Bluetooth Core
vcoubard 1131:692ddf04fc42 40 Specification v4.0, Vol. 3, Part C, Sections 11 and 18).
vcoubard 1131:692ddf04fc42 41
vcoubard 1131:692ddf04fc42 42 \par
vcoubard 1131:692ddf04fc42 43 Each AD type has its own standardized assigned number, as defined
vcoubard 1131:692ddf04fc42 44 by the Bluetooth SIG:
vcoubard 1131:692ddf04fc42 45 https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile
vcoubard 1131:692ddf04fc42 46
vcoubard 1131:692ddf04fc42 47 \par
vcoubard 1131:692ddf04fc42 48 For convenience, all appropriate AD types are encapsulated
vcoubard 1131:692ddf04fc42 49 in GapAdvertisingData::DataType.
vcoubard 1131:692ddf04fc42 50
vcoubard 1131:692ddf04fc42 51 \par
vcoubard 1131:692ddf04fc42 52 Before the AD Types and their payload (if any) can be inserted into
vcoubard 1131:692ddf04fc42 53 the Advertising or Scan Response frames, they need to be formatted as
vcoubard 1131:692ddf04fc42 54 follows:
vcoubard 1131:692ddf04fc42 55
vcoubard 1131:692ddf04fc42 56 \li \c Record length (1 byte).
vcoubard 1131:692ddf04fc42 57 \li \c AD Type (1 byte).
vcoubard 1131:692ddf04fc42 58 \li \c AD payload (optional; only present if record length > 1).
vcoubard 1131:692ddf04fc42 59
vcoubard 1131:692ddf04fc42 60 \par
vcoubard 1131:692ddf04fc42 61 This class takes care of properly formatting the payload, performs
vcoubard 1131:692ddf04fc42 62 some basic checks on the payload length, and tries to avoid common
vcoubard 1131:692ddf04fc42 63 errors like adding an exclusive AD field twice in the Advertising
vcoubard 1131:692ddf04fc42 64 or Scan Response payload.
vcoubard 1131:692ddf04fc42 65
vcoubard 1131:692ddf04fc42 66 \par EXAMPLE
vcoubard 1131:692ddf04fc42 67
vcoubard 1131:692ddf04fc42 68 \code
vcoubard 1131:692ddf04fc42 69
vcoubard 1131:692ddf04fc42 70 // ToDo
vcoubard 1131:692ddf04fc42 71
vcoubard 1131:692ddf04fc42 72 \endcode
vcoubard 1131:692ddf04fc42 73 */
vcoubard 1131:692ddf04fc42 74 /**************************************************************************/
vcoubard 1131:692ddf04fc42 75 class GapAdvertisingData
vcoubard 1131:692ddf04fc42 76 {
vcoubard 1131:692ddf04fc42 77 public:
vcoubard 1131:692ddf04fc42 78 /**********************************************************************/
vcoubard 1131:692ddf04fc42 79 /*!
vcoubard 1131:692ddf04fc42 80 \brief
vcoubard 1131:692ddf04fc42 81 A list of Advertising Data types commonly used by peripherals.
vcoubard 1131:692ddf04fc42 82 These AD types are used to describe the capabilities of the
vcoubard 1131:692ddf04fc42 83 peripheral, and are inserted inside the advertising or scan
vcoubard 1131:692ddf04fc42 84 response payloads.
vcoubard 1131:692ddf04fc42 85
vcoubard 1131:692ddf04fc42 86 \par Source
vcoubard 1131:692ddf04fc42 87 \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 11, 18
vcoubard 1131:692ddf04fc42 88 \li \c https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile
vcoubard 1131:692ddf04fc42 89 */
vcoubard 1131:692ddf04fc42 90 /**********************************************************************/
vcoubard 1131:692ddf04fc42 91 enum DataType_t {
vcoubard 1131:692ddf04fc42 92 FLAGS = 0x01, /**< \ref *Flags */
vcoubard 1131:692ddf04fc42 93 INCOMPLETE_LIST_16BIT_SERVICE_IDS = 0x02, /**< Incomplete list of 16-bit Service IDs */
vcoubard 1131:692ddf04fc42 94 COMPLETE_LIST_16BIT_SERVICE_IDS = 0x03, /**< Complete list of 16-bit Service IDs */
vcoubard 1131:692ddf04fc42 95 INCOMPLETE_LIST_32BIT_SERVICE_IDS = 0x04, /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
vcoubard 1131:692ddf04fc42 96 COMPLETE_LIST_32BIT_SERVICE_IDS = 0x05, /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */
vcoubard 1131:692ddf04fc42 97 INCOMPLETE_LIST_128BIT_SERVICE_IDS = 0x06, /**< Incomplete list of 128-bit Service IDs */
vcoubard 1131:692ddf04fc42 98 COMPLETE_LIST_128BIT_SERVICE_IDS = 0x07, /**< Complete list of 128-bit Service IDs */
vcoubard 1131:692ddf04fc42 99 SHORTENED_LOCAL_NAME = 0x08, /**< Shortened Local Name */
vcoubard 1131:692ddf04fc42 100 COMPLETE_LOCAL_NAME = 0x09, /**< Complete Local Name */
vcoubard 1131:692ddf04fc42 101 TX_POWER_LEVEL = 0x0A, /**< TX Power Level (in dBm) */
vcoubard 1131:692ddf04fc42 102 DEVICE_ID = 0x10, /**< Device ID */
vcoubard 1131:692ddf04fc42 103 SLAVE_CONNECTION_INTERVAL_RANGE = 0x12, /**< Slave Connection Interval Range */
vcoubard 1131:692ddf04fc42 104 LIST_128BIT_SOLICITATION_IDS = 0x15, /**< List of 128 bit service UUIDs the device is looking for */
vcoubard 1131:692ddf04fc42 105 SERVICE_DATA = 0x16, /**< Service Data */
vcoubard 1131:692ddf04fc42 106 APPEARANCE = 0x19, /**< \ref Appearance */
vcoubard 1131:692ddf04fc42 107 ADVERTISING_INTERVAL = 0x1A, /**< Advertising Interval */
vcoubard 1131:692ddf04fc42 108 MANUFACTURER_SPECIFIC_DATA = 0xFF /**< Manufacturer Specific Data */
vcoubard 1131:692ddf04fc42 109 };
vcoubard 1131:692ddf04fc42 110 typedef enum DataType_t DataType; /* Deprecated type alias. This may be dropped in a future release. */
vcoubard 1131:692ddf04fc42 111
vcoubard 1131:692ddf04fc42 112 /**********************************************************************/
vcoubard 1131:692ddf04fc42 113 /*!
vcoubard 1131:692ddf04fc42 114 \brief
vcoubard 1131:692ddf04fc42 115 A list of values for the FLAGS AD Type.
vcoubard 1131:692ddf04fc42 116
vcoubard 1131:692ddf04fc42 117 \note
vcoubard 1131:692ddf04fc42 118 You can use more than one value in the FLAGS AD Type (ex.
vcoubard 1131:692ddf04fc42 119 LE_GENERAL_DISCOVERABLE and BREDR_NOT_SUPPORTED).
vcoubard 1131:692ddf04fc42 120
vcoubard 1131:692ddf04fc42 121 \par Source
vcoubard 1131:692ddf04fc42 122 \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 18.1
vcoubard 1131:692ddf04fc42 123 */
vcoubard 1131:692ddf04fc42 124 /**********************************************************************/
vcoubard 1131:692ddf04fc42 125 enum Flags_t {
vcoubard 1131:692ddf04fc42 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 1131:692ddf04fc42 132 typedef enum Flags_t Flags; /* Deprecated type alias. This may be dropped in a future release. */
vcoubard 1131:692ddf04fc42 133
vcoubard 1131:692ddf04fc42 134 /**********************************************************************/
vcoubard 1131:692ddf04fc42 135 /*!
vcoubard 1131:692ddf04fc42 136 \brief
vcoubard 1131:692ddf04fc42 137 A list of values for the APPEARANCE AD Type, which describes the
vcoubard 1131:692ddf04fc42 138 physical shape or appearance of the device.
vcoubard 1131:692ddf04fc42 139
vcoubard 1131:692ddf04fc42 140 \par Source
vcoubard 1131:692ddf04fc42 141 \li \c Bluetooth Core Specification Supplement, Part A, Section 1.12
vcoubard 1131:692ddf04fc42 142 \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 12.2
vcoubard 1131:692ddf04fc42 143 \li \c https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
vcoubard 1131:692ddf04fc42 144 */
vcoubard 1131:692ddf04fc42 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 1131:692ddf04fc42 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 1131:692ddf04fc42 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 1135:22aada733dbd 225 // find field
vcoubard 1135:22aada733dbd 226 uint8_t* field = findField(advDataType);
vcoubard 1135:22aada733dbd 227
vcoubard 1135:22aada733dbd 228 if (field) {
vcoubard 1135:22aada733dbd 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 1135:22aada733dbd 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 1135:22aada733dbd 252 // find field
vcoubard 1135:22aada733dbd 253 uint8_t* field = findField(advDataType);
vcoubard 1131:692ddf04fc42 254
vcoubard 1135:22aada733dbd 255 if (field) {
vcoubard 1135:22aada733dbd 256 // Field type already exist, replace field contents
vcoubard 1135:22aada733dbd 257 return updateField(advDataType, payload, len, field);
vcoubard 1135:22aada733dbd 258 } else {
vcoubard 1135:22aada733dbd 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 1131:692ddf04fc42 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 1131:692ddf04fc42 280 * @param flags
vcoubard 1131:692ddf04fc42 281 * LE_LIMITED_DISCOVERABLE
vcoubard 1131:692ddf04fc42 282 * The peripheral is discoverable for a limited period of time.
vcoubard 1131:692ddf04fc42 283 * LE_GENERAL_DISCOVERABLE
vcoubard 1131:692ddf04fc42 284 * The peripheral is permanently discoverable.
vcoubard 1131:692ddf04fc42 285 * BREDR_NOT_SUPPORTED
vcoubard 1131:692ddf04fc42 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 1131:692ddf04fc42 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 1131:692ddf04fc42 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 1131:692ddf04fc42 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 1131:692ddf04fc42 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 1131:692ddf04fc42 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 1131:692ddf04fc42 336 * Search advertisement data for field.
vcoubard 1131:692ddf04fc42 337 * Returns pointer to the first element in the field if found, NULL otherwise.
vcoubard 1131:692ddf04fc42 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 1131:692ddf04fc42 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 1131:692ddf04fc42 372 * Returns pointer to the first element in the field if found, NULL otherwise.
vcoubard 1131:692ddf04fc42 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 1131:692ddf04fc42 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 1131:692ddf04fc42 384 // advance to next field
vcoubard 1131:692ddf04fc42 385 idx += _payload[idx] + 1;
vcoubard 1131:692ddf04fc42 386 }
vcoubard 1131:692ddf04fc42 387
vcoubard 1131:692ddf04fc42 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 1135:22aada733dbd 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 1135:22aada733dbd 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 1135:22aada733dbd 418 // check if data fits
vcoubard 1135:22aada733dbd 419 if ((_payloadLen + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
vcoubard 1135:22aada733dbd 420 // make room for new field by moving the remainder of the
vcoubard 1135:22aada733dbd 421 // advertisement payload "to the right" starting after the
vcoubard 1135:22aada733dbd 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 1135:22aada733dbd 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 1135:22aada733dbd 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 1135:22aada733dbd 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 1135:22aada733dbd 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 1135:22aada733dbd 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 1135:22aada733dbd 473 // check if data fits
vcoubard 1135:22aada733dbd 474 if ((_payloadLen - dataLength + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
vcoubard 1135:22aada733dbd 475
vcoubard 1135:22aada733dbd 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 1135:22aada733dbd 482 // reduce length
vcoubard 1135:22aada733dbd 483 _payloadLen -= dataLength + 2;
vcoubard 1135:22aada733dbd 484
vcoubard 1135:22aada733dbd 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
rgrover1 710:b2e1a2660ec2 498 #endif // ifndef __GAP_ADVERTISING_DATA_H__