High level Bluetooth Low Energy API and radio abstraction layer

Dependencies:   nRF51822

Dependents:   LinkNode_LIS3DH

Fork of BLE_API by Bluetooth Low Energy

Files at this revision

API Documentation at this revision

Comitter:
ktownsend
Date:
Thu Dec 12 02:20:54 2013 +0000
Parent:
3:46de446e82ed
Child:
5:7635f81a8e09
Commit message:
More GAP refactoring

Changed in this revision

GapAdvertisingData.cpp Show annotated file Show diff for this revision Revisions of this file
GapAdvertisingData.h Show annotated file Show diff for this revision Revisions of this file
GapAdvertisingParams.cpp Show annotated file Show diff for this revision Revisions of this file
GapAdvertisingParams.h Show annotated file Show diff for this revision Revisions of this file
GattCharacteristic.cpp Show annotated file Show diff for this revision Revisions of this file
GattCharacteristic.h Show annotated file Show diff for this revision Revisions of this file
blecommon.h Show annotated file Show diff for this revision Revisions of this file
--- a/GapAdvertisingData.cpp	Wed Dec 11 22:15:59 2013 +0000
+++ b/GapAdvertisingData.cpp	Thu Dec 12 02:20:54 2013 +0000
@@ -31,19 +31,10 @@
 
 /**************************************************************************/
 /*!
-    @brief Returns the current payload length (0..31 bytes)
-*/
-/**************************************************************************/
-uint8_t GapAdvertisingData::getPayloadLen(void)
-{
-    return _payloadLen;
-}
+    @brief  Adds advertising data based on the specified AD type (see
+            \ref DataType)
 
-/**************************************************************************/
-/*!
-    @brief Adds advertising data based on the specified AD types
-
-    @args[in]   adType      The advertising data type to add
+    @args[in]   advDataType The Advertising \ref DataType to add
     @args[in]   payload     Pointer to the payload contents
     @args[in]   len         Size of the payload in bytes
     
@@ -51,6 +42,45 @@
     
     @retval     BLE_ERROR_NONE
                 Everything executed properly
+                
+    @retval     BLE_ERROR_BUFFER_OVERFLOW
+                The specified data would cause the advertising buffer
+                to overflow
+    
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t GapAdvertisingData::addData(DataType advDataType, uint8_t * payload, uint8_t len)
+{
+    /* ToDo: Check if an AD type already exists and if the existing */
+    /*       value is exclusive or not (flags, etc.) */
+    
+    /* Make sure we don't exceed the 31 byte payload limit */
+    if (_payloadLen + len >= GAP_ADVERTISING_DATA_MAX_PAYLOAD)
+        return BLE_ERROR_BUFFER_OVERFLOW;
+    
+    memcpy(&_payload[_payloadLen], payload, len);
+    _payloadLen += len;
+    
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Helper function to add \ref APPEARANCE data to the advertising
+            payload
+
+    @args[in]   appearance  The \ref APPEARANCE value to add
+    
+    @returns    ble_error_t
+    
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+                
     @retval     BLE_ERROR_BUFFER_OVERFLOW
                 The specified data would cause the advertising buffer
                 to overflow
@@ -62,14 +92,93 @@
     @endcode
 */
 /**************************************************************************/
