High level Bluetooth Low Energy API and radio abstraction layer

Dependents:   BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate BLE_ANCS_SDAPI_IRC ... more

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