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:
Mon Nov 02 09:09:07 2015 +0000
Parent:
857:7f578be2d01d
Child:
859:2a1cb15098ba
Commit message:
Synchronized with git rev e46cef5d
Author: Rohit Grover
Merge pull request #91 from rgrover/develop

BLE::init() now takes in a callback paramter

Changed in this revision

ble/BLE.h Show annotated file 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/blecommon.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/ble/BLE.h	Mon Nov 02 09:09:06 2015 +0000
+++ b/ble/BLE.h	Mon Nov 02 09:09:07 2015 +0000
@@ -21,7 +21,6 @@
 #include "Gap.h"
 #include "GattServer.h"
 #include "GattClient.h"
-#include "BLEInstanceBase.h"
 
 #ifdef YOTTA_CFG_MBED_OS
 #include "mbed-drivers/mbed_error.h"
@@ -29,6 +28,9 @@
 #include "mbed_error.h"
 #endif
 
+/* forward declaration for the implementation class */
+class BLEInstanceBase;
+
 /**
  * The base class used to abstract away BLE capable radio transceivers or SOCs,
  * to enable this BLE API to work with any radio transparently.
@@ -36,6 +38,20 @@
 class BLE
 {
 public:
+    typedef unsigned InstanceID_t; /** The type returned by BLE::getInstanceID(). */
+
+    /**
+     * The function signature for callbacks for initialization completion.
+     * @param  ble
+     *             A reference to the BLE instance being initialized.
+     * @param  error
+     *             This captures the result of initialization. It is set to
+     *             BLE_ERROR_NONE if initialization completed successfully. Else
+     *             the error value is implementation specific.
+     *
+     */
+    typedef void (*InitializationCompleteCallback_t)(BLE &ble, ble_error_t error);
+
     /**
      * Initialize the BLE controller. This should be called before using
      * anything else in the BLE_API.
@@ -46,21 +62,44 @@
      * system startup. It may not be safe to call init() from global static
      * context where ordering is compiler specific and can't be guaranteed--it
      * is safe to call BLE::init() from within main().
+     *
+     * @param  callback
+     *           A callback for when initialization completes for a BLE
+     *           instance. This is an optional parameter, if no callback is
+     *           setup the application can still determine the status of
+     *           initialization using BLE::hasInitialized() (see below).
+     *
+     * @return  BLE_ERROR_NONE if the initialization procedure was started
+     *     successfully.
+     *
+     * @note The underlying stack must invoke the initialization completion
+     *     callback in response to init(). In some cases, initialization is
+     *     instantaneous (or blocking); if so, it is acceptable for the stack-
+     *     specific implementation of init() to invoke the completion callback
+     *     directly--i.e. within its own context.
+     *
+     * @note Nearly all BLE APIs would return
+     *     BLE_ERROR_INITIALIZATION_INCOMPLETE if used on an instance before the
+     *     corresponding transport is initialized.
      */
-    ble_error_t init();
+    ble_error_t init(InitializationCompleteCallback_t callback = NULL);
+
+    /**
+     * @return true if initialization has completed for the underlying BLE
+     *     transport.
+     *
+     * The application can setup a callback to signal completion of
+     * initialization when using init(). Otherwise, this method can be used to
+     * poll the state of initialization.
+     */
+    bool hasInitialized(void) const;
 
     /**
      * Purge the BLE stack of GATT and GAP state. init() must be called
      * afterwards to re-instate services and GAP state. This API offers a way to
      * repopulate the GATT database with new services and characteristics.
      */
-    ble_error_t shutdown(void) {
-        clearAdvertisingPayload();
-        if (!transport) {
-            error("bad handle to underlying transport");
-        }
-        return transport->shutdown();
-    }
+    ble_error_t shutdown(void);
 
     /**
      * This call allows the application to get the BLE stack version information.
@@ -68,81 +107,36 @@
      * @return  A pointer to a const string representing the version.
      *          Note: The string is owned by the BLE_API.
      */
-    const char *getVersion(void) {
-        if (!transport) {
-            error("bad handle to underlying transport");
-        }
-        return transport->getVersion();
-    }
+    const char *getVersion(void);
 
     /*
      * Accessors to GAP. Please refer to Gap.h. All GAP related functionality requires
      * going through this accessor.
      */
-    const Gap &gap() const {
-        if (!transport) {
-            error("bad handle to underlying transport");
-        }
-        return transport->getGap();
-    }
-    Gap &gap() {
-        if (!transport) {
-            error("bad handle to underlying transport");
-        }
-        return transport->getGap();
-    }
+    const Gap &gap() const;
+    Gap &gap();
 
     /*
      * Accessors to GATT Server. Please refer to GattServer.h. All GATTServer related
      * functionality requires going through this accessor.
      */
-    const GattServer& gattServer() const {
-        if (!transport) {
-            error("bad handle to underlying transport");
-        }
-        return transport->getGattServer();
-    }
-    GattServer& gattServer() {
-        if (!transport) {
-            error("bad handle to underlying transport");
-        }
-        return transport->getGattServer();
-    }
+    const GattServer& gattServer() const;
+    GattServer& gattServer();
 
     /*
      * Accessors to GATT Client. Please refer to GattClient.h. All GATTClient related
      * functionality requires going through this accessor.
      */
