Updated

Fork of BLE_API by Bluetooth Low Energy

Revision:
1042:21a86ac7f5b1
Parent:
993:4d62b7967c11
Child:
1048:efb29faf12fc
--- a/ble/GapAdvertisingData.h	Thu Dec 10 09:15:05 2015 +0000
+++ b/ble/GapAdvertisingData.h	Mon Jan 11 08:51:25 2016 +0000
@@ -28,10 +28,10 @@
 /*!
     \brief
     This class provides several helper functions to generate properly
-    formatted GAP Advertising and Scan Response data payloads.
+    formatted GAP Advertising and Scan Response data payloads
 
     \note
-    See Bluetooth Specification 4.0 (Vol. 3), Part C, Sections 11 and 18
+    See Bluetooth Specification 4.0 (Vol. 3), Part C, Section 11 and 18
     for further information on Advertising and Scan Response data.
 
     \par Advertising and Scan Response Payloads
@@ -40,22 +40,22 @@
     Specification v4.0, Vol. 3, Part C, Sections 11 and 18).
 
     \par
-    Each AD type has its own standardized assigned number, as defined
+    Each AD type has it's own standardized 'assigned number', as defined
     by the Bluetooth SIG:
     https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile
 
     \par
-    For convenience, all appropriate AD types are encapsulated
-    in GapAdvertisingData::DataType.
+    For convenience sake, all appropriate AD types have been encapsulated
+    into GapAdvertisingData::DataType.
 
     \par
     Before the AD Types and their payload (if any) can be inserted into
     the Advertising or Scan Response frames, they need to be formatted as
     follows:
 
-    \li \c Record length (1 byte).
-    \li \c AD Type (1 byte).
-    \li \c AD payload (optional; only present if record length > 1).
+    \li \c Record length (1 byte)
+    \li \c AD Type (1 byte)
+    \li \c AD payload (optional, only present if record length > 1)
 
     \par
     This class takes care of properly formatting the payload, performs
@@ -80,7 +80,7 @@
         \brief
         A list of Advertising Data types commonly used by peripherals.
         These AD types are used to describe the capabilities of the
-        peripheral, and are inserted inside the advertising or scan
+        peripheral, and get inserted inside the advertising or scan
         response payloads.
 
         \par Source
@@ -101,7 +101,6 @@
         TX_POWER_LEVEL                     = 0x0A, /**< TX Power Level (in dBm) */
         DEVICE_ID                          = 0x10, /**< Device ID */
         SLAVE_CONNECTION_INTERVAL_RANGE    = 0x12, /**< Slave Connection Interval Range */
-        LIST_128BIT_SOLICITATION_IDS       = 0x15, /**< List of 128 bit service UUIDs the device is looking for */
         SERVICE_DATA                       = 0x16, /**< Service Data */
         APPEARANCE                         = 0x19, /**< \ref Appearance */
         ADVERTISING_INTERVAL               = 0x1A, /**< Advertising Interval */
@@ -112,7 +111,7 @@
     /**********************************************************************/
     /*!
         \brief
-        A list of values for the FLAGS AD Type.
+        A list of values for the FLAGS AD Type
 
         \note
         You can use more than one value in the FLAGS AD Type (ex.
@@ -123,11 +122,11 @@
     */
     /**********************************************************************/
     enum Flags_t {
-        LE_LIMITED_DISCOVERABLE = 0x01, /**< *Peripheral device is discoverable for a limited period of time. */
-        LE_GENERAL_DISCOVERABLE = 0x02, /**< Peripheral device is discoverable at any moment. */
-        BREDR_NOT_SUPPORTED     = 0x04, /**< Peripheral device is LE only. */
-        SIMULTANEOUS_LE_BREDR_C = 0x08, /**< Not relevant - central mode only. */
-        SIMULTANEOUS_LE_BREDR_H = 0x10  /**< Not relevant - central mode only. */
+        LE_LIMITED_DISCOVERABLE = 0x01, /**< *Peripheral device is discoverable for a limited period of time */
+        LE_GENERAL_DISCOVERABLE = 0x02, /**< Peripheral device is discoverable at any moment */
+        BREDR_NOT_SUPPORTED     = 0x04, /**< Peripheral device is LE only */
+        SIMULTANEOUS_LE_BREDR_C = 0x08, /**< Not relevant - central mode only */
+        SIMULTANEOUS_LE_BREDR_H = 0x10  /**< Not relevant - central mode only */
     };
     typedef enum Flags_t Flags; /* Deprecated type alias. This may be dropped in a future release. */
 
