Lancaster University's fork of the mbed BLE API. Lives on github, https://github.com/lancaster-university/BLE_API

Dependents:   microbit-dal microbit-dal microbit-ble-open microbit-dal ... more

Fork of BLE_API by Bluetooth Low Energy

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GattClient.h Source File

GattClient.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef __GATT_CLIENT_H__
00018 #define __GATT_CLIENT_H__
00019 
00020 #include "Gap.h"
00021 #include "GattAttribute.h"
00022 #include "ServiceDiscovery.h"
00023 #include "CharacteristicDescriptorDiscovery.h"
00024 
00025 #include "GattCallbackParamTypes.h"
00026 
00027 #include "CallChainOfFunctionPointersWithContext.h"
00028 
00029 class GattClient {
00030 public:
00031     typedef FunctionPointerWithContext<const GattReadCallbackParams*>  ReadCallback_t;
00032     typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams*>  ReadCallbackChain_t;
00033 
00034     enum WriteOp_t {
00035         GATT_OP_WRITE_REQ = 0x01,  /**< Write request. */
00036         GATT_OP_WRITE_CMD = 0x02,  /**< Write command. */
00037     };
00038 
00039     typedef FunctionPointerWithContext<const GattWriteCallbackParams*>  WriteCallback_t;
00040     typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*>  WriteCallbackChain_t;
00041 
00042     typedef FunctionPointerWithContext<const GattHVXCallbackParams*>  HVXCallback_t;
00043     typedef CallChainOfFunctionPointersWithContext<const GattHVXCallbackParams*>  HVXCallbackChain_t;
00044 
00045     typedef FunctionPointerWithContext<const GattClient *>  GattClientShutdownCallback_t;
00046     typedef CallChainOfFunctionPointersWithContext<const GattClient *>  GattClientShutdownCallbackChain_t;
00047 
00048     /*
00049      * The following functions are meant to be overridden in the platform-specific sub-class.
00050      */
00051 public:
00052     /**
00053      * Launch service discovery. Once launched, application callbacks will be
00054      * invoked for matching services or characteristics. isServiceDiscoveryActive()
00055      * can be used to determine status, and a termination callback (if one was set up)
00056      * will be invoked at the end. Service discovery can be terminated prematurely,
00057      * if needed, using terminateServiceDiscovery().
00058      *
00059      * @param  connectionHandle
00060      *           Handle for the connection with the peer.
00061      * @param  sc
00062      *           This is the application callback for a matching service. Taken as
00063      *           NULL by default. Note: service discovery may still be active
00064      *           when this callback is issued; calling asynchronous BLE-stack
00065      *           APIs from within this application callback might cause the
00066      *           stack to abort service discovery. If this becomes an issue, it
00067      *           may be better to make a local copy of the discoveredService and
00068      *           wait for service discovery to terminate before operating on the
00069      *           service.
00070      * @param  cc
00071      *           This is the application callback for a matching characteristic.
00072      *           Taken as NULL by default. Note: service discovery may still be
00073      *           active when this callback is issued; calling asynchronous
00074      *           BLE-stack APIs from within this application callback might cause
00075      *           the stack to abort service discovery. If this becomes an issue,
00076      *           it may be better to make a local copy of the discoveredCharacteristic
00077      *           and wait for service discovery to terminate before operating on the
00078      *           characteristic.
00079      * @param  matchingServiceUUID
00080      *           UUID-based filter for specifying a service in which the application is
00081      *           interested. By default it is set as the wildcard UUID_UNKNOWN,
00082      *           in which case it matches all services. If characteristic-UUID
00083      *           filter (below) is set to the wildcard value, then a service
00084      *           callback will be invoked for the matching service (or for every
00085      *           service if the service filter is a wildcard).
00086      * @param  matchingCharacteristicUUIDIn
00087      *           UUID-based filter for specifying characteristic in which the application
00088      *           is interested. By default it is set as the wildcard UUID_UKNOWN
00089      *           to match against any characteristic. If both service-UUID
00090      *           filter and characteristic-UUID filter are used with non-wildcard
00091      *           values, then only a single characteristic callback is
00092      *           invoked for the matching characteristic.
00093      *
00094      * @note     Using wildcard values for both service-UUID and characteristic-
00095      *           UUID will result in complete service discovery: callbacks being
00096      *           called for every service and characteristic.
00097      *
00098      * @note     Providing NULL for the characteristic callback will result in
00099      *           characteristic discovery being skipped for each matching
00100      *           service. This allows for an inexpensive method to discover only
00101      *           services.
00102      *
00103      * @return
00104      *           BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error.
00105      */
00106     virtual ble_error_t launchServiceDiscovery(Gap::Handle_t                               connectionHandle,
00107                                                ServiceDiscovery::ServiceCallback_t          sc                           = NULL,
00108                                                ServiceDiscovery::CharacteristicCallback_t   cc                           = NULL,
00109                                                const UUID                                 &matchingServiceUUID          = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
00110                                                const UUID                                 &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) {
00111         /* Avoid compiler warnings about unused variables. */
00112         (void)connectionHandle;
00113         (void)sc;
00114         (void)cc;
00115         (void)matchingServiceUUID;
00116         (void)matchingCharacteristicUUIDIn;
00117 
00118         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00119     }
00120 
00121     /**
00122      * Launch service discovery for services. Once launched, service discovery will remain
00123      * active with service-callbacks being issued back into the application for matching
00124      * services. isServiceDiscoveryActive() can be used to
00125      * determine status, and a termination callback (if set up) will be invoked
00126      * at the end. Service discovery can be terminated prematurely, if needed,
00127      * using terminateServiceDiscovery().
00128      *
00129      * @param  connectionHandle
00130      *           Handle for the connection with the peer.
00131      * @param  sc
00132      *           This is the application callback for a matching service. Note: service discovery may still be active
00133      *           when this callback is issued; calling asynchronous BLE-stack
00134      *           APIs from within this application callback might cause the
00135      *           stack to abort service discovery. If this becomes an issue, it
00136      *           may be better to make a local copy of the discoveredService and
00137      *           wait for service discovery to terminate before operating on the
00138      *           service.
00139      * @param  matchingServiceUUID
00140      *           UUID-based filter for specifying a service in which the application is
00141      *           interested. By default it is set as the wildcard UUID_UNKNOWN,
00142      *           in which case it matches all services.
00143      *
00144      * @return
00145      *           BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error.
00146      */
00147     virtual ble_error_t discoverServices(Gap::Handle_t                        connectionHandle,
00148                                          ServiceDiscovery::ServiceCallback_t   callback,
00149                                          const UUID                          &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) {
00150         return launchServiceDiscovery(connectionHandle, callback, NULL, matchingServiceUUID); /* We take advantage of the property
00151                                                                 * that providing NULL for the characteristic callback will result in
00152                                                                 * characteristic discovery being skipped for each matching
00153                                                                 * service. This allows for an inexpensive method to discover only
00154                                                                 * services. Porters are free to override this. */
00155     }
00156 
00157     /**
00158      * Launch service discovery for services. Once launched, service discovery will remain
00159      * active with service-callbacks being issued back into the application for matching
00160      * services. isServiceDiscoveryActive() can be used to
00161      * determine status, and a termination callback (if set up) will be invoked
00162      * at the end. Service discovery can be terminated prematurely, if needed,
00163      * using terminateServiceDiscovery().
00164      *
00165      * @param  connectionHandle
00166      *           Handle for the connection with the peer.
00167      * @param  sc
00168      *           This is the application callback for a matching service. Note: service discovery may still be active
00169      *           when this callback is issued; calling asynchronous BLE-stack
00170      *           APIs from within this application callback might cause the
00171      *           stack to abort service discovery. If this becomes an issue, it
00172      *           may be better to make a local copy of the discoveredService and
00173      *           wait for service discovery to terminate before operating on the
00174      *           service.
00175      * @param  startHandle, endHandle
00176      *           Handle range within which to limit the search.
00177      *
00178      * @return
00179      *           BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error.
00180      */
00181     virtual ble_error_t discoverServices(Gap::Handle_t                        connectionHandle,
00182                                          ServiceDiscovery::ServiceCallback_t   callback,
00183                                          GattAttribute::Handle_t              startHandle,
00184                                          GattAttribute::Handle_t              endHandle) {
00185         /* Avoid compiler warnings about unused variables. */
00186         (void)connectionHandle;
00187         (void)callback;
00188         (void)startHandle;
00189         (void)endHandle;
00190 
00191         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00192     }
00193 
00194     /**
00195      * Is service-discovery currently active?
00196      */
00197     virtual bool isServiceDiscoveryActive(void) const {
00198         return false; /* Requesting action from porters: override this API if this capability is supported. */
00199     }
00200 
00201     /**
00202      * Terminate an ongoing service discovery. This should result in an
00203      * invocation of TerminationCallback if service-discovery is active.
00204      */
00205     virtual void terminateServiceDiscovery(void) {
00206         /* Requesting action from porters: override this API if this capability is supported. */
00207     }
00208 
00209     /* Initiate a GATT Client read procedure by attribute-handle. */
00210     virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const {
00211         /* Avoid compiler warnings about unused variables. */
00212         (void)connHandle;
00213         (void)attributeHandle;
00214         (void)offset;
00215 
00216         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00217     }
00218 
00219     /**
00220      * Initiate a GATT Client write procedure.
00221      *
00222      * @param[in] cmd
00223      *              Command can be either a write-request (which generates a
00224      *              matching response from the peripheral), or a write-command
00225      *              (which doesn't require the connected peer to respond).
00226      * @param[in] connHandle
00227      *              Connection handle.
00228      * @param[in] attributeHandle
00229      *              Handle for the target attribtue on the remote GATT server.
00230      * @param[in] length
00231      *              Length of the new value.
00232      * @param[in] value
00233      *              New value being written.
00234      */
00235     virtual ble_error_t write(GattClient::WriteOp_t    cmd,
00236                               Gap::Handle_t            connHandle,
00237                               GattAttribute::Handle_t  attributeHandle,
00238                               size_t                   length,
00239                               const uint8_t           *value) const {
00240         /* Avoid compiler warnings about unused variables. */
00241         (void)cmd;
00242         (void)connHandle;
00243         (void)attributeHandle;
00244         (void)length;
00245         (void)value;
00246 
00247         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00248     }
00249 
00250     /* Event callback handlers. */
00251 public:
00252     /**
00253      * Set up a callback for read response events.
00254      * It is possible to remove registered callbacks using
00255      * onDataRead().detach(callbackToRemove)
00256      */
00257     void onDataRead(ReadCallback_t callback) {
00258         onDataReadCallbackChain.add(callback);
00259     }
00260 
00261     /**
00262      * @brief provide access to the callchain of read callbacks
00263      * It is possible to register callbacks using onDataRead().add(callback);
00264      * It is possible to unregister callbacks using onDataRead().detach(callback)
00265      * @return The read callbacks chain
00266      */
00267     ReadCallbackChain_t& onDataRead() {
00268         return onDataReadCallbackChain;
00269     }
00270 
00271     /**
00272      * Set up a callback for write response events.
00273      * It is possible to remove registered callbacks using
00274      * onDataWritten().detach(callbackToRemove).
00275      * @Note: Write commands (issued using writeWoResponse) don't generate a response.
00276      */
00277     void onDataWritten(WriteCallback_t callback) {
00278         onDataWriteCallbackChain.add(callback);
00279     }
00280 
00281     /**
00282      * @brief provide access to the callchain of data written callbacks
00283      * It is possible to register callbacks using onDataWritten().add(callback);
00284      * It is possible to unregister callbacks using onDataWritten().detach(callback)
00285      * @return The data written callbacks chain
00286      */
00287     WriteCallbackChain_t& onDataWritten() {
00288         return onDataWriteCallbackChain;
00289     }
00290 
00291     /**
00292      * Set up a callback for write response events.
00293      * @Note: Write commands (issued using writeWoResponse) don't generate a response.
00294      *
00295      * @note: This API is now *deprecated* and will be dropped in the future.
00296      * Please use onDataWritten() instead.
00297      */
00298     void onDataWrite(WriteCallback_t callback) {
00299         onDataWritten(callback);
00300     }
00301 
00302     /**
00303      * Set up a callback for when serviceDiscovery terminates.
00304      */
00305     virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) {
00306         (void)callback; /* Avoid compiler warnings about ununsed variables. */
00307 
00308         /* Requesting action from porters: override this API if this capability is supported. */
00309     }
00310 
00311     /**
00312      * @brief launch discovery of descriptors for a given characteristic
00313      * @details This function will discover all descriptors available for a
00314      * specific characteristic.
00315      *
00316      * @param characteristic[in] The characteristic targeted by this discovery
00317      * procedure
00318      * @param discoveryCallback[in] User function called each time a descriptor
00319      * is found during the procedure.
00320      * @param terminationCallback[in] User provided function which will be called
00321      * once the discovery procedure is terminating. This will get called when all
00322      * the descriptors have been discovered or if an error occur during the discovery
00323      * procedure.
00324      *
00325      * @return
00326      *   BLE_ERROR_NONE if characteristic descriptor discovery is launched
00327      *   successfully; else an appropriate error.
00328      */
00329     virtual ble_error_t discoverCharacteristicDescriptors(
00330         const DiscoveredCharacteristic& characteristic,
00331         const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
00332         const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) {
00333         (void) characteristic;
00334         (void) discoveryCallback;
00335         (void) terminationCallback;
00336         /* Requesting action from porter(s): override this API if this capability is supported. */
00337         return BLE_ERROR_NOT_IMPLEMENTED;
00338     }
00339 
00340     /**
00341      * @brief Indicate if the discovery of characteristic descriptors is active for a given characteristic
00342      * or not.
00343      * @param characteristic[in] The characteristic concerned by the descriptors discovery.
00344      * @return true if a descriptors discovery is active for the characteristic in input; otherwise false.
00345      */
00346     virtual bool isCharacteristicDescriptorDiscoveryActive(const DiscoveredCharacteristic& characteristic) const
00347      {
00348         (void) characteristic;
00349         return false; /* Requesting action from porter(s): override this API if this capability is supported. */
00350     }
00351 
00352     /**
00353      * @brief Terminate an ongoing characteristic descriptor discovery.
00354      * @detail This should result in an invocation of the TerminationCallback if
00355      * the characteristic descriptor discovery is active.
00356      * @param characteristic[in] The characteristic on which the running descriptors
00357      * discovery should be stopped.
00358      */
00359     virtual void terminateCharacteristicDescriptorDiscovery(const DiscoveredCharacteristic& characteristic) {
00360         /* Requesting action from porter(s): override this API if this capability is supported. */
00361         (void) characteristic;
00362     }
00363 
00364     /**
00365      * Set up a callback for when the GATT client receives an update event
00366      * corresponding to a change in the value of a characteristic on the remote
00367      * GATT server.
00368      * It is possible to remove registered callbacks using onHVX().detach(callbackToRemove).
00369      */
00370     void onHVX(HVXCallback_t callback) {
00371         onHVXCallbackChain.add(callback);
00372     }
00373 
00374     /**
00375      * Setup a callback to be invoked to notify the user application that the
00376      * GattClient instance is about to shutdown (possibly as a result of a call
00377      * to BLE::shutdown()).
00378      *
00379      * @Note: It is possible to chain together multiple onShutdown callbacks
00380      * (potentially from different modules of an application) to be notified
00381      * before the GattClient is shutdown.
00382      *
00383      * @Note: It is also possible to set up a callback into a member function of
00384      * some object.
00385      *
00386      * @Note It is possible to unregister a callback using onShutdown().detach(callback)
00387      */
00388     void onShutdown(const GattClientShutdownCallback_t& callback) {
00389         shutdownCallChain.add(callback);
00390     }
00391     template <typename T>
00392     void onShutdown(T *objPtr, void (T::*memberPtr)(void)) {
00393         shutdownCallChain.add(objPtr, memberPtr);
00394     }
00395 
00396     /**
00397      * @brief provide access to the callchain of shutdown event callbacks
00398      * It is possible to register callbacks using onShutdown().add(callback);
00399      * It is possible to unregister callbacks using onShutdown().detach(callback)
00400      * @return The shutdown event callbacks chain
00401      */
00402     GattClientShutdownCallbackChain_t& onShutdown() {
00403         return shutdownCallChain;
00404     }
00405 
00406     /**
00407      * @brief provide access to the callchain of HVX callbacks
00408      * It is possible to register callbacks using onHVX().add(callback);
00409      * It is possible to unregister callbacks using onHVX().detach(callback)
00410      * @return The HVX callbacks chain
00411      */
00412     HVXCallbackChain_t& onHVX() {
00413         return onHVXCallbackChain;
00414     }
00415 
00416 public:
00417     /**
00418      * Notify all registered onShutdown callbacks that the GattClient is
00419      * about to be shutdown and clear all GattClient state of the
00420      * associated object.
00421      *
00422      * This function is meant to be overridden in the platform-specific
00423      * sub-class. Nevertheless, the sub-class is only expected to reset its
00424      * state and not the data held in GattClient members. This shall be achieved
00425      * by a call to GattClient::reset() from the sub-class' reset()
00426      * implementation.
00427      *
00428      * @return BLE_ERROR_NONE on success.
00429      */
00430     virtual ble_error_t reset(void) {
00431         /* Notify that the instance is about to shutdown */
00432         shutdownCallChain.call(this);
00433         shutdownCallChain.clear();
00434 
00435         onDataReadCallbackChain.clear();
00436         onDataWriteCallbackChain.clear();
00437         onHVXCallbackChain.clear();
00438 
00439         return BLE_ERROR_NONE;
00440     }
00441 
00442 protected:
00443     GattClient() {
00444         /* Empty */
00445     }
00446 
00447     /* Entry points for the underlying stack to report events back to the user. */
00448 public:
00449     void processReadResponse(const GattReadCallbackParams *params) {
00450         onDataReadCallbackChain(params);
00451     }
00452 
00453     void processWriteResponse(const GattWriteCallbackParams *params) {
00454         onDataWriteCallbackChain(params);
00455     }
00456 
00457     void processHVXEvent(const GattHVXCallbackParams *params) {
00458         if (onHVXCallbackChain) {
00459             onHVXCallbackChain(params);
00460         }
00461     }
00462 
00463 protected:
00464     ReadCallbackChain_t               onDataReadCallbackChain;
00465     WriteCallbackChain_t              onDataWriteCallbackChain;
00466     HVXCallbackChain_t                onHVXCallbackChain;
00467     GattClientShutdownCallbackChain_t shutdownCallChain;
00468 
00469 private:
00470     /* Disallow copy and assignment. */
00471     GattClient(const GattClient &);
00472     GattClient& operator=(const GattClient &);
00473 };
00474 
00475 #endif // ifndef __GATT_CLIENT_H__