Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

Committer:
switches
Date:
Fri Nov 11 20:59:50 2016 +0000
Revision:
0:5c4d7b2438d3
Initial commit

Who changed what in which revision?

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