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