-ble_error_t GapAdvertisingData::addData(ble_gap_adv_datatype_t adType, uint8_t * payload, uint8_t len)
+ble_error_t GapAdvertisingData::addAppearance(Appearance appearance)
 {
-    /* ToDo: Make sure we don't exceed the 31 byte payload limit */
-    if (_payloadLen + len >= GAP_ADVERTISING_DATA_MAX_PAYLOAD)
-        return BLE_ERROR_BUFFER_OVERFLOW;
+    return addData(GapAdvertisingData::APPEARANCE, (uint8_t*)&appearance, 2);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Helper function to add \ref FLAGS data to the advertising
+            payload
+
+    @args[in]   flag  The \ref FLAGS value to add
+
+                @para
+                \ref LE_LIMITED_DISCOVERABLE - The peripheral is
+                discoverable for a limited period of time
+
+                @para
+                \ref LE_GENERAL_DISCOVERABLE - The peripheral is
+                permanently discoverable
+
+    @returns    ble_error_t
+    
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+                
+    @retval     BLE_ERROR_BUFFER_OVERFLOW
+                The specified data would cause the advertising buffer
+                to overflow
     
-    memcpy(&_payload[_payloadLen], payload, len);
-    _payloadLen += len;
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t GapAdvertisingData::addFlags(Flags flag)
+{
+    return addData(GapAdvertisingData::FLAGS, (uint8_t*)&flag, 1);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Helper function to add \ref TX_POWER_LEVEL data to the
+            advertising payload
+
+    @args[in]   flag  The \ref TX_POWER_LEVEL value to add
+    
+    @returns    ble_error_t
+    
+    @retval     BLE_ERROR_NONE
+                Everything executed properly
+                
+    @retval     BLE_ERROR_BUFFER_OVERFLOW
+                The specified data would cause the advertising buffer
+                to overflow
     
-    return BLE_ERROR_NONE;
+    @section EXAMPLE
+
+    @code
+
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t GapAdvertisingData::addTxPower(int8_t txPower)
+{
+    /* ToDo: Basic error checking to make sure txPower is in range */
+    return addData(GapAdvertisingData::TX_POWER_LEVEL, (uint8_t*)&txPower, 1);
 }
+
+/**************************************************************************/
+/*!
+    @brief Clears the payload and resets the payload length counter
+*/
+/**************************************************************************/
+void GapAdvertisingData::clear(void)
+{
+    memset(&_payload, 0, GAP_ADVERTISING_DATA_MAX_PAYLOAD);
+    _payloadLen = 0;
+}
+
+/**************************************************************************/
+/*!
+    @brief Returns the current payload length (0..31 bytes)
+*/
+/**************************************************************************/
+uint8_t GapAdvertisingData::getPayloadLen(void)
+{
+    return _payloadLen;
+}
--- a/GapAdvertisingData.h	Wed Dec 11 22:15:59 2013 +0000
+++ b/GapAdvertisingData.h	Thu Dec 12 02:20:54 2013 +0000
@@ -10,13 +10,17 @@
     @brief
     This class provides several helper functions to generate properly
     formatted GAP Advertising and Scan Response data payloads
-    
+
+    @note See Bluetooth Specification 4.0 (Vol. 3), Part C, Section 11 and 18
+    for further information on Advertising and Scan Response data.
+        
     @section Advertising and Scan Response Payloads
     
     @para
     Advertising data and Scan Response data are organized around a set of
-    data types called 'AD types' in the Bluetooth 4.0 specification.
-            
+    data types called 'AD types' in Bluetooth 4.0 (see the Bluetooth Core
+    Specification v4.0, Vol. 3, Part C, Sections 11 and 18).
+
     @para
     Each AD type has it's own standardized 'assigned number', as defined
     by the Bluetooth SIG:
@@ -24,24 +28,23 @@
     
     @para
     For convenience sake, all appropriate AD types have been encapsulated
-    into an enum at \ref ble_gap_adv_datatype_t.
+    into an enum at \ref DataType.
     
     @para
-    Raw Advertising or Scan Response payloads are formatted as follows:
+    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:
     
     - Record length (1 byte)
     - AD Type (1 byte)
     - AD payload (optional, only present if record length > 1)
-    
+
     @para
-    When multiple AD types are present, the individual records are simply
+    When multiple AD records are present, the individual records are
     appended one after the other, up to the maximum payload length of 31
-    bytes.
+    bytes, as can be seen in the example payload below.
     
-    @note See Bluetooth Specification 4.0 (Vol. 3) Section 11, 18 for
-    further information on Advertising and Scan Response data.
-    
-    @section Sample Advertising Payload
+    @section Sample Raw Advertising Payload
     
     // Two record payload containing BLE_GAP_ADV_DATATYPE_FLAGS (0x01) and 
     // BLE_GAP_ADV_DATATYPE_COMPLETE_LOCAL_NAME (0x09) fields
@@ -62,14 +65,105 @@
 /**************************************************************************/
 class GapAdvertisingData
 {
-public:    
+  public:
+    /* Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 11, 18 */
+    /* https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile */
+    enum DataType
+    {
+      FLAGS                                             = 0x01,
+      INCOMPLETE_LIST_16BIT_SERVICE_IDS                 = 0x02,
+      COMPLETE_LIST_16BIT_SERVICE_IDS                   = 0x03,
+      INCOMPLETE_LIST_32BIT_SERVICE_IDS                 = 0x04,
+      COMPLETE_LIST_32BIT_SERVICE_IDS                   = 0x05,
+      INCOMPLETE_LIST_128BIT_SERVICE_IDS                = 0x06,
+      COMPLETE_LIST_128BIT_SERVICE_IDS                  = 0x07,
+      SHORTENED_LOCAL_NAME                              = 0x08,
+      COMPLETE_LOCAL_NAME                               = 0x09,
+      TX_POWER_LEVEL                                    = 0x0A,
+      DEVICE_ID                                         = 0x10,
+      SLAVE_CONNECTION_INTERVAL_RANGE                   = 0x12,
+      SERVICE_DATA                                      = 0x16,
+      APPEARANCE                                        = 0x19,
+      ADVERTISING_INTERVAL                              = 0x1A,
+      MANUFACTURER_SPECIFIC_DATA                        = 0xFF
+    };
+    
+    /* Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 18.1 */
+    enum Flags
+    {
+      LE_LIMITED_DISCOVERABLE                           = 0x01,
+      LE_GENERAL_DISCOVERABLE                           = 0x02,
+      BREDR_NOT_SUPPORTED                               = 0x04,
+      SIMULTANEOUS_LE_BREDR_C                           = 0x08,
+      SIMULTANEOUS_LE_BREDR_H                           = 0x10
+    };
+
+    /* Bluetooth Core Specification Supplement, Part A, Section 1.12 */
+    /* Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 12.2 */
+    /* https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml */
+    enum Appearance
+    {
+      UNKNOWN                                           = 0,
+      GENERIC_PHONE                                     = 64,
+      GENERIC_COMPUTER                                  = 128,
+      GENERIC_WATCH                                     = 192,
+      WATCH_SPORTS_WATCH                                = 193,
+      GENERIC_CLOCK                                     = 256,
+      GENERIC_DISPLAY                                   = 320,
+      GENERIC_REMOTE_CONTROL                            = 384,
+      GENERIC_EYE_GLASSES                               = 448,
+      GENERIC_TAG                                       = 512,
+      GENERIC_KEYRING                                   = 576,
+      GENERIC_MEDIA_PLAYER                              = 640,
+      GENERIC_BARCODE_SCANNER                           = 704,
+      GENERIC_THERMOMETER                               = 768,
+      THERMOMETER_EAR                                   = 769,
+      GENERIC_HEART_RATE_SENSOR                         = 832,
+      HEART_RATE_SENSOR_HEART_RATE_BELT                 = 833,
+      GENERIC_BLOOD_PRESSURE                            = 896,
+      BLOOD_PRESSURE_ARM                                = 897,
+      BLOOD_PRESSURE_WRIST                              = 898,
+      HUMAN_INTERFACE_DEVICE_HID                        = 960,
+      KEYBOARD                                          = 961,
+      MOUSE                                             = 962,
+      JOYSTICK                                          = 963,
+      GAMEPAD                                           = 964,
+      DIGITIZER_TABLET                                  = 965,
+      CARD_READER                                       = 966,
+      DIGITAL_PEN                                       = 967,
+      BARCODE_SCANNER                                   = 968,
+      GENERIC_GLUCOSE_METER                             = 1024,
+      GENERIC_RUNNING_WALKING_SENSOR                    = 1088,
+      RUNNING_WALKING_SENSOR_IN_SHOE                    = 1089,
+      RUNNING_WALKING_SENSOR_ON_SHOE                    = 1090,
+      RUNNING_WALKING_SENSOR_ON_HIP                     = 1091,
+      GENERIC_CYCLING                                   = 1152,
+      CYCLING_CYCLING_COMPUTER                          = 1153,
+      CYCLING_SPEED_SENSOR                              = 1154,
+      CYCLING_CADENCE_SENSOR                            = 1155,
+      CYCLING_POWER_SENSOR                              = 1156,
+      CYCLING_SPEED_AND_CADENCE_SENSOR                  = 1157,
+      PULSE_OXIMETER_GENERIC                            = 3136,
+      PULSE_OXIMETER_FINGERTIP                          = 3137,
+      PULSE_OXIMETER_WRIST_WORN                         = 3138,
+      OUTDOOR_GENERIC                                   = 5184,
+      OUTDOOR_LOCATION_DISPLAY_DEVICE                   = 5185,
+      OUTDOOR_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE    = 5186,
+      OUTDOOR_LOCATION_POD                              = 5187,
+      OUTDOOR_LOCATION_AND_NAVIGATION_POD               = 5188
+    };
+
     GapAdvertisingData(void);
     virtual ~GapAdvertisingData(void);
 
-    ble_error_t addData(ble_gap_adv_datatype_t, uint8_t *, uint8_t);
+    ble_error_t addData(DataType, uint8_t *, uint8_t);
+    ble_error_t addAppearance(Appearance appearance = UNKNOWN);
+    ble_error_t addFlags(Flags flag = LE_GENERAL_DISCOVERABLE);
+    ble_error_t addTxPower(int8_t txPower);
+    void        clear(void);
     uint8_t     getPayloadLen(void);
-    
-private:
+
+  private:
     uint8_t _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD];
     uint8_t _payloadLen;
 };
--- a/GapAdvertisingParams.cpp	Wed Dec 11 22:15:59 2013 +0000
+++ b/GapAdvertisingParams.cpp	Thu Dec 12 02:20:54 2013 +0000
@@ -1,12 +1,49 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "blecommon.h"
 #include "GapAdvertisingParams.h"
 
 /**************************************************************************/
 /*!
-    @brief  Creates a new GapAdvertisingParams
+    @brief  Instantiates a new GapAdvertisingParams instance
+
+    @param[in]  connectionMode
+                The GAP connection mode to use for this device. Valid
+                values are defined in \ref ConnectionMode
 
+                @para
+                NON_CONNECTABLE - All connections to the peripheral device
+                will be refused.
+                
+                @para
+                DIRECTED_CONNECTABLE - Only connections from a pre-defined
+                central device will be accepted.
+                
+                @para
+                UNDIRECTED_CONNECTABLE - Any central device can connect to
+                this peripheral.
+                
+                @note See Bluetooth Core Specification 4.0 (Vol. 3),
+                Part C, Section 9.3 for further information on GAP
+                connection modes
+
+    @param[in]  interval
+                Advertising interval between 0x20 and 0x4000 (32 and 16384)
+                in 0.625ms intervals (20ms to 10.24s).
+
+                @para
+                Increasing this value will allow central devices to detect
+                your peripheral faster at the expense of more power being
+                used by the radio due to the higher data transmit rate.
+                
+                @note This field must be set to 0 if connectionMode is equal
+                to \ref DIRECTED_CONNECTABLE
+
+    @param[in]  timeout
+                Advertising timeout between 0x1 and 0x3FFF (1 and 16383)
+                in seconds.  Enter 0 to disable the advertising timeout.
+                
     @section EXAMPLE
 
     @code
@@ -14,11 +51,40 @@
     @endcode
 */
 /**************************************************************************/
-GapAdvertisingParams::GapAdvertisingParams(uint8_t advType, uint16_t interval, uint16_t timeout)
+GapAdvertisingParams::GapAdvertisingParams(ConnectionMode connectionMode, uint16_t interval, uint16_t timeout)
 {
-    _advType = advType;
+    _connectionMode = connectionMode;
     _interval = interval;
     _timeout = timeout;
+
+    /* Interval checks */
+    if (_connectionMode == DIRECTED_CONNECTABLE)
+    {
+        /* Interval must be 0 in directed connectable mode */
+        _interval = 0;
+    }
+    else
+    {
+        /* Stay within interval limits */
+        if (_interval < GAP_ADV_PARAMS_INTERVAL_MIN)
+        {
+            _interval = GAP_ADV_PARAMS_INTERVAL_MIN;
+        }
+        if (_interval > GAP_ADV_PARAMS_INTERVAL_MAX)
+        {
+            _interval = GAP_ADV_PARAMS_INTERVAL_MAX;
+        }
+    }
+
+    /* Timeout checks */
+    if (timeout)
+    {
+        /* Stay within timeout limits */
+        if (_timeout > GAP_ADV_PARAMS_TIMEOUT_MAX)
+        {
+            _timeout = GAP_ADV_PARAMS_TIMEOUT_MAX;
+        }
+    }
 }
 
 /**************************************************************************/
--- a/GapAdvertisingParams.h	Wed Dec 11 22:15:59 2013 +0000
+++ b/GapAdvertisingParams.h	Thu Dec 12 02:20:54 2013 +0000
@@ -3,14 +3,28 @@
 
 #include "blecommon.h"
 
+#define GAP_ADV_PARAMS_INTERVAL_MIN     (0x0020)
+#define GAP_ADV_PARAMS_INTERVAL_MAX     (0x4000)
+#define GAP_ADV_PARAMS_TIMEOUT_MAX      (0x3FFF)
+
 class GapAdvertisingParams
 {
-public:
-    GapAdvertisingParams(uint8_t advType, uint16_t interval, uint16_t timeout);
+  public:
+    /* See Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 9.3 */
+    enum ConnectionMode
+    {
+      NON_CONNECTABLE,          /**< Section 9.3.2 */
+      DIRECTED_CONNECTABLE,     /**< Section 9.3.3 */
+      UNDIRECTED_CONNECTABLE    /**< Section 9.3.4 */
+    };
+  
+    GapAdvertisingParams(ConnectionMode connectionMode = GapAdvertisingParams::UNDIRECTED_CONNECTABLE,
+                         uint16_t interval = GAP_ADV_PARAMS_INTERVAL_MIN, 
+                         uint16_t timeout = 0);
     virtual ~GapAdvertisingParams(void);
 
-private:
-    uint8_t  _advType;
+  private:
+    ConnectionMode  _connectionMode;
     uint16_t _interval;
     uint16_t _timeout;
 };
--- a/GattCharacteristic.cpp	Wed Dec 11 22:15:59 2013 +0000
+++ b/GattCharacteristic.cpp	Thu Dec 12 02:20:54 2013 +0000
@@ -25,7 +25,7 @@
     @code
 
     // UUID = 0x2A19, Min length 2, Max len = 2, Properties = write
-    GattCharacteristic c = GattCharacteristic( 0x2A19, 2, 2, 0x08 );
+    GattCharacteristic c = GattCharacteristic( 0x2A19, 2, 2, BLE_GATT_CHAR_PROPERTIES_WRITE );
    
     @endcode
 */
--- a/GattCharacteristic.h	Wed Dec 11 22:15:59 2013 +0000
+++ b/GattCharacteristic.h	Thu Dec 12 02:20:54 2013 +0000
@@ -16,18 +16,7 @@
     uint16_t lenMin;            /* Minimum length of the value */
     uint16_t lenMax;            /* Maximum length of the value */
     uint8_t  index;
-    
-    struct Properties
-    {
-        /* Standard properties */
-        uint8_t broadcast       :1;         /**< Broadcasting of value permitted. */
-        uint8_t read            :1;         /**< Reading value permitted. */
-        uint8_t write_wo_resp   :1;         /**< Writing value with Write Command permitted. */
-        uint8_t write           :1;         /**< Writing value with Write Request permitted. */
-        uint8_t notify          :1;         /**< Notications of value permitted. */ // https://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
-        uint8_t indicate        :1;         /**< Indications of value permitted. */ // https://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
-        uint8_t auth_signed_wr  :1;         /**< Writing value with Signed Write Command permitted. */
-    } properties;
+    uint8_t  properties;
 };
 
 #endif
