High level Bluetooth Low Energy API and radio abstraction layer

Fork of BLE_API by Bluetooth Low Energy

Revision:
993:4d62b7967c11
Parent:
992:ca834f7ae8ed
Child:
1042:21a86ac7f5b1
diff -r ca834f7ae8ed -r 4d62b7967c11 ble/GattClient.h
--- a/ble/GattClient.h	Wed Dec 02 10:29:44 2015 +0000
+++ b/ble/GattClient.h	Wed Dec 02 10:29:44 2015 +0000
@@ -23,18 +23,23 @@
 
 #include "GattCallbackParamTypes.h"
 
+#include "CallChainOfFunctionPointersWithContext.h"
+
 class GattClient {
 public:
-    typedef void (*ReadCallback_t)(const GattReadCallbackParams *params);
+    typedef FunctionPointerWithContext<const GattReadCallbackParams*> ReadCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams*> ReadCallbackChain_t;
 
     enum WriteOp_t {
-        GATT_OP_WRITE_REQ = 0x01,  /**< Write Request. */
-        GATT_OP_WRITE_CMD = 0x02,  /**< Write Command. */
+        GATT_OP_WRITE_REQ = 0x01,  /**< Write request. */
+        GATT_OP_WRITE_CMD = 0x02,  /**< Write command. */
     };
 
-    typedef void (*WriteCallback_t)(const GattWriteCallbackParams *params);
+    typedef FunctionPointerWithContext<const GattWriteCallbackParams*> WriteCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*> WriteCallbackChain_t;
 
-    typedef void (*HVXCallback_t)(const GattHVXCallbackParams *params);
+    typedef FunctionPointerWithContext<const GattHVXCallbackParams*> HVXCallback_t;
+    typedef CallChainOfFunctionPointersWithContext<const GattHVXCallbackParams*> HVXCallbackChain_t;
 
     /*
      * The following functions are meant to be overridden in the platform-specific sub-class.
@@ -42,48 +47,48 @@
 public:
     /**
      * Launch service discovery. Once launched, application callbacks will be
-     * invoked for matching services/characteristics. isServiceDiscoveryActive()
-     * can be used to determine status; and a termination callback (if setup)
-     * will be invoked at the end. Service discovery can be terminated prematurely
-     * if needed using terminateServiceDiscovery().
+     * invoked for matching services or characteristics. isServiceDiscoveryActive()
+     * can be used to determine status, and a termination callback (if one was set up)
+     * will be invoked at the end. Service discovery can be terminated prematurely,
+     * if needed, using terminateServiceDiscovery().
      *
      * @param  connectionHandle
      *           Handle for the connection with the peer.
      * @param  sc
-     *           This is the application callback for matching service. Taken as
+     *           This is the application callback for a matching service. Taken as
      *           NULL by default. Note: service discovery may still be active
      *           when this callback is issued; calling asynchronous BLE-stack
      *           APIs from within this application callback might cause the
      *           stack to abort service discovery. If this becomes an issue, it
-     *           may be better to make local copy of the discoveredService and
+     *           may be better to make a local copy of the discoveredService and
      *           wait for service discovery to terminate before operating on the
      *           service.
      * @param  cc
-     *           This is the application callback for matching characteristic.
+     *           This is the application callback for a matching characteristic.
      *           Taken as NULL by default. Note: service discovery may still be
      *           active when this callback is issued; calling asynchronous
      *           BLE-stack APIs from within this application callback might cause
      *           the stack to abort service discovery. If this becomes an issue,
-     *           it may be better to make local copy of the discoveredCharacteristic
+     *           it may be better to make a local copy of the discoveredCharacteristic
      *           and wait for service discovery to terminate before operating on the
      *           characteristic.
      * @param  matchingServiceUUID
-     *           UUID based filter for specifying a service in which the application is
+     *           UUID-based filter for specifying a service in which the application is
      *           interested. By default it is set as the wildcard UUID_UNKNOWN,
      *           in which case it matches all services. If characteristic-UUID
      *           filter (below) is set to the wildcard value, then a service
      *           callback will be invoked for the matching service (or for every
      *           service if the service filter is a wildcard).
      * @param  matchingCharacteristicUUIDIn
-     *           UUID based filter for specifying characteristic in which the application
+     *           UUID-based filter for specifying characteristic in which the application
      *           is interested. By default it is set as the wildcard UUID_UKNOWN
      *           to match against any characteristic. If both service-UUID
-     *           filter and characteristic-UUID filter are used with non- wildcard
+     *           filter and characteristic-UUID filter are used with non-wildcard
      *           values, then only a single characteristic callback is
      *           invoked for the matching characteristic.
      *
      * @note     Using wildcard values for both service-UUID and characteristic-
-     *           UUID will result in complete service discovery--callbacks being
+     *           UUID will result in complete service discovery: callbacks being
      *           called for every service and characteristic.
      *
      * @note     Providing NULL for the characteristic callback will result in
@@ -99,36 +104,36 @@
                                                ServiceDiscovery::CharacteristicCallback_t  cc                           = NULL,
                                                const UUID                                 &matchingServiceUUID          = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
                                                const UUID                                 &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) {
-        /* avoid compiler warnings about unused variables */
+        /* Avoid compiler warnings about unused variables. */
         (void)connectionHandle;
         (void)sc;
         (void)cc;
         (void)matchingServiceUUID;
         (void)matchingCharacteristicUUIDIn;
 
-        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
     }
 
     /**
      * Launch service discovery for services. Once launched, service discovery will remain
      * active with service-callbacks being issued back into the application for matching
      * services. isServiceDiscoveryActive() can be used to
-     * determine status; and a termination callback (if setup) will be invoked
-     * at the end. Service discovery can be terminated prematurely if needed
+     * determine status, and a termination callback (if set up) will be invoked
+     * at the end. Service discovery can be terminated prematurely, if needed,
      * using terminateServiceDiscovery().
      *
      * @param  connectionHandle
      *           Handle for the connection with the peer.
      * @param  sc
-     *           This is the application callback for matching service. Note: service discovery may still be active
+     *           This is the application callback for a matching service. Note: service discovery may still be active
      *           when this callback is issued; calling asynchronous BLE-stack
      *           APIs from within this application callback might cause the
      *           stack to abort service discovery. If this becomes an issue, it
-     *           may be better to make local copy of the discoveredService and
+     *           may be better to make a local copy of the discoveredService and
      *           wait for service discovery to terminate before operating on the
      *           service.
      * @param  matchingServiceUUID
-     *           UUID based filter for specifying a service in which the application is
+     *           UUID-based filter for specifying a service in which the application is
      *           interested. By default it is set as the wildcard UUID_UNKNOWN,
      *           in which case it matches all services.
      *
@@ -142,29 +147,29 @@
                                                                 * that providing NULL for the characteristic callback will result in
                                                                 * characteristic discovery being skipped for each matching
                                                                 * service. This allows for an inexpensive method to discover only
-                                                                * services. Porter(s) are free to override this. */
+                                                                * services. Porters are free to override this. */
     }
 
     /**
      * Launch service discovery for services. Once launched, service discovery will remain
      * active with service-callbacks being issued back into the application for matching
      * services. isServiceDiscoveryActive() can be used to
-     * determine status; and a termination callback (if setup) will be invoked
-     * at the end. Service discovery can be terminated prematurely if needed
+     * determine status, and a termination callback (if set up) will be invoked
+     * at the end. Service discovery can be terminated prematurely, if needed,
      * using terminateServiceDiscovery().
      *
      * @param  connectionHandle
      *           Handle for the connection with the peer.
      * @param  sc
-     *           This is the application callback for matching service. Note: service discovery may still be active
+     *           This is the application callback for a matching service. Note: service discovery may still be active
      *           when this callback is issued; calling asynchronous BLE-stack
      *           APIs from within this application callback might cause the
      *           stack to abort service discovery. If this becomes an issue, it
-     *           may be better to make local copy of the discoveredService and
+     *           may be better to make a local copy of the discoveredService and
      *           wait for service discovery to terminate before operating on the
      *           service.
      * @param  startHandle, endHandle
-     *           Handle range within which to limit the search
+     *           Handle range within which to limit the search.
      *
      * @return
      *           BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error.
@@ -173,91 +178,115 @@
                                          ServiceDiscovery::ServiceCallback_t  callback,
                                          GattAttribute::Handle_t              startHandle,
                                          GattAttribute::Handle_t              endHandle) {
-        /* avoid compiler warnings about unused variables */
+        /* Avoid compiler warnings about unused variables. */
         (void)connectionHandle;
         (void)callback;
         (void)startHandle;
         (void)endHandle;
 