@@ -135,7 +134,7 @@
     /*!
         \brief
         A list of values for the APPEARANCE AD Type, which describes the
-        physical shape or appearance of the device.
+        physical shape or appearance of the device
 
         \par Source
         \li \c Bluetooth Core Specification Supplement, Part A, Section 1.12
@@ -144,54 +143,54 @@
     */
     /**********************************************************************/
     enum Appearance_t {
-        UNKNOWN                                        = 0,     /**< Unknown or unspecified appearance type. */
-        GENERIC_PHONE                                  = 64,    /**< Generic Phone. */
-        GENERIC_COMPUTER                               = 128,   /**< Generic Computer. */
-        GENERIC_WATCH                                  = 192,   /**< Generic Watch. */
-        WATCH_SPORTS_WATCH                             = 193,   /**< Sports Watch. */
-        GENERIC_CLOCK                                  = 256,   /**< Generic Clock. */
-        GENERIC_DISPLAY                                = 320,   /**< Generic Display. */
-        GENERIC_REMOTE_CONTROL                         = 384,   /**< Generic Remote Control. */
-        GENERIC_EYE_GLASSES                            = 448,   /**< Generic Eye Glasses. */
-        GENERIC_TAG                                    = 512,   /**< Generic Tag. */
-        GENERIC_KEYRING                                = 576,   /**< Generic Keyring. */
-        GENERIC_MEDIA_PLAYER                           = 640,   /**< Generic Media Player. */
-        GENERIC_BARCODE_SCANNER                        = 704,   /**< Generic Barcode Scanner. */
-        GENERIC_THERMOMETER                            = 768,   /**< Generic Thermometer. */
-        THERMOMETER_EAR                                = 769,   /**< Ear Thermometer. */
-        GENERIC_HEART_RATE_SENSOR                      = 832,   /**< Generic Heart Rate Sensor. */
-        HEART_RATE_SENSOR_HEART_RATE_BELT              = 833,   /**< Belt Heart Rate Sensor. */
-        GENERIC_BLOOD_PRESSURE                         = 896,   /**< Generic Blood Pressure. */
-        BLOOD_PRESSURE_ARM                             = 897,   /**< Arm Blood Pressure. */
-        BLOOD_PRESSURE_WRIST                           = 898,   /**< Wrist Blood Pressure. */
-        HUMAN_INTERFACE_DEVICE_HID                     = 960,   /**< Human Interface Device (HID). */
-        KEYBOARD                                       = 961,   /**< Keyboard. */
-        MOUSE                                          = 962,   /**< Mouse. */
-        JOYSTICK                                       = 963,   /**< Joystick. */
-        GAMEPAD                                        = 964,   /**< Gamepad. */
-        DIGITIZER_TABLET                               = 965,   /**< Digitizer Tablet. */
-        CARD_READER                                    = 966,   /**< Card Reader. */
-        DIGITAL_PEN                                    = 967,   /**< Digital Pen. */
-        BARCODE_SCANNER                                = 968,   /**< Barcode Scanner. */
-        GENERIC_GLUCOSE_METER                          = 1024,  /**< Generic Glucose Meter. */
-        GENERIC_RUNNING_WALKING_SENSOR                 = 1088,  /**< Generic Running/Walking Sensor. */
-        RUNNING_WALKING_SENSOR_IN_SHOE                 = 1089,  /**< In Shoe Running/Walking Sensor. */
-        RUNNING_WALKING_SENSOR_ON_SHOE                 = 1090,  /**< On Shoe Running/Walking Sensor. */
-        RUNNING_WALKING_SENSOR_ON_HIP                  = 1091,  /**< On Hip Running/Walking Sensor. */
-        GENERIC_CYCLING                                = 1152,  /**< Generic Cycling. */
-        CYCLING_CYCLING_COMPUTER                       = 1153,  /**< Cycling Computer. */
-        CYCLING_SPEED_SENSOR                           = 1154,  /**< Cycling Speed Sensor. */
-        CYCLING_CADENCE_SENSOR                         = 1155,  /**< Cycling Cadence Sensor. */
-        CYCLING_POWER_SENSOR                           = 1156,  /**< Cycling Power Sensor. */
-        CYCLING_SPEED_AND_CADENCE_SENSOR               = 1157,  /**< Cycling Speed and Cadence Sensor. */
-        PULSE_OXIMETER_GENERIC                         = 3136,  /**< Generic Pulse Oximeter. */
-        PULSE_OXIMETER_FINGERTIP                       = 3137,  /**< Fingertip Pulse Oximeter. */
-        PULSE_OXIMETER_WRIST_WORN                      = 3138,  /**< Wrist Worn Pulse Oximeter. */
-        OUTDOOR_GENERIC                                = 5184,  /**< Generic Outdoor. */
-        OUTDOOR_LOCATION_DISPLAY_DEVICE                = 5185,  /**< Outdoor Location Display Device. */
-        OUTDOOR_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE = 5186,  /**< Outdoor Location and Navigation Display Device. */
-        OUTDOOR_LOCATION_POD                           = 5187,  /**< Outdoor Location Pod. */
-        OUTDOOR_LOCATION_AND_NAVIGATION_POD            = 5188   /**< Outdoor Location and Navigation Pod. */
+        UNKNOWN                                        = 0,     /**< Unknown of unspecified appearance type */
+        GENERIC_PHONE                                  = 64,    /**< Generic Phone */
+        GENERIC_COMPUTER                               = 128,   /**< Generic Computer */
+        GENERIC_WATCH                                  = 192,   /**< Generic Watch */
+        WATCH_SPORTS_WATCH                             = 193,   /**< Sports Watch */
+        GENERIC_CLOCK                                  = 256,   /**< Generic Clock */
+        GENERIC_DISPLAY                                = 320,   /**< Generic Display */
+        GENERIC_REMOTE_CONTROL                         = 384,   /**< Generic Remote Control */
+        GENERIC_EYE_GLASSES                            = 448,   /**< Generic Eye Glasses */
+        GENERIC_TAG                                    = 512,   /**< Generic Tag */
+        GENERIC_KEYRING                                = 576,   /**< Generic Keyring */
+        GENERIC_MEDIA_PLAYER                           = 640,   /**< Generic Media Player */
+        GENERIC_BARCODE_SCANNER                        = 704,   /**< Generic Barcode Scanner */
+        GENERIC_THERMOMETER                            = 768,   /**< Generic Thermometer */
+        THERMOMETER_EAR                                = 769,   /**< Ear Thermometer */
+        GENERIC_HEART_RATE_SENSOR                      = 832,   /**< Generic Heart Rate Sensor */
+        HEART_RATE_SENSOR_HEART_RATE_BELT              = 833,   /**< Belt Heart Rate Sensor */
+        GENERIC_BLOOD_PRESSURE                         = 896,   /**< Generic Blood Pressure */
+        BLOOD_PRESSURE_ARM                             = 897,   /**< Arm Blood Pressure */
+        BLOOD_PRESSURE_WRIST                           = 898,   /**< Wrist Blood Pressure */
+        HUMAN_INTERFACE_DEVICE_HID                     = 960,   /**< Human Interface Device (HID) */
+        KEYBOARD                                       = 961,   /**< Keyboard */
+        MOUSE                                          = 962,   /**< Mouse */
+        JOYSTICK                                       = 963,   /**< Joystick */
+        GAMEPAD                                        = 964,   /**< Gamepad */
+        DIGITIZER_TABLET                               = 965,   /**< Digitizer Tablet */
+        CARD_READER                                    = 966,   /**< Card Read */
+        DIGITAL_PEN                                    = 967,   /**< Digital Pen */
+        BARCODE_SCANNER                                = 968,   /**< Barcode Scanner */
+        GENERIC_GLUCOSE_METER                          = 1024,  /**< Generic Glucose Meter */
+        GENERIC_RUNNING_WALKING_SENSOR                 = 1088,  /**< Generic Running/Walking Sensor */
+        RUNNING_WALKING_SENSOR_IN_SHOE                 = 1089,  /**< In Shoe Running/Walking Sensor */
+        RUNNING_WALKING_SENSOR_ON_SHOE                 = 1090,  /**< On Shoe Running/Walking Sensor */
+        RUNNING_WALKING_SENSOR_ON_HIP                  = 1091,  /**< On Hip Running/Walking Sensor */
+        GENERIC_CYCLING                                = 1152,  /**< Generic Cycling */
+        CYCLING_CYCLING_COMPUTER                       = 1153,  /**< Cycling Computer */
+        CYCLING_SPEED_SENSOR                           = 1154,  /**< Cycling Speed Senspr */
+        CYCLING_CADENCE_SENSOR                         = 1155,  /**< Cycling Cadence Sensor */
+        CYCLING_POWER_SENSOR                           = 1156,  /**< Cycling Power Sensor */
+        CYCLING_SPEED_AND_CADENCE_SENSOR               = 1157,  /**< Cycling Speed and Cadence Sensor */
+        PULSE_OXIMETER_GENERIC                         = 3136,  /**< Generic Pulse Oximeter */
+        PULSE_OXIMETER_FINGERTIP                       = 3137,  /**< Fingertip Pulse Oximeter */
+        PULSE_OXIMETER_WRIST_WORN                      = 3138,  /**< Wrist Worn Pulse Oximeter */
+        OUTDOOR_GENERIC                                = 5184,  /**< Generic Outdoor */
+        OUTDOOR_LOCATION_DISPLAY_DEVICE                = 5185,  /**< Outdoor Location Display Device */
+        OUTDOOR_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE = 5186,  /**< Outdoor Location and Navigation Display Device */
+        OUTDOOR_LOCATION_POD                           = 5187,  /**< Outdoor Location Pod */
+        OUTDOOR_LOCATION_AND_NAVIGATION_POD            = 5188   /**< Outdoor Location and Navigation Pod */
     };
     typedef enum Appearance_t Appearance; /* Deprecated type alias. This may be dropped in a future release. */
 