--- a/blecommon.h	Wed Dec 11 22:15:59 2013 +0000
+++ b/blecommon.h	Thu Dec 12 02:20:54 2013 +0000
@@ -1,6 +1,10 @@
 #ifndef __BLE_COMMON_H__
 #define __BLE_COMMON_H__
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <stdint.h>
 
 typedef enum ble_error_e
@@ -9,92 +13,7 @@
   BLE_ERROR_BUFFER_OVERFLOW         = 1
 } ble_error_t;
 
-/* Bluetooth Specification 4.0 (Vol. 3) Section 18.1 */
-typedef enum ble_gap_adv_flags_e
-{
-  BLE_GAP_ADV_FLAGS_LE_LIMITED_DISCOVERABLE                               = 0x01,
-  BLE_GAP_ADV_FLAGS_LE_GENERAL_DISCOVERABLE                               = 0x02,
-  BLE_GAP_ADV_FLAGS_BREDR_NOT_SUPPORTED                                   = 0x04,
-  BLE_GAP_ADV_FLAGS_SIMULTANEOUS_LE_BREDR_C                               = 0x08,
-  BLE_GAP_ADV_FLAGS_SIMULTANEOUS_LE_BREDR_H                               = 0x10
-} ble_gap_adv_flags_t;
-
-/* https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile */
-/* Bluetooth Specification 4.0 (Vol. 3) Section 11, 18 */
-typedef enum ble_gap_adv_datatype_e
-{
-  BLE_GAP_ADV_DATATYPE_FLAGS                                              = 0x01,
-  BLE_GAP_ADV_DATATYPE_INCOMPLETE_LIST_16BIT_SERVICE_IDS                  = 0x02,
-  BLE_GAP_ADV_DATATYPE_COMPLETE_LIST_16BIT_SERVICE_IDS                    = 0x03,
-  BLE_GAP_ADV_DATATYPE_INCOMPLETE_LIST_32BIT_SERVICE_IDS                  = 0x04,
-  BLE_GAP_ADV_DATATYPE_COMPLETE_LIST_32BIT_SERVICE_IDS                    = 0x05,
-  BLE_GAP_ADV_DATATYPE_INCOMPLETE_LIST_128BIT_SERVICE_IDS                 = 0x06,
-  BLE_GAP_ADV_DATATYPE_COMPLETE_LIST_128BIT_SERVICE_IDS                   = 0x07,
-  BLE_GAP_ADV_DATATYPE_SHORTENED_LOCAL_NAME                               = 0x08,
-  BLE_GAP_ADV_DATATYPE_COMPLETE_LOCAL_NAME                                = 0x09,
-  BLE_GAP_ADV_DATATYPE_TX_POWER_LEVEL                                     = 0x0A,
-  BLE_GAP_ADV_DATATYPE_DEVICE_ID                                          = 0x10,
-  BLE_GAP_ADV_DATATYPE_SLAVE_CONNECTION_INTERVAL_RANGE                    = 0x12,
-  BLE_GAP_ADV_DATATYPE_SERVICE_DATA                                       = 0x16,
-  BLE_GAP_ADV_DATATYPE_APPEARANCE                                         = 0x19,
-  BLE_GAP_ADV_DATATYPE_ADVERTISING_INTERVAL                               = 0x1A,
-  BLE_GAP_ADV_DATATYPE_MANUFACTURER_SPECIFIC_DATA                         = 0xFF
-} ble_gap_adv_datatype_t;
-
-// https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
-typedef enum ble_gap_char_appearance_e
-{
-  BLE_GAP_CHAR_APPEARANCE_UNKNOWN                                         = 0,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_PHONE                                   = 64,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_COMPUTER                                = 128,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_WATCH                                   = 192,
-  BLE_GAP_CHAR_APPEARANCE_WATCH_SPORTS_WATCH                              = 193,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_CLOCK                                   = 256,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_DISPLAY                                 = 320,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_REMOTE_CONTROL                          = 384,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_EYE_GLASSES                             = 448,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_TAG                                     = 512,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_KEYRING                                 = 576,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_MEDIA_PLAYER                            = 640,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_BARCODE_SCANNER                         = 704,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_THERMOMETER                             = 768,
-  BLE_GAP_CHAR_APPEARANCE_THERMOMETER_EAR                                 = 769,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_HEART_RATE_SENSOR                       = 832,
-  BLE_GAP_CHAR_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT               = 833,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_BLOOD_PRESSURE                          = 896,
-  BLE_GAP_CHAR_APPEARANCE_BLOOD_PRESSURE_ARM                              = 897,
-  BLE_GAP_CHAR_APPEARANCE_BLOOD_PRESSURE_WRIST                            = 898,
-  BLE_GAP_CHAR_APPEARANCE_HUMAN_INTERFACE_DEVICE_HID                      = 960,
-  BLE_GAP_CHAR_APPEARANCE_KEYBOARD                                        = 961,
-  BLE_GAP_CHAR_APPEARANCE_MOUSE                                           = 962,
-  BLE_GAP_CHAR_APPEARANCE_JOYSTICK                                        = 963,
-  BLE_GAP_CHAR_APPEARANCE_GAMEPAD                                         = 964,
-  BLE_GAP_CHAR_APPEARANCE_DIGITIZER_TABLET                                = 965,
-  BLE_GAP_CHAR_APPEARANCE_CARD_READER                                     = 966,
-  BLE_GAP_CHAR_APPEARANCE_DIGITAL_PEN                                     = 967,
-  BLE_GAP_CHAR_APPEARANCE_BARCODE_SCANNER                                 = 968,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_GLUCOSE_METER                           = 1024,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR                  = 1088,
-  BLE_GAP_CHAR_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE                  = 1089,
-  BLE_GAP_CHAR_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE                  = 1090,
-  BLE_GAP_CHAR_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP                   = 1091,
-  BLE_GAP_CHAR_APPEARANCE_GENERIC_CYCLING                                 = 1152,
-  BLE_GAP_CHAR_APPEARANCE_CYCLING_CYCLING_COMPUTER                        = 1153,
-  BLE_GAP_CHAR_APPEARANCE_CYCLING_SPEED_SENSOR                            = 1154,
-  BLE_GAP_CHAR_APPEARANCE_CYCLING_CADENCE_SENSOR                          = 1155,
-  BLE_GAP_CHAR_APPEARANCE_CYCLING_POWER_SENSOR                            = 1156,
-  BLE_GAP_CHAR_APPEARANCE_CYCLING_SPEED_AND_CADENCE_SENSOR                = 1157,
-  BLE_GAP_CHAR_APPEARANCE_PULSE_OXIMETER_GENERIC                          = 3136,
-  BLE_GAP_CHAR_APPEARANCE_PULSE_OXIMETER_FINGERTIP                        = 3137,
-  BLE_GAP_CHAR_APPEARANCE_PULSE_OXIMETER_WRIST_WORN                       = 3138,
-  BLE_GAP_CHAR_APPEARANCE_OUTDOOR_GENERIC                                 = 5184,
-  BLE_GAP_CHAR_APPEARANCE_OUTDOOR_LOCATION_DISPLAY_DEVICE                 = 5185,
-  BLE_GAP_CHAR_APPEARANCE_OUTDOOR_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE  = 5186,
-  BLE_GAP_CHAR_APPEARANCE_OUTDOOR_LOCATION_POD                            = 5187,
-  BLE_GAP_CHAR_APPEARANCE_OUTDOOR_LOCATION_AND_NAVIGATION_POD             = 5188
-} ble_gap_char_appearance_t;
-
-// https://developer.bluetooth.org/gatt/units/Pages/default.aspx
+/* https://developer.bluetooth.org/gatt/units/Pages/default.aspx */
 typedef enum ble_gatt_unit_e
 {
   BLE_GATT_UNIT_NONE                                                   = 0x2700,
@@ -208,7 +127,8 @@
   BLE_GATT_UNIT_IRRADIANCE_WATT_PER_SQUARE_METRE                       = 0x27B6
 } ble_gatt_unit_t;
 
