Official Sheffield ARMBand micro:bit program

Committer:
MrBedfordVan
Date:
Mon Oct 17 12:41:20 2016 +0000
Revision:
0:b9164b348919
Official Sheffield ARMBand Micro:bit program

Who changed what in which revision?

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