Ollie Ford / BLE_API

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