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 GattServer.h Source File

GattServer.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_SERVER_H__
00018 #define __GATT_SERVER_H__
00019 
00020 #include "Gap.h"
00021 #include "GattService.h"
00022 #include "GattAttribute.h"
00023 #include "GattServerEvents.h"
00024 #include "GattCallbackParamTypes.h"
00025 #include "CallChainOfFunctionPointersWithContext.h"
00026 
00027 class GattServer {
00028 public:
00029     /* Event callback handlers. */
00030     typedef FunctionPointerWithContext<unsigned>  DataSentCallback_t;
00031     typedef CallChainOfFunctionPointersWithContext<unsigned>  DataSentCallbackChain_t;
00032 
00033     typedef FunctionPointerWithContext<const GattWriteCallbackParams*>  DataWrittenCallback_t;
00034     typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*>  DataWrittenCallbackChain_t;
00035 
00036     typedef FunctionPointerWithContext<const GattReadCallbackParams*>  DataReadCallback_t;
00037     typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams *>  DataReadCallbackChain_t;
00038 
00039     typedef FunctionPointerWithContext<const GattServer *>  GattServerShutdownCallback_t;
00040     typedef CallChainOfFunctionPointersWithContext<const GattServer *>  GattServerShutdownCallbackChain_t;
00041 
00042     typedef FunctionPointerWithContext<const GattSysAttrMissingCallbackParams*>  SysAttrMissingCallback_t;
00043     typedef CallChainOfFunctionPointersWithContext<const GattSysAttrMissingCallbackParams*>  SysAttrMissingCallbackChain_t;
00044 
00045     typedef FunctionPointerWithContext<GattAttribute::Handle_t>  EventCallback_t;
00046 
00047 protected:
00048     GattServer() :
00049         serviceCount(0),
00050         characteristicCount(0),
00051         dataSentCallChain(),
00052         dataWrittenCallChain(),
00053         dataReadCallChain(),
00054         sysAttrMissingCallChain(),
00055         updatesEnabledCallback(NULL),
00056         updatesDisabledCallback(NULL),
00057         confirmationReceivedCallback(NULL) {
00058         /* empty */
00059     }
00060 
00061     /*
00062      * The following functions are meant to be overridden in the platform-specific sub-class.
00063      */
00064 public:
00065 
00066     /**
00067      * Add a service declaration to the local server ATT table. Also add the
00068      * characteristics contained within.
00069      */
00070     virtual ble_error_t addService(GattService &service) {
00071         /* Avoid compiler warnings about unused variables. */
00072         (void)service;
00073 
00074         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00075     }
00076 
00077     /**
00078      * Read the value of a characteristic from the local GATT server.
00079      * @param[in]     attributeHandle
00080      *                  Attribute handle for the value attribute of the characteristic.
00081      * @param[out]    buffer
00082      *                  A buffer to hold the value being read.
00083      * @param[in/out] lengthP
00084      *                  Length of the buffer being supplied. If the attribute
00085      *                  value is longer than the size of the supplied buffer,
00086      *                  this variable will hold upon return the total attribute value length
00087      *                  (excluding offset). The application may use this
00088      *                  information to allocate a suitable buffer size.
00089      *
00090      * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
00091      */
00092     virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) {
00093         /* Avoid compiler warnings about unused variables. */
00094         (void)attributeHandle;
00095         (void)buffer;
00096         (void)lengthP;
00097 
00098         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00099     }
00100 
00101     /**
00102      * Read the value of a characteristic from the local GATT server.
00103      * @param[in]     connectionHandle
00104      *                  Connection handle.
00105      * @param[in]     attributeHandle
00106      *                  Attribute handle for the value attribute of the characteristic.
00107      * @param[out]    buffer
00108      *                  A buffer to hold the value being read.
00109      * @param[in/out] lengthP
00110      *                  Length of the buffer being supplied. If the attribute
00111      *                  value is longer than the size of the supplied buffer,
00112      *                  this variable will hold upon return the total attribute value length
00113      *                  (excluding offset). The application may use this
00114      *                  information to allocate a suitable buffer size.
00115      *
00116      * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
00117      *
00118      * @note This API is a version of the above, with an additional connection handle
00119      *     parameter to allow fetches for connection-specific multivalued
00120      *     attributes (such as the CCCDs).
00121      */
00122     virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) {
00123         /* Avoid compiler warnings about unused variables. */
00124         (void)connectionHandle;
00125         (void)attributeHandle;
00126         (void)buffer;
00127         (void)lengthP;
00128 
00129         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00130     }
00131 
00132     /**
00133      * Update the value of a characteristic on the local GATT server.
00134      *
00135      * @param[in] attributeHandle
00136      *              Handle for the value attribute of the characteristic.
00137      * @param[in] value
00138      *              A pointer to a buffer holding the new value.
00139      * @param[in] size
00140      *              Size of the new value (in bytes).
00141      * @param[in] localOnly
00142      *              Should this update be kept on the local
00143      *              GATT server regardless of the state of the
00144      *              notify/indicate flag in the CCCD for this
00145      *              Characteristic? If set to true, no notification
00146      *              or indication is generated.
00147      *
00148      * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
00149      */
00150     virtual ble_error_t write(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false) {
00151         /* Avoid compiler warnings about unused variables. */
00152         (void)attributeHandle;
00153         (void)value;
00154         (void)size;
00155         (void)localOnly;
00156 
00157         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00158     }
00159 
00160     /**
00161      * Update the value of a characteristic on the local GATT server. A version
00162      * of the same as the above, with a connection handle parameter to allow updates
00163      * for connection-specific multivalued attributes (such as the CCCDs).
00164      *
00165      * @param[in] connectionHandle
00166      *              Connection handle.
00167      * @param[in] attributeHandle
00168      *              Handle for the value attribute of the characteristic.
00169      * @param[in] value
00170      *              A pointer to a buffer holding the new value.
00171      * @param[in] size
00172      *              Size of the new value (in bytes).
00173      * @param[in] localOnly
00174      *              Should this update be kept on the local
00175      *              GattServer regardless of the state of the
00176      *              notify/indicate flag in the CCCD for this
00177      *              Characteristic? If set to true, no notification
00178      *              or indication is generated.
00179      *
00180      * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
00181      */
00182     virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false) {
00183         /* Avoid compiler warnings about unused variables. */
00184         (void)connectionHandle;
00185         (void)attributeHandle;
00186         (void)value;
00187         (void)size;
00188         (void)localOnly;
00189 
00190         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00191     }
00192 
00193     /**
00194      * Perform an explicit BLE notification of a given attribute.
00195      *
00196      * @param[in] attributeHandle
00197      *              Handle for the value attribute of the Characteristic.
00198      * @param[in] value
00199      *              A pointer to a buffer holding the new value
00200      * @param[in] size
00201      *              Size of the new value (in bytes).
00202      *
00203      * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
00204      */
00205     virtual ble_error_t notify(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size)
00206     {
00207         (void)attributeHandle;
00208         (void)value;
00209         (void)size;
00210 
00211         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
00212     }
00213 
00214     /**
00215      * Determine the updates-enabled status (notification or indication) for the current connection from a characteristic's CCCD.
00216      *
00217      * @param       characteristic
00218      *                The characteristic.
00219      * @param[out]  enabledP
00220      *                Upon return, *enabledP is true if updates are enabled, else false.
00221      *
00222      * @return BLE_ERROR_NONE if the connection and handle are found. False otherwise.
00223      */
00224     virtual ble_error_t areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP) {
00225         /* Avoid compiler warnings about unused variables. */
00226         (void)characteristic;
00227         (void)enabledP;
00228 
00229         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00230     }
00231 
00232     /**
00233      * Determine the connection-specific updates-enabled status (notification or indication) from a characteristic's CCCD.
00234      *
00235      * @param       connectionHandle
00236      *                The connection handle.
00237      * @param[out]  enabledP
00238      *                Upon return, *enabledP is true if updates are enabled, else false.
00239      *
00240      * @param  characteristic
00241      *           The characteristic.
00242      *
00243      * @return BLE_ERROR_NONE if the connection and handle are found. False otherwise.
00244      */
00245     virtual ble_error_t areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP) {
00246         /* Avoid compiler warnings about unused variables. */
00247         (void)connectionHandle;
00248         (void)characteristic;
00249         (void)enabledP;
00250 
00251         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00252     }
00253 
00254     /**
00255      * A virtual function to allow underlying stacks to indicate if they support
00256      * onDataRead(). It should be overridden to return true as applicable.
00257      */
00258     virtual bool isOnDataReadAvailable() const {
00259         return false; /* Requesting action from porters: override this API if this capability is supported. */
00260     }
00261 
00262     /*
00263      * APIs with non-virtual implementations.
00264      */
00265 public:
00266     /**
00267      * Add a callback for the GATT event DATA_SENT (which is triggered when
00268      * updates are sent out by GATT in the form of notifications).
00269      *
00270      * @Note: It is possible to chain together multiple onDataSent callbacks
00271      * (potentially from different modules of an application) to receive updates
00272      * to characteristics.
00273      *
00274      * @Note: It is also possible to set up a callback into a member function of
00275      * some object.
00276      */
00277     void onDataSent(const DataSentCallback_t& callback) {dataSentCallChain.add(callback);}
00278     template <typename T>
00279     void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) {
00280         dataSentCallChain.add(objPtr, memberPtr);
00281     }
00282 
00283     /**
00284      * @brief get the callback chain called when the event DATA_EVENT is triggered.
00285      */
00286     DataSentCallbackChain_t& onDataSent() {
00287         return dataSentCallChain;
00288     }
00289 
00290     /**
00291      * Set up a callback for when an attribute has its value updated by or at the
00292      * connected peer. For a peripheral, this callback is triggered when the local
00293      * GATT server has an attribute updated by a write command from the peer.
00294      * For a central, this callback is triggered when a response is received for
00295      * a write request.
00296      *
00297      * @Note: It is possible to chain together multiple onDataWritten callbacks
00298      * (potentially from different modules of an application) to receive updates
00299      * to characteristics. Many services, such as DFU and UART, add their own
00300      * onDataWritten callbacks behind the scenes to trap interesting events.
00301      *
00302      * @Note: It is also possible to set up a callback into a member function of
00303      * some object.
00304      *
00305      * @Note It is possible to unregister a callback using onDataWritten().detach(callback)
00306      */
00307     void onDataWritten(const DataWrittenCallback_t& callback) {dataWrittenCallChain.add(callback);}
00308     template <typename T>
00309     void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) {
00310         dataWrittenCallChain.add(objPtr, memberPtr);
00311     }
00312 
00313     /**
00314      * @brief provide access to the callchain of data written event callbacks
00315      * It is possible to register callbacks using onDataWritten().add(callback);
00316      * It is possible to unregister callbacks using onDataWritten().detach(callback)
00317      * @return The data written event callbacks chain
00318      */
00319     DataWrittenCallbackChain_t& onDataWritten() {
00320         return dataWrittenCallChain;
00321     }
00322 
00323     /**
00324      * Set up a callback for when asystem descriptor (CCCD) is missing.
00325      * This may be raised in response to a BLE profile change om a bonded connection.
00326      * This callback provides the opportunity for user applications to restore
00327      * CCCD state at the appropriate time.
00328      *
00329      * @Note: It is possible to chain together multiple onSysAttrMissing callbacks
00330      * (potentially from different modules of an application), although it is unlikely
00331      * that this will be beneficial.
00332      *
00333      * @Note: It is also possible to set up a callback into a member function of
00334      * some object.
00335      *
00336      * @Note It is possible to unregister a callback using onSysAttrMissing().detach(callback)
00337      */
00338     void onSysAttrMissing(const SysAttrMissingCallback_t& callback) {sysAttrMissingCallChain.add(callback);}
00339     template <typename T>
00340     void onSysAttrMissing(T *objPtr, void (T::*memberPtr)(const GattSysAttrMissingCallbackParams* connectionHandle)) {
00341         sysAttrMissingCallChain.add(objPtr, memberPtr);
00342     }
00343 
00344     /**
00345      * @brief provide access to the callchain of data written event callbacks
00346      * It is possible to register callbacks using onDataWritten().add(callback);
00347      * It is possible to unregister callbacks using onDataWritten().detach(callback)
00348      * @return The data written event callbacks chain
00349      */
00350     SysAttrMissingCallbackChain_t& onSysAttrMissing() {
00351         return sysAttrMissingCallChain;
00352     }
00353     /**
00354      * Setup a callback to be invoked on the peripheral when an attribute is
00355      * being read by a remote client.
00356      *
00357      * @Note: This functionality may not be available on all underlying stacks.
00358      * You could use GattCharacteristic::setReadAuthorizationCallback() as an
00359      * alternative. Refer to isOnDataReadAvailable().
00360      *
00361      * @Note: It is possible to chain together multiple onDataRead callbacks
00362      * (potentially from different modules of an application) to receive updates
00363      * to characteristics. Services may add their own onDataRead callbacks
00364      * behind the scenes to trap interesting events.
00365      *
00366      * @Note: It is also possible to set up a callback into a member function of
00367      * some object.
00368      *
00369      * @Note It is possible to unregister a callback using onDataRead().detach(callback)
00370      *
00371      * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available;
00372      *         else BLE_ERROR_NONE.
00373      */
00374     ble_error_t onDataRead(const DataReadCallback_t& callback) {
00375         if (!isOnDataReadAvailable()) {
00376             return BLE_ERROR_NOT_IMPLEMENTED;
00377         }
00378 
00379         dataReadCallChain.add(callback);
00380         return BLE_ERROR_NONE;
00381     }
00382     template <typename T>
00383     ble_error_t onDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) {
00384         if (!isOnDataReadAvailable()) {
00385             return BLE_ERROR_NOT_IMPLEMENTED;
00386         }
00387 
00388         dataReadCallChain.add(objPtr, memberPtr);
00389         return BLE_ERROR_NONE;
00390     }
00391 
00392     /**
00393      * @brief provide access to the callchain of data read event callbacks
00394      * It is possible to register callbacks using onDataRead().add(callback);
00395      * It is possible to unregister callbacks using onDataRead().detach(callback)
00396      * @return The data read event callbacks chain
00397      */
00398     DataReadCallbackChain_t& onDataRead() {
00399         return dataReadCallChain;
00400     }
00401 
00402     /**
00403      * Setup a callback to be invoked to notify the user application that the
00404      * GattServer instance is about to shutdown (possibly as a result of a call
00405      * to BLE::shutdown()).
00406      *
00407      * @Note: It is possible to chain together multiple onShutdown callbacks
00408      * (potentially from different modules of an application) to be notified
00409      * before the GattServer is shutdown.
00410      *
00411      * @Note: It is also possible to set up a callback into a member function of
00412      * some object.
00413      *
00414      * @Note It is possible to unregister a callback using onShutdown().detach(callback)
00415      */
00416     void onShutdown(const GattServerShutdownCallback_t& callback) {
00417         shutdownCallChain.add(callback);
00418     }
00419     template <typename T>
00420     void onShutdown(T *objPtr, void (T::*memberPtr)(void)) {
00421         shutdownCallChain.add(objPtr, memberPtr);
00422     }
00423 
00424     /**
00425      * @brief provide access to the callchain of shutdown event callbacks
00426      * It is possible to register callbacks using onShutdown().add(callback);
00427      * It is possible to unregister callbacks using onShutdown().detach(callback)
00428      * @return The shutdown event callbacks chain
00429      */
00430     GattServerShutdownCallbackChain_t& onShutdown() {
00431         return shutdownCallChain;
00432     }
00433 
00434     /**
00435      * Set up a callback for when notifications or indications are enabled for a
00436      * characteristic on the local GATT server.
00437      */
00438     void onUpdatesEnabled(EventCallback_t callback) {updatesEnabledCallback = callback;}
00439 
00440     /**
00441      * Set up a callback for when notifications or indications are disabled for a
00442      * characteristic on the local GATT server.
00443      */
00444     void onUpdatesDisabled(EventCallback_t callback) {updatesDisabledCallback = callback;}
00445 
00446     /**
00447      * Set up a callback for when the GATT server receives a response for an
00448      * indication event sent previously.
00449      */
00450     void onConfirmationReceived(EventCallback_t callback) {confirmationReceivedCallback = callback;}
00451 
00452     /* Entry points for the underlying stack to report events back to the user. */
00453 protected:
00454     void handleSysAttrMissingEvent(const GattSysAttrMissingCallbackParams *params) {
00455         sysAttrMissingCallChain.call(params);
00456     }
00457 
00458     void handleDataWrittenEvent(const GattWriteCallbackParams *params) {
00459         dataWrittenCallChain.call(params);
00460     }
00461 
00462     void handleDataReadEvent(const GattReadCallbackParams *params) {
00463         dataReadCallChain.call(params);
00464     }
00465 
00466     void handleEvent(GattServerEvents::gattEvent_e  type, GattAttribute::Handle_t attributeHandle) {
00467         switch (type) {
00468             case GattServerEvents::GATT_EVENT_UPDATES_ENABLED:
00469                 if (updatesEnabledCallback) {
00470                     updatesEnabledCallback(attributeHandle);
00471                 }
00472                 break;
00473             case GattServerEvents::GATT_EVENT_UPDATES_DISABLED:
00474                 if (updatesDisabledCallback) {
00475                     updatesDisabledCallback(attributeHandle);
00476                 }
00477                 break;
00478             case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED:
00479                 if (confirmationReceivedCallback) {
00480                     confirmationReceivedCallback(attributeHandle);
00481                 }
00482                 break;
00483             default:
00484                 break;
00485         }
00486     }
00487 
00488     void handleDataSentEvent(unsigned count) {
00489         dataSentCallChain.call(count);
00490     }
00491 
00492 public:
00493     /**
00494      * Notify all registered onShutdown callbacks that the GattServer is
00495      * about to be shutdown and clear all GattServer state of the
00496      * associated object.
00497      *
00498      * This function is meant to be overridden in the platform-specific
00499      * sub-class. Nevertheless, the sub-class is only expected to reset its
00500      * state and not the data held in GattServer members. This shall be achieved
00501      * by a call to GattServer::reset() from the sub-class' reset()
00502      * implementation.
00503      *
00504      * @return BLE_ERROR_NONE on success.
00505      */
00506     virtual ble_error_t reset(void) {
00507         /* Notify that the instance is about to shutdown */
00508         shutdownCallChain.call(this);
00509         shutdownCallChain.clear();
00510 
00511         serviceCount = 0;
00512         characteristicCount = 0;
00513 
00514         dataSentCallChain.clear();
00515         dataWrittenCallChain.clear();
00516         dataReadCallChain.clear();
00517         sysAttrMissingCallChain.clear();
00518         updatesEnabledCallback       = NULL;
00519         updatesDisabledCallback      = NULL;
00520         confirmationReceivedCallback = NULL;
00521 
00522         return BLE_ERROR_NONE;
00523     }
00524 
00525 protected:
00526     uint8_t serviceCount;
00527     uint8_t characteristicCount;
00528 
00529 private:
00530     DataSentCallbackChain_t           dataSentCallChain;
00531     DataWrittenCallbackChain_t        dataWrittenCallChain;
00532     DataReadCallbackChain_t           dataReadCallChain;
00533     SysAttrMissingCallbackChain_t     sysAttrMissingCallChain;
00534     GattServerShutdownCallbackChain_t shutdownCallChain;
00535     EventCallback_t                   updatesEnabledCallback;
00536     EventCallback_t                   updatesDisabledCallback;
00537     EventCallback_t                   confirmationReceivedCallback;
00538 
00539 private:
00540     /* Disallow copy and assignment. */
00541     GattServer(const GattServer &);
00542     GattServer& operator=(const GattServer &);
00543 };
00544 
00545 #endif // ifndef __GATT_SERVER_H__