-    const GattClient& gattClient() const {
-        if (!transport) {
-            error("bad handle to underlying transport");
-        }
-        return transport->getGattClient();
-    }
-    GattClient& gattClient() {
-        if (!transport) {
-            error("bad handle to underlying transport");
-        }
-        return transport->getGattClient();
-    }
+    const GattClient& gattClient() const;
+    GattClient& gattClient();
 
     /*
      * Accessors to Security Manager. Please refer to SecurityManager.h. All
      * SecurityManager related functionality requires going through this
      * accessor.
      */
-    const SecurityManager& securityManager() const {
-        if (!transport) {
-            error("bad handle to underlying transport");
-        }
-        return transport->getSecurityManager();
-    }
-    SecurityManager& securityManager() {
-        if (!transport) {
-            error("bad handle to underlying transport");
-        }
-        return transport->getSecurityManager();
-    }
+    const SecurityManager& securityManager() const;
+    SecurityManager& securityManager();
 
     /**
      * Yield control to the BLE stack or to other tasks waiting for events. This
@@ -151,15 +145,9 @@
      * returning (to service the stack). This is not always interchangeable with
      * WFE().
      */
-    void waitForEvent(void) {
-        if (!transport) {
-            error("bad handle to underlying transport");
-        }
-        transport->waitForEvent();
-    }
+    void waitForEvent(void);
 
 public:
-    typedef unsigned InstanceID_t;
     static const InstanceID_t DEFAULT_INSTANCE = 0;
 #ifndef YOTTA_CFG_BLE_INSTANCES_COUNT
     static const InstanceID_t NUM_INSTANCES = 1;
@@ -194,6 +182,12 @@
      */
     BLE(InstanceID_t instanceID = DEFAULT_INSTANCE);
 
+    /**
+     * Fetch the ID of a BLE instance. Typically there would only be the DEFAULT_INSTANCE.
+     */
+    InstanceID_t getInstanceID(void) const {
+        return instanceID;
+    }
 
     /*
      * Deprecation alert!
@@ -1398,6 +1392,7 @@
     BLE &operator=(const BLE &);
 
 private:
+    InstanceID_t     instanceID;
     BLEInstanceBase *transport; /* the device specific backend */
 };
 
--- a/ble/BLEInstanceBase.h	Mon Nov 02 09:09:06 2015 +0000
+++ b/ble/BLEInstanceBase.h	Mon Nov 02 09:09:07 2015 +0000
@@ -19,6 +19,7 @@
 
 #include "Gap.h"
 #include "ble/SecurityManager.h"
+#include "ble/BLE.h"
 
 /* forward declarations */
 class GattServer;
@@ -31,17 +32,18 @@
 class BLEInstanceBase
 {
 public:
-    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 ble_error_t            init(BLE::InstanceID_t instanceID, BLE::InitializationCompleteCallback_t) = 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 const SecurityManager& getSecurityManager() const = 0;
-    virtual void        waitForEvent(void)         = 0;
+    virtual void                   waitForEvent(void)         = 0;
 };
 
 /**
--- a/ble/blecommon.h	Mon Nov 02 09:09:06 2015 +0000
+++ b/ble/blecommon.h	Mon Nov 02 09:09:07 2015 +0000
@@ -114,16 +114,18 @@
 */
 /**************************************************************************/
 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_UNSPECIFIED             = 9, /**< 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_INITIALIZATION_INCOMPLETE = 9,
+    BLE_ERROR_ALREADY_INITIALIZED       = 10,
+    BLE_ERROR_UNSPECIFIED               = 11, /**< Unknown error. */
 };
 
 /** @brief Default MTU size. */
--- a/module.json	Mon Nov 02 09:09:06 2015 +0000
+++ b/module.json	Mon Nov 02 09:09:07 2015 +0000
@@ -1,6 +1,6 @@
 {
   "name": "ble",
-  "version": "1.0.0",
+  "version": "1.1.0",
   "description": "The BLE module offers a high level abstraction for using Bluetooth Low Energy on multiple platforms.",
   "keywords": [
     "Bluetooth",
--- a/source/BLE.cpp	Mon Nov 02 09:09:06 2015 +0000
+++ b/source/BLE.cpp	Mon Nov 02 09:09:07 2015 +0000
@@ -15,15 +15,16 @@
  */
 
 #include "ble/BLE.h"
+#include "ble/BLEInstanceBase.h"
 
 #if defined(TARGET_OTA_ENABLED)
 #include "ble/services/DFUService.h"
 #endif
 
 ble_error_t
-BLE::init()
+BLE::init(BLE::InitializationCompleteCallback_t callback)
 {
-    ble_error_t err = transport->init();
+    ble_error_t err = transport->init(instanceID, callback);
     if (err != BLE_ERROR_NONE) {
         return err;
     }
@@ -105,7 +106,7 @@
     return badSingleton;
 }
 
-BLE::BLE(InstanceID_t instanceID) : transport()
+BLE::BLE(InstanceID_t instanceIDIn) : instanceID(instanceIDIn), transport()
 {
     static BLEInstanceBase *transportInstances[NUM_INSTANCES];
 
@@ -117,4 +118,113 @@
     } 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