add "LE Device Address" 0x1B to advertising data types
Fork of BLE_API by
GapAdvertisingData.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef __GAP_ADVERTISING_DATA_H__ 00018 #define __GAP_ADVERTISING_DATA_H__ 00019 00020 #include <stdint.h> 00021 #include <string.h> 00022 00023 #include "blecommon.h" 00024 00025 #define GAP_ADVERTISING_DATA_MAX_PAYLOAD (31) 00026 00027 /**************************************************************************/ 00028 /*! 00029 \brief 00030 This class provides several helper functions to generate properly 00031 formatted GAP Advertising and Scan Response data payloads. 00032 00033 \note 00034 See Bluetooth Specification 4.0 (Vol. 3), Part C, Sections 11 and 18 00035 for further information on Advertising and Scan Response data. 00036 00037 \par Advertising and Scan Response Payloads 00038 Advertising data and Scan Response data are organized around a set of 00039 data types called 'AD types' in Bluetooth 4.0 (see the Bluetooth Core 00040 Specification v4.0, Vol. 3, Part C, Sections 11 and 18). 00041 00042 \par 00043 Each AD type has its own standardized assigned number, as defined 00044 by the Bluetooth SIG: 00045 https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile 00046 00047 \par 00048 For convenience, all appropriate AD types are encapsulated 00049 in GapAdvertisingData::DataType. 00050 00051 \par 00052 Before the AD Types and their payload (if any) can be inserted into 00053 the Advertising or Scan Response frames, they need to be formatted as 00054 follows: 00055 00056 \li \c Record length (1 byte). 00057 \li \c AD Type (1 byte). 00058 \li \c AD payload (optional; only present if record length > 1). 00059 00060 \par 00061 This class takes care of properly formatting the payload, performs 00062 some basic checks on the payload length, and tries to avoid common 00063 errors like adding an exclusive AD field twice in the Advertising 00064 or Scan Response payload. 00065 00066 \par EXAMPLE 00067 00068 \code 00069 00070 // ToDo 00071 00072 \endcode 00073 */ 00074 /**************************************************************************/ 00075 class GapAdvertisingData 00076 { 00077 public: 00078 /**********************************************************************/ 00079 /*! 00080 \brief 00081 A list of Advertising Data types commonly used by peripherals. 00082 These AD types are used to describe the capabilities of the 00083 peripheral, and are inserted inside the advertising or scan 00084 response payloads. 00085 00086 \par Source 00087 \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 11, 18 00088 \li \c https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile 00089 */ 00090 /**********************************************************************/ 00091 enum DataType_t { 00092 FLAGS = 0x01, /**< \ref *Flags */ 00093 INCOMPLETE_LIST_16BIT_SERVICE_IDS = 0x02, /**< Incomplete list of 16-bit Service IDs */ 00094 COMPLETE_LIST_16BIT_SERVICE_IDS = 0x03, /**< Complete list of 16-bit Service IDs */ 00095 INCOMPLETE_LIST_32BIT_SERVICE_IDS = 0x04, /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ 00096 COMPLETE_LIST_32BIT_SERVICE_IDS = 0x05, /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ 00097 INCOMPLETE_LIST_128BIT_SERVICE_IDS = 0x06, /**< Incomplete list of 128-bit Service IDs */ 00098 COMPLETE_LIST_128BIT_SERVICE_IDS = 0x07, /**< Complete list of 128-bit Service IDs */ 00099 SHORTENED_LOCAL_NAME = 0x08, /**< Shortened Local Name */ 00100 COMPLETE_LOCAL_NAME = 0x09, /**< Complete Local Name */ 00101 TX_POWER_LEVEL = 0x0A, /**< TX Power Level (in dBm) */ 00102 DEVICE_ID = 0x10, /**< Device ID */ 00103 SLAVE_CONNECTION_INTERVAL_RANGE = 0x12, /**< Slave Connection Interval Range */ 00104 LIST_128BIT_SOLICITATION_IDS = 0x15, /**< List of 128 bit service UUIDs the device is looking for */ 00105 SERVICE_DATA = 0x16, /**< Service Data */ 00106 APPEARANCE = 0x19, /**< \ref Appearance */ 00107 ADVERTISING_INTERVAL = 0x1A, /**< Advertising Interval */ 00108 BLE_ADDRESS = 0x1B, /**< Bluetooth device address */ 00109 MANUFACTURER_SPECIFIC_DATA = 0xFF /**< Manufacturer Specific Data */ 00110 }; 00111 typedef enum DataType_t DataType; /* Deprecated type alias. This may be dropped in a future release. */ 00112 00113 /**********************************************************************/ 00114 /*! 00115 \brief 00116 A list of values for the FLAGS AD Type. 00117 00118 \note 00119 You can use more than one value in the FLAGS AD Type (ex. 00120 LE_GENERAL_DISCOVERABLE and BREDR_NOT_SUPPORTED). 00121 00122 \par Source 00123 \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 18.1 00124 */ 00125 /**********************************************************************/ 00126 enum Flags_t { 00127 LE_LIMITED_DISCOVERABLE = 0x01, /**< *Peripheral device is discoverable for a limited period of time. */ 00128 LE_GENERAL_DISCOVERABLE = 0x02, /**< Peripheral device is discoverable at any moment. */ 00129 BREDR_NOT_SUPPORTED = 0x04, /**< Peripheral device is LE only. */ 00130 SIMULTANEOUS_LE_BREDR_C = 0x08, /**< Not relevant - central mode only. */ 00131 SIMULTANEOUS_LE_BREDR_H = 0x10 /**< Not relevant - central mode only. */ 00132 }; 00133 typedef enum Flags_t Flags; /* Deprecated type alias. This may be dropped in a future release. */ 00134 00135 /**********************************************************************/ 00136 /*! 00137 \brief 00138 A list of values for the APPEARANCE AD Type, which describes the 00139 physical shape or appearance of the device. 00140 00141 \par Source 00142 \li \c Bluetooth Core Specification Supplement, Part A, Section 1.12 00143 \li \c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 12.2 00144 \li \c https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml 00145 */ 00146 /**********************************************************************/ 00147 enum Appearance_t { 00148 UNKNOWN = 0, /**< Unknown or unspecified appearance type. */ 00149 GENERIC_PHONE = 64, /**< Generic Phone. */ 00150 GENERIC_COMPUTER = 128, /**< Generic Computer. */ 00151 GENERIC_WATCH = 192, /**< Generic Watch. */ 00152 WATCH_SPORTS_WATCH = 193, /**< Sports Watch. */ 00153 GENERIC_CLOCK = 256, /**< Generic Clock. */ 00154 GENERIC_DISPLAY = 320, /**< Generic Display. */ 00155 GENERIC_REMOTE_CONTROL = 384, /**< Generic Remote Control. */ 00156 GENERIC_EYE_GLASSES = 448, /**< Generic Eye Glasses. */ 00157 GENERIC_TAG = 512, /**< Generic Tag. */ 00158 GENERIC_KEYRING = 576, /**< Generic Keyring. */ 00159 GENERIC_MEDIA_PLAYER = 640, /**< Generic Media Player. */ 00160 GENERIC_BARCODE_SCANNER = 704, /**< Generic Barcode Scanner. */ 00161 GENERIC_THERMOMETER = 768, /**< Generic Thermometer. */ 00162 THERMOMETER_EAR = 769, /**< Ear Thermometer. */ 00163 GENERIC_HEART_RATE_SENSOR = 832, /**< Generic Heart Rate Sensor. */ 00164 HEART_RATE_SENSOR_HEART_RATE_BELT = 833, /**< Belt Heart Rate Sensor. */ 00165 GENERIC_BLOOD_PRESSURE = 896, /**< Generic Blood Pressure. */ 00166 BLOOD_PRESSURE_ARM = 897, /**< Arm Blood Pressure. */ 00167 BLOOD_PRESSURE_WRIST = 898, /**< Wrist Blood Pressure. */ 00168 HUMAN_INTERFACE_DEVICE_HID = 960, /**< Human Interface Device (HID). */ 00169 KEYBOARD = 961, /**< Keyboard. */ 00170 MOUSE = 962, /**< Mouse. */ 00171 JOYSTICK = 963, /**< Joystick. */ 00172 GAMEPAD = 964, /**< Gamepad. */ 00173 DIGITIZER_TABLET = 965, /**< Digitizer Tablet. */ 00174 CARD_READER = 966, /**< Card Reader. */ 00175 DIGITAL_PEN = 967, /**< Digital Pen. */ 00176 BARCODE_SCANNER = 968, /**< Barcode Scanner. */ 00177 GENERIC_GLUCOSE_METER = 1024, /**< Generic Glucose Meter. */ 00178 GENERIC_RUNNING_WALKING_SENSOR = 1088, /**< Generic Running/Walking Sensor. */ 00179 RUNNING_WALKING_SENSOR_IN_SHOE = 1089, /**< In Shoe Running/Walking Sensor. */ 00180 RUNNING_WALKING_SENSOR_ON_SHOE = 1090, /**< On Shoe Running/Walking Sensor. */ 00181 RUNNING_WALKING_SENSOR_ON_HIP = 1091, /**< On Hip Running/Walking Sensor. */ 00182 GENERIC_CYCLING = 1152, /**< Generic Cycling. */ 00183 CYCLING_CYCLING_COMPUTER = 1153, /**< Cycling Computer. */ 00184 CYCLING_SPEED_SENSOR = 1154, /**< Cycling Speed Sensor. */ 00185 CYCLING_CADENCE_SENSOR = 1155, /**< Cycling Cadence Sensor. */ 00186 CYCLING_POWER_SENSOR = 1156, /**< Cycling Power Sensor. */ 00187 CYCLING_SPEED_AND_CADENCE_SENSOR = 1157, /**< Cycling Speed and Cadence Sensor. */ 00188 PULSE_OXIMETER_GENERIC = 3136, /**< Generic Pulse Oximeter. */ 00189 PULSE_OXIMETER_FINGERTIP = 3137, /**< Fingertip Pulse Oximeter. */ 00190 PULSE_OXIMETER_WRIST_WORN = 3138, /**< Wrist Worn Pulse Oximeter. */ 00191 GENERIC_WEIGHT_SCALE = 3200, /**< Generic Weight Scale. */ 00192 OUTDOOR_GENERIC = 5184, /**< Generic Outdoor. */ 00193 OUTDOOR_LOCATION_DISPLAY_DEVICE = 5185, /**< Outdoor Location Display Device. */ 00194 OUTDOOR_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE = 5186, /**< Outdoor Location and Navigation Display Device. */ 00195 OUTDOOR_LOCATION_POD = 5187, /**< Outdoor Location Pod. */ 00196 OUTDOOR_LOCATION_AND_NAVIGATION_POD = 5188 /**< Outdoor Location and Navigation Pod. */ 00197 }; 00198 typedef enum Appearance_t Appearance; /* Deprecated type alias. This may be dropped in a future release. */ 00199 00200 GapAdvertisingData(void) : _payload(), _payloadLen(0), _appearance(GENERIC_TAG) { 00201 /* empty */ 00202 } 00203 00204 /** 00205 * Adds advertising data based on the specified AD type (see DataType). 00206 * If the supplied AD type is already present in the advertising 00207 * payload, then the value is updated. 00208 * 00209 * @param[in] advDataType The Advertising 'DataType' to add. 00210 * @param[in] payload Pointer to the payload contents. 00211 * @param[in] len Size of the payload in bytes. 00212 * 00213 * @return BLE_ERROR_BUFFER_OVERFLOW if the new value causes the 00214 * advertising buffer to overflow. BLE_ERROR_NONE is returned 00215 * on success. 00216 * 00217 * @note When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS, 00218 * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS, 00219 * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS, 00220 * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the 00221 * supplied value is appended to the values previously added to the 00222 * payload. 00223 */ 00224 ble_error_t addData(DataType_t advDataType, const uint8_t *payload, uint8_t len) 00225 { 00226 // find field 00227 uint8_t* field = findField(advDataType); 00228 00229 if (field) { 00230 // Field type already exist, either add to field or replace 00231 return addField(advDataType, payload, len, field); 00232 } else { 00233 // field doesn't exists, insert new 00234 return appendField(advDataType, payload, len); 00235 } 00236 } 00237 00238 /** 00239 * Update a particular ADV field in the advertising payload (based on 00240 * matching type). 00241 * 00242 * @param[in] advDataType The Advertising 'DataType' to add. 00243 * @param[in] payload Pointer to the payload contents. 00244 * @param[in] len Size of the payload in bytes. 00245 * 00246 * @return BLE_ERROR_UNSPECIFIED if the specified field is not found, 00247 * BLE_ERROR_BUFFER_OVERFLOW if the new value causes the 00248 * advertising buffer to overflow. BLE_ERROR_NONE is returned 00249 * on success. 00250 */ 00251 ble_error_t updateData(DataType_t advDataType, const uint8_t *payload, uint8_t len) 00252 { 00253 // find field 00254 uint8_t* field = findField(advDataType); 00255 00256 if (field) { 00257 // Field type already exist, replace field contents 00258 return updateField(advDataType, payload, len, field); 00259 } else { 00260 // field doesn't exists, return an error 00261 return BLE_ERROR_UNSPECIFIED; 00262 } 00263 } 00264 00265 /** 00266 * Helper function to add APPEARANCE data to the advertising payload. 00267 * 00268 * @param appearance 00269 * The APPEARANCE value to add. 00270 * 00271 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the 00272 * advertising buffer to overflow, else BLE_ERROR_NONE. 00273 */ 00274 ble_error_t addAppearance(Appearance appearance = GENERIC_TAG) { 00275 _appearance = appearance; 00276 return addData(GapAdvertisingData::APPEARANCE, (uint8_t *)&appearance, 2); 00277 } 00278 00279 /** 00280 * Helper function to add FLAGS data to the advertising payload. 00281 * @param flags 00282 * LE_LIMITED_DISCOVERABLE 00283 * The peripheral is discoverable for a limited period of time. 00284 * LE_GENERAL_DISCOVERABLE 00285 * The peripheral is permanently discoverable. 00286 * BREDR_NOT_SUPPORTED 00287 * This peripheral is a Bluetooth Low Energy only device (no EDR support). 00288 * 00289 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the 00290 * advertising buffer to overflow, else BLE_ERROR_NONE. 00291 */ 00292 ble_error_t addFlags(uint8_t flags = LE_GENERAL_DISCOVERABLE) { 00293 return addData(GapAdvertisingData::FLAGS, &flags, 1); 00294 } 00295 00296 /** 00297 * Helper function to add TX_POWER_LEVEL data to the advertising payload. 00298 * 00299 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the 00300 * advertising buffer to overflow, else BLE_ERROR_NONE. 00301 */ 00302 ble_error_t addTxPower(int8_t txPower) { 00303 /* To Do: Basic error checking to make sure txPower is in range. */ 00304 return addData(GapAdvertisingData::TX_POWER_LEVEL, (uint8_t *)&txPower, 1); 00305 } 00306 00307 /** 00308 * Clears the payload and resets the payload length counter. 00309 */ 00310 void clear(void) { 00311 memset(&_payload, 0, GAP_ADVERTISING_DATA_MAX_PAYLOAD); 00312 _payloadLen = 0; 00313 } 00314 00315 /** 00316 * Returns a pointer to the current payload. 00317 */ 00318 const uint8_t *getPayload(void) const { 00319 return _payload; 00320 } 00321 00322 /** 00323 * Returns the current payload length (0..31 bytes). 00324 */ 00325 uint8_t getPayloadLen(void) const { 00326 return _payloadLen; 00327 } 00328 00329 /** 00330 * Returns the 16-bit appearance value for this device. 00331 */ 00332 uint16_t getAppearance(void) const { 00333 return (uint16_t)_appearance; 00334 } 00335 00336 /** 00337 * Search advertisement data for field. 00338 * Returns pointer to the first element in the field if found, NULL otherwise. 00339 * Where the first element is the length of the field. 00340 */ 00341 const uint8_t* findField(DataType_t type) const { 00342 return findField(type); 00343 } 00344 00345 private: 00346 /** 00347 * Append advertising data based on the specified AD type (see DataType) 00348 */ 00349 ble_error_t appendField(DataType advDataType, const uint8_t *payload, uint8_t len) 00350 { 00351 /* Make sure we don't exceed the 31 byte payload limit */ 00352 if (_payloadLen + len + 2 > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { 00353 return BLE_ERROR_BUFFER_OVERFLOW; 00354 } 00355 00356 /* Field length. */ 00357 memset(&_payload[_payloadLen], len + 1, 1); 00358 _payloadLen++; 00359 00360 /* Field ID. */ 00361 memset(&_payload[_payloadLen], (uint8_t)advDataType, 1); 00362 _payloadLen++; 00363 00364 /* Payload. */ 00365 memcpy(&_payload[_payloadLen], payload, len); 00366 _payloadLen += len; 00367 00368 return BLE_ERROR_NONE; 00369 } 00370 00371 /** 00372 * Search advertisement data for field. 00373 * Returns pointer to the first element in the field if found, NULL otherwise. 00374 * Where the first element is the length of the field. 00375 */ 00376 uint8_t* findField(DataType_t type) { 00377 // scan through advertisement data 00378 for (uint8_t idx = 0; idx < _payloadLen; ) { 00379 uint8_t fieldType = _payload[idx + 1]; 00380 00381 if (fieldType == type) { 00382 return &_payload[idx]; 00383 } 00384 00385 // advance to next field 00386 idx += _payload[idx] + 1; 00387 } 00388 00389 // field not found 00390 return NULL; 00391 } 00392 00393 /** 00394 * Given the a pointer to a field in the advertising payload it replaces 00395 * the existing data in the field with the supplied data. 00396 * 00397 * When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS, 00398 * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS, 00399 * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS, 00400 * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the 00401 * supplied value is appended to the values previously added to the 00402 * payload. 00403 * 00404 * Returns BLE_ERROR_NONE on success. 00405 */ 00406 ble_error_t addField(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field) 00407 { 00408 ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW; 00409 00410 switch(advDataType) { 00411 // These fields will have the new data appended if there is sufficient space 00412 case INCOMPLETE_LIST_16BIT_SERVICE_IDS: 00413 case COMPLETE_LIST_16BIT_SERVICE_IDS: 00414 case INCOMPLETE_LIST_32BIT_SERVICE_IDS: 00415 case COMPLETE_LIST_32BIT_SERVICE_IDS: 00416 case INCOMPLETE_LIST_128BIT_SERVICE_IDS: 00417 case COMPLETE_LIST_128BIT_SERVICE_IDS: 00418 case LIST_128BIT_SOLICITATION_IDS: { 00419 // check if data fits 00420 if ((_payloadLen + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) { 00421 // make room for new field by moving the remainder of the 00422 // advertisement payload "to the right" starting after the 00423 // TYPE field. 00424 uint8_t* end = &_payload[_payloadLen]; 00425 00426 while (&field[1] < end) { 00427 end[len] = *end; 00428 end--; 00429 } 00430 00431 // insert new data 00432 for (uint8_t idx = 0; idx < len; idx++) { 00433 field[2 + idx] = payload[idx]; 00434 } 00435 00436 // increment lengths 00437 field[0] += len; 00438 _payloadLen += len; 00439 00440 result = BLE_ERROR_NONE; 00441 } 00442 00443 break; 00444 } 00445 // These fields will be overwritten with the new value 00446 default: { 00447 result = updateField(advDataType, payload, len, field); 00448 00449 break; 00450 } 00451 } 00452 00453 return result; 00454 } 00455 00456 /** 00457 * Given the a pointer to a field in the advertising payload it replaces 00458 * the existing data in the field with the supplied data. 00459 * Returns BLE_ERROR_NONE on success. 00460 */ 00461 ble_error_t updateField(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field) 00462 { 00463 ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW; 00464 uint8_t dataLength = field[0] - 1; 00465 00466 // new data has same length, do in-order replacement 00467 if (len == dataLength) { 00468 for (uint8_t idx = 0; idx < dataLength; idx++) { 00469 field[2 + idx] = payload[idx]; 00470 } 00471 00472 result = BLE_ERROR_NONE; 00473 } else { 00474 // check if data fits 00475 if ((_payloadLen - dataLength + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) { 00476 00477 // remove old field 00478 while ((field + dataLength + 2) < &_payload[_payloadLen]) { 00479 *field = field[dataLength + 2]; 00480 field++; 00481 } 00482 00483 // reduce length 00484 _payloadLen -= dataLength + 2; 00485 00486 // add new field 00487 result = appendField(advDataType, payload, len); 00488 } 00489 } 00490 00491 return result; 00492 } 00493 00494 uint8_t _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD]; 00495 uint8_t _payloadLen; 00496 uint16_t _appearance; 00497 }; 00498 00499 #endif // ifndef __GAP_ADVERTISING_DATA_H__
Generated on Fri Jul 15 2022 20:49:45 by 1.7.2