High level Bluetooth Low Energy API and radio abstraction layer

Dependents:   BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate BLE_ANCS_SDAPI_IRC ... more

Overview

The BLE_API is a high level abstraction for using Bluetooth Low Energy on multiple platforms. For details and examples using the BLE_API please see the BLE_API Summary Page. Or click on the API Documentation tab above.

Supported Services

Supported services can be found in the BLE_API/services folder.

Files at this revision

API Documentation at this revision

Comitter:
rgrover1
Date:
Thu Nov 26 12:52:00 2015 +0000
Parent:
889:958c04685226
Child:
891:96514cb1c4c1
Commit message:
Synchronized with git rev 216f73bc
Author: Irit Arkin
New version

Based on the main repo's master version, with edits to the API.

Changed in this revision

CONTRIBUTING.md Show diff for this revision Revisions of this file
ble/BLEInstanceBase.h Show annotated file Show diff for this revision Revisions of this file
ble/FunctionPointerWithContext.h Show annotated file Show diff for this revision Revisions of this file
ble/Gap.h Show annotated file Show diff for this revision Revisions of this file
ble/GattCharacteristic.h Show annotated file Show diff for this revision Revisions of this file
ble/GattService.h Show annotated file Show diff for this revision Revisions of this file
ble/UUID.h Show annotated file Show diff for this revision Revisions of this file
ble/blecommon.h Show annotated file Show diff for this revision Revisions of this file
ble/services/EddystoneConfigService.h Show annotated file Show diff for this revision Revisions of this file
ble/services/EddystoneService.h Show annotated file Show diff for this revision Revisions of this file
ble/services/EnvironmentalService.h Show diff for this revision Revisions of this file
ble/services/HealthThermometerService.h Show annotated file Show diff for this revision Revisions of this file
ble/services/LinkLossService.h Show annotated file Show diff for this revision Revisions of this file
ble/services/UARTService.h Show annotated file Show diff for this revision Revisions of this file
ble/services/URIBeaconConfigService.h Show annotated file Show diff for this revision Revisions of this file
module.json Show annotated file Show diff for this revision Revisions of this file
source/BLE.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/CONTRIBUTING.md	Thu Nov 26 12:52:00 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-# Hello!
-We are an open source project of [ARM mbed](www.mbed.com). Contributions via [pull request](https://github.com/armmbed/yotta/pulls), and [bug reports](https://github.com/armmbed/yotta/issues) are welcome!
-
-Please submit your pull request to the 'develop' branch of this module. Commits to develop will merge into master at the time of the next release.
-
-# Contributor agreement
-For your pull request to be accepted, we will need you to agree to our [contributor agreement](http://developer.mbed.org/contributor_agreement/) to give us the necessary rights to use and distribute your contributions. (To click through the agreement create an account on mbed.com and log in.)
\ No newline at end of file
--- a/ble/BLEInstanceBase.h	Thu Nov 26 12:52:00 2015 +0000
+++ b/ble/BLEInstanceBase.h	Thu Nov 26 12:52:00 2015 +0000
@@ -18,8 +18,6 @@
 #define __BLE_DEVICE_INSTANCE_BASE__
 
 #include "Gap.h"
-#include "ble/SecurityManager.h"
-#include "ble/BLE.h"
 
 /* forward declarations */
 class GattServer;
@@ -32,19 +30,17 @@
 class BLEInstanceBase
 {
 public:
-    virtual ble_error_t            init(BLE::InstanceID_t instanceID,
-                                        FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> initCallback) = 0;
-    virtual bool                   hasInitialized(void) const = 0;
-    virtual ble_error_t            shutdown(void)             = 0;
-    virtual const char *           getVersion(void)           = 0;
-    virtual Gap&                   getGap()                   = 0;
-    virtual const Gap&             getGap() const             = 0;
-    virtual GattServer&            getGattServer()            = 0;
-    virtual const GattServer&      getGattServer() const      = 0;
-    virtual GattClient&            getGattClient()            = 0;
-    virtual SecurityManager&       getSecurityManager()       = 0;
+    virtual ble_error_t init(void)                  = 0;
+    virtual ble_error_t shutdown(void)              = 0;
+    virtual const char *getVersion(void)            = 0;
+    virtual Gap&        getGap()                    = 0;
+    virtual const Gap&  getGap() const              = 0;
+    virtual GattServer& getGattServer()             = 0;
+    virtual const GattServer& getGattServer() const = 0;
+    virtual GattClient& getGattClient()             = 0;
+    virtual SecurityManager& getSecurityManager()   = 0;
     virtual const SecurityManager& getSecurityManager() const = 0;
-    virtual void                   waitForEvent(void)         = 0;
+    virtual void        waitForEvent(void)         = 0;
 };
 
 /**
--- a/ble/FunctionPointerWithContext.h	Thu Nov 26 12:52:00 2015 +0000
+++ b/ble/FunctionPointerWithContext.h	Thu Nov 26 12:52:00 2015 +0000
@@ -19,6 +19,7 @@
 
 #include <string.h>
 
+
 /** A class for storing and calling a pointer to a static or member void function
  *  which takes a context.
  */
@@ -33,7 +34,7 @@
      *  @param function The void static function to attach (default is none)
      */
     FunctionPointerWithContext(void (*function)(ContextType context) = NULL) :
-        _function(NULL), _caller(NULL), _next(NULL) {
+        _function(NULL), _object(NULL), _member(), _membercaller(NULL), _next(NULL) {
         attach(function);
     }
 
@@ -44,7 +45,7 @@
      */
     template<typename T>
     FunctionPointerWithContext(T *object, void (T::*member)(ContextType context)) :
-        _memberFunctionAndPointer(), _caller(NULL), _next(NULL) {
+        _function(NULL), _object(NULL), _member(), _membercaller(NULL), _next(NULL) {
         attach(object, member);
     }
 
@@ -54,7 +55,6 @@
      */
     void attach(void (*function)(ContextType context) = NULL) {
         _function = function;
-        _caller = functioncaller;
     }
 
     /** Attach a member function
@@ -64,9 +64,9 @@
      */
     template<typename T>
     void attach(T *object, void (T::*member)(ContextType context)) {
-        _memberFunctionAndPointer._object = static_cast<void *>(object);
-        memcpy(_memberFunctionAndPointer._memberFunction, (char*) &member, sizeof(member));
-        _caller = &FunctionPointerWithContext::membercaller<T>;
+        _object = static_cast<void *>(object);
+        memcpy(_member, (char *)&member, sizeof(member));
+        _membercaller = &FunctionPointerWithContext::membercaller<T>;
     }
 
     /** Call the attached static or member function; and if there are chained
@@ -74,7 +74,11 @@
      *  @Note: all chained callbacks stack up; so hopefully there won't be too
      *  many FunctionPointers in a chain. */
     void call(ContextType context) {
-        _caller(this, context);
+        if (_function) {
+            _function(context);
+        } else if (_object && _membercaller) {
+            _membercaller(_object, _member, context);
+        }
 
         /* Propagate the call to next in the chain. */
         if (_next) {
@@ -103,49 +107,19 @@
 
 private:
     template<typename T>
-    static void membercaller(pFunctionPointerWithContext_t self, ContextType context) {
-        if (self->_memberFunctionAndPointer._object) {
-            T *o = static_cast<T *>(self->_memberFunctionAndPointer._object);
-            void (T::*m)(ContextType);
-            memcpy((char*) &m, self->_memberFunctionAndPointer._memberFunction, sizeof(m));
-            (o->*m)(context);
-        }
-    }
-
-    static void functioncaller(pFunctionPointerWithContext_t self, ContextType context) {
-        if (self->_function) {
-            self->_function(context);
-        }
+    static void membercaller(void *object, char *member, ContextType context) {
+        T *o = static_cast<T *>(object);
+        void (T::*m)(ContextType);
+        memcpy((char *)&m, member, sizeof(m));
+        (o->*m)(context);
     }
 
-    struct MemberFunctionAndPtr {
-        /*
-         * forward declaration of a class and a member function to this class.
-         * Because the compiler doesn't know anything about the forwarded member
-         * function, it will always use the biggest size and the biggest alignment
-         * that a member function can take for objects of type UndefinedMemberFunction.
-         */
-        class UndefinedClass;
-        typedef void (UndefinedClass::*UndefinedMemberFunction)(ContextType);
-
-        void* _object;
-        union {
-            char _memberFunction[sizeof(UndefinedMemberFunction)];
-            UndefinedMemberFunction _alignment;
-        };
-    };
-
-    union {
-        pvoidfcontext_t _function;                      /**< static function pointer - NULL if none attached */
-        /**
-         * object this pointer and pointer to member -
-         * _memberFunctionAndPointer._object will be NULL if none attached
-         */
-        MemberFunctionAndPtr _memberFunctionAndPointer;
-    };
-
-    void (*_caller)(FunctionPointerWithContext*, ContextType);
-
+    void (*_function)(ContextType context);             /**< static function pointer - NULL if none attached */
+    void *_object;                                      /**< object this pointer - NULL if none attached */
+    char _member[16];                                   /**< raw member function pointer storage - converted back by
+                                                         *   registered _membercaller */
+    void (*_membercaller)(void *, char *, ContextType); /**< registered membercaller function to convert back and call
+                                                         *   _member on _object passing the context. */
     pFunctionPointerWithContext_t _next;                /**< Optional link to make a chain out of functionPointers; this
                                                          *   allows chaining function pointers without requiring
                                                          *   external memory to manage the chain. Also refer to
--- a/ble/Gap.h	Thu Nov 26 12:52:00 2015 +0000
+++ b/ble/Gap.h	Thu Nov 26 12:52:00 2015 +0000
@@ -867,8 +867,8 @@
     }
 
 private:
-    virtual ble_error_t setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) = 0;
-    virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0;
+    virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &) = 0;
+    virtual ble_error_t startAdvertising(const GapAdvertisingParams &)                             = 0;
 
 public:
     /**
--- a/ble/GattCharacteristic.h	Thu Nov 26 12:52:00 2015 +0000
+++ b/ble/GattCharacteristic.h	Thu Nov 26 12:52:00 2015 +0000
@@ -57,7 +57,6 @@
         UUID_HEART_RATE_MEASUREMENT_CHAR                  = 0x2A37,
         UUID_HID_CONTROL_POINT_CHAR                       = 0x2A4C,
         UUID_HID_INFORMATION_CHAR                         = 0x2A4A,
-        UUID_HUMIDITY_CHAR                                = 0x2A6F,
         UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR = 0x2A2A,
         UUID_INTERMEDIATE_CUFF_PRESSURE_CHAR              = 0x2A36,
         UUID_INTERMEDIATE_TEMPERATURE_CHAR                = 0x2A1E,
@@ -68,7 +67,6 @@
         UUID_UNREAD_ALERT_CHAR                            = 0x2A45,
         UUID_NEW_ALERT_CHAR                               = 0x2A46,
         UUID_PNP_ID_CHAR                                  = 0x2A50,
-        UUID_PRESSURE_CHAR                                = 0x2A6D,
         UUID_PROTOCOL_MODE_CHAR                           = 0x2A4E,
         UUID_RECORD_ACCESS_CONTROL_POINT_CHAR             = 0x2A52,
         UUID_REFERENCE_TIME_INFORMATION_CHAR              = 0x2A14,
@@ -83,7 +81,6 @@
         UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR            = 0x2A47,
         UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR         = 0x2A48,
         UUID_SYSTEM_ID_CHAR                               = 0x2A23,
-        UUID_TEMPERATURE_CHAR                             = 0x2A6E,
         UUID_TEMPERATURE_MEASUREMENT_CHAR                 = 0x2A1C,
         UUID_TEMPERATURE_TYPE_CHAR                        = 0x2A1D,
         UUID_TIME_ACCURACY_CHAR                           = 0x2A12,
@@ -96,7 +93,7 @@
         UUID_CSC_FEATURE_CHAR                             = 0x2A5C,
         UUID_CSC_MEASUREMENT_CHAR                         = 0x2A5B,
         UUID_RSC_FEATURE_CHAR                             = 0x2A54,
-        UUID_RSC_MEASUREMENT_CHAR                         = 0x2A53
+        UUID_RSC_MEASUREMENT_CHAR                         = 0x2A53,
     };
 
     /**************************************************************************/
--- a/ble/GattService.h	Thu Nov 26 12:52:00 2015 +0000
+++ b/ble/GattService.h	Thu Nov 26 12:52:00 2015 +0000
@@ -29,7 +29,6 @@
         UUID_CURRENT_TIME_SERVICE           = 0x1805,
         UUID_CYCLING_SPEED_AND_CADENCE      = 0x1816,
         UUID_DEVICE_INFORMATION_SERVICE     = 0x180A,
-        UUID_ENVIRONMENTAL_SERVICE          = 0x181A,
         UUID_GLUCOSE_SERVICE                = 0x1808,
         UUID_HEALTH_THERMOMETER_SERVICE     = 0x1809,
         UUID_HEART_RATE_SERVICE             = 0x180D,
--- a/ble/UUID.h	Thu Nov 26 12:52:00 2015 +0000
+++ b/ble/UUID.h	Thu Nov 26 12:52:00 2015 +0000
@@ -74,7 +74,7 @@
      *
      * @note we don't yet support 32-bit shortened UUIDs.
      */
-    UUID(ShortUUIDBytes_t _shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(_shortUUID) {
+    UUID(ShortUUIDBytes_t shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(shortUUID) {
         /* empty */
     }
 
--- a/ble/blecommon.h	Thu Nov 26 12:52:00 2015 +0000
+++ b/ble/blecommon.h	Thu Nov 26 12:52:00 2015 +0000
@@ -114,18 +114,16 @@
 */
 /**************************************************************************/
 enum ble_error_t {
-    BLE_ERROR_NONE                      = 0, /**< No error */
-    BLE_ERROR_BUFFER_OVERFLOW           = 1, /**< The requested action would cause a buffer overflow and has been aborted */
-    BLE_ERROR_NOT_IMPLEMENTED           = 2, /**< Requested a feature that isn't yet implement or isn't supported by the target HW */
-    BLE_ERROR_PARAM_OUT_OF_RANGE        = 3, /**< One of the supplied parameters is outside the valid range */
-    BLE_ERROR_INVALID_PARAM             = 4, /**< One of the supplied parameters is invalid */
-    BLE_STACK_BUSY                      = 5, /**< The stack is busy */
-    BLE_ERROR_INVALID_STATE             = 6, /**< Invalid state. */
-    BLE_ERROR_NO_MEM                    = 7, /**< Out of Memory */
-    BLE_ERROR_OPERATION_NOT_PERMITTED   = 8,
-    BLE_ERROR_INITIALIZATION_INCOMPLETE = 9,
-    BLE_ERROR_ALREADY_INITIALIZED       = 10,
-    BLE_ERROR_UNSPECIFIED               = 11, /**< Unknown error. */
+    BLE_ERROR_NONE                    = 0, /**< No error */
+    BLE_ERROR_BUFFER_OVERFLOW         = 1, /**< The requested action would cause a buffer overflow and has been aborted */
+    BLE_ERROR_NOT_IMPLEMENTED         = 2, /**< Requested a feature that isn't yet implement or isn't supported by the target HW */
+    BLE_ERROR_PARAM_OUT_OF_RANGE      = 3, /**< One of the supplied parameters is outside the valid range */
+    BLE_ERROR_INVALID_PARAM           = 4, /**< One of the supplied parameters is invalid */
+    BLE_STACK_BUSY                    = 5, /**< The stack is busy */
+    BLE_ERROR_INVALID_STATE           = 6, /**< Invalid state. */
+    BLE_ERROR_NO_MEM                  = 7, /**< Out of Memory */
+    BLE_ERROR_OPERATION_NOT_PERMITTED = 8,
+    BLE_ERROR_UNSPECIFIED             = 9, /**< Unknown error. */
 };
 
 /** @brief Default MTU size. */
--- a/ble/services/EddystoneConfigService.h	Thu Nov 26 12:52:00 2015 +0000
+++ b/ble/services/EddystoneConfigService.h	Thu Nov 26 12:52:00 2015 +0000
@@ -215,7 +215,7 @@
         DBG("Setting Default TLM Data, version = %d, advPeriodInMind= %f", tlmVersionIn, advPeriodInSec);
         defaultTlmVersion   = tlmVersionIn;
         TlmBatteryVoltage   = 0;
-        TlmBeaconTemp       = 0x8000;
+        TlmBeaconTemp       = 0;
         TlmPduCount         = 0;
         TlmTimeSinceBoot    = 0;
         defaultTlmAdvPeriod = advPeriodInSec;
@@ -285,7 +285,7 @@
         ble.setTxPower(radioPowerLevels[params.txPowerMode]);
         ble.setDeviceName(reinterpret_cast<const uint8_t *>(&DEVICE_NAME));
         ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
-        ble.setAdvertisingInterval(ADVERTISING_INTERVAL_MSEC);
+        ble.setAdvertisingInterval(GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADVERTISING_INTERVAL_MSEC));
     }
 
     /*
@@ -306,7 +306,7 @@
             eddyServ.setTLMFrameData(params.tlmVersion, params.tlmBeaconPeriod);
         }
         if (params.uriEnabled) {
-            eddyServ.setURLFrameEncodedData(params.advPowerLevels[params.txPowerMode], (const char *) params.uriData, params.uriDataLength, params.uriBeaconPeriod);
+            eddyServ.setURLFrameData(params.advPowerLevels[params.txPowerMode], (const char *) params.uriData, params.uriBeaconPeriod);
         }
         if (params.uidEnabled) {
             eddyServ.setUIDFrameData(params.advPowerLevels[params.txPowerMode],
@@ -340,7 +340,7 @@
         } else if (handle == uriDataChar.getValueHandle()) {
             params.uriDataLength = writeParams->len;
             memset(params.uriData, 0x00, URI_DATA_MAX);                      // clear URI string
-            memcpy(params.uriData, writeParams->data, writeParams->len); // set URI string
+            memcpy(params.uriData, writeParams->data, params.uriDataLength); // set URI string
             params.uriEnabled = true;
             INFO("URI = %s, URILen = %d", writeParams->data, writeParams->len);
         } else if (handle == flagsChar.getValueHandle()) {
@@ -389,7 +389,7 @@
         params.flags = 0x10;
         memcpy(params.advPowerLevels, defaultAdvPowerLevels, sizeof(PowerLevels_t));
         params.txPowerMode  = TX_POWER_MODE_LOW;
-        params.beaconPeriod = (uint16_t) defaultUriAdvPeriod * 1000;
+        params.beaconPeriod = 1000;
 
         // TLM Frame
         params.tlmVersion      = defaultTlmVersion;
--- a/ble/services/EddystoneService.h	Thu Nov 26 12:52:00 2015 +0000
+++ b/ble/services/EddystoneService.h	Thu Nov 26 12:52:00 2015 +0000
@@ -101,9 +101,9 @@
     void setUIDFrameData(int8_t           power,
                          UIDNamespaceID_t namespaceID,
                          UIDInstanceID_t  instanceID,
-                         float            uidAdvPeriodIn,
+                         uint32_t         uidAdvPeriodIn,
                          uint16_t         RFU = 0x0000) {
-        if (0.0f == uidAdvPeriodIn) {
+        if (0 == uidAdvPeriodIn) {
             uidIsSet = false;
             return;
         }
@@ -170,45 +170,21 @@
      *  @param[in] urlAdvPeriodIn How long to advertise the URL frame (measured in # of adv periods)
      *  @return false on success, true on failure.
      */
-    bool setURLFrameData(int8_t power, const char *urlIn, float urlAdvPeriodIn) {
-        if (0.0f == urlAdvPeriodIn) {
+    bool setURLFrameData(int8_t power, const char *urlIn, uint32_t urlAdvPeriodIn) {
+        if (0 == urlAdvPeriodIn) {
             urlIsSet = false;
             return false;
         }
+        defaultUrlPower = power;
         encodeURL(urlIn, defaultUriData, defaultUriDataLength); // encode URL to URL Formatting
         if (defaultUriDataLength > URI_DATA_MAX) {
             return true;                                        // error, URL is too big
         }
-        defaultUrlPower = power;
         urlAdvPeriod = urlAdvPeriodIn;
         urlIsSet     = true;
         return false;
     }
 
-    /**
-     *  Set Eddystone URL Frame information.
-     *  @param[in] power              TX Power in dB measured at 0 meters from the device.
-     *  @param[in] encodedUrlIn       Encoded URL
-     *  @param[in] encodedUrlInLength Length of the encoded URL
-     *  @param[in] urlAdvPeriodIn     How long to advertise the URL frame (measured in # of adv periods)
-     *  @return false on success, true on failure.
-     */
-    bool setURLFrameEncodedData(int8_t power, const char *encodedUrlIn, uint8_t encodedUrlInLength, float urlAdvPeriodIn) {
-        if (0.0f == urlAdvPeriodIn) {
-            urlIsSet = false;
-            return false;
-        }
-        memcpy(defaultUriData, encodedUrlIn, encodedUrlInLength);
-        if (defaultUriDataLength > URI_DATA_MAX) {
-            return true;                                        // error, URL is too big
-        }
-        defaultUrlPower      = power;
-        defaultUriDataLength = encodedUrlInLength;
-        urlAdvPeriod         = urlAdvPeriodIn;
-        urlIsSet             = true;
-        return false;
-    }
-
     /*
     *  Construct URL frame from private variables
     *  @param[in/out] Data pointer to array to store constructed frame in
@@ -235,12 +211,12 @@
     *
     */
     void setTLMFrameData(uint8_t  version        = 0,
-                         float    advPeriod      = 60.0f,
+                         uint32_t advPeriod      = 60,
                          uint16_t batteryVoltage = 0,
-                         uint16_t beaconTemp     = 0x8000,
+                         uint16_t beaconTemp     = 0,
                          uint32_t pduCount       = 0,
                          uint32_t timeSinceBoot  = 0) {
-        if (0.0f == advPeriod) {
+        if (0 == advPeriod) {
             tlmIsSet = false;
             return;
         }
@@ -260,10 +236,6 @@
     *  @return number of bytes used. negative number indicates error message.
     */
     int constructTLMFrame(uint8_t *Data, uint8_t maxSize) {
-        uint32_t now = timeSinceBootTimer.read_ms();
-        TlmTimeSinceBoot += (now - lastBootTimerRead) / 100;
-        lastBootTimerRead = now;
-
         int index = 0;
         Data[index++] = FRAME_TYPE_TLM;                    // Eddystone frame type = Telemetry
         Data[index++] = TlmVersion;                        // TLM Version Number
@@ -320,6 +292,14 @@
     }
 
     /*
+    *  callback function, called every 0.1s, incriments the TimeSinceBoot field in the TLM frame
+    *  @return nothing
+    */
+    void tsbCallback(void) {
+        TlmTimeSinceBoot++;
+    }
+
+    /*
     * Update advertising data
     * @return true on success, false on failure
     */
@@ -507,7 +487,7 @@
         // Initialize Frame transition, start with URL to pass eddystone validator app on first try
         if (urlIsSet) {
             frameIndex = url;
-            urlTicker.attach(this, &EddystoneService::urlCallback, (float) advPeriodus / 1000.0f);
+            urlTicker.attach(this, &EddystoneService::urlCallback, urlAdvPeriod);
             DBG("attached urlCallback every %d seconds", urlAdvPeriod);
         }
         if (uidIsSet) {
@@ -520,8 +500,7 @@
             // Make double sure the PDUCount and TimeSinceBoot fields are set to zero at reset
             updateTlmPduCount(0);
             updateTlmTimeSinceBoot(0);
-            lastBootTimerRead = 0;
-            timeSinceBootTimer.start();
+            timeSinceBootTick.attach(this, &EddystoneService::tsbCallback, 0.1); // incriment the TimeSinceBoot ticker every 0.1s
             tlmTicker.attach(this, &EddystoneService::tlmCallback, TlmAdvPeriod);
             DBG("attached tlmCallback every %d seconds", TlmAdvPeriod);
         }
@@ -540,8 +519,7 @@
     BLEDevice           &ble;
     uint16_t            advPeriodus;
     uint8_t             txPower;
-    Timer               timeSinceBootTimer;
-    volatile uint32_t   lastBootTimerRead;
+    Ticker              timeSinceBootTick;  // counter that counts time since boot
     volatile bool       advLock;
     volatile FrameTypes frameIndex;
     Timeout             stopAdv;
@@ -552,7 +530,7 @@
     UriData_t           defaultUriData;
     int8_t              defaultUrlPower;
     bool                urlIsSet;       // flag that enables / disable URI Frames
-    float               urlAdvPeriod;   // how long the url frame will be advertised for
+    uint32_t            urlAdvPeriod;   // how long the url frame will be advertised for
     Ticker              urlTicker;
 
     // UID Frame Variables
@@ -561,7 +539,7 @@
     int8_t              defaultUidPower;
     uint16_t            uidRFU;
     bool                uidIsSet;       // flag that enables / disable UID Frames
-    float               uidAdvPeriod;   // how long the uid frame will be advertised for
+    uint32_t            uidAdvPeriod;   // how long the uid frame will be advertised for
     Ticker              uidTicker;
 
     // TLM Frame Variables
@@ -571,7 +549,7 @@
     volatile uint32_t   TlmPduCount;
     volatile uint32_t   TlmTimeSinceBoot;
     bool                tlmIsSet;          // flag that enables / disables TLM frames
-    float               TlmAdvPeriod;      // number of minutes between adv frames
+    uint32_t            TlmAdvPeriod;      // number of minutes between adv frames
     Ticker              tlmTicker;
 
 public:
--- a/ble/services/EnvironmentalService.h	Thu Nov 26 12:52:00 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-/* mbed Microcontroller Library
- * Copyright (c) 2006-2013 ARM Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __BLE_ENVIRONMENTAL_SERVICE_H__
-#define __BLE_ENVIRONMENTAL_SERVICE_H__
-
-#include "ble/BLE.h"
-
-/**
-* @class EnvironmentalService
-* @brief BLE Environmental Service. This service provides the location of the thermometer and the temperature.  <br>
-* Service:  https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.environmental_sensing.xml <br>
-* Temperature: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature.xml <br>
-* Humidity: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.humidity.xml <br>
-* Pressure: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.pressure.xml
-*/
-class EnvironmentalService {
-public:
-    typedef int16_t  TemperatureType_t;
-    typedef uint16_t HumidityType_t;
-    typedef uint32_t PressureType_t;
-
-    /**
-     * @brief   EnvironmentalService constructor.
-     * @param   ble Reference to BLE device.
-     * @param   temperature_en Enable this characteristic.
-     * @param   humidity_en Enable this characteristic.
-     * @param   pressure_en Enable this characteristic.
-     */
-    EnvironmentalService(BLE& _ble) :
-        ble(_ble),
-        temperatureCharacteristic(GattCharacteristic::UUID_TEMPERATURE_CHAR, &temperature),
-        humidityCharacteristic(GattCharacteristic::UUID_HUMIDITY_CHAR, &humidity),
-        pressureCharacteristic(GattCharacteristic::UUID_PRESSURE_CHAR, &pressure)
-    {
-        static bool serviceAdded = false; /* We should only ever need to add the information service once. */
-        if (serviceAdded) {
-            return;
-        }
-
-        GattCharacteristic *charTable[] = { &humidityCharacteristic,
-                                            &pressureCharacteristic,
-                                            &temperatureCharacteristic };
-
-        GattService environmentalService(GattService::UUID_ENVIRONMENTAL_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
-
-        ble.gattServer().addService(environmentalService);
-        serviceAdded = true;
-    }
-
-    /**
-     * @brief   Update humidity characteristic.
-     * @param   newHumidityVal New humidity measurement.
-     */
-    void updateHumidity(HumidityType_t newHumidityVal)
-    {
-        humidity = (HumidityType_t) (newHumidityVal * 100);
-        ble.gattServer().write(humidityCharacteristic.getValueHandle(), (uint8_t *) &humidity, sizeof(HumidityType_t));
-    }
-
-    /**
-     * @brief   Update pressure characteristic.
-     * @param   newPressureVal New pressure measurement.
-     */
-    void updatePressure(PressureType_t newPressureVal)
-    {
-        pressure = (PressureType_t) (newPressureVal * 10);
-        ble.gattServer().write(pressureCharacteristic.getValueHandle(), (uint8_t *) &pressure, sizeof(PressureType_t));
-    }
-
-    /**
-     * @brief   Update temperature characteristic.
-     * @param   newTemperatureVal New temperature measurement.
-     */
-    void updateTemperature(float newTemperatureVal)
-    {
-        temperature = (TemperatureType_t) (newTemperatureVal * 100);
-        ble.gattServer().write(temperatureCharacteristic.getValueHandle(), (uint8_t *) &temperature, sizeof(TemperatureType_t));
-    }
-
-private:
-    BLE& ble;
-
-    TemperatureType_t temperature;
-    HumidityType_t    humidity;
-    PressureType_t    pressure;
-
-    ReadOnlyGattCharacteristic<TemperatureType_t> temperatureCharacteristic;
-    ReadOnlyGattCharacteristic<HumidityType_t>    humidityCharacteristic;
-    ReadOnlyGattCharacteristic<PressureType_t>    pressureCharacteristic;
-};
-
-#endif /* #ifndef __BLE_ENVIRONMENTAL_SERVICE_H__*/
\ No newline at end of file
--- a/ble/services/HealthThermometerService.h	Thu Nov 26 12:52:00 2015 +0000
+++ b/ble/services/HealthThermometerService.h	Thu Nov 26 12:52:00 2015 +0000
@@ -17,7 +17,7 @@
 #ifndef __BLE_HEALTH_THERMOMETER_SERVICE_H__
 #define __BLE_HEALTH_THERMOMETER_SERVICE_H__
 
-#include "ble/BLE.h"
+#include "BLE.h"
 
 /**
 * @class HealthThermometerService
--- a/ble/services/LinkLossService.h	Thu Nov 26 12:52:00 2015 +0000
+++ b/ble/services/LinkLossService.h	Thu Nov 26 12:52:00 2015 +0000
@@ -17,7 +17,7 @@
 #ifndef __BLE_LINK_LOSS_SERVICE_H__
 #define __BLE_LINK_LOSS_SERVICE_H__
 
-#include "ble/Gap.h"
+#include "Gap.h"
 
 /**
 * @class LinkLossService
@@ -52,11 +52,11 @@
         GattCharacteristic *charTable[] = {&alertLevelChar};
         GattService         linkLossService(GattService::UUID_LINK_LOSS_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
 
-        ble.gattServer().addService(linkLossService);
+        ble.addService(linkLossService);
         serviceAdded = true;
 
-        ble.gap().onDisconnection(this, &LinkLossService::onDisconnectionFilter);
-        ble.gattServer().onDataWritten(this, &LinkLossService::onDataWritten);
+        ble.addToDisconnectionCallChain(this, &LinkLossService::onDisconnectionFilter);
+        ble.onDataWritten(this, &LinkLossService::onDataWritten);
     }
 
     /**
@@ -86,7 +86,7 @@
         }
     }
 
-    void onDisconnectionFilter(const Gap::DisconnectionCallbackParams_t *params) {
+    void onDisconnectionFilter(void) {
         if (alertLevel != NO_ALERT) {
             callback(alertLevel);
         }
--- a/ble/services/UARTService.h	Thu Nov 26 12:52:00 2015 +0000
+++ b/ble/services/UARTService.h	Thu Nov 26 12:52:00 2015 +0000
@@ -17,13 +17,8 @@
 #ifndef __BLE_UART_SERVICE_H__
 #define __BLE_UART_SERVICE_H__
 
-#ifdef YOTTA_CFG_MBED_OS
-#include "mbed-drivers/mbed.h"
-#include "mbed-drivers/Stream.h"
-#else
 #include "mbed.h"
 #include "Stream.h"
-#endif
 
 #include "ble/UUID.h"
 #include "ble/BLE.h"
--- a/ble/services/URIBeaconConfigService.h	Thu Nov 26 12:52:00 2015 +0000
+++ b/ble/services/URIBeaconConfigService.h	Thu Nov 26 12:52:00 2015 +0000
@@ -18,12 +18,7 @@
 #define SERVICES_URIBEACONCONFIGSERVICE_H_
 
 #include "ble/BLE.h"
-
-#ifdef YOTTA_CFG_MBED_OS
-#include "mbed-drivers/mbed.h"
-#else
 #include "mbed.h"
-#endif
 
 extern const uint8_t UUID_URI_BEACON_SERVICE[UUID::LENGTH_OF_LONG_UUID];
 extern const uint8_t UUID_LOCK_STATE_CHAR[UUID::LENGTH_OF_LONG_UUID];
--- a/module.json	Thu Nov 26 12:52:00 2015 +0000
+++ b/module.json	Thu Nov 26 12:52:00 2015 +0000
@@ -1,16 +1,14 @@
 {
   "name": "ble",
-  "version": "2.0.4",
+  "version": "0.4.8",
   "description": "The BLE module offers a high level abstraction for using Bluetooth Low Energy on multiple platforms.",
   "keywords": [
     "Bluetooth",
-    "BLE",
-    "mbed",
-    "mbed-official"
+    "BLE"
   ],
   "author": "Rohit Grover",
   "repository": {
-    "url": "https://github.com/ARMmbed/ble.git",
+    "url": "git@github.com:ARMmbed/ble.git",
     "type": "git"
   },
   "homepage": "http://mbed.org/ble",
@@ -22,14 +20,8 @@
   ],
   "dependencies": {},
   "targetDependencies": {
-    "st-ble-shield": {
-      "x-nucleo-idb0xa1": "ARMmbed/ble-x-nucleo-idb0xa1"
-    },
     "nrf51822": {
-      "ble-nrf51822": "^2.0.0"
-    },
-    "cordio": {
-      "ble-wicentric": "~0.0.4"
+      "ble-nrf51822": "~0.4.7"
     },
     "mbed-classic": {
       "mbed-classic": "~0.0.1"
--- a/source/BLE.cpp	Thu Nov 26 12:52:00 2015 +0000
+++ b/source/BLE.cpp	Thu Nov 26 12:52:00 2015 +0000
@@ -15,16 +15,15 @@
  */
 
 #include "ble/BLE.h"
-#include "ble/BLEInstanceBase.h"
 
 #if defined(TARGET_OTA_ENABLED)
 #include "ble/services/DFUService.h"
 #endif
 
 ble_error_t
-BLE::initImplementation(FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback)
+BLE::init()
 {
-    ble_error_t err = transport->init(instanceID, callback);
+    ble_error_t err = transport->init();
     if (err != BLE_ERROR_NONE) {
         return err;
     }
@@ -106,7 +105,7 @@
     return badSingleton;
 }
 
-BLE::BLE(InstanceID_t instanceIDIn) : instanceID(instanceIDIn), transport()
+BLE::BLE(InstanceID_t instanceID) : transport()
 {
     static BLEInstanceBase *transportInstances[NUM_INSTANCES];
 
@@ -118,113 +117,4 @@
     } else {
         transport = NULL;
     }
-}
-
-bool BLE::hasInitialized(void) const
-{
-    if (!transport) {
-        error("bad handle to underlying transport");
-    }
-
-    return transport->hasInitialized();
-}
-
-ble_error_t BLE::shutdown(void)
-{
-    clearAdvertisingPayload();
-    if (!transport) {
-        error("bad handle to underlying transport");
-    }
-
-    return transport->shutdown();
-}
-
-const char *BLE::getVersion(void)
-{
-    if (!transport) {
-        error("bad handle to underlying transport");
-    }
-
-    return transport->getVersion();
-}
-
-const Gap &BLE::gap() const
-{
-    if (!transport) {
-        error("bad handle to underlying transport");
-    }
-
-    return transport->getGap();
-}
-
-Gap &BLE::gap()
-{
-    if (!transport) {
-        error("bad handle to underlying transport");
-    }
-
-    return transport->getGap();
-}
-
-const GattServer& BLE::gattServer() const
-{
-    if (!transport) {
-        error("bad handle to underlying transport");
-    }
-
-    return transport->getGattServer();
-}
-
-GattServer& BLE::gattServer()
-{
-    if (!transport) {
-        error("bad handle to underlying transport");
-    }
-
-    return transport->getGattServer();
-}
-
-const GattClient& BLE::gattClient() const
-{
-    if (!transport) {
-        error("bad handle to underlying transport");
-    }
-
-    return transport->getGattClient();
-}
-
-GattClient& BLE::gattClient()
-{
-    if (!transport) {
-        error("bad handle to underlying transport");
-    }
-
-    return transport->getGattClient();
-}
-
-const SecurityManager& BLE::securityManager() const
-{
-    if (!transport) {
-        error("bad handle to underlying transport");
-    }
-
-    return transport->getSecurityManager();
-}
-
-SecurityManager& BLE::securityManager()
-{
-    if (!transport) {
-        error("bad handle to underlying transport");
-    }
-
-    return transport->getSecurityManager();
-}
-
-void BLE::waitForEvent(void)
-{
-    if (!transport) {
-        error("bad handle to underlying transport");
-    }
-
-    transport->waitForEvent();
 }
\ No newline at end of file