High level Bluetooth Low Energy API and radio abstraction layer

Dependents:   BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate BLE_ANCS_SDAPI_IRC ... more

Overview

The BLE_API is a high level abstraction for using Bluetooth Low Energy on multiple platforms. For details and examples using the BLE_API please see the BLE_API Summary Page. Or click on the API Documentation tab above.

Supported Services

Supported services can be found in the BLE_API/services folder.

Committer:
Vincent Coubard
Date:
Wed Sep 14 14:18:00 2016 +0100
Revision:
1208:65474dc93927
Parent:
1183:1589830dbdb7
Sync with 8d97fced5440d78c9557693b6d1632f1ab5d77b7

2016-09-01 08:21:37+01:00: Vincent Coubard
version v2.7.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 1183:1589830dbdb7 27 /**
vcoubard 1183:1589830dbdb7 28 * @brief This class provides several helper functions to generate properly
vcoubard 1183:1589830dbdb7 29 * formatted GAP Advertising and Scan Response data payloads.
vcoubard 1183:1589830dbdb7 30 *
vcoubard 1183:1589830dbdb7 31 * @note See Bluetooth Specification 4.0 (Vol. 3), Part C, Sections 11 and 18
vcoubard 1183:1589830dbdb7 32 * for further information on Advertising and Scan Response data.
vcoubard 1183:1589830dbdb7 33 *
vcoubard 1183:1589830dbdb7 34 * @par Advertising and Scan Response Payloads
vcoubard 1183:1589830dbdb7 35 * Advertising data and Scan Response data are organized around a set of
vcoubard 1183:1589830dbdb7 36 * data types called 'AD types' in Bluetooth 4.0 (see the Bluetooth Core
vcoubard 1183:1589830dbdb7 37 * Specification v4.0, Vol. 3, Part C, Sections 11 and 18).
vcoubard 1183:1589830dbdb7 38 *
vcoubard 1183:1589830dbdb7 39 * @par
vcoubard 1183:1589830dbdb7 40 * Each AD type has its own standardized assigned number, as defined
vcoubard 1183:1589830dbdb7 41 * by the Bluetooth SIG:
vcoubard 1183:1589830dbdb7 42 * https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile.
vcoubard 1183:1589830dbdb7 43 *
vcoubard 1183:1589830dbdb7 44 * @par
vcoubard 1183:1589830dbdb7 45 * For convenience, all appropriate AD types are encapsulated
vcoubard 1183:1589830dbdb7 46 * in GapAdvertisingData::DataType.
vcoubard 1183:1589830dbdb7 47 *
vcoubard 1183:1589830dbdb7 48 * @par
vcoubard 1183:1589830dbdb7 49 * Before the AD Types and their payload (if any) can be inserted into
vcoubard 1183:1589830dbdb7 50 * the Advertising or Scan Response frames, they need to be formatted as
vcoubard 1183:1589830dbdb7 51 * follows:
vcoubard 1183:1589830dbdb7 52 *
vcoubard 1183:1589830dbdb7 53 * @li @c Record length (1 byte).
vcoubard 1183:1589830dbdb7 54 * @li @c AD Type (1 byte).
vcoubard 1183:1589830dbdb7 55 * @li @c AD payload (optional; only present if record length > 1).
vcoubard 1183:1589830dbdb7 56 *
vcoubard 1183:1589830dbdb7 57 * @par
vcoubard 1183:1589830dbdb7 58 * This class takes care of properly formatting the payload, performs
vcoubard 1183:1589830dbdb7 59 * some basic checks on the payload length, and tries to avoid common
vcoubard 1183:1589830dbdb7 60 * errors like adding an exclusive AD field twice in the Advertising
vcoubard 1183:1589830dbdb7 61 * or Scan Response payload.
vcoubard 1183:1589830dbdb7 62 *
vcoubard 1183:1589830dbdb7 63 * @par EXAMPLE
vcoubard 1183:1589830dbdb7 64 *
vcoubard 1183:1589830dbdb7 65 * @code
vcoubard 1183:1589830dbdb7 66 *
vcoubard 1183:1589830dbdb7 67 * // ToDo
vcoubard 1183:1589830dbdb7 68 *
vcoubard 1183:1589830dbdb7 69 * @endcode
vcoubard 1183:1589830dbdb7 70 */
vcoubard 1131:692ddf04fc42 71 class GapAdvertisingData
vcoubard 1131:692ddf04fc42 72 {
vcoubard 1131:692ddf04fc42 73 public:
vcoubard 1131:692ddf04fc42 74 /*!
vcoubard 1183:1589830dbdb7 75 * @brief A list of Advertising Data types commonly used by peripherals.
vcoubard 1183:1589830dbdb7 76 * These AD types are used to describe the capabilities of the
vcoubard 1183:1589830dbdb7 77 * peripheral, and are inserted inside the advertising or scan
vcoubard 1183:1589830dbdb7 78 * response payloads.
vcoubard 1183:1589830dbdb7 79 *
vcoubard 1183:1589830dbdb7 80 * @par Source
vcoubard 1183:1589830dbdb7 81 *
vcoubard 1183:1589830dbdb7 82 * @li @c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 11, 18.
vcoubard 1183:1589830dbdb7 83 * @li @c https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile.
vcoubard 1183:1589830dbdb7 84 */
vcoubard 1131:692ddf04fc42 85 enum DataType_t {
vcoubard 1183:1589830dbdb7 86 FLAGS = 0x01, /**< Flags, refer to GapAdvertisingData::Flags_t. */
vcoubard 1183:1589830dbdb7 87 INCOMPLETE_LIST_16BIT_SERVICE_IDS = 0x02, /**< Incomplete list of 16-bit Service IDs. */
vcoubard 1183:1589830dbdb7 88 COMPLETE_LIST_16BIT_SERVICE_IDS = 0x03, /**< Complete list of 16-bit Service IDs. */
vcoubard 1183:1589830dbdb7 89 INCOMPLETE_LIST_32BIT_SERVICE_IDS = 0x04, /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0). */
vcoubard 1183:1589830dbdb7 90 COMPLETE_LIST_32BIT_SERVICE_IDS = 0x05, /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0). */
vcoubard 1183:1589830dbdb7 91 INCOMPLETE_LIST_128BIT_SERVICE_IDS = 0x06, /**< Incomplete list of 128-bit Service IDs. */
vcoubard 1183:1589830dbdb7 92 COMPLETE_LIST_128BIT_SERVICE_IDS = 0x07, /**< Complete list of 128-bit Service IDs. */
vcoubard 1183:1589830dbdb7 93 SHORTENED_LOCAL_NAME = 0x08, /**< Shortened Local Name. */
vcoubard 1183:1589830dbdb7 94 COMPLETE_LOCAL_NAME = 0x09, /**< Complete Local Name. */
vcoubard 1183:1589830dbdb7 95 TX_POWER_LEVEL = 0x0A, /**< TX Power Level (in dBm). */
vcoubard 1183:1589830dbdb7 96 DEVICE_ID = 0x10, /**< Device ID. */
vcoubard 1183:1589830dbdb7 97 SLAVE_CONNECTION_INTERVAL_RANGE = 0x12, /**< Slave Connection Interval Range. */
vcoubard 1183:1589830dbdb7 98 LIST_128BIT_SOLICITATION_IDS = 0x15, /**< List of 128 bit service UUIDs the device is looking for. */
vcoubard 1183:1589830dbdb7 99 SERVICE_DATA = 0x16, /**< Service Data. */
vcoubard 1183:1589830dbdb7 100 APPEARANCE = 0x19, /**< Appearance, refer to GapAdvertisingData::Appearance_t. */
vcoubard 1183:1589830dbdb7 101 ADVERTISING_INTERVAL = 0x1A, /**< Advertising Interval. */
vcoubard 1183:1589830dbdb7 102 MANUFACTURER_SPECIFIC_DATA = 0xFF /**< Manufacturer Specific Data. */
vcoubard 1131:692ddf04fc42 103 };
vcoubard 1183:1589830dbdb7 104 /**
vcoubard 1183:1589830dbdb7 105 * Type alias for GapAdvertisingData::DataType_t.
vcoubard 1183:1589830dbdb7 106 *
vcoubard 1183:1589830dbdb7 107 * @deprecated This type alias will be dropped in future releases.
vcoubard 1183:1589830dbdb7 108 */
vcoubard 1183:1589830dbdb7 109 typedef enum DataType_t DataType;
vcoubard 1131:692ddf04fc42 110
vcoubard 1183:1589830dbdb7 111 /**
vcoubard 1183:1589830dbdb7 112 * @brief A list of values for the FLAGS AD Type.
vcoubard 1183:1589830dbdb7 113 *
vcoubard 1183:1589830dbdb7 114 * @note You can use more than one value in the FLAGS AD Type (ex.
vcoubard 1183:1589830dbdb7 115 * LE_GENERAL_DISCOVERABLE and BREDR_NOT_SUPPORTED).
vcoubard 1183:1589830dbdb7 116 *
vcoubard 1183:1589830dbdb7 117 * @par Source
vcoubard 1183:1589830dbdb7 118 *
vcoubard 1183:1589830dbdb7 119 * @li @c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 18.1.
vcoubard 1183:1589830dbdb7 120 */
vcoubard 1131:692ddf04fc42 121 enum Flags_t {
vcoubard 1183:1589830dbdb7 122 LE_LIMITED_DISCOVERABLE = 0x01, /**< Peripheral device is discoverable for a limited period of time. */
vcoubard 1131:692ddf04fc42 123 LE_GENERAL_DISCOVERABLE = 0x02, /**< Peripheral device is discoverable at any moment. */
vcoubard 1131:692ddf04fc42 124 BREDR_NOT_SUPPORTED = 0x04, /**< Peripheral device is LE only. */
vcoubard 1131:692ddf04fc42 125 SIMULTANEOUS_LE_BREDR_C = 0x08, /**< Not relevant - central mode only. */
vcoubard 1131:692ddf04fc42 126 SIMULTANEOUS_LE_BREDR_H = 0x10 /**< Not relevant - central mode only. */
vcoubard 1131:692ddf04fc42 127 };
vcoubard 1183:1589830dbdb7 128 /**
vcoubard 1183:1589830dbdb7 129 * Type alias for GapAdvertisingData::Flags_t.
vcoubard 1183:1589830dbdb7 130 *
vcoubard 1183:1589830dbdb7 131 * @deprecated This type alias will be dropped in future releases.
vcoubard 1183:1589830dbdb7 132 */
vcoubard 1183:1589830dbdb7 133 typedef enum Flags_t Flags;
vcoubard 1131:692ddf04fc42 134
vcoubard 1183:1589830dbdb7 135 /**
vcoubard 1183:1589830dbdb7 136 * @brief
vcoubard 1183:1589830dbdb7 137 * A list of values for the APPEARANCE AD Type, which describes the
vcoubard 1183:1589830dbdb7 138 * physical shape or appearance of the device.
vcoubard 1183:1589830dbdb7 139 *
vcoubard 1183:1589830dbdb7 140 * @par Source
vcoubard 1183:1589830dbdb7 141 *
vcoubard 1183:1589830dbdb7 142 * @li @c Bluetooth Core Specification Supplement, Part A, Section 1.12.
vcoubard 1183:1589830dbdb7 143 * @li @c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 12.2.
vcoubard 1183:1589830dbdb7 144 * @li @c https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml.
vcoubard 1183:1589830dbdb7 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 1183:1589830dbdb7 197 /**
vcoubard 1183:1589830dbdb7 198 * Type alias for GapAdvertisingData::Appearance_t.
vcoubard 1183:1589830dbdb7 199 *
vcoubard 1183:1589830dbdb7 200 * @deprecated This type alias will be dropped in future releases.
vcoubard 1183:1589830dbdb7 201 */
vcoubard 1183:1589830dbdb7 202 typedef enum Appearance_t Appearance;
vcoubard 1131:692ddf04fc42 203
vcoubard 1183:1589830dbdb7 204 /**
vcoubard 1183:1589830dbdb7 205 * Empty constructor.
vcoubard 1183:1589830dbdb7 206 */
vcoubard 1131:692ddf04fc42 207 GapAdvertisingData(void) : _payload(), _payloadLen(0), _appearance(GENERIC_TAG) {
vcoubard 1131:692ddf04fc42 208 /* empty */
vcoubard 1131:692ddf04fc42 209 }
vcoubard 1131:692ddf04fc42 210
vcoubard 1131:692ddf04fc42 211 /**
vcoubard 1183:1589830dbdb7 212 * Adds advertising data based on the specified AD type (see GapAdvertisingData::DataType_t).
vcoubard 1135:22aada733dbd 213 * If the supplied AD type is already present in the advertising
vcoubard 1135:22aada733dbd 214 * payload, then the value is updated.
vcoubard 1131:692ddf04fc42 215 *
vcoubard 1131:692ddf04fc42 216 * @param[in] advDataType The Advertising 'DataType' to add.
vcoubard 1131:692ddf04fc42 217 * @param[in] payload Pointer to the payload contents.
vcoubard 1131:692ddf04fc42 218 * @param[in] len Size of the payload in bytes.
vcoubard 1131:692ddf04fc42 219 *
vcoubard 1135:22aada733dbd 220 * @return BLE_ERROR_BUFFER_OVERFLOW if the new value causes the
vcoubard 1135:22aada733dbd 221 * advertising buffer to overflow. BLE_ERROR_NONE is returned
vcoubard 1135:22aada733dbd 222 * on success.
vcoubard 1135:22aada733dbd 223 *
vcoubard 1135:22aada733dbd 224 * @note When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS,
vcoubard 1135:22aada733dbd 225 * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS,
vcoubard 1135:22aada733dbd 226 * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS,
vcoubard 1135:22aada733dbd 227 * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the
vcoubard 1135:22aada733dbd 228 * supplied value is appended to the values previously added to the
vcoubard 1135:22aada733dbd 229 * payload.
vcoubard 1135:22aada733dbd 230 */
vcoubard 1135:22aada733dbd 231 ble_error_t addData(DataType_t advDataType, const uint8_t *payload, uint8_t len)
vcoubard 1135:22aada733dbd 232 {
vcoubard 1183:1589830dbdb7 233 /* Find field */
vcoubard 1135:22aada733dbd 234 uint8_t* field = findField(advDataType);
vcoubard 1135:22aada733dbd 235
vcoubard 1135:22aada733dbd 236 if (field) {
vcoubard 1183:1589830dbdb7 237 /* Field type already exist, either add to field or replace */
vcoubard 1135:22aada733dbd 238 return addField(advDataType, payload, len, field);
vcoubard 1135:22aada733dbd 239 } else {
vcoubard 1183:1589830dbdb7 240 /* Field doesn't exists, insert new */
vcoubard 1135:22aada733dbd 241 return appendField(advDataType, payload, len);
vcoubard 1135:22aada733dbd 242 }
vcoubard 1135:22aada733dbd 243 }
vcoubard 1135:22aada733dbd 244
vcoubard 1135:22aada733dbd 245 /**
vcoubard 1135:22aada733dbd 246 * Update a particular ADV field in the advertising payload (based on
vcoubard 1135:22aada733dbd 247 * matching type).
vcoubard 1135:22aada733dbd 248 *
vcoubard 1135:22aada733dbd 249 * @param[in] advDataType The Advertising 'DataType' to add.
vcoubard 1135:22aada733dbd 250 * @param[in] payload Pointer to the payload contents.
vcoubard 1135:22aada733dbd 251 * @param[in] len Size of the payload in bytes.
vcoubard 1135:22aada733dbd 252 *
vcoubard 1135:22aada733dbd 253 * @return BLE_ERROR_UNSPECIFIED if the specified field is not found,
vcoubard 1135:22aada733dbd 254 * BLE_ERROR_BUFFER_OVERFLOW if the new value causes the
vcoubard 1135:22aada733dbd 255 * advertising buffer to overflow. BLE_ERROR_NONE is returned
vcoubard 1135:22aada733dbd 256 * on success.
vcoubard 1131:692ddf04fc42 257 */
vcoubard 1131:692ddf04fc42 258 ble_error_t updateData(DataType_t advDataType, const uint8_t *payload, uint8_t len)
vcoubard 1131:692ddf04fc42 259 {
vcoubard 1183:1589830dbdb7 260 /* Find field */
vcoubard 1135:22aada733dbd 261 uint8_t* field = findField(advDataType);
vcoubard 1131:692ddf04fc42 262
vcoubard 1135:22aada733dbd 263 if (field) {
vcoubard 1183:1589830dbdb7 264 /* Field type already exist, replace field contents */
vcoubard 1135:22aada733dbd 265 return updateField(advDataType, payload, len, field);
vcoubard 1135:22aada733dbd 266 } else {
vcoubard 1183:1589830dbdb7 267 /* field doesn't exists, return an error */
vcoubard 1135:22aada733dbd 268 return BLE_ERROR_UNSPECIFIED;
vcoubard 1131:692ddf04fc42 269 }
vcoubard 1131:692ddf04fc42 270 }
vcoubard 1131:692ddf04fc42 271
vcoubard 1131:692ddf04fc42 272 /**
vcoubard 1131:692ddf04fc42 273 * Helper function to add APPEARANCE data to the advertising payload.
vcoubard 1131:692ddf04fc42 274 *
vcoubard 1131:692ddf04fc42 275 * @param appearance
vcoubard 1131:692ddf04fc42 276 * The APPEARANCE value to add.
vcoubard 1131:692ddf04fc42 277 *
vcoubard 1131:692ddf04fc42 278 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
vcoubard 1183:1589830dbdb7 279 * advertising buffer to overflow, else BLE_ERROR_NONE.
vcoubard 1131:692ddf04fc42 280 */
vcoubard 1131:692ddf04fc42 281 ble_error_t addAppearance(Appearance appearance = GENERIC_TAG) {
vcoubard 1131:692ddf04fc42 282 _appearance = appearance;
vcoubard 1131:692ddf04fc42 283 return addData(GapAdvertisingData::APPEARANCE, (uint8_t *)&appearance, 2);
vcoubard 1131:692ddf04fc42 284 }
vcoubard 1131:692ddf04fc42 285
vcoubard 1131:692ddf04fc42 286 /**
vcoubard 1131:692ddf04fc42 287 * Helper function to add FLAGS data to the advertising payload.
vcoubard 1183:1589830dbdb7 288 *
vcoubard 1183:1589830dbdb7 289 * @param[in] flags
vcoubard 1183:1589830dbdb7 290 * LE_LIMITED_DISCOVERABLE
vcoubard 1183:1589830dbdb7 291 * The peripheral is discoverable for a limited period of time.
vcoubard 1183:1589830dbdb7 292 * LE_GENERAL_DISCOVERABLE
vcoubard 1183:1589830dbdb7 293 * The peripheral is permanently discoverable.
vcoubard 1183:1589830dbdb7 294 * BREDR_NOT_SUPPORTED
vcoubard 1183:1589830dbdb7 295 * This peripheral is a Bluetooth Low Energy only device (no EDR support).
vcoubard 1131:692ddf04fc42 296 *
vcoubard 1131:692ddf04fc42 297 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
vcoubard 1183:1589830dbdb7 298 * advertising buffer to overflow, else BLE_ERROR_NONE.
vcoubard 1131:692ddf04fc42 299 */
vcoubard 1131:692ddf04fc42 300 ble_error_t addFlags(uint8_t flags = LE_GENERAL_DISCOVERABLE) {
vcoubard 1131:692ddf04fc42 301 return addData(GapAdvertisingData::FLAGS, &flags, 1);
vcoubard 1131:692ddf04fc42 302 }
vcoubard 1131:692ddf04fc42 303
vcoubard 1131:692ddf04fc42 304 /**
vcoubard 1131:692ddf04fc42 305 * Helper function to add TX_POWER_LEVEL data to the advertising payload.
vcoubard 1131:692ddf04fc42 306 *
vcoubard 1131:692ddf04fc42 307 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
vcoubard 1183:1589830dbdb7 308 * advertising buffer to overflow, else BLE_ERROR_NONE.
vcoubard 1131:692ddf04fc42 309 */
vcoubard 1131:692ddf04fc42 310 ble_error_t addTxPower(int8_t txPower) {
vcoubard 1131:692ddf04fc42 311 /* To Do: Basic error checking to make sure txPower is in range. */
vcoubard 1131:692ddf04fc42 312 return addData(GapAdvertisingData::TX_POWER_LEVEL, (uint8_t *)&txPower, 1);
vcoubard 1131:692ddf04fc42 313 }
vcoubard 1131:692ddf04fc42 314
vcoubard 1131:692ddf04fc42 315 /**
vcoubard 1131:692ddf04fc42 316 * Clears the payload and resets the payload length counter.
vcoubard 1131:692ddf04fc42 317 */
vcoubard 1131:692ddf04fc42 318 void clear(void) {
vcoubard 1131:692ddf04fc42 319 memset(&_payload, 0, GAP_ADVERTISING_DATA_MAX_PAYLOAD);
vcoubard 1131:692ddf04fc42 320 _payloadLen = 0;
vcoubard 1131:692ddf04fc42 321 }
vcoubard 1131:692ddf04fc42 322
vcoubard 1131:692ddf04fc42 323 /**
vcoubard 1183:1589830dbdb7 324 * Access the current payload.
vcoubard 1183:1589830dbdb7 325 *
vcoubard 1183:1589830dbdb7 326 * @return A pointer to the current payload.
vcoubard 1131:692ddf04fc42 327 */
vcoubard 1131:692ddf04fc42 328 const uint8_t *getPayload(void) const {
vcoubard 1131:692ddf04fc42 329 return _payload;
vcoubard 1131:692ddf04fc42 330 }
vcoubard 1131:692ddf04fc42 331
vcoubard 1131:692ddf04fc42 332 /**
vcoubard 1183:1589830dbdb7 333 * Get the current payload length.
vcoubard 1183:1589830dbdb7 334 *
vcoubard 1183:1589830dbdb7 335 * @return The current payload length (0..31 bytes).
vcoubard 1131:692ddf04fc42 336 */
vcoubard 1131:692ddf04fc42 337 uint8_t getPayloadLen(void) const {
vcoubard 1131:692ddf04fc42 338 return _payloadLen;
vcoubard 1131:692ddf04fc42 339 }
vcoubard 1131:692ddf04fc42 340
vcoubard 1131:692ddf04fc42 341 /**
vcoubard 1183:1589830dbdb7 342 * Get the current appearance value.
vcoubard 1183:1589830dbdb7 343 *
vcoubard 1183:1589830dbdb7 344 * @return The 16-bit appearance value for this device.
vcoubard 1131:692ddf04fc42 345 */
vcoubard 1131:692ddf04fc42 346 uint16_t getAppearance(void) const {
vcoubard 1131:692ddf04fc42 347 return (uint16_t)_appearance;
vcoubard 1131:692ddf04fc42 348 }
vcoubard 1131:692ddf04fc42 349
vcoubard 1131:692ddf04fc42 350 /**
vcoubard 1183:1589830dbdb7 351 * Search advertisement data for a specific field.
vcoubard 1183:1589830dbdb7 352 *
vcoubard 1183:1589830dbdb7 353 * @param[in] type
vcoubard 1183:1589830dbdb7 354 * The type of the field to find.
vcoubard 1183:1589830dbdb7 355 *
vcoubard 1183:1589830dbdb7 356 * @return A pointer to the first element in the field if found, NULL otherwise.
vcoubard 1183:1589830dbdb7 357 * Where the first element is the length of the field.
vcoubard 1131:692ddf04fc42 358 */
vcoubard 1131:692ddf04fc42 359 const uint8_t* findField(DataType_t type) const {
vcoubard 1131:692ddf04fc42 360 return findField(type);
vcoubard 1131:692ddf04fc42 361 }
vcoubard 1131:692ddf04fc42 362
vcoubard 1131:692ddf04fc42 363 private:
vcoubard 1131:692ddf04fc42 364 /**
vcoubard 1183:1589830dbdb7 365 * Append advertising data based on the specified AD type (see
vcoubard 1183:1589830dbdb7 366 * GapAdvertisingData::DataType_t).
vcoubard 1183:1589830dbdb7 367 *
vcoubard 1183:1589830dbdb7 368 * @param[in] advDataType
vcoubard 1183:1589830dbdb7 369 * The type of the new data.
vcoubard 1183:1589830dbdb7 370 * @param[in] payload
vcoubard 1183:1589830dbdb7 371 * A pointer to the data to be appended to the advertising
vcoubard 1183:1589830dbdb7 372 * payload.
vcoubard 1183:1589830dbdb7 373 * @param[in] len
vcoubard 1183:1589830dbdb7 374 * The length of th data pointed to by @p payload.
vcoubard 1183:1589830dbdb7 375 *
vcoubard 1183:1589830dbdb7 376 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
vcoubard 1183:1589830dbdb7 377 * advertising buffer to overflow, else BLE_ERROR_NONE.
vcoubard 1131:692ddf04fc42 378 */
vcoubard 1131:692ddf04fc42 379 ble_error_t appendField(DataType advDataType, const uint8_t *payload, uint8_t len)
vcoubard 1131:692ddf04fc42 380 {
vcoubard 1131:692ddf04fc42 381 /* Make sure we don't exceed the 31 byte payload limit */
vcoubard 1131:692ddf04fc42 382 if (_payloadLen + len + 2 > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
vcoubard 1131:692ddf04fc42 383 return BLE_ERROR_BUFFER_OVERFLOW;
vcoubard 1131:692ddf04fc42 384 }
vcoubard 1131:692ddf04fc42 385
vcoubard 1131:692ddf04fc42 386 /* Field length. */
vcoubard 1131:692ddf04fc42 387 memset(&_payload[_payloadLen], len + 1, 1);
vcoubard 1131:692ddf04fc42 388 _payloadLen++;
vcoubard 1131:692ddf04fc42 389
vcoubard 1131:692ddf04fc42 390 /* Field ID. */
vcoubard 1131:692ddf04fc42 391 memset(&_payload[_payloadLen], (uint8_t)advDataType, 1);
vcoubard 1131:692ddf04fc42 392 _payloadLen++;
vcoubard 1131:692ddf04fc42 393
vcoubard 1131:692ddf04fc42 394 /* Payload. */
vcoubard 1131:692ddf04fc42 395 memcpy(&_payload[_payloadLen], payload, len);
vcoubard 1131:692ddf04fc42 396 _payloadLen += len;
vcoubard 1131:692ddf04fc42 397
vcoubard 1131:692ddf04fc42 398 return BLE_ERROR_NONE;
vcoubard 1131:692ddf04fc42 399 }
vcoubard 1131:692ddf04fc42 400
vcoubard 1131:692ddf04fc42 401 /**
vcoubard 1131:692ddf04fc42 402 * Search advertisement data for field.
vcoubard 1183:1589830dbdb7 403 *
vcoubard 1183:1589830dbdb7 404 * @param[in] type
vcoubard 1183:1589830dbdb7 405 * The type of the data to find.
vcoubard 1183:1589830dbdb7 406 *
vcoubard 1183:1589830dbdb7 407 * @return A pointer to the first element in the field if found, NULL
vcoubard 1183:1589830dbdb7 408 * otherwise. Where the first element is the length of the field.
vcoubard 1131:692ddf04fc42 409 */
vcoubard 1131:692ddf04fc42 410 uint8_t* findField(DataType_t type) {
vcoubard 1183:1589830dbdb7 411 /* Scan through advertisement data */
vcoubard 1131:692ddf04fc42 412 for (uint8_t idx = 0; idx < _payloadLen; ) {
vcoubard 1131:692ddf04fc42 413 uint8_t fieldType = _payload[idx + 1];
vcoubard 1131:692ddf04fc42 414
vcoubard 1131:692ddf04fc42 415 if (fieldType == type) {
vcoubard 1131:692ddf04fc42 416 return &_payload[idx];
vcoubard 1131:692ddf04fc42 417 }
vcoubard 1131:692ddf04fc42 418
vcoubard 1183:1589830dbdb7 419 /* Advance to next field */
vcoubard 1131:692ddf04fc42 420 idx += _payload[idx] + 1;
vcoubard 1131:692ddf04fc42 421 }
vcoubard 1131:692ddf04fc42 422
vcoubard 1183:1589830dbdb7 423 /* Field not found */
vcoubard 1131:692ddf04fc42 424 return NULL;
vcoubard 1131:692ddf04fc42 425 }
vcoubard 1131:692ddf04fc42 426
vcoubard 1135:22aada733dbd 427 /**
vcoubard 1135:22aada733dbd 428 * Given the a pointer to a field in the advertising payload it replaces
vcoubard 1135:22aada733dbd 429 * the existing data in the field with the supplied data.
vcoubard 1135:22aada733dbd 430 *
vcoubard 1183:1589830dbdb7 431 * @param[in] advDataType
vcoubard 1183:1589830dbdb7 432 * The type of the new data.
vcoubard 1183:1589830dbdb7 433 * @param[in] payload
vcoubard 1183:1589830dbdb7 434 * A pointer to the data to be added to the advertising
vcoubard 1183:1589830dbdb7 435 * payload.
vcoubard 1183:1589830dbdb7 436 * @param[in] len
vcoubard 1183:1589830dbdb7 437 * The length of th data pointed to by @p payload.
vcoubard 1183:1589830dbdb7 438 * @param[in] field
vcoubard 1183:1589830dbdb7 439 * A pointer to the field of type @p advDataType in the
vcoubard 1183:1589830dbdb7 440 * advertising buffer.
vcoubard 1183:1589830dbdb7 441 *
vcoubard 1135:22aada733dbd 442 * When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS,
vcoubard 1135:22aada733dbd 443 * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS,
vcoubard 1135:22aada733dbd 444 * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS,
vcoubard 1135:22aada733dbd 445 * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the
vcoubard 1135:22aada733dbd 446 * supplied value is appended to the values previously added to the
vcoubard 1135:22aada733dbd 447 * payload.
vcoubard 1135:22aada733dbd 448 *
vcoubard 1183:1589830dbdb7 449 * @return BLE_ERROR_NONE on success.
vcoubard 1135:22aada733dbd 450 */
vcoubard 1135:22aada733dbd 451 ble_error_t addField(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field)
vcoubard 1135:22aada733dbd 452 {
vcoubard 1135:22aada733dbd 453 ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW;
vcoubard 1135:22aada733dbd 454
vcoubard 1135:22aada733dbd 455 switch(advDataType) {
vcoubard 1183:1589830dbdb7 456 /* These fields will have the new data appended if there is sufficient space */
vcoubard 1135:22aada733dbd 457 case INCOMPLETE_LIST_16BIT_SERVICE_IDS:
vcoubard 1135:22aada733dbd 458 case COMPLETE_LIST_16BIT_SERVICE_IDS:
vcoubard 1135:22aada733dbd 459 case INCOMPLETE_LIST_32BIT_SERVICE_IDS:
vcoubard 1135:22aada733dbd 460 case COMPLETE_LIST_32BIT_SERVICE_IDS:
vcoubard 1135:22aada733dbd 461 case INCOMPLETE_LIST_128BIT_SERVICE_IDS:
vcoubard 1135:22aada733dbd 462 case COMPLETE_LIST_128BIT_SERVICE_IDS:
vcoubard 1135:22aada733dbd 463 case LIST_128BIT_SOLICITATION_IDS: {
vcoubard 1183:1589830dbdb7 464 /* Check if data fits */
vcoubard 1135:22aada733dbd 465 if ((_payloadLen + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
vcoubard 1183:1589830dbdb7 466 /*
vcoubard 1183:1589830dbdb7 467 * Make room for new field by moving the remainder of the
vcoubard 1183:1589830dbdb7 468 * advertisement payload "to the right" starting after the
vcoubard 1183:1589830dbdb7 469 * TYPE field.
vcoubard 1183:1589830dbdb7 470 */
vcoubard 1135:22aada733dbd 471 uint8_t* end = &_payload[_payloadLen];
vcoubard 1135:22aada733dbd 472
vcoubard 1135:22aada733dbd 473 while (&field[1] < end) {
vcoubard 1135:22aada733dbd 474 end[len] = *end;
vcoubard 1135:22aada733dbd 475 end--;
vcoubard 1135:22aada733dbd 476 }
vcoubard 1135:22aada733dbd 477
vcoubard 1183:1589830dbdb7 478 /* Insert new data */
vcoubard 1135:22aada733dbd 479 for (uint8_t idx = 0; idx < len; idx++) {
vcoubard 1135:22aada733dbd 480 field[2 + idx] = payload[idx];
vcoubard 1135:22aada733dbd 481 }
vcoubard 1135:22aada733dbd 482
vcoubard 1183:1589830dbdb7 483 /* Increment lengths */
vcoubard 1135:22aada733dbd 484 field[0] += len;
vcoubard 1135:22aada733dbd 485 _payloadLen += len;
vcoubard 1135:22aada733dbd 486
vcoubard 1135:22aada733dbd 487 result = BLE_ERROR_NONE;
vcoubard 1135:22aada733dbd 488 }
vcoubard 1135:22aada733dbd 489
vcoubard 1135:22aada733dbd 490 break;
vcoubard 1135:22aada733dbd 491 }
vcoubard 1183:1589830dbdb7 492 /* These fields will be overwritten with the new value */
vcoubard 1135:22aada733dbd 493 default: {
vcoubard 1135:22aada733dbd 494 result = updateField(advDataType, payload, len, field);
vcoubard 1135:22aada733dbd 495
vcoubard 1135:22aada733dbd 496 break;
vcoubard 1135:22aada733dbd 497 }
vcoubard 1135:22aada733dbd 498 }
vcoubard 1135:22aada733dbd 499
vcoubard 1135:22aada733dbd 500 return result;
vcoubard 1135:22aada733dbd 501 }
vcoubard 1135:22aada733dbd 502
vcoubard 1135:22aada733dbd 503 /**
vcoubard 1135:22aada733dbd 504 * Given the a pointer to a field in the advertising payload it replaces
vcoubard 1135:22aada733dbd 505 * the existing data in the field with the supplied data.
vcoubard 1183:1589830dbdb7 506 *
vcoubard 1183:1589830dbdb7 507 * @param[in] advDataType
vcoubard 1183:1589830dbdb7 508 * The type of the data to be updated.
vcoubard 1183:1589830dbdb7 509 * @param[in] payload
vcoubard 1183:1589830dbdb7 510 * A pointer to the data to be updated to the advertising
vcoubard 1183:1589830dbdb7 511 * payload.
vcoubard 1183:1589830dbdb7 512 * @param[in] len
vcoubard 1183:1589830dbdb7 513 * The length of th data pointed to by @p payload.
vcoubard 1183:1589830dbdb7 514 * @param[in] field
vcoubard 1183:1589830dbdb7 515 * A pointer to the field of type @p advDataType in the
vcoubard 1183:1589830dbdb7 516 * advertising buffer.
vcoubard 1183:1589830dbdb7 517 *
vcoubard 1183:1589830dbdb7 518 * @return BLE_ERROR_NONE on success.
vcoubard 1135:22aada733dbd 519 */
vcoubard 1135:22aada733dbd 520 ble_error_t updateField(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field)
vcoubard 1135:22aada733dbd 521 {
vcoubard 1135:22aada733dbd 522 ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW;
vcoubard 1135:22aada733dbd 523 uint8_t dataLength = field[0] - 1;
vcoubard 1135:22aada733dbd 524
vcoubard 1183:1589830dbdb7 525 /* New data has same length, do in-order replacement */
vcoubard 1135:22aada733dbd 526 if (len == dataLength) {
vcoubard 1135:22aada733dbd 527 for (uint8_t idx = 0; idx < dataLength; idx++) {
vcoubard 1135:22aada733dbd 528 field[2 + idx] = payload[idx];
vcoubard 1135:22aada733dbd 529 }
vcoubard 1135:22aada733dbd 530
vcoubard 1135:22aada733dbd 531 result = BLE_ERROR_NONE;
vcoubard 1135:22aada733dbd 532 } else {
vcoubard 1183:1589830dbdb7 533 /* Check if data fits */
vcoubard 1135:22aada733dbd 534 if ((_payloadLen - dataLength + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
vcoubard 1135:22aada733dbd 535
vcoubard 1183:1589830dbdb7 536 /* Remove old field */
vcoubard 1135:22aada733dbd 537 while ((field + dataLength + 2) < &_payload[_payloadLen]) {
vcoubard 1135:22aada733dbd 538 *field = field[dataLength + 2];
vcoubard 1135:22aada733dbd 539 field++;
vcoubard 1135:22aada733dbd 540 }
vcoubard 1135:22aada733dbd 541
vcoubard 1183:1589830dbdb7 542 /* Reduce length */
vcoubard 1135:22aada733dbd 543 _payloadLen -= dataLength + 2;
vcoubard 1135:22aada733dbd 544
vcoubard 1183:1589830dbdb7 545 /* Add new field */
vcoubard 1135:22aada733dbd 546 result = appendField(advDataType, payload, len);
vcoubard 1135:22aada733dbd 547 }
vcoubard 1135:22aada733dbd 548 }
vcoubard 1135:22aada733dbd 549
vcoubard 1135:22aada733dbd 550 return result;
vcoubard 1135:22aada733dbd 551 }
vcoubard 1135:22aada733dbd 552
vcoubard 1183:1589830dbdb7 553 /**
vcoubard 1183:1589830dbdb7 554 * The advertising data buffer
vcoubard 1183:1589830dbdb7 555 */
vcoubard 1131:692ddf04fc42 556 uint8_t _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD];
vcoubard 1183:1589830dbdb7 557 /**
vcoubard 1183:1589830dbdb7 558 * The length of the data added to the advertising buffer.
vcoubard 1183:1589830dbdb7 559 */
vcoubard 1131:692ddf04fc42 560 uint8_t _payloadLen;
vcoubard 1183:1589830dbdb7 561 /**
vcoubard 1183:1589830dbdb7 562 * Appearance value.
vcoubard 1183:1589830dbdb7 563 */
vcoubard 1131:692ddf04fc42 564 uint16_t _appearance;
vcoubard 1131:692ddf04fc42 565 };
vcoubard 1131:692ddf04fc42 566
vcoubard 1183:1589830dbdb7 567 #endif /* ifndef __GAP_ADVERTISING_DATA_H__ */