BLE FORK

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 
00030     /* Event callback handlers. */
00031     typedef FunctionPointerWithContext<unsigned>  DataSentCallback_t;
00032     typedef CallChainOfFunctionPointersWithContext<unsigned>  DataSentCallbackChain_t;
00033 
00034     typedef FunctionPointerWithContext<const GattWriteCallbackParams*>  DataWrittenCallback_t;
00035     typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*>  DataWrittenCallbackChain_t;    
00036 
00037     typedef FunctionPointerWithContext<const GattReadCallbackParams*>  DataReadCallback_t;
00038     typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams *>  DataReadCallbackChain_t;
00039 
00040     typedef FunctionPointerWithContext<GattAttribute::Handle_t>  EventCallback_t;
00041 
00042 protected:
00043     GattServer() :
00044         serviceCount(0),
00045         characteristicCount(0),
00046         dataSentCallChain(),
00047         dataWrittenCallChain(),
00048         dataReadCallChain(),
00049         updatesEnabledCallback(NULL),
00050         updatesDisabledCallback(NULL),
00051         confirmationReceivedCallback(NULL) {
00052         /* empty */
00053     }
00054 
00055     /*
00056      * The following functions are meant to be overridden in the platform-specific sub-class.
00057      */
00058 public:
00059 
00060     /**
00061      * Add a service declaration to the local server ATT table. Also add the
00062      * characteristics contained within.
00063      */
00064     virtual ble_error_t addService(GattService &service) {
00065         /* Avoid compiler warnings about unused variables. */
00066         (void)service;
00067 
00068         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00069     }
00070 
00071     /**
00072      * Read the value of a characteristic from the local GATT server.
00073      * @param[in]     attributeHandle
00074      *                  Attribute handle for the value attribute of the characteristic.
00075      * @param[out]    buffer
00076      *                  A buffer to hold the value being read.
00077      * @param[in/out] lengthP
00078      *                  Length of the buffer being supplied. If the attribute
00079      *                  value is longer than the size of the supplied buffer,
00080      *                  this variable will hold upon return the total attribute value length
00081      *                  (excluding offset). The application may use this
00082      *                  information to allocate a suitable buffer size.
00083      *
00084      * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
00085      */
00086     virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) {
00087         /* Avoid compiler warnings about unused variables. */
00088         (void)attributeHandle;
00089         (void)buffer;
00090         (void)lengthP;
00091 
00092         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00093     }
00094 
00095     /**
00096      * Read the value of a characteristic from the local GATT server.
00097      * @param[in]     connectionHandle
00098      *                  Connection handle.
00099      * @param[in]     attributeHandle
00100      *                  Attribute handle for the value attribute of the characteristic.
00101      * @param[out]    buffer
00102      *                  A buffer to hold the value being read.
00103      * @param[in/out] lengthP
00104      *                  Length of the buffer being supplied. If the attribute
00105      *                  value is longer than the size of the supplied buffer,
00106      *                  this variable will hold upon return the total attribute value length
00107      *                  (excluding offset). The application may use this
00108      *                  information to allocate a suitable buffer size.
00109      *
00110      * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
00111      *
00112      * @note This API is a version of the above, with an additional connection handle
00113      *     parameter to allow fetches for connection-specific multivalued
00114      *     attributes (such as the CCCDs).
00115      */
00116     virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) {
00117         /* Avoid compiler warnings about unused variables. */
00118         (void)connectionHandle;
00119         (void)attributeHandle;
00120         (void)buffer;
00121         (void)lengthP;
00122 
00123         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00124     }
00125 
00126     /**
00127      * Update the value of a characteristic on the local GATT server.
00128      *
00129      * @param[in] attributeHandle
00130      *              Handle for the value attribute of the characteristic.
00131      * @param[in] value
00132      *              A pointer to a buffer holding the new value.
00133      * @param[in] size
00134      *              Size of the new value (in bytes).
00135      * @param[in] localOnly
00136      *              Should this update be kept on the local
00137      *              GATT server regardless of the state of the
00138      *              notify/indicate flag in the CCCD for this
00139      *              Characteristic? If set to true, no notification
00140      *              or indication is generated.
00141      *
00142      * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
00143      */
00144     virtual ble_error_t write(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false) {
00145         /* Avoid compiler warnings about unused variables. */
00146         (void)attributeHandle;
00147         (void)value;
00148         (void)size;
00149         (void)localOnly;
00150 
00151         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00152     }
00153 
00154     /**
00155      * Update the value of a characteristic on the local GATT server. A version
00156      * of the same as the above, with a connection handle parameter to allow updates
00157      * for connection-specific multivalued attributes (such as the CCCDs).
00158      *
00159      * @param[in] connectionHandle
00160      *              Connection handle.
00161      * @param[in] attributeHandle
00162      *              Handle for the value attribute of the characteristic.
00163      * @param[in] value
00164      *              A pointer to a buffer holding the new value.
00165      * @param[in] size
00166      *              Size of the new value (in bytes).
00167      * @param[in] localOnly
00168      *              Should this update be kept on the local
00169      *              GattServer regardless of the state of the
00170      *              notify/indicate flag in the CCCD for this
00171      *              Characteristic? If set to true, no notification
00172      *              or indication is generated.
00173      *
00174      * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
00175      */
00176     virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false) {
00177         /* Avoid compiler warnings about unused variables. */
00178         (void)connectionHandle;
00179         (void)attributeHandle;
00180         (void)value;
00181         (void)size;
00182         (void)localOnly;
00183 
00184         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00185     }
00186 
00187     /**
00188      * Determine the updates-enabled status (notification or indication) for the current connection from a characteristic's CCCD.
00189      *
00190      * @param       characteristic
00191      *                The characteristic.
00192      * @param[out]  enabledP
00193      *                Upon return, *enabledP is true if updates are enabled, else false.
00194      *
00195      * @return BLE_ERROR_NONE if the connection and handle are found. False otherwise.
00196      */
00197     virtual ble_error_t areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP) {
00198         /* Avoid compiler warnings about unused variables. */
00199         (void)characteristic;
00200         (void)enabledP;
00201 
00202         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00203     }
00204 
00205     /**
00206      * Determine the connection-specific updates-enabled status (notification or indication) from a characteristic's CCCD.
00207      *
00208      * @param       connectionHandle
00209      *                The connection handle.
00210      * @param[out]  enabledP
00211      *                Upon return, *enabledP is true if updates are enabled, else false.
00212      *
00213      * @param  characteristic
00214      *           The characteristic.
00215      *
00216      * @return BLE_ERROR_NONE if the connection and handle are found. False otherwise.
00217      */
00218     virtual ble_error_t areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP) {
00219         /* Avoid compiler warnings about unused variables. */
00220         (void)connectionHandle;
00221         (void)characteristic;
00222         (void)enabledP;
00223 
00224         return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
00225     }
00226 
00227     /**
00228      * A virtual function to allow underlying stacks to indicate if they support
00229      * onDataRead(). It should be overridden to return true as applicable.
00230      */
00231     virtual bool isOnDataReadAvailable() const {
00232         return false; /* Requesting action from porters: override this API if this capability is supported. */
00233     }
00234 
00235     /*
00236      * APIs with non-virtual implementations.
00237      */
00238 public:
00239     /**
00240      * Add a callback for the GATT event DATA_SENT (which is triggered when
00241      * updates are sent out by GATT in the form of notifications).
00242      *
00243      * @Note: It is possible to chain together multiple onDataSent callbacks
00244      * (potentially from different modules of an application) to receive updates
00245      * to characteristics.
00246      *
00247      * @Note: It is also possible to set up a callback into a member function of
00248      * some object.
00249      */
00250     void onDataSent(const DataSentCallback_t& callback) {dataSentCallChain.add(callback);}
00251     template <typename T>
00252     void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) {
00253         dataSentCallChain.add(objPtr, memberPtr);
00254     }
00255 
00256     /**
00257      * @brief get the callback chain called when the event DATA_EVENT is triggered. 
00258      */
00259     DataSentCallbackChain_t& onDataSent() { 
00260         return dataSentCallChain;
00261     }
00262 
00263     /**
00264      * Set up a callback for when an attribute has its value updated by or at the
00265      * connected peer. For a peripheral, this callback is triggered when the local
00266      * GATT server has an attribute updated by a write command from the peer.
00267      * For a central, this callback is triggered when a response is received for
00268      * a write request.
00269      *
00270      * @Note: It is possible to chain together multiple onDataWritten callbacks
00271      * (potentially from different modules of an application) to receive updates
00272      * to characteristics. Many services, such as DFU and UART, add their own
00273      * onDataWritten callbacks behind the scenes to trap interesting events.
00274      *
00275      * @Note: It is also possible to set up a callback into a member function of
00276      * some object.
00277      * 
00278      * @Note It is possible to unregister a callback using onDataWritten().detach(callback)
00279      */
00280     void onDataWritten(const DataWrittenCallback_t& callback) {dataWrittenCallChain.add(callback);}
00281     template <typename T>
00282     void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) {
00283         dataWrittenCallChain.add(objPtr, memberPtr);
00284     }
00285 
00286     /**
00287      * @brief provide access to the callchain of data written event callbacks
00288      * It is possible to register callbacks using onDataWritten().add(callback);
00289      * It is possible to unregister callbacks using onDataWritten().detach(callback) 
00290      * @return The data written event callbacks chain
00291      */    
00292     DataWrittenCallbackChain_t& onDataWritten() {
00293         return dataWrittenCallChain;
00294     }
00295 
00296     /**
00297      * Setup a callback to be invoked on the peripheral when an attribute is
00298      * being read by a remote client.
00299      *
00300      * @Note: This functionality may not be available on all underlying stacks.
00301      * You could use GattCharacteristic::setReadAuthorizationCallback() as an
00302      * alternative. Refer to isOnDataReadAvailable().
00303      *
00304      * @Note: It is possible to chain together multiple onDataRead callbacks
00305      * (potentially from different modules of an application) to receive updates
00306      * to characteristics. Services may add their own onDataRead callbacks
00307      * behind the scenes to trap interesting events.
00308      *
00309      * @Note: It is also possible to set up a callback into a member function of
00310      * some object.
00311      *
00312      * @Note It is possible to unregister a callback using onDataRead().detach(callback)
00313      *
00314      * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available;
00315      *         else BLE_ERROR_NONE.
00316      */
00317     ble_error_t onDataRead(const DataReadCallback_t& callback) {
00318         if (!isOnDataReadAvailable()) {
00319             return BLE_ERROR_NOT_IMPLEMENTED;
00320         }
00321 
00322         dataReadCallChain.add(callback);
00323         return BLE_ERROR_NONE;
00324     }
00325     template <typename T>
00326     ble_error_t onDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) {
00327         if (!isOnDataReadAvailable()) {
00328             return BLE_ERROR_NOT_IMPLEMENTED;
00329         }
00330 
00331         dataReadCallChain.add(objPtr, memberPtr);
00332         return BLE_ERROR_NONE;
00333     }
00334 
00335     /**
00336      * @brief provide access to the callchain of data read event callbacks
00337      * It is possible to register callbacks using onDataRead().add(callback);
00338      * It is possible to unregister callbacks using onDataRead().detach(callback) 
00339      * @return The data read event callbacks chain
00340      */
00341     DataReadCallbackChain_t& onDataRead() {
00342         return dataReadCallChain;
00343     }
00344 
00345     /**
00346      * Set up a callback for when notifications or indications are enabled for a
00347      * characteristic on the local GATT server.
00348      */
00349     void onUpdatesEnabled(EventCallback_t callback) {updatesEnabledCallback = callback;}
00350 
00351     /**
00352      * Set up a callback for when notifications or indications are disabled for a
00353      * characteristic on the local GATT server.
00354      */
00355     void onUpdatesDisabled(EventCallback_t callback) {updatesDisabledCallback = callback;}
00356 
00357     /**
00358      * Set up a callback for when the GATT server receives a response for an
00359      * indication event sent previously.
00360      */
00361     void onConfirmationReceived(EventCallback_t callback) {confirmationReceivedCallback = callback;}
00362 
00363     /* Entry points for the underlying stack to report events back to the user. */
00364 protected:
00365     void handleDataWrittenEvent(const GattWriteCallbackParams *params) {
00366         dataWrittenCallChain.call(params);
00367     }
00368 
00369     void handleDataReadEvent(const GattReadCallbackParams *params) {
00370         dataReadCallChain.call(params);
00371     }
00372 
00373     void handleEvent(GattServerEvents::gattEvent_e  type, GattAttribute::Handle_t attributeHandle) {
00374         switch (type) {
00375             case GattServerEvents::GATT_EVENT_UPDATES_ENABLED:
00376                 if (updatesEnabledCallback) {
00377                     updatesEnabledCallback(attributeHandle);
00378                 }
00379                 break;
00380             case GattServerEvents::GATT_EVENT_UPDATES_DISABLED:
00381                 if (updatesDisabledCallback) {
00382                     updatesDisabledCallback(attributeHandle);
00383                 }
00384                 break;
00385             case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED:
00386                 if (confirmationReceivedCallback) {
00387                     confirmationReceivedCallback(attributeHandle);
00388                 }
00389                 break;
00390             default:
00391                 break;
00392         }
00393     }
00394 
00395     void handleDataSentEvent(unsigned count) {
00396         dataSentCallChain.call(count);
00397     }
00398 
00399 protected:
00400     uint8_t serviceCount;
00401     uint8_t characteristicCount;
00402 
00403 private:
00404     DataSentCallbackChain_t    dataSentCallChain;
00405     DataWrittenCallbackChain_t dataWrittenCallChain;
00406     DataReadCallbackChain_t    dataReadCallChain;
00407     EventCallback_t            updatesEnabledCallback;
00408     EventCallback_t            updatesDisabledCallback;
00409     EventCallback_t            confirmationReceivedCallback;
00410 
00411 private:
00412     /* Disallow copy and assignment. */
00413     GattServer(const GattServer &);
00414     GattServer& operator=(const GattServer &);
00415 };
00416 
00417 #endif // ifndef __GATT_SERVER_H__