From aa7e4b2da7bb239a61d486466014dbaf4c97075c Mon Sep 17 00:00:00 2001 From: Rohit Grover Date: Tue, 3 Nov 2015 10:55:00 +0000 Subject: [PATCH] BLE::init() should also be able to take a tuple. --- ble/BLE.h | 41 +++++++++++++++++++++++++++++++++-------- ble/BLEInstanceBase.h | 3 ++- source/BLE.cpp | 22 +++++++++++++++++++++- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/ble/BLE.h b/ble/BLE.h index 00bce18..18cbc16 100644 --- a/ble/BLE.h +++ b/ble/BLE.h @@ -41,16 +41,28 @@ public: typedef unsigned InstanceID_t; /** The type returned by BLE::getInstanceID(). */ /** - * The function signature for callbacks for initialization completion. + * The context provided to init-completion-callbacks (see init() below). + * * @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); + struct InitializationCompleteCallbackContext { + BLE& ble; /* Reference to the BLE object which has been initialized */ + ble_error_t error; /* Error status of the initialization. It is set to BLE_ERROR_NONE initialization completed successfully. */ + }; + + /** + * The signature for function-pointer like callbacks for initialization-completion. + * + * @note There are two versions of init(). In addition to the simple + * function-pointer, init() can also take a tuple as its + * callback target. In case of the latter, the following declaration doesn't apply. + */ + typedef void (*InitializationCompleteCallback_t)(InitializationCompleteCallbackContext *context); /** * Initialize the BLE controller. This should be called before using @@ -72,18 +84,31 @@ public: * @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 If init() returns BLE_ERROR_NONE, the underlying stack must invoke + * the initialization completion callback at some point. + * + * @note 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. + * + * @note There are two versions of init(). In addition to the simple + * function-pointer, init() can also take an tuple as its + * callback target. */ ble_error_t init(InitializationCompleteCallback_t callback = NULL); + /** + * An alternate declaration for init(). This one takes an tuple as its + * callback target. + */ + template + ble_error_t init(T *object, void (T::*initCompleteCallback)(InitializationCompleteCallbackContext *context)); + /** * @return true if initialization has completed for the underlying BLE * transport. diff --git a/ble/BLEInstanceBase.h b/ble/BLEInstanceBase.h index e8cfc0d..7949ed4 100644 --- a/ble/BLEInstanceBase.h +++ b/ble/BLEInstanceBase.h @@ -32,7 +32,8 @@ class GattClient; class BLEInstanceBase { public: - virtual ble_error_t init(BLE::InstanceID_t instanceID, BLE::InitializationCompleteCallback_t) = 0; + virtual ble_error_t init(BLE::InstanceID_t instanceID, + FunctionPointerWithContext initCallback) = 0; virtual bool hasInitialized(void) const = 0; virtual ble_error_t shutdown(void) = 0; virtual const char * getVersion(void) = 0; diff --git a/source/BLE.cpp b/source/BLE.cpp index 0328ef9..eb673c1 100644 --- a/source/BLE.cpp +++ b/source/BLE.cpp @@ -22,8 +22,28 @@ #endif ble_error_t -BLE::init(BLE::InitializationCompleteCallback_t callback) +BLE::init(BLE::InitializationCompleteCallback_t initCompleteCallback) { + FunctionPointerWithContextcallback(initCompleteCallback); + ble_error_t err = transport->init(instanceID, callback); + if (err != BLE_ERROR_NONE) { + return err; + } + + /* Platforms enabled for DFU should introduce the DFU Service into + * applications automatically. */ +#if defined(TARGET_OTA_ENABLED) + static DFUService dfu(*this); // defined static so that the object remains alive +#endif // TARGET_OTA_ENABLED + + return BLE_ERROR_NONE; +} + +template +ble_error_t +BLE::init(T *object, void (T::*initCompleteCallback)(InitializationCompleteCallbackContext *)) +{ + FunctionPointerWithContextcallback(object, initCompleteCallback); ble_error_t err = transport->init(instanceID, callback); if (err != BLE_ERROR_NONE) { return err;