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:
Fri Nov 29 14:42:22 2013 +0000
Child:
1:fd3ec64b2345
Commit message:
First commit

Changed in this revision

blecharacteristic.cpp Show annotated file Show diff for this revision Revisions of this file
blecharacteristic.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
bleservice.cpp Show annotated file Show diff for this revision Revisions of this file
bleservice.h Show annotated file Show diff for this revision Revisions of this file
hw/bleradio.h Show annotated file Show diff for this revision Revisions of this file
hw/nrf51822.cpp Show annotated file Show diff for this revision Revisions of this file
hw/nrf51822.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-src-flowcontrol.lib Show annotated file Show diff for this revision Revisions of this file
uuid.cpp Show annotated file Show diff for this revision Revisions of this file
uuid.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/blecharacteristic.cpp	Fri Nov 29 14:42:22 2013 +0000
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "blecharacteristic.h"
+
+/**************************************************************************/
+/*!
+    @brief  Creates a new BLECharacteristic using the specified 16-bit
+            UUID, value length, and properties
+            
+    @note   The UUID value must be unique in the service and is normally >1
+
+    @param[in]  id
+                The 16-bit UUID to use for this characteristic
+    @param[in]  minLen
+                The min length in bytes of this characteristic's value
+    @param[in]  maxLen
+                The max length in bytes of this characteristic's value
+    @param[in]  props
+                The 8-bit bit field containing the characteristic's
+                properties
+
+    @section EXAMPLE
+
+    @code
+
+    // UUID = 0x2A19, Min length 2, Max len = 2, Properties = write
+    BLECharacteristic c = BLECharacteristic( 0x2A19, 2, 2, 0x08 );
+   
+    @endcode
+*/
+/**************************************************************************/
+BLECharacteristic::BLECharacteristic(uint16_t id, uint16_t minLen, uint16_t maxLen, uint8_t props)
+{
+    uuid = id;
+    memcpy(&properties, &props, 1);
+    lenMin = minLen;
+    lenMax = maxLen;
+}
+
+/**************************************************************************/
+/*!
+    Destructor
+*/
+/**************************************************************************/
+BLECharacteristic::~BLECharacteristic(void)
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/blecharacteristic.h	Fri Nov 29 14:42:22 2013 +0000
@@ -0,0 +1,33 @@
+#ifndef __BLE_CHARACTERISTIC_H__
+#define __BLE_CHARACTERISTIC_H__
+
+#include "blecommon.h"
+#include "uuid.h"
+
+class BLECharacteristic
+{
+private:
+
+public:
+    BLECharacteristic(uint16_t uuid, uint16_t minLen, uint16_t maxLen, uint8_t properties);
+    virtual ~BLECharacteristic(void);
+
+    uint16_t uuid;              /* Characteristic UUID */
+    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;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/blecommon.h	Fri Nov 29 14:42:22 2013 +0000
@@ -0,0 +1,239 @@
+#ifndef __BLE_COMMON_H__
+#define __BLE_COMMON_H__
+
+#include <stdint.h>
+
+typedef enum ble_error_e
+{
+  BLE_ERROR_NONE = 0
+} ble_error_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_BLOD_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_OXIMETERFINGERTIP                         = 3137,
+  BLE_GAP_CHAR_APPEARANCE_PULSE_OXIMETERWRIST_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
+typedef enum ble_gatt_unit_e
+{
+  BLE_GATT_UNIT_NONE                                                   = 0x2700,
+  BLE_GATT_UNIT_LENGTH_METRE                                           = 0x2701,
+  BLE_GATT_UNIT_MASS_KILOGRAM                                          = 0x2702,
+  BLE_GATT_UNIT_TIME_SECOND                                            = 0x2703,
+  BLE_GATT_UNIT_ELECTRIC_CURRENT_AMPERE                                = 0x2704,
+  BLE_GATT_UNIT_THERMODYNAMIC_TEMPERATURE_KELVIN                       = 0x2705,
+  BLE_GATT_UNIT_AMOUNT_OF_SUBSTANCE_MOLE                               = 0x2706,
+  BLE_GATT_UNIT_LUMINOUS_INTENSITY_CANDELA                             = 0x2707,
+  BLE_GATT_UNIT_AREA_SQUARE_METRES                                     = 0x2710,
+  BLE_GATT_UNIT_VOLUME_CUBIC_METRES                                    = 0x2711,
+  BLE_GATT_UNIT_VELOCITY_METRES_PER_SECOND                             = 0x2712,
+  BLE_GATT_UNIT_ACCELERATION_METRES_PER_SECOND_SQUARED                 = 0x2713,
+  BLE_GATT_UNIT_WAVENUMBER_RECIPROCAL_METRE                            = 0x2714,
+  BLE_GATT_UNIT_DENSITY_KILOGRAM_PER_CUBIC_METRE                       = 0x2715,
+  BLE_GATT_UNIT_SURFACE_DENSITY_KILOGRAM_PER_SQUARE_METRE              = 0x2716,
+  BLE_GATT_UNIT_SPECIFIC_VOLUME_CUBIC_METRE_PER_KILOGRAM               = 0x2717,
+  BLE_GATT_UNIT_CURRENT_DENSITY_AMPERE_PER_SQUARE_METRE                = 0x2718,
+  BLE_GATT_UNIT_MAGNETIC_FIELD_STRENGTH_AMPERE_PER_METRE               = 0x2719,
+  BLE_GATT_UNIT_AMOUNT_CONCENTRATION_MOLE_PER_CUBIC_METRE              = 0x271A,
+  BLE_GATT_UNIT_MASS_CONCENTRATION_KILOGRAM_PER_CUBIC_METRE            = 0x271B,
+  BLE_GATT_UNIT_LUMINANCE_CANDELA_PER_SQUARE_METRE                     = 0x271C,
+  BLE_GATT_UNIT_REFRACTIVE_INDEX                                       = 0x271D,
+  BLE_GATT_UNIT_RELATIVE_PERMEABILITY                                  = 0x271E,
+  BLE_GATT_UNIT_PLANE_ANGLE_RADIAN                                     = 0x2720,
+  BLE_GATT_UNIT_SOLID_ANGLE_STERADIAN                                  = 0x2721,
+  BLE_GATT_UNIT_FREQUENCY_HERTZ                                        = 0x2722,
+  BLE_GATT_UNIT_FORCE_NEWTON                                           = 0x2723,
+  BLE_GATT_UNIT_PRESSURE_PASCAL                                        = 0x2724,
+  BLE_GATT_UNIT_ENERGY_JOULE                                           = 0x2725,
+  BLE_GATT_UNIT_POWER_WATT                                             = 0x2726,
+  BLE_GATT_UNIT_ELECTRIC_CHARGE_COULOMB                                = 0x2727,
+  BLE_GATT_UNIT_ELECTRIC_POTENTIAL_DIFFERENCE_VOLT                     = 0x2728,
+  BLE_GATT_UNIT_CAPACITANCE_FARAD                                      = 0x2729,
+  BLE_GATT_UNIT_ELECTRIC_RESISTANCE_OHM                                = 0x272A,
+  BLE_GATT_UNIT_ELECTRIC_CONDUCTANCE_SIEMENS                           = 0x272B,
+  BLE_GATT_UNIT_MAGNETIC_FLEX_WEBER                                    = 0x272C,
+  BLE_GATT_UNIT_MAGNETIC_FLEX_DENSITY_TESLA                            = 0x272D,
+  BLE_GATT_UNIT_INDUCTANCE_HENRY                                       = 0x272E,
+  BLE_GATT_UNIT_THERMODYNAMIC_TEMPERATURE_DEGREE_CELSIUS               = 0x272F,
+  BLE_GATT_UNIT_LUMINOUS_FLUX_LUMEN                                    = 0x2730,
+  BLE_GATT_UNIT_ILLUMINANCE_LUX                                        = 0x2731,
+  BLE_GATT_UNIT_ACTIVITY_REFERRED_TO_A_RADIONUCLIDE_BECQUEREL          = 0x2732,
+  BLE_GATT_UNIT_ABSORBED_DOSE_GRAY                                     = 0x2733,
+  BLE_GATT_UNIT_DOSE_EQUIVALENT_SIEVERT                                = 0x2734,
+  BLE_GATT_UNIT_CATALYTIC_ACTIVITY_KATAL                               = 0x2735,
+  BLE_GATT_UNIT_DYNAMIC_VISCOSITY_PASCAL_SECOND                        = 0x2740,
+  BLE_GATT_UNIT_MOMENT_OF_FORCE_NEWTON_METRE                           = 0x2741,
+  BLE_GATT_UNIT_SURFACE_TENSION_NEWTON_PER_METRE                       = 0x2742,
+  BLE_GATT_UNIT_ANGULAR_VELOCITY_RADIAN_PER_SECOND                     = 0x2743,
+  BLE_GATT_UNIT_ANGULAR_ACCELERATION_RADIAN_PER_SECOND_SQUARED         = 0x2744,
+  BLE_GATT_UNIT_HEAT_FLUX_DENSITY_WATT_PER_SQUARE_METRE                = 0x2745,
+  BLE_GATT_UNIT_HEAT_CAPACITY_JOULE_PER_KELVIN                         = 0x2746,
+  BLE_GATT_UNIT_SPECIFIC_HEAT_CAPACITY_JOULE_PER_KILOGRAM_KELVIN       = 0x2747,
+  BLE_GATT_UNIT_SPECIFIC_ENERGY_JOULE_PER_KILOGRAM                     = 0x2748,
+  BLE_GATT_UNIT_THERMAL_CONDUCTIVITY_WATT_PER_METRE_KELVIN             = 0x2749,
+  BLE_GATT_UNIT_ENERGY_DENSITY_JOULE_PER_CUBIC_METRE                   = 0x274A,
+  BLE_GATT_UNIT_ELECTRIC_FIELD_STRENGTH_VOLT_PER_METRE                 = 0x274B,
+  BLE_GATT_UNIT_ELECTRIC_CHARGE_DENSITY_COULOMB_PER_CUBIC_METRE        = 0x274C,
+  BLE_GATT_UNIT_SURFACE_CHARGE_DENSITY_COULOMB_PER_SQUARE_METRE        = 0x274D,
+  BLE_GATT_UNIT_ELECTRIC_FLUX_DENSITY_COULOMB_PER_SQUARE_METRE         = 0x274E,
+  BLE_GATT_UNIT_PERMITTIVITY_FARAD_PER_METRE                           = 0x274F,
+  BLE_GATT_UNIT_PERMEABILITY_HENRY_PER_METRE                           = 0x2750,
+  BLE_GATT_UNIT_MOLAR_ENERGY_JOULE_PER_MOLE                            = 0x2751,
+  BLE_GATT_UNIT_MOLAR_ENTROPY_JOULE_PER_MOLE_KELVIN                    = 0x2752,
+  BLE_GATT_UNIT_EXPOSURE_COULOMB_PER_KILOGRAM                          = 0x2753,
+  BLE_GATT_UNIT_ABSORBED_DOSE_RATE_GRAY_PER_SECOND                     = 0x2754,
+  BLE_GATT_UNIT_RADIANT_INTENSITY_WATT_PER_STERADIAN                   = 0x2755,
+  BLE_GATT_UNIT_RADIANCE_WATT_PER_SQUARE_METRE_STERADIAN               = 0x2756,
+  BLE_GATT_UNIT_CATALYTIC_ACTIVITY_CONCENTRATION_KATAL_PER_CUBIC_METRE = 0x2757,
+  BLE_GATT_UNIT_TIME_MINUTE                                            = 0x2760,
+  BLE_GATT_UNIT_TIME_HOUR                                              = 0x2761,
+  BLE_GATT_UNIT_TIME_DAY                                               = 0x2762,
+  BLE_GATT_UNIT_PLANE_ANGLE_DEGREE                                     = 0x2763,
+  BLE_GATT_UNIT_PLANE_ANGLE_MINUTE                                     = 0x2764,
+  BLE_GATT_UNIT_PLANE_ANGLE_SECOND                                     = 0x2765,
+  BLE_GATT_UNIT_AREA_HECTARE                                           = 0x2766,
+  BLE_GATT_UNIT_VOLUME_LITRE                                           = 0x2767,
+  BLE_GATT_UNIT_MASS_TONNE                                             = 0x2768,
+  BLE_GATT_UNIT_PRESSURE_BAR                                           = 0x2780,
+  BLE_GATT_UNIT_PRESSURE_MILLIMETRE_OF_MERCURY                         = 0x2781,
+  BLE_GATT_UNIT_LENGTH_ANGSTROM                                        = 0x2782,
+  BLE_GATT_UNIT_LENGTH_NAUTICAL_MILE                                   = 0x2783,
+  BLE_GATT_UNIT_AREA_BARN                                              = 0x2784,
+  BLE_GATT_UNIT_VELOCITY_KNOT                                          = 0x2785,
+  BLE_GATT_UNIT_LOGARITHMIC_RADIO_QUANTITY_NEPER                       = 0x2786,
+  BLE_GATT_UNIT_LOGARITHMIC_RADIO_QUANTITY_BEL                         = 0x2787,
+  BLE_GATT_UNIT_LENGTH_YARD                                            = 0x27A0,
+  BLE_GATT_UNIT_LENGTH_PARSEC                                          = 0x27A1,
+  BLE_GATT_UNIT_LENGTH_INCH                                            = 0x27A2,
+  BLE_GATT_UNIT_LENGTH_FOOT                                            = 0x27A3,
+  BLE_GATT_UNIT_LENGTH_MILE                                            = 0x27A4,
+  BLE_GATT_UNIT_PRESSURE_POUND_FORCE_PER_SQUARE_INCH                   = 0x27A5,
+  BLE_GATT_UNIT_VELOCITY_KILOMETRE_PER_HOUR                            = 0x27A6,
+  BLE_GATT_UNIT_VELOCITY_MILE_PER_HOUR                                 = 0x27A7,
+  BLE_GATT_UNIT_ANGULAR_VELOCITY_REVOLUTION_PER_MINUTE                 = 0x27A8,
+  BLE_GATT_UNIT_ENERGY_GRAM_CALORIE                                    = 0x27A9,
+  BLE_GATT_UNIT_ENERGY_KILOGRAM_CALORIE                                = 0x27AA,
+  BLE_GATT_UNIT_ENERGY_KILOWATT_HOUR                                   = 0x27AB,
+  BLE_GATT_UNIT_THERMODYNAMIC_TEMPERATURE_DEGREE_FAHRENHEIT            = 0x27AC,
+  BLE_GATT_UNIT_PERCENTAGE                                             = 0x27AD,
+  BLE_GATT_UNIT_PER_MILLE                                              = 0x27AE,
+  BLE_GATT_UNIT_PERIOD_BEATS_PER_MINUTE                                = 0x27AF,
+  BLE_GATT_UNIT_ELECTRIC_CHARGE_AMPERE_HOURS                           = 0x27B0,
+  BLE_GATT_UNIT_MASS_DENSITY_MILLIGRAM_PER_DECILITRE                   = 0x27B1,
+  BLE_GATT_UNIT_MASS_DENSITY_MILLIMOLE_PER_LITRE                       = 0x27B2,
+  BLE_GATT_UNIT_TIME_YEAR                                              = 0x27B3,
+  BLE_GATT_UNIT_TIME_MONTH                                             = 0x27B4,
+  BLE_GATT_UNIT_CONCENTRATION_COUNT_PER_CUBIC_METRE                    = 0x27B5,
+  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
+typedef enum ble_gatt_format_e
+{
+  BLE_GATT_FORMAT_RFU                 = 0x00, /**< Reserved For Future Use. */
+  BLE_GATT_FORMAT_BOOLEAN             = 0x01, /**< Boolean. */
+  BLE_GATT_FORMAT_2BIT                = 0x02, /**< Unsigned 2-bit integer. */
+  BLE_GATT_FORMAT_NIBBLE              = 0x03, /**< Unsigned 4-bit integer. */
+  BLE_GATT_FORMAT_UINT8               = 0x04, /**< Unsigned 8-bit integer. */
+  BLE_GATT_FORMAT_UINT12              = 0x05, /**< Unsigned 12-bit integer. */
+  BLE_GATT_FORMAT_UINT16              = 0x06, /**< Unsigned 16-bit integer. */
+  BLE_GATT_FORMAT_UINT24              = 0x07, /**< Unsigned 24-bit integer. */
+  BLE_GATT_FORMAT_UINT32              = 0x08, /**< Unsigned 32-bit integer. */
+  BLE_GATT_FORMAT_UINT48              = 0x09, /**< Unsigned 48-bit integer. */
+  BLE_GATT_FORMAT_UINT64              = 0x0A, /**< Unsigned 64-bit integer. */
+  BLE_GATT_FORMAT_UINT128             = 0x0B, /**< Unsigned 128-bit integer. */
+  BLE_GATT_FORMAT_SINT8               = 0x0C, /**< Signed 2-bit integer. */
+  BLE_GATT_FORMAT_SINT12              = 0x0D, /**< Signed 12-bit integer. */
+  BLE_GATT_FORMAT_SINT16              = 0x0E, /**< Signed 16-bit integer. */
+  BLE_GATT_FORMAT_SINT24              = 0x0F, /**< Signed 24-bit integer. */
+  BLE_GATT_FORMAT_SINT32              = 0x10, /**< Signed 32-bit integer. */
+  BLE_GATT_FORMAT_SINT48              = 0x11, /**< Signed 48-bit integer. */
+  BLE_GATT_FORMAT_SINT64              = 0x12, /**< Signed 64-bit integer. */
+  BLE_GATT_FORMAT_SINT128             = 0x13, /**< Signed 128-bit integer. */
+  BLE_GATT_FORMAT_FLOAT32             = 0x14, /**< IEEE-754 32-bit floating point. */
+  BLE_GATT_FORMAT_FLOAT64             = 0x15, /**< IEEE-754 64-bit floating point. */
+  BLE_GATT_FORMAT_SFLOAT              = 0x16, /**< IEEE-11073 16-bit SFLOAT. */
+  BLE_GATT_FORMAT_FLOAT               = 0x17, /**< IEEE-11073 32-bit FLOAT. */
+  BLE_GATT_FORMAT_DUINT16             = 0x18, /**< IEEE-20601 format. */
+  BLE_GATT_FORMAT_UTF8S               = 0x19, /**< UTF-8 string. */
+  BLE_GATT_FORMAT_UTF16S              = 0x1A, /**< UTF-16 string. */
+  BLE_GATT_FORMAT_STRUCT              = 0x1B /**< Opaque Structure. */
+} ble_gatt_format_t;
+
+struct UTF8String
+{
+  uint16_t  length;         /**< String length. */
+  uint8_t  str[32];         /**< String data. */
+};
+
+struct UTF16String
+{
+  uint16_t  length;         /**< String length. */
+  uint16_t  str[32];        /**< String data. */
+};
+
+struct SecurityMode
+{
+  uint8_t  mode;            /**< Security Mode (1 or 2), 0 for no permissions at all. */
+  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
+struct PresentationFormat
+{
+  uint8_t   format;         /**< Format of the value, see @ref ble_gatt_format_t. */
+  int8_t    exponent;       /**< Exponent for integer data types. */
+  uint16_t  unit;           /**< UUID from Bluetooth Assigned Numbers, see @ref ble_gatt_unit_t. */
+  uint8_t   name_space;     /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
+  uint16_t  desc;           /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bleservice.cpp	Fri Nov 29 14:42:22 2013 +0000
@@ -0,0 +1,116 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "bleservice.h"
+
+/**************************************************************************/
+/*!
+    @brief  Creates a new BLEService using the specified 16 byte UUID
+            
+    @note   The UUID value must be unique on the device
+
+    @param[in]  uuid
+                The 16 byte (128-bit) UUID to use for this characteristic
+
+    @section EXAMPLE
+
+    @code
+   
+    @endcode
+*/
+/**************************************************************************/
+BLEService::BLEService(uint8_t base_uuid[16])
+{
+    primaryServiceID.update(base_uuid);
+    characteristicCount = 0;
+    memset(&characteristics, 0, sizeof(serialisedChar_t) * BLE_SERVICE_MAX_CHARACTERISTICS);
+    index = 0;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Creates a new BLEService using the specified 2 byte BLE UUID
+            
+    @param[in]  ble_uuid
+                The standardised 16-bit (2 byte) BLE UUID to use for this
+                characteristic
+
+    @section EXAMPLE
+
+    @code
+   
+    @endcode
+*/
+/**************************************************************************/
+BLEService::BLEService(uint16_t ble_uuid)
+{
+    primaryServiceID.update( ble_uuid );
+    characteristicCount = 0;
+    memset(&characteristics, 0, sizeof(serialisedChar_t) * BLE_SERVICE_MAX_CHARACTERISTICS);
+    index = 0;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Destructor
+*/
+/**************************************************************************/
+BLEService::~BLEService(void)
+{
+}
+
+/**************************************************************************/
+/*!
+    @brief  Adds a BLECharacterisic to the service, serialising the
+            essential data for the characteristic.
+            
+    @note   The BLEService does not store a reference to the source
+            BLECharacteristic, only a serialised version of the key
+            properties required to create the characteristic on the
+            target radio board.
+            
+    @note   This function will update the .index field in the
+            BLECharacteristic to indicate where this characteristic was
+            stored in the BLEService's characteristic array.
+
+    @param[in]  characteristic
+                The BLECharacteristic object describing the characteristic
+                to add to this service
+
+    @returns    BLE_ERROR_NONE (0) if everything executed correctly, or an
+                error code if there was a problem
+    @retval     BLE_ERROR_NONE
+                Everything executed correctly
+
+    @section EXAMPLE
+
+    @code
+   
+    @endcode
+*/
+/**************************************************************************/
+ble_error_t BLEService::addCharacteristic(BLECharacteristic & characteristic)
+{
+    /* ToDo: Make sure we don't overflow the array, etc. */
+    /* ToDo: Make sure this characteristic UUID doesn't already exist */
+    /* ToDo: Basic validation */
+    
+    serialisedChar_t c;
+    
+    /* Serialise the source BLECharacteristic */
+    memcpy(&c.id, &characteristic.uuid, 2);
+    memcpy(&c.lenMin, &characteristic.lenMin, 2);
+    memcpy(&c.lenMax, &characteristic.lenMax, 2);
+    memcpy(&c.properties, &characteristic.properties, 2);
+    memset(&c.reserved, 0, 1);
+    
+    /* Insert the serialised object into the buffer */
+    memcpy(&characteristics[characteristicCount], &c, sizeof(serialisedChar_t));
+    
+    /* Update the index value */
+    characteristic.index = characteristicCount;
+    
+    characteristicCount++;
+    
+    return BLE_ERROR_NONE;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bleservice.h	Fri Nov 29 14:42:22 2013 +0000
@@ -0,0 +1,36 @@
+#ifndef __BLE_SERVICE_H__
+#define __BLE_SERVICE_H__
+
+#include "blecommon.h"
+#include "uuid.h"
+#include "blecharacteristic.h"
+
+#define BLE_SERVICE_MAX_CHARACTERISTICS (5)
+
+class BLEService
+{
+private:
+
+public:
+    typedef struct
+    {
+        uint16_t    id;
+        uint16_t    lenMin;
+        uint16_t    lenMax;
+        uint8_t     properties;
+        uint8_t     reserved;
+    } serialisedChar_t;
+    
+    BLEService(uint8_t[16]);  /* 128-bit Base UUID */
+    BLEService(uint16_t);     /* 16-bit BLE UUID */
+    virtual ~BLEService(void);
+
+    UUID                primaryServiceID;
+    uint8_t             characteristicCount;
+    serialisedChar_t    characteristics[BLE_SERVICE_MAX_CHARACTERISTICS];
+    uint8_t             index;
+
+    ble_error_t         addCharacteristic(BLECharacteristic &);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hw/bleradio.h	Fri Nov 29 14:42:22 2013 +0000
@@ -0,0 +1,31 @@
+#ifndef __BLE_RADIO_H__
+#define __BLE_RADIO_H__
+
+#include "blecommon.h"
+#include "bleservice.h"
+
+class BLERadio
+{
+    public:
+        typedef enum radio_event_e
+        {
+            RADIO_EVENT_CONNECT     = 0x01,
+            RADIO_EVENT_DISCONNECT  = 0x02,
+            RADIO_EVENT_WRITE       = 0x03,
+            RADIO_EVENT_RADIOERROR  = 0x80
+        } radioEvent_t;
+        
+        uint8_t serviceCount;
+        
+        /* ToDo: Force constructor with event handler callback */
+
+        /* These functions must be defined in the sub-class */
+        virtual ble_error_t attach(void (*fptr)(void));
+        virtual ble_error_t addService(BLEService &) = 0;
+        virtual ble_error_t updateValue(uint8_t, uint8_t, uint8_t[], uint16_t) = 0;
+        virtual ble_error_t start(void) = 0;
+        virtual ble_error_t stop(void) = 0;
+        virtual ble_error_t reset(void) = 0;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hw/nrf51822.cpp	Fri Nov 29 14:42:22 2013 +0000
@@ -0,0 +1,212 @@
+#include "nrf51822.h"
+#include "mbed.h"
+
+/**************************************************************************/
+/*!
+    @brief  UART callback function
+*/
+/**************************************************************************/
+void nRF51822::uartCallback(void)
+{
+    /* ToDo: Check responses and set a flag for success/error/etc. */
+    
+    /* Read serial to clear the RX interrupt */
+    uart.getc();
+}
+
+/**************************************************************************/
+/*!
+    @brief  Constructor
+    
+    @args   fptr[in]    Pointer to the callback function when any radio
+                        event is raised by the radio HW.
+*/
+/**************************************************************************/
+nRF51822::nRF51822() : uart(P0_4, P0_0)
+{
+    /* Setup the nRF UART interface */
+    uart.baud(9600);
+ 
+    /* Echo data on the debug CDC port */
+    uart.attach(this, &nRF51822::uartCallback);
+    
+    /* Add flow control for UART (required by the nRF51822) */
+    uart.set_flow_control(Serial::RTSCTS, P0_6, P0_8);
+    
+    /* Reset the service counter */
+    serviceCount = 0;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Destructor
+*/
+/**************************************************************************/
+nRF51822::~nRF51822(void)
+{
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+ble_error_t nRF51822::attach(void (*fptr)(void))
+{
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+
+*/
+/**************************************************************************/
+ble_error_t nRF51822::addService(BLEService & service)
+{
+    /* ToDo: Make sure we don't overflow the array, etc. */
+    /* ToDo: Make sure this service UUID doesn't already exist (?) */
+    /* ToDo: Basic validation */
+    
+    /* Add the service to the nRF51 */
+    if (service.primaryServiceID.type == UUID::UUID_TYPE_SHORT)
+    {
+        /* 16-bit BLE UUID */
+        uart.printf("10 01 00 04 01 02 %02X %02X\r\n",
+                    service.primaryServiceID.value & 0xFF,
+                    service.primaryServiceID.value >> 8);
+    }
+    else
+    {
+        /* 128-bit Custom UUID */
+        uart.printf("10 01 00 12 01 10 %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n",
+            service.primaryServiceID.base[0], 
+            service.primaryServiceID.base[1], 
+            service.primaryServiceID.base[2], 
+            service.primaryServiceID.base[3], 
+            service.primaryServiceID.base[4], 
+            service.primaryServiceID.base[5], 
+            service.primaryServiceID.base[6], 
+            service.primaryServiceID.base[7], 
+            service.primaryServiceID.base[8], 
+            service.primaryServiceID.base[9], 
+            service.primaryServiceID.base[10], 
+            service.primaryServiceID.base[11], 
+            service.primaryServiceID.base[12], 
+            service.primaryServiceID.base[13], 
+            service.primaryServiceID.base[14], 
+            service.primaryServiceID.base[15]);
+    }
+    
+    /* ToDo: Check response */
+    wait(0.1);
+    
+    /* Add characteristics to the service */
+    for (uint8_t i = 0; i < service.characteristicCount; i++)
+    {
+        /* Command ID = 0x0002 */
+        uart.printf("10 02 00 0F 01 02 %02X %02X 04 02 %02X %02X 05 02 %02X %02X 03 01 %02X\r\n",
+                    service.characteristics[i].id & 0xFF, 
+                    service.characteristics[i].id >> 8,
+                    service.characteristics[i].lenMin & 0xFF,
+                    service.characteristics[i].lenMin >> 8,
+                    service.characteristics[i].lenMax & 0xFF,
+                    service.characteristics[i].lenMax >> 8,
+                    service.characteristics[i].properties);
+                    
+        /* ToDo: Check response */
+        wait(0.1);
+    }    
+
+    /* Update the service index value */
+    service.index = serviceCount;
+    serviceCount++;
+    
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Updates the value of a characteristic, based on the service
+            and characteristic index fields
+            
+    @param[in]  sIndex  
+                The BLEService's index value (.index)
+    @param[in]  cIndex
+                The BLECharacteristic's index value (.index)
+    @param[in]  buffer
+                Data to use when updating the characteristic's value
+                (raw byte array in LSB format)
+    @param[in]  len
+                The number of bytes in buffer
+*/
+/**************************************************************************/
+ble_error_t nRF51822::updateValue(uint8_t sIndex, uint8_t cIndex, uint8_t buffer[], uint16_t len)
+{
+    /* Command ID = 0x0006, Payload = Service ID, Characteristic ID, Value */
+    uart.printf("10 06 00 %02X %02X %02X", len + 2, cIndex, sIndex);
+    for (uint16_t i = 0; i<len; i++)
+    {
+        uart.printf(" %02X", buffer[i]);
+    }
+    uart.printf("\r\n");
+
+    /* ToDo: Check response */
+    wait(0.1);
+    
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Starts the BLE HW, initialising any services that were
+            added before this function was called.
+            
+    @note   All services must be added before calling this function!
+*/
+/**************************************************************************/
+ble_error_t nRF51822::start(void)
+{
+    /* Command ID = 0x0003, No payload */
+    uart.printf("10 03 00 00\r\n");
+
+    /* ToDo: Check response */
+    wait(0.5);
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Stops the BLE HW and disconnects from any devices
+*/
+/**************************************************************************/
+ble_error_t nRF51822::stop(void)
+{
+    /* Command ID = 0x0004, No payload */
+    uart.printf("10 04 00 00\r\n");
+
+    /* ToDo: Check response */
+    wait(0.1);
+
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Resets the BLE HW, removing any existing services and
+            characteristics
+*/
+/**************************************************************************/
+ble_error_t nRF51822::reset(void)
+{
+    /* Command ID = 0x0005, No payload */
+    uart.printf("10 05 00 00\r\n");
+
+    /* Reset the service counter */
+    serviceCount = 0;
+
+    /* Wait for the radio to come back up */    
+    wait(1);
+    
+    return BLE_ERROR_NONE;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hw/nrf51822.h	Fri Nov 29 14:42:22 2013 +0000
@@ -0,0 +1,30 @@
+#ifndef __NRF51822_H__
+#define __NRF51822_H__
+
+#include "mbed.h"
+#include "blecommon.h"
+#include "bleservice.h"
+#include "bleradio.h"
+
+class nRF51822 : public BLERadio
+{
+    public:
+        nRF51822();
+        virtual ~nRF51822(void);
+
+        /* Functions that mus be implemented from NRFRadio */
+        virtual ble_error_t attach(void (*fptr)(void));
+        virtual ble_error_t addService(BLEService &);
+        virtual ble_error_t updateValue(uint8_t, uint8_t, uint8_t[], uint16_t);
+        virtual ble_error_t start(void);
+        virtual ble_error_t stop(void);
+        virtual ble_error_t reset(void);
+        
+        /* nRF51 Functions */
+        void uartCallback(void);
+
+    private:
+        Serial uart;        
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Nov 29 14:42:22 2013 +0000
@@ -0,0 +1,114 @@
+#include "mbed.h"
+
+#include "uuid.h"
+#include "bleservice.h"
+#include "blecharacteristic.h"
+#include "hw/nrf51822.h"
+
+DigitalOut        myled ( LED1 );
+
+/* Radio HW abstraction layer */
+nRF51822 radio;
+
+/* Battery Level Service */
+/* See --> https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml */
+BLEService        battService   ( 0x180F );
+BLECharacteristic battLevel     ( 0x2A19, 1, 1, 0x10 | 0x02);   /* Read + Notify */
+
+/* Heart Rate Monitor Service */
+/* See --> https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml */
+BLEService        hrmService    ( 0x180D );
+BLECharacteristic hrmRate       ( 0x2A37, 2, 3, 0x10 );         /* Notify */
+BLECharacteristic hrmLocation   ( 0x2A39, 1, 1, 0x02 );         /* Read */
+
+/* Health Thermometer Service */
+/* See --> https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.health_thermometer.xml */
+BLEService        thermService  ( 0x1809 );
+BLECharacteristic thermTemp     ( 0x2A1C, 5, 13, 0x20 );         /* Indicate */
+BLECharacteristic thermType     ( 0x2A1D, 1, 1, 0x02 );          /* Read */
+BLECharacteristic thermInterval ( 0x2A21, 2, 2, 0x02 );          /* Read */
+
+/* Notify   = device (server) sends data when it changes */
+/* Indicate = device (server) sends data when it changes and client confirms reception */ 
+ 
+int main()
+{
+    /* Add the battery level characteristic to the battery service          */
+    /* Note: This will also update the characteristic's .index field        */
+    /* so that we know where it's stored in the BLEService.characteristics  */
+    /* array.                                                               */
+    battService.addCharacteristic(battLevel);
+    
+    /* Add the heart rate and sensor location chars to the HRM service      */
+    hrmService.addCharacteristic(hrmRate);
+    hrmService.addCharacteristic(hrmLocation);
+    
+    /* Add the Health Thermometer server characteristics                    */
+    thermService.addCharacteristic(thermTemp);
+    thermService.addCharacteristic(thermType);
+    thermService.addCharacteristic(thermInterval);
+    
+    /* Reset the BLE hardware to make sure we get a clean start             */
+    wait(2);
+    radio.reset();
+    
+    /* Add the services to the radio HAL */
+    radio.addService(battService);
+    radio.addService(hrmService);
+    radio.addService(thermService);
+    
+    /* Start the services so that we can start pushing data out */
+    radio.start();
+
+    /* Set the heart rate monitor location (one time only) */
+    /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml */
+    uint8_t location = 0x01; /* Chest */
+    radio.updateValue(hrmService.index, hrmLocation.index, (uint8_t*)&location, sizeof(location));
+
+    /* Update the battery level */
+    /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml */
+    uint8_t batt = 72; /* Percentage (0..100) */
+    radio.updateValue(battService.index, battLevel.index, (uint8_t*)&batt, sizeof(batt));
+
+    /* Update the fixed health thermometer characteristics */
+    /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml */
+    uint8_t thermLocation = 6; /* Location = mouth */
+    radio.updateValue(thermService.index, thermType.index, (uint8_t*)&thermLocation, sizeof(thermLocation));
+    /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.measurement_interval.xml */
+    uint16_t thermDelay = 5;
+    radio.updateValue(thermService.index, thermInterval.index, (uint8_t*)&thermDelay, sizeof(thermDelay));
+    
+    /* Blinky + value updates */
+    uint8_t hrmCounter = 100;
+        
+    while(1)
+    {
+        myled = 1;
+        wait(0.1);
+        myled = 0;
+        wait(0.1);
+                
+        /* Update the HRM measurement */
+        /* First byte = 8-bit values, no extra info, Second byte = uint8_t HRM value */
+        /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */
+        hrmCounter++;
+        if (hrmCounter == 175) hrmCounter = 100;
+        uint8_t bpm[2] = { 0x00, hrmCounter };
+        radio.updateValue(hrmService.index, hrmRate.index, bpm, 2);
+        
+        /* Update the Health Thermometer measurement */
+        
+        // NOTE: This is an IEEE-11073 32-bit float NOT a IEEE-754 float (standard single precision float type) !!!
+        // See: Section 2.2 of https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=242961
+        // Example:
+        // Consider a temperature measurement of 36.4 degrees Celsius with precision of 0.1 degrees Celsius.
+        // The FLOAT-Type representation is a 32-bit value consisting of an exponent of an 8-bit signed integer
+        // followed by a mantissa of a 24-bit signed integer; here, the exponent is -1 (0xFF) and the mantissa
+        // is 364 (0x00016C). Therefore, the FLOAT-Type representation of 36.4 is 0xFF00016C.
+        
+        uint8_t temperature[5] = { 0x00, 0x00, 0x00, 0x00, 0xFF };
+        // Use the hrm counter to provide a shifting temperature value (175 = 17.5C, etc.)
+        memcpy (temperature+1, &hrmCounter, 1);
+        radio.updateValue(thermService.index, thermTemp.index, temperature, 5);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-src-flowcontrol.lib	Fri Nov 29 14:42:22 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/bogdanm/code/mbed-src-flowcontrol/#8804ac57fc7e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uuid.cpp	Fri Nov 29 14:42:22 2013 +0000
@@ -0,0 +1,177 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "uuid.h"
+
+/**************************************************************************/
+/*!
+    @brief  Creates an empty 128-bit UUID
+            
+    @note   This UUID must be assigned a valid value via the 'update'
+            function before it can be safely used!
+*/
+/**************************************************************************/
+UUID::UUID(void)
+{
+    memset(base, 0, 16);
+    value = 0;
+    type  = UUID_TYPE_SHORT;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Creates a new 128-bit UUID
+            
+    @note   The UUID is a unique 128-bit (16 byte) ID used to identify
+            different service or characteristics on the BLE device.
+            
+    @note   When creating a UUID, the constructor will check if all bytes
+            except bytes 2/3 are equal to 0.  If only bytes 2/3 have a
+            value, the UUID will be treated as a short/BLE UUID, and the
+            .type field will be set to UUID::UUID_TYPE_SHORT.  If any
+            of the bytes outside byte 2/3 have a non-zero value, the UUID
+            will be considered a 128-bit ID, and .type will be assigned 
+            as UUID::UUID_TYPE_LONG. 
+
+    @param[in]  uuid_base
+                The 128-bit (16-byte) UUID value.  For 128-bit values,
+                assign all 16 bytes.  For 16-bit values, assign the
+                16-bits to byte 2 and 3, and leave the rest of the bytes
+                as 0.
+
+    @section EXAMPLE
+
+    @code
+
+    // Create a short UUID (0x180F)
+    uint8_t shortID[16] = { 0, 0, 0x0F, 0x18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+    UUID ble_uuid = UUID(shortID);
+    // ble_uuid.type  = UUID_TYPE_SHORT
+    // ble_uuid.value = 0x180F
+    
+    // Creeate a long UUID
+    uint8_t longID[16] = { 0x00, 0x11, 0x22, 0x33,
+                           0x44, 0x55, 0x66, 0x77, 
+                           0x88, 0x99, 0xAA, 0xBB, 
+                           0xCC, 0xDD, 0xEE, 0xFF };
+    UUID custom_uuid = UUID(longID);
+    // custom_uuid.type  = UUID_TYPE_LONG
+    // custom_uuid.value = 0x3322
+    // custom_uuid.base  = 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
+   
+    @endcode
+*/
+/**************************************************************************/
+UUID::UUID(uint8_t const uuid_base[16])
+{
+    memcpy(base, uuid_base, 16);
+    value = (uint16_t)((uuid_base[3] << 8) | (uuid_base[2]));
+
+    /* Check if this is a short of a long UUID */
+    if (uuid_base[0]  + uuid_base[1]  +
+        uuid_base[4]  + uuid_base[5]  + uuid_base[6]  + uuid_base[7] +
+        uuid_base[8]  + uuid_base[9]  + uuid_base[10] + uuid_base[11] +
+        uuid_base[12] + uuid_base[13] + uuid_base[14] + uuid_base[15] == 0)
+    {
+        type = UUID_TYPE_SHORT; 
+    }
+    else
+    {
+        type = UUID_TYPE_LONG;
+    }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Creates a short (16-bit) UUID
+
+    @param[in]  ble_uuid
+                The 16-bit BLE UUID value.
+*/
+/**************************************************************************/
+UUID::UUID(uint16_t const ble_uuid)
+{
+    memset(base, 0, 16);
+    memcpy(base+2, (uint8_t *)&ble_uuid, 2);
+    value = ble_uuid;
+    type = UUID_TYPE_SHORT;
+}
+
+/**************************************************************************/
+/*!
+    @brief  UUID destructor
+*/
+/**************************************************************************/
+UUID::~UUID(void)
+{
+}
+
+/**************************************************************************/
+/*!
+    @brief  Updates the value of the UUID
+    
+    @args[in]   uuid_base
+                The 128-bit value to use when updating the UUID.  For
+                16-bit IDs, insert the ID in bytes 2/3 in LSB format.
+                
+    @returns    BLE_ERROR_NONE (0) if everything executed correctly, or an
+                error code if there was a problem
+    @retval     BLE_ERROR_NONE
+                Everything executed correctly
+
+    @section EXAMPLE
+
+    @code
+   
+    @endcode    
+*/
+/**************************************************************************/
+ble_error_t UUID::update(uint8_t const uuid_base[16])
+{
+    memcpy(base, uuid_base, 16);
+    value = (uint16_t)((uuid_base[3] << 8) | (uuid_base[2]));
+
+    /* Check if this is a short of a long UUID */
+    if (uuid_base[0]  + uuid_base[1]  +
+        uuid_base[4]  + uuid_base[5]  + uuid_base[6]  + uuid_base[7] +
+        uuid_base[8]  + uuid_base[9]  + uuid_base[10] + uuid_base[11] +
+        uuid_base[12] + uuid_base[13] + uuid_base[14] + uuid_base[15] == 0)
+    {
+        type = UUID_TYPE_SHORT; 
+    }
+    else
+    {
+        type = UUID_TYPE_LONG;
+    }
+    
+    return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Updates the value of the UUID
+    
+    @args[in]   ble_uuid
+                The 16-bit value to use when updating the UUID.
+                
+    @returns    BLE_ERROR_NONE (0) if everything executed correctly, or an
+                error code if there was a problem
+    @retval     BLE_ERROR_NONE
+                Everything executed correctly
+
+    @section EXAMPLE
+
+    @code
+   
+    @endcode    
+*/
+/**************************************************************************/
+ble_error_t UUID::update(uint16_t const ble_uuid)
+{
+    memset(base, 0, 16);
+    memcpy(base+2, (uint8_t *)&ble_uuid, 2);
+    value = ble_uuid;
+    type = UUID_TYPE_SHORT;
+    
+    return BLE_ERROR_NONE;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uuid.h	Fri Nov 29 14:42:22 2013 +0000
@@ -0,0 +1,30 @@
+#ifndef __UUID_H__
+#define __UUID_H__
+
+#include "blecommon.h"
+
+class UUID
+{
+private:
+    
+public:
+    enum
+    {
+        UUID_TYPE_SHORT = 0,    // Short BLE UUID
+        UUID_TYPE_LONG  = 1     // Full 128-bit UUID
+    };
+    
+    UUID(void);
+    UUID(uint8_t const[16]);
+    UUID(uint16_t const);
+    virtual ~UUID(void);
+    
+    uint8_t   type;        // UUID_TYPE_SHORT or UUID_TYPE_LONG
+    uint8_t   base[16];    // in case of custom
+    uint16_t  value;       // 16 bit uuid (byte 2-3 using with base)
+    
+    ble_error_t update(uint8_t const[16]);
+    ble_error_t update(uint16_t const);
+};
+
+#endif