-// http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
+/* Bluetooth Specification 4.0 (Vol. 3), Part G, Section 3.3.3.5.2 */
+/* http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml */
 typedef enum ble_gatt_format_e
 {
   BLE_GATT_FORMAT_RFU                 = 0x00, /**< Reserved For Future Use. */
@@ -241,6 +161,8 @@
   BLE_GATT_FORMAT_STRUCT              = 0x1B  /**< Opaque Structure. */
 } ble_gatt_format_t;
 
+/* Bluetooth Specification 4.0 (Vol. 3), Part G, Section 3.3.1.1 */
+/* See Section 3.3.3.1 for Extended Properties */
 typedef enum ble_gatt_char_properties_e
 {
   BLE_GATT_CHAR_PROPERTIES_BROADCAST                    = 0x01, /**< Permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. */
@@ -253,6 +175,17 @@
   BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES          = 0x80  /**< Additional characteristic properties are defined in the Characteristic Extended Properties Descriptor */
 } ble_gatt_char_properties_t;
 
+/* Bluetooth Specification 4.0 (Vol. 3), Part G, Section 3.3.3.5 */
+/* See https://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml */
+typedef struct PresentationFormat
+{
+  uint8_t   gatt_format;    /**< Format of the value, see @ref ble_gatt_format_t. */
+  int8_t    exponent;       /**< Exponent for integer data types. Ex. if Exponent = -3 and the char value is 3892, the actual value is 3.892 */
+  uint16_t  gatt_unit;      /**< UUID from Bluetooth Assigned Numbers, see @ref ble_gatt_unit_t. */
+  uint8_t   gatt_namespace; /**< Namespace from Bluetooth Assigned Numbers, normally '1',  see @ref BLE_GATT_CPF_NAMESPACES. */
+  uint16_t  gatt_nsdesc;    /**< Namespace description from Bluetooth Assigned Numbers, normally '0', see @ref BLE_GATT_CPF_NAMESPACES. */
+} presentation_format_t;
+
 struct UTF8String
 {
   uint16_t  length;         /**< String length. */
@@ -271,14 +204,8 @@
   uint8_t  level;           /**< Level (1, 2 or 3), 0 for no permissions at all. */
 };
 
-// See https://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
-typedef struct PresentationFormat
-{
-  uint8_t   gatt_format;    /**< Format of the value, see @ref ble_gatt_format_t. */
-  int8_t    exponent;       /**< Exponent for integer data types. */
-  uint16_t  gatt_unit;      /**< UUID from Bluetooth Assigned Numbers, see @ref ble_gatt_unit_t. */
-  uint8_t   gatt_namespace; /**< Namespace from Bluetooth Assigned Numbers, normally '1',  see @ref BLE_GATT_CPF_NAMESPACES. */
-  uint16_t  gatt_nsdesc;    /**< Namespace description from Bluetooth Assigned Numbers, normally '0', see @ref BLE_GATT_CPF_NAMESPACES. */
-} presentation_format_t;
+#ifdef __cplusplus
+}
+#endif
 
 #endif