Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GapAdvertisingData.h Source File

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 &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__ */