Pinned to some recent date

Committer:
Simon Cooksey
Date:
Thu Nov 17 16:43:53 2016 +0000
Revision:
0:fb7af294d5d9
Initial commit

Who changed what in which revision?

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