@@ -200,109 +199,38 @@
     }
 
     /**
-     * Adds advertising data based on the specified AD type (see DataType).
+     * Adds advertising data based on the specified AD type (see DataType)
      *
-     * @param  advDataType The Advertising 'DataType' to add.
-     * @param  payload     Pointer to the payload contents.
-     * @param  len         Size of the payload in bytes.
+     * @param  advDataType The Advertising 'DataType' to add
+     * @param  payload     Pointer to the payload contents
+     * @param  len         Size of the payload in bytes
      *
      * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
      * advertising buffer to overflow, else BLE_ERROR_NONE.
      */
     ble_error_t addData(DataType advDataType, const uint8_t *payload, uint8_t len)
     {
-        ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW;
-
-        // find field
-        uint8_t* field = findField(advDataType);
-
-        // Field type already exist, either add to field or replace
-        if (field) {
-            switch(advDataType) {
-                //  These fields will be overwritten with the new value
-                case FLAGS:
-                case SHORTENED_LOCAL_NAME:
-                case COMPLETE_LOCAL_NAME:
-                case TX_POWER_LEVEL:
-                case DEVICE_ID:
-                case SLAVE_CONNECTION_INTERVAL_RANGE:
-                case SERVICE_DATA:
-                case APPEARANCE:
-                case ADVERTISING_INTERVAL:
-                case MANUFACTURER_SPECIFIC_DATA: {
-                    // current field length, with the type subtracted
-                    uint8_t dataLength = field[0] - 1;
-
-                    // new data has same length, do in-order replacement
-                    if (len == dataLength) {
-                        for (uint8_t idx = 0; idx < dataLength; idx++) {
-                            field[2 + idx] = payload[idx];
-                        }
-                    } else {
-                        // check if data fits
-                        if ((_payloadLen - dataLength + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
-
-                            // remove old field
-                            while ((field + dataLength + 2) < &_payload[_payloadLen]) {
-                                *field = field[dataLength + 2];
-                                field++;
-                            }
-
-                            // reduce length
-                            _payloadLen -= dataLength + 2;
-
-                            // add new field
-                            result = appendField(advDataType, payload, len);
-                        }
-                    }
+        /* ToDo: Check if an AD type already exists and if the existing */
+        /*       value is exclusive or not (flags, etc.) */
 
-                    break;
-                }
-                // These fields will have the new data appended if there is sufficient space
-                case INCOMPLETE_LIST_16BIT_SERVICE_IDS:
-                case COMPLETE_LIST_16BIT_SERVICE_IDS:
-                case INCOMPLETE_LIST_32BIT_SERVICE_IDS:
-                case COMPLETE_LIST_32BIT_SERVICE_IDS:
-                case INCOMPLETE_LIST_128BIT_SERVICE_IDS:
-                case COMPLETE_LIST_128BIT_SERVICE_IDS:
-                case LIST_128BIT_SOLICITATION_IDS: {
-                    // check if data fits
-                    if ((_payloadLen + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
-                        // make room for new field by moving the remainder of the
-                        // advertisement payload "to the right" starting after the
-                        // TYPE field.
-                        uint8_t* end = &_payload[_payloadLen];
-
-                        while (&field[1] < end) {
-                            end[len] = *end;
-                            end--;
-                        }
-
-                        // insert new data
-                        for (uint8_t idx = 0; idx < len; idx++) {
-                            field[2 + idx] = payload[idx];
-                        }
-
-                        // increment lengths
-                        field[0] += len;
-                        _payloadLen += len;
-
-                        result = BLE_ERROR_NONE;
-                    }
-
-                    break;
-                }
-                // Field exists but updating it is not supported. Abort operation.
-                default:
-                    result = BLE_ERROR_NOT_IMPLEMENTED;
-                    break;
-            }
-        } else {
-            // field doesn't exists, insert new
-            result = appendField(advDataType, payload, len);
+        /* Make sure we don't exceed the 31 byte payload limit */
+        if (_payloadLen + len + 2 > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
+            return BLE_ERROR_BUFFER_OVERFLOW;
         }
 
-        return result;
+        /* Field length */
+        memset(&_payload[_payloadLen], len + 1, 1);
+        _payloadLen++;
+
+        /* Field ID */
+        memset(&_payload[_payloadLen], (uint8_t)advDataType, 1);
+        _payloadLen++;
+
+        /* Payload */
+        memcpy(&_payload[_payloadLen], payload, len);
+        _payloadLen += len;
+
+        return BLE_ERROR_NONE;
     }
 
     /**
@@ -325,7 +253,7 @@
 
         /* A local struct to describe an ADV field. This definition comes from the Bluetooth Core Spec. (v4.2) Part C, Section 11. */
         struct ADVField_t {
-            uint8_t  len;      /* Describes the length (in bytes) of the following type and bytes. */
+            uint8_t  len;      /* Describes the length (in bytes) of the following 'type' and 'bytes'. */
             uint8_t  type;     /* Should have the same representation of DataType_t (above). */
             uint8_t  bytes[0]; /* A placeholder for variable length data. */
         };
@@ -334,23 +262,23 @@
         uint8_t byteIndex = 0;
         while (byteIndex < _payloadLen) {
             ADVField_t *currentADV = (ADVField_t *)&_payload[byteIndex];
-            if ((currentADV->len  == (len + 1)) && /* Incoming len only describes the payload, whereas ADV->len describes [type + payload]. */
+            if ((currentADV->len  == (len + 1)) && /* incoming 'len' only describes the payload, whereas ADV->len describes 'type + payload' */
                 (currentADV->type == advDataType)) {
                 memcpy(currentADV->bytes, payload, len);
                 return BLE_ERROR_NONE;
             }
 
-            byteIndex += (currentADV->len + 1); /* Advance by len+1; '+1' is needed to span the len field itself. */
+            byteIndex += (currentADV->len + 1); /* advance by len+1; '+1' is needed to span the len field itself. */
         }
 
         return BLE_ERROR_UNSPECIFIED;
     }
 
     /**
-     * Helper function to add APPEARANCE data to the advertising payload.
+     * Helper function to add APPEARANCE data to the advertising payload
      *
      * @param  appearance
-     *           The APPEARANCE value to add.
+     *           The APPEARANCE value to add
      *
      * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
      * advertising buffer to overflow, else BLE_ERROR_NONE.
@@ -378,18 +306,18 @@
     }
 
     /**
-     * Helper function to add TX_POWER_LEVEL data to the advertising payload.
+     * Helper function to add TX_POWER_LEVEL data to the advertising payload
      *
      * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
      * advertising buffer to overflow, else BLE_ERROR_NONE.
      */
     ble_error_t addTxPower(int8_t txPower) {
-        /* To Do: Basic error checking to make sure txPower is in range. */
+        /* ToDo: Basic error checking to make sure txPower is in range */
         return addData(GapAdvertisingData::TX_POWER_LEVEL, (uint8_t *)&txPower, 1);
     }
 
     /**
-     * Clears the payload and resets the payload length counter.
+     * Clears the payload and resets the payload length counter
      */
     void        clear(void) {
         memset(&_payload, 0, GAP_ADVERTISING_DATA_MAX_PAYLOAD);
@@ -397,83 +325,27 @@
     }
 
     /**
-     * Returns a pointer to the current payload.
+     * Returns a pointer to the the current payload
      */
     const uint8_t *getPayload(void) const {
         return _payload;
     }
 
     /**
-     * Returns the current payload length (0..31 bytes).
+     * Returns the current payload length (0..31 bytes)
      */
     uint8_t     getPayloadLen(void) const {
         return _payloadLen;
     }
 
     /**
-     * Returns the 16-bit appearance value for this device.
+     * Returns the 16-bit appearance value for this device
      */
     uint16_t    getAppearance(void) const {
         return (uint16_t)_appearance;
     }
 
-    /**
-     * Search advertisement data for field.
-     * Returns pointer to the first element in the field if found, NULL otherwise.
-     * Where the first element is the length of the field.
-     */
-    const uint8_t* findField(DataType_t type) const {
-        return findField(type);
-    }
-
 private:
-    /**
-     * Append advertising data based on the specified AD type (see DataType)
-     */
-    ble_error_t appendField(DataType advDataType, const uint8_t *payload, uint8_t len)
-    {
-        /* Make sure we don't exceed the 31 byte payload limit */
-        if (_payloadLen + len + 2 > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
-            return BLE_ERROR_BUFFER_OVERFLOW;
-        }
-
-        /* Field length. */
-        memset(&_payload[_payloadLen], len + 1, 1);
-        _payloadLen++;
-
-        /* Field ID. */
-        memset(&_payload[_payloadLen], (uint8_t)advDataType, 1);
-        _payloadLen++;
-
-        /* Payload. */
-        memcpy(&_payload[_payloadLen], payload, len);
-        _payloadLen += len;
-
-        return BLE_ERROR_NONE;
-    }
-
-    /**
-     * Search advertisement data for field.
-     * Returns pointer to the first element in the field if found, NULL otherwise.
-     * Where the first element is the length of the field.
-     */
-    uint8_t* findField(DataType_t type) {
-        // scan through advertisement data
-        for (uint8_t idx = 0; idx < _payloadLen; ) {
-            uint8_t fieldType = _payload[idx + 1];
-
-            if (fieldType == type) {
-                return &_payload[idx];
-            }
-
-            // advance to next field
-            idx += _payload[idx] + 1;
-        }
-
-        // field not found
-        return NULL;
-    }
-
     uint8_t  _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD];
     uint8_t  _payloadLen;
     uint16_t _appearance;