Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 MBED_GAP_ADVERTISING_DATA_H__ 00018 #define MBED_GAP_ADVERTISING_DATA_H__ 00019 00020 #include <stdint.h> 00021 #include <string.h> 00022 00023 #include "blecommon.h" 00024 00025 /** 00026 * @addtogroup ble 00027 * @{ 00028 * @addtogroup gap 00029 * @{ 00030 */ 00031 00032 #define GAP_ADVERTISING_DATA_MAX_PAYLOAD (31) 00033 00034 /** 00035 * GAP advertising data builder. 00036 * 00037 * Advertising data are used by broadcaster or peripheral to advertise state 00038 * about the device. This class offers the function to add and update states present 00039 * in an advertisement payload. 00040 * 00041 * After construction, the advertising payload contained in the instance of 00042 * GapAdvertisingData is empty. Adding new states and named fields can be 00043 * achieved by invoking the function addData(), and updating existing state 00044 * involves calling the function updateData(). 00045 * 00046 * Fields present in the payload can be retrieved by a call to the function 00047 * findField. 00048 * 00049 * This class includes shorthand for the most common fields: 00050 * - FLAGS: addFlags(). 00051 * - APPEARANCE: addAppearance(). 00052 * - TX_POWER_LEVEL: addTxPower(). 00053 * 00054 * @code 00055 * 00056 * Gap ⪆ 00057 * 00058 * static const uint8_t device_name[] = "HRM"; 00059 * 00060 * // construct an empty advertising payload 00061 * GapAdvertisingData advertising_data; 00062 * 00063 * // set the flags of the advertising device 00064 * advertising_data.addFlags( 00065 * GapAdvertisingData::LE_GENERAL_DISCOVERABLE | 00066 * GapAdvertisingData::BREDR_NOT_SUPPORTED 00067 * ); 00068 * 00069 * // set the advertised name of the device 00070 * advertising_data.addData( 00071 * GapAdvertisingData::COMPLETE_LOCAL_NAME, 00072 * device_name, 00073 * sizeof(device_name) 00074 * ); 00075 * 00076 * // update the advertising data of the gap payload 00077 * gap.setAdvertisingPayload(advertising_data); 00078 * 00079 * @endcode 00080 * 00081 * @note See Bluetooth Specification 4.0 (Vol. 3), Part C, Sections 11 and 18 00082 * for further information on advertising and scan response data. 00083 * 00084 * @par Advertising and Scan Response Payloads 00085 * Advertising data and scan response data are organized around a set of 00086 * data types called 'AD types' in Bluetooth 4.0 (see the Bluetooth Core 00087 * Specification v4.0, Vol. 3, Part C, Sections 11 and 18). 00088 * 00089 * @par 00090 * Each AD type has its own standardized assigned number, as 00091 * the Bluetooth SIG defines: 00092 * https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile. 00093 * 00094 * @par 00095 * For convenience, all appropriate AD types are encapsulated in 00096 * GapAdvertisingData::DataType. 00097 * 00098 * @par 00099 * Before the AD Types and their payload (if any) can be inserted into 00100 * the advertising or scan response frames, they need to be formatted as 00101 * follows: 00102 * 00103 * @li @c Record length (1 byte). 00104 * @li @c AD Type (1 byte). 00105 * @li @c AD payload (optional; only present if record length > 1). 00106 * 00107 * @par 00108 * This class takes care of properly formatting the payload, performs 00109 * some basic checks on the payload length and tries to avoid common 00110 * errors such as adding an exclusive AD field twice in the advertising 00111 * or scan response payload. 00112 */ 00113 class GapAdvertisingData 00114 { 00115 public: 00116 /*! 00117 * List of standard Advertising Data types. 00118 * 00119 * These AD types are used to describe the capabilities of the peripheral 00120 * and are inserted inside the advertising or scan response payloads. 00121 * 00122 * @par Source 00123 * 00124 * @li @c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 11, 18. 00125 * @li @c https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile. 00126 */ 00127 enum DataType_t { 00128 /** 00129 * Flags, refer to GapAdvertisingData::Flags_t. 00130 */ 00131 FLAGS = 0x01, 00132 00133 /** 00134 * Incomplete list of 16-bit Service IDs. 00135 */ 00136 INCOMPLETE_LIST_16BIT_SERVICE_IDS = 0x02, 00137 00138 /** 00139 * Complete list of 16-bit Service IDs. 00140 */ 00141 COMPLETE_LIST_16BIT_SERVICE_IDS = 0x03, 00142 00143 /** 00144 * Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0). 00145 */ 00146 INCOMPLETE_LIST_32BIT_SERVICE_IDS = 0x04, 00147 00148 /** 00149 * Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0). 00150 */ 00151 COMPLETE_LIST_32BIT_SERVICE_IDS = 0x05, 00152 00153 /** 00154 * Incomplete list of 128-bit Service IDs. 00155 */ 00156 INCOMPLETE_LIST_128BIT_SERVICE_IDS = 0x06, 00157 00158 /** 00159 * Complete list of 128-bit Service IDs. 00160 */ 00161 COMPLETE_LIST_128BIT_SERVICE_IDS = 0x07, 00162 00163 /** 00164 * Shortened Local Name. 00165 */ 00166 SHORTENED_LOCAL_NAME = 0x08, 00167 00168 /** 00169 * Complete Local Name. 00170 */ 00171 COMPLETE_LOCAL_NAME = 0x09, 00172 00173 /** 00174 * TX Power Level (in dBm). 00175 */ 00176 TX_POWER_LEVEL = 0x0A, 00177 00178 /** 00179 * Device ID. 00180 */ 00181 DEVICE_ID = 0x10, 00182 00183 /** 00184 * Slave Connection Interval Range. 00185 */ 00186 SLAVE_CONNECTION_INTERVAL_RANGE = 0x12, 00187 00188 /** 00189 * List of 128-bit service UUIDs the device is looking for. 00190 */ 00191 LIST_128BIT_SOLICITATION_IDS = 0x15, 00192 00193 /** 00194 * Service Data. 00195 */ 00196 SERVICE_DATA = 0x16, 00197 00198 /** 00199 * Appearance, refer to GapAdvertisingData::Appearance_t. 00200 */ 00201 APPEARANCE = 0x19, 00202 00203 /** 00204 * Advertising Interval. 00205 */ 00206 ADVERTISING_INTERVAL = 0x1A, 00207 00208 /** 00209 * Manufacturer Specific Data. 00210 */ 00211 MANUFACTURER_SPECIFIC_DATA = 0xFF 00212 00213 }; 00214 00215 /** 00216 * Alias for GapAdvertisingData::DataType_t. 00217 * 00218 * @deprecated Future releases will drop this type alias. 00219 */ 00220 typedef enum DataType_t DataType; 00221 00222 /** 00223 * Enumeration of allowed flags for DataType_t::FLAGS. 00224 * 00225 * @note DataType_t::FLAGS may contain several flags that the bitwise 00226 * and operator (ex.LE_GENERAL_DISCOVERABLE & BREDR_NOT_SUPPORTED) assembled. 00227 * 00228 * @par Source 00229 * 00230 * @li @c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 18.1. 00231 */ 00232 enum Flags_t { 00233 /** 00234 * Peripheral device is discoverable for a limited period of time. 00235 */ 00236 LE_LIMITED_DISCOVERABLE = 0x01, 00237 00238 /** 00239 * Peripheral device is discoverable at any moment. 00240 */ 00241 LE_GENERAL_DISCOVERABLE = 0x02, 00242 00243 /** 00244 * Peripheral device is LE only and does not support Bluetooth Enhanced 00245 * DataRate. 00246 */ 00247 BREDR_NOT_SUPPORTED = 0x04, 00248 00249 /** 00250 * Not relevant - dual mode only. 00251 */ 00252 SIMULTANEOUS_LE_BREDR_C = 0x08, 00253 00254 /** 00255 * Not relevant - dual mode only. 00256 */ 00257 SIMULTANEOUS_LE_BREDR_H = 0x10 00258 00259 }; 00260 00261 /** 00262 * Alias for GapAdvertisingData::Flags_t. 00263 * 00264 * @deprecated Future releases will drop this type alias. 00265 */ 00266 typedef enum Flags_t Flags; 00267 00268 /** 00269 * Enumeration of values for the DataType_t::APPEARANCE. 00270 * 00271 * These values describe the physical shape or appearance of the device. 00272 * 00273 * @par Source 00274 * 00275 * @li @c Bluetooth Core Specification Supplement, Part A, Section 1.12. 00276 * @li @c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 12.2. 00277 * @li @c https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml. 00278 */ 00279 enum Appearance_t { 00280 /** 00281 * Unknown or unspecified appearance type. 00282 */ 00283 UNKNOWN = 0, 00284 00285 /** 00286 * Generic Phone. 00287 */ 00288 GENERIC_PHONE = 64, 00289 00290 /** 00291 * Generic Computer. 00292 */ 00293 GENERIC_COMPUTER = 128, 00294 00295 /** 00296 * Generic Watch. 00297 */ 00298 GENERIC_WATCH = 192, 00299 00300 /** 00301 * Sports Watch. 00302 */ 00303 WATCH_SPORTS_WATCH = 193, 00304 00305 /** 00306 * Generic Clock. 00307 */ 00308 GENERIC_CLOCK = 256, 00309 00310 /** 00311 * Generic Display. 00312 */ 00313 GENERIC_DISPLAY = 320, 00314 00315 /** 00316 * Generic Remote Control. 00317 */ 00318 GENERIC_REMOTE_CONTROL = 384, 00319 00320 /** 00321 * Generic Eye Glasses. 00322 */ 00323 GENERIC_EYE_GLASSES = 448, 00324 00325 /** 00326 * Generic Tag. 00327 */ 00328 GENERIC_TAG = 512, 00329 00330 /** 00331 * Generic Keyring. 00332 */ 00333 GENERIC_KEYRING = 576, 00334 00335 /** 00336 * Generic Media Player. 00337 */ 00338 GENERIC_MEDIA_PLAYER = 640, 00339 00340 /** 00341 * Generic Bar Code Scanner. 00342 */ 00343 GENERIC_BARCODE_SCANNER = 704, 00344 00345 /** 00346 * Generic Thermometer. 00347 */ 00348 GENERIC_THERMOMETER = 768, 00349 00350 /** 00351 * Ear Thermometer. 00352 */ 00353 THERMOMETER_EAR = 769, 00354 00355 /** 00356 * Generic Heart Rate Sensor. 00357 */ 00358 GENERIC_HEART_RATE_SENSOR = 832, 00359 00360 /** 00361 * Belt Heart Rate Sensor. 00362 */ 00363 HEART_RATE_SENSOR_HEART_RATE_BELT = 833, 00364 00365 /** 00366 * Generic Blood Pressure. 00367 */ 00368 GENERIC_BLOOD_PRESSURE = 896, 00369 00370 /** 00371 * Arm Blood Pressure. 00372 */ 00373 BLOOD_PRESSURE_ARM = 897, 00374 00375 /** 00376 * Wrist Blood Pressure. 00377 */ 00378 BLOOD_PRESSURE_WRIST = 898, 00379 00380 /** 00381 * Human Interface Device (HID). 00382 */ 00383 HUMAN_INTERFACE_DEVICE_HID = 960, 00384 00385 /** 00386 * Keyboard. 00387 */ 00388 KEYBOARD = 961, 00389 00390 /** 00391 * Mouse. 00392 */ 00393 MOUSE = 962, 00394 00395 /** 00396 * Joystick. 00397 */ 00398 JOYSTICK = 963, 00399 00400 /** 00401 * Gamepad. 00402 */ 00403 GAMEPAD = 964, 00404 00405 /** 00406 * Digitizer Tablet. 00407 */ 00408 DIGITIZER_TABLET = 965, 00409 00410 /** 00411 * Card Reader. 00412 */ 00413 CARD_READER = 966, 00414 00415 /** 00416 * Digital Pen. 00417 */ 00418 DIGITAL_PEN = 967, 00419 00420 /** 00421 * Bar Code Scanner. 00422 */ 00423 BARCODE_SCANNER = 968, 00424 00425 /** 00426 * Generic Glucose Meter. 00427 */ 00428 GENERIC_GLUCOSE_METER = 1024, 00429 00430 /** 00431 * Generic Running/Walking Sensor. 00432 */ 00433 GENERIC_RUNNING_WALKING_SENSOR = 1088, 00434 00435 /** 00436 * In Shoe Running/Walking Sensor. 00437 */ 00438 RUNNING_WALKING_SENSOR_IN_SHOE = 1089, 00439 00440 /** 00441 * On Shoe Running/Walking Sensor. 00442 */ 00443 RUNNING_WALKING_SENSOR_ON_SHOE = 1090, 00444 00445 /** 00446 * On Hip Running/Walking Sensor. 00447 */ 00448 RUNNING_WALKING_SENSOR_ON_HIP = 1091, 00449 00450 /** 00451 * Generic Cycling. 00452 */ 00453 GENERIC_CYCLING = 1152, 00454 00455 /** 00456 * Cycling Computer. 00457 */ 00458 CYCLING_CYCLING_COMPUTER = 1153, 00459 00460 /** 00461 * Cycling Speed Sensor. 00462 */ 00463 CYCLING_SPEED_SENSOR = 1154, 00464 00465 /** 00466 * Cycling Cadence Sensor. 00467 */ 00468 CYCLING_CADENCE_SENSOR = 1155, 00469 00470 /** 00471 * Cycling Power Sensor. 00472 */ 00473 CYCLING_POWER_SENSOR = 1156, 00474 00475 /** 00476 * Cycling Speed and Cadence Sensor. 00477 */ 00478 CYCLING_SPEED_AND_CADENCE_SENSOR = 1157, 00479 00480 /** 00481 * Generic Pulse Oximeter. 00482 */ 00483 PULSE_OXIMETER_GENERIC = 3136, 00484 00485 /** 00486 * Fingertip Pulse Oximeter. 00487 */ 00488 PULSE_OXIMETER_FINGERTIP = 3137, 00489 00490 /** 00491 * Wrist Worn Pulse Oximeter. 00492 */ 00493 PULSE_OXIMETER_WRIST_WORN = 3138, 00494 00495 /** 00496 * Generic Weight Scale. 00497 */ 00498 GENERIC_WEIGHT_SCALE = 3200, 00499 00500 /** 00501 * Generic Outdoor. 00502 */ 00503 OUTDOOR_GENERIC = 5184, 00504 00505 /** 00506 * Outdoor Location Display Device. 00507 */ 00508 OUTDOOR_LOCATION_DISPLAY_DEVICE = 5185, 00509 00510 /** 00511 * Outdoor Location and Navigation Display Device. 00512 */ 00513 OUTDOOR_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE = 5186, 00514 00515 /** 00516 * Outdoor Location Pod. 00517 */ 00518 OUTDOOR_LOCATION_POD = 5187, 00519 00520 /** 00521 * Outdoor Location and Navigation Pod. 00522 */ 00523 OUTDOOR_LOCATION_AND_NAVIGATION_POD = 5188 00524 00525 }; 00526 00527 /** 00528 * Alias for GapAdvertisingData::Appearance_t. 00529 * 00530 * @deprecated Future releases will drop this type alias. 00531 */ 00532 typedef enum Appearance_t Appearance; 00533 00534 /** 00535 * Construct a GapAdvertising instance with an empty payload. 00536 */ 00537 GapAdvertisingData(void) : 00538 _payload(), 00539 _payloadLen(0), 00540 _appearance(GENERIC_TAG) { 00541 } 00542 00543 /** 00544 * Adds a new field into the payload. 00545 * 00546 * If the supplied advertising data type is already present in the 00547 * advertising payload, then the value is updated. 00548 * 00549 * @param[in] advDataType The type of the field to add. 00550 * @param[in] payload Pointer to the value of the field to add. 00551 * @param[in] len Size in bytes of the value to add. 00552 * 00553 * @return BLE_ERROR_NONE on success. 00554 * @return BLE_ERROR_BUFFER_OVERFLOW if the new value causes the advertising 00555 * buffer to overflow. 00556 * 00557 * @note When the specified data type is INCOMPLETE_LIST_16BIT_SERVICE_IDS, 00558 * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS, 00559 * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS, 00560 * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS, the 00561 * supplied value is appended to the values present in the payload. 00562 */ 00563 ble_error_t addData(DataType_t advDataType, const uint8_t *payload, uint8_t len) 00564 { 00565 /* Find field */ 00566 uint8_t* field = findField(advDataType); 00567 00568 if (field) { 00569 /* Field type already exists, either add to field or replace */ 00570 return addField(advDataType, payload, len, field); 00571 } else { 00572 /* Field doesn't exist, insert new */ 00573 return appendField(advDataType, payload, len); 00574 } 00575 } 00576 00577 /** 00578 * Update a specific field in the advertising payload. 00579 * 00580 * @param[in] advDataType The type of the field to update. 00581 * @param[in] payload Pointer to the updated value of the field. 00582 * @param[in] len Size of the new value in bytes. 00583 * 00584 * @return BLE_ERROR_NONE returned on success. 00585 * @return BLE_ERROR_UNSPECIFIED if the specified field is not found, 00586 * @return BLE_ERROR_BUFFER_OVERFLOW if the new value causes the 00587 * advertising buffer to overflow. 00588 */ 00589 ble_error_t updateData(DataType_t advDataType, const uint8_t *payload, uint8_t len) 00590 { 00591 /* Find field */ 00592 uint8_t* field = findField(advDataType); 00593 00594 if (field) { 00595 /* Field type already exists, replace field contents */ 00596 return updateField(advDataType, payload, len, field); 00597 } else { 00598 /* field doesn't exist, return an error */ 00599 return BLE_ERROR_UNSPECIFIED; 00600 } 00601 } 00602 00603 /** 00604 * Add device appearance in the advertising payload. 00605 * 00606 * @param[in] appearance The appearance to advertise. 00607 * 00608 * @return BLE_ERROR_NONE on success. 00609 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the 00610 * advertising buffer to overflow. 00611 * 00612 * @note This call is equivalent to calling addData() with 00613 * GapAdvertisingData::APPEARANCE as the field type. 00614 */ 00615 ble_error_t addAppearance(Appearance appearance = GENERIC_TAG) 00616 { 00617 _appearance = appearance; 00618 return addData(GapAdvertisingData::APPEARANCE, (uint8_t *)&appearance, 2); 00619 } 00620 00621 /** 00622 * Add BLE flags in the advertising payload. 00623 * 00624 * @param[in] flags Bitfield describing the capability of the device. See 00625 * allowed flags in Flags_t. 00626 * 00627 * @return BLE_ERROR_NONE on success. 00628 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the 00629 * advertising buffer to overflow. 00630 * 00631 * @note This call is equivalent to calling addData() with 00632 * GapAdvertisingData::FLAGS as the field type. 00633 */ 00634 ble_error_t addFlags(uint8_t flags = LE_GENERAL_DISCOVERABLE) 00635 { 00636 return addData(GapAdvertisingData::FLAGS, &flags, 1); 00637 } 00638 00639 /** 00640 * Add the advertising TX in the advertising payload. 00641 * 00642 * @param[in] txPower Transmission power level in dB. 00643 * 00644 * @return BLE_ERROR_NONE on success. 00645 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the 00646 * advertising buffer to overflow. 00647 * 00648 * @note This call is equivalent to calling addData() with 00649 * GapAdvertisingData::TX_POWER_LEVEL as the field type. 00650 */ 00651 ble_error_t addTxPower(int8_t txPower) 00652 { 00653 /* To Do: Basic error checking to make sure txPower is in range. */ 00654 return addData(GapAdvertisingData::TX_POWER_LEVEL, (uint8_t *)&txPower, 1); 00655 } 00656 00657 /** 00658 * Clears the advertising data payload. 00659 * 00660 * @post getPayloadLen() returns 0. 00661 */ 00662 void clear(void) 00663 { 00664 memset(&_payload, 0, GAP_ADVERTISING_DATA_MAX_PAYLOAD); 00665 _payloadLen = 0; 00666 } 00667 00668 /** 00669 * Get the pointer to the advertising payload bytes. 00670 * 00671 * @return A pointer to the payload. 00672 */ 00673 const uint8_t *getPayload(void) const 00674 { 00675 return _payload; 00676 } 00677 00678 /** 00679 * Get the payload length. 00680 * 00681 * @return The payload length in bytes. 00682 */ 00683 uint8_t getPayloadLen(void) const 00684 { 00685 return _payloadLen; 00686 } 00687 00688 /** 00689 * Get the appearance set. 00690 * 00691 * If no value has been set, this function returns GENERIC_TAG. 00692 * 00693 * @return The appearance value set for this device. 00694 */ 00695 uint16_t getAppearance(void) const 00696 { 00697 return (uint16_t)_appearance; 00698 } 00699 00700 /** 00701 * Search advertisement data for a specific field. 00702 * 00703 * @param[in] type The type of the field to find. 00704 * 00705 * @return A pointer to the first element in the field if found. The first 00706 * element being the length of the field followed by the value of the field. 00707 * @return NULL if the field is not present in the payload. 00708 */ 00709 const uint8_t* findField(DataType_t type) const 00710 { 00711 /* Scan through advertisement data */ 00712 for (uint8_t idx = 0; idx < _payloadLen; ) { 00713 uint8_t fieldType = _payload[idx + 1]; 00714 00715 if (fieldType == type) { 00716 return &_payload[idx]; 00717 } 00718 00719 /* Advance to next field */ 00720 idx += _payload[idx] + 1; 00721 } 00722 00723 /* Field not found */ 00724 return NULL; 00725 } 00726 00727 private: 00728 /** 00729 * Append advertising data based on the specified type. 00730 * 00731 * @param[in] advDataType Type of the new data. 00732 * @param[in] payload Pointer to the data to be appended to the advertising 00733 * payload. 00734 * @param[in] len Length of the data pointed to by @p payload. 00735 * 00736 * @return BLE_ERROR_NONE on success. 00737 * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the 00738 * advertising buffer to overflow. 00739 */ 00740 ble_error_t appendField(DataType advDataType, const uint8_t *payload, uint8_t len) 00741 { 00742 /* Make sure we don't exceed the 31-byte payload limit */ 00743 if (_payloadLen + len + 2 > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { 00744 return BLE_ERROR_BUFFER_OVERFLOW; 00745 } 00746 00747 /* Field length. */ 00748 memset(&_payload[_payloadLen], len + 1, 1); 00749 _payloadLen++; 00750 00751 /* Field ID. */ 00752 memset(&_payload[_payloadLen], (uint8_t)advDataType, 1); 00753 _payloadLen++; 00754 00755 /* Payload. */ 00756 memcpy(&_payload[_payloadLen], payload, len); 00757 _payloadLen += len; 00758 00759 return BLE_ERROR_NONE; 00760 } 00761 00762 /** 00763 * Search advertisement data for a specific field. 00764 * 00765 * @param[in] type The type of the field to find. 00766 * 00767 * @return A pointer to the first element in the field if found. The first 00768 * element being the length of the field followed by the value of the field. 00769 * @return NULL if the field is not present in the payload. 00770 */ 00771 uint8_t* findField(DataType_t type) 00772 { 00773 return const_cast<uint8_t*>( 00774 static_cast<const GapAdvertisingData*>(this)->findField(type) 00775 ); 00776 } 00777 00778 /** 00779 * Update in place the value of a field in the advertising payload. 00780 * 00781 * @param[in] advDataType Type of the new data. 00782 * @param[in] payload Pointer to the data to be added to the advertising 00783 * payload. 00784 * @param[in] len Length of the data pointed to by @p payload. 00785 * @param[in] field Pointer to the field of type @p advDataType in the 00786 * advertising buffer. 00787 * 00788 * @note When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS, 00789 * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS, 00790 * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS, 00791 * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS, the 00792 * supplied value is appended to the values previously added to the 00793 * payload. 00794 * 00795 * @return BLE_ERROR_NONE on success. 00796 */ 00797 ble_error_t addField( 00798 DataType_t advDataType, 00799 const uint8_t *payload, 00800 uint8_t len, 00801 uint8_t* field 00802 ) { 00803 ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW; 00804 00805 switch(advDataType) { 00806 /* These fields have the new data appended if there is sufficient space. */ 00807 case INCOMPLETE_LIST_16BIT_SERVICE_IDS: 00808 case COMPLETE_LIST_16BIT_SERVICE_IDS: 00809 case INCOMPLETE_LIST_32BIT_SERVICE_IDS: 00810 case COMPLETE_LIST_32BIT_SERVICE_IDS: 00811 case INCOMPLETE_LIST_128BIT_SERVICE_IDS: 00812 case COMPLETE_LIST_128BIT_SERVICE_IDS: 00813 case LIST_128BIT_SOLICITATION_IDS: { 00814 /* Check if data fits */ 00815 if ((_payloadLen + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) { 00816 /* 00817 * Make room for new field by moving the remainder of the 00818 * advertisement payload "to the right" starting after the 00819 * TYPE field. 00820 */ 00821 uint8_t* end = &_payload[_payloadLen]; 00822 00823 while (&field[1] < end) { 00824 end[len] = *end; 00825 end--; 00826 } 00827 00828 /* Insert new data */ 00829 for (uint8_t idx = 0; idx < len; idx++) { 00830 field[2 + idx] = payload[idx]; 00831 } 00832 00833 /* Increment lengths */ 00834 field[0] += len; 00835 _payloadLen += len; 00836 00837 result = BLE_ERROR_NONE; 00838 } 00839 00840 break; 00841 } 00842 /* These fields are overwritten with the new value */ 00843 default: { 00844 result = updateField(advDataType, payload, len, field); 00845 00846 break; 00847 } 00848 } 00849 00850 return result; 00851 } 00852 00853 /** 00854 * Update in place the value of a field in the advertising payload. 00855 * 00856 * @param[in] advDataType Type of the new data. 00857 * @param[in] payload Pointer to the data to be added to the advertising 00858 * payload. 00859 * @param[in] len Length of the data pointed to by @p payload. 00860 * @param[in] field Pointer to the field of type @p advDataType in the 00861 * advertising buffer. 00862 * 00863 * @return BLE_ERROR_NONE on success. 00864 */ 00865 ble_error_t updateField( 00866 DataType_t advDataType, 00867 const uint8_t *payload, 00868 uint8_t len, 00869 uint8_t* field 00870 ) { 00871 ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW; 00872 uint8_t dataLength = field[0] - 1; 00873 00874 /* New data has same length, do in-order replacement */ 00875 if (len == dataLength) { 00876 for (uint8_t idx = 0; idx < dataLength; idx++) { 00877 field[2 + idx] = payload[idx]; 00878 } 00879 00880 result = BLE_ERROR_NONE; 00881 } else { 00882 /* Check if data fits */ 00883 if ((_payloadLen - dataLength + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) { 00884 00885 /* Remove old field */ 00886 while ((field + dataLength + 2) < &_payload[_payloadLen]) { 00887 *field = field[dataLength + 2]; 00888 field++; 00889 } 00890 00891 /* Reduce length */ 00892 _payloadLen -= dataLength + 2; 00893 00894 /* Add new field */ 00895 result = appendField(advDataType, payload, len); 00896 } 00897 } 00898 00899 return result; 00900 } 00901 00902 /** 00903 * Advertising data buffer. 00904 */ 00905 uint8_t _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD]; 00906 00907 /** 00908 * Length of the data added to the advertising buffer. 00909 */ 00910 uint8_t _payloadLen; 00911 00912 /** 00913 * Appearance value. 00914 */ 00915 uint16_t _appearance; 00916 }; 00917 00918 /** 00919 * @} 00920 * @} 00921 */ 00922 00923 00924 #endif /* ifndef MBED_GAP_ADVERTISING_DATA_H__ */
Generated on Tue Jul 12 2022 12:44:15 by