-        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
     }
 
     /**
      * Is service-discovery currently active?
      */
     virtual bool isServiceDiscoveryActive(void) const {
-        return false; /* Requesting action from porter(s): override this API if this capability is supported. */
+        return false; /* Requesting action from porters: override this API if this capability is supported. */
     }
 
     /**
-     * Terminate an ongoing service-discovery. This should result in an
-     * invocation of the TerminationCallback if service-discovery is active.
+     * Terminate an ongoing service discovery. This should result in an
+     * invocation of TerminationCallback if service-discovery is active.
      */
     virtual void terminateServiceDiscovery(void) {
-        /* Requesting action from porter(s): override this API if this capability is supported. */
+        /* Requesting action from porters: override this API if this capability is supported. */
     }
 
-    /* Initiate a Gatt Client read procedure by attribute-handle. */
+    /* Initiate a GATT Client read procedure by attribute-handle. */
     virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const {
-        /* avoid compiler warnings about unused variables */
+        /* Avoid compiler warnings about unused variables. */
         (void)connHandle;
         (void)attributeHandle;
         (void)offset;
 
-        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
     }
 
     /**
      * Initiate a GATT Client write procedure.
      *
      * @param[in] cmd
-     *              Command can be either a write-request (which generates a
-     *              matching response from the peripheral), or a write-command,
-     *              which doesn't require the connected peer to respond.
+     *              Command can be either a write-request (which generates a 
+     *              matching response from the peripheral), or a write-command 
+     *              (which doesn't require the connected peer to respond).
      * @param[in] connHandle
      *              Connection handle.
      * @param[in] attributeHandle
-     *              handle for the target attribtue on the remote GATT server.
+     *              Handle for the target attribtue on the remote GATT server.
      * @param[in] length
-     *              length of the new value.
+     *              Length of the new value.
      * @param[in] value
-     *              new value being written.
+     *              New value being written.
      */
     virtual ble_error_t write(GattClient::WriteOp_t    cmd,
                               Gap::Handle_t            connHandle,
                               GattAttribute::Handle_t  attributeHandle,
                               size_t                   length,
                               const uint8_t           *value) const {
-        /* avoid compiler warnings about unused variables */
+        /* Avoid compiler warnings about unused variables. */
         (void)cmd;
         (void)connHandle;
         (void)attributeHandle;
         (void)length;
         (void)value;
 
-        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
+        return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
     }
 
     /* Event callback handlers. */
 public:
     /**
-     * Setup a callback for read response events.
+     * Set up a callback for read response events. 
+     * It is possible to remove registered callbacks using 
+     * onDataRead().detach(callbackToRemove)
      */
     void onDataRead(ReadCallback_t callback) {
-        onDataReadCallback = callback;
+        onDataReadCallbackChain.add(callback);
+    }
+
+    /**
+     * @brief provide access to the callchain of read callbacks
+     * It is possible to register callbacks using onDataRead().add(callback);
+     * It is possible to unregister callbacks using onDataRead().detach(callback) 
+     * @return The read callbacks chain
+     */
+    ReadCallbackChain_t& onDataRead() {
+        return onDataReadCallbackChain;
     }
 
     /**
-     * Setup a callback for write response events.
-     * @Note: write commands (issued using writeWoResponse) don't generate a response.
+     * Set up a callback for write response events.
+     * It is possible to remove registered callbacks using 
+     * onDataWritten().detach(callbackToRemove).
+     * @Note: Write commands (issued using writeWoResponse) don't generate a response.
      */
     void onDataWritten(WriteCallback_t callback) {
-        onDataWriteCallback = callback;
+        onDataWriteCallbackChain.add(callback);
     }
 
     /**
-     * Setup a callback for write response events.
-     * @Note: write commands (issued using writeWoResponse) don't generate a response.
+     * @brief provide access to the callchain of data written callbacks
+     * It is possible to register callbacks using onDataWritten().add(callback);
+     * It is possible to unregister callbacks using onDataWritten().detach(callback) 
+     * @return The data written callbacks chain
+     */
+    WriteCallbackChain_t& onDataWritten() { 
+        return onDataWriteCallbackChain;
+    }
+
+    /**
+     * Set up a callback for write response events.
+     * @Note: Write commands (issued using writeWoResponse) don't generate a response.
      *
      * @note: This API is now *deprecated* and will be dropped in the future.
      * Please use onDataWritten() instead.
@@ -267,55 +296,63 @@
     }
 
     /**
-     * Setup callback for when serviceDiscovery terminates.
+     * Set up a callback for when serviceDiscovery terminates.
      */
     virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) {
-        (void)callback; /* avoid compiler warnings about ununsed variables */
+        (void)callback; /* Avoid compiler warnings about ununsed variables. */
 
-        /* Requesting action from porter(s): override this API if this capability is supported. */
+        /* Requesting action from porters: override this API if this capability is supported. */
     }
 
     /**
-     * Setup a callback for when GattClient receives an update event
-     * corresponding to a change in value of a characteristic on the remote
-     * GattServer.
+     * Set up a callback for when the GATT client receives an update event
+     * corresponding to a change in the value of a characteristic on the remote
+     * GATT server.
+     * It is possible to remove registered callbacks using onHVX().detach(callbackToRemove).
      */
     void onHVX(HVXCallback_t callback) {
-        onHVXCallback = callback;
+        onHVXCallbackChain.add(callback);
+    }
+
+
+    /**
+     * @brief provide access to the callchain of HVX callbacks
+     * It is possible to register callbacks using onHVX().add(callback);
+     * It is possible to unregister callbacks using onHVX().detach(callback) 
+     * @return The HVX callbacks chain
+     */
+    HVXCallbackChain_t& onHVX() { 
+        return onHVXCallbackChain;
     }
 
 protected:
     GattClient() {
-        /* empty */
+        /* Empty */
     }
 
     /* Entry points for the underlying stack to report events back to the user. */
 public:
     void processReadResponse(const GattReadCallbackParams *params) {
-        if (onDataReadCallback) {
-            onDataReadCallback(params);
-        }
+        onDataReadCallbackChain(params);
     }
 
     void processWriteResponse(const GattWriteCallbackParams *params) {
-        if (onDataWriteCallback) {
-            onDataWriteCallback(params);
-        }
+        onDataWriteCallbackChain(params);
     }
 
     void processHVXEvent(const GattHVXCallbackParams *params) {
-        if (onHVXCallback) {
-            onHVXCallback(params);
+        if (onHVXCallbackChain) {
+            onHVXCallbackChain(params);
         }
     }
 
 protected:
-    ReadCallback_t  onDataReadCallback;
-    WriteCallback_t onDataWriteCallback;
-    HVXCallback_t   onHVXCallback;
+    ReadCallbackChain_t  onDataReadCallbackChain;
+    WriteCallbackChain_t onDataWriteCallbackChain;
+    HVXCallbackChain_t   onHVXCallbackChain;
 
 private:
-    /* disallow copy and assignment */
+    /* Disallow copy and assignment. */
     GattClient(const GattClient &);
     GattClient& operator=(const GattClient &);
 };