just a fork

Fork of BLE_API by Bluetooth Low Energy

Committer:
vcoubard
Date:
Mon Jan 11 08:51:37 2016 +0000
Revision:
1062:a3fd424b73ca
Parent:
1052:b55e1ad3e1b3
Child:
1063:187f9929cb60
Synchronized with git rev b817cf3e
Author: Andres Amaya Garcia
Improve API to facilitate full shutdown procedure

The BLE API exposes a shutdown() function in BLE.h. This function is meant to
be overwridden by platform-specific sub-classes to clear all GAP and GATT
state. However, from the platform-specific implementation it is dificult to
achieve this because the Gap, GattClient, GattServer and SecurityManager
components of the API do not expose any functionality to shutdown.

This commit introduces the following changes:

* Add a static member pointer to Gap, GattClient, GattServer and
SecurityManager that is used to keep track of the initialized objects.
* Add a function member cleanup() to Gap, GattClient, GattServer and
SecurityManager to allow easy reset of the instance's state. This function
is meant to be overriden and called from the derived classes to fully clear the
state of the BLE API and the platform-specific implementation.
* Add a static member function shutdown() to Gap, GattClient, GattServer and
SecurityManager. This function shall be called from the shutdown()
overriding BLE::shutdown() for Gap, GattClient, GattServer and SecurityManager
that will in-turn clear the state of each of the components.

**NOTE:** Platform-specific implementations of this API must be modified to
this changes into account.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 710:b2e1a2660ec2 1 /* mbed Microcontroller Library
rgrover1 710:b2e1a2660ec2 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 710:b2e1a2660ec2 3 *
rgrover1 710:b2e1a2660ec2 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 710:b2e1a2660ec2 5 * you may not use this file except in compliance with the License.
rgrover1 710:b2e1a2660ec2 6 * You may obtain a copy of the License at
rgrover1 710:b2e1a2660ec2 7 *
rgrover1 710:b2e1a2660ec2 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 710:b2e1a2660ec2 9 *
rgrover1 710:b2e1a2660ec2 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 710:b2e1a2660ec2 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 710:b2e1a2660ec2 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 710:b2e1a2660ec2 13 * See the License for the specific language governing permissions and
rgrover1 710:b2e1a2660ec2 14 * limitations under the License.
rgrover1 710:b2e1a2660ec2 15 */
rgrover1 710:b2e1a2660ec2 16
rgrover1 710:b2e1a2660ec2 17 #ifndef __GATT_SERVER_H__
rgrover1 710:b2e1a2660ec2 18 #define __GATT_SERVER_H__
rgrover1 710:b2e1a2660ec2 19
rgrover1 710:b2e1a2660ec2 20 #include "Gap.h"
rgrover1 710:b2e1a2660ec2 21 #include "GattService.h"
rgrover1 710:b2e1a2660ec2 22 #include "GattAttribute.h"
rgrover1 710:b2e1a2660ec2 23 #include "GattServerEvents.h"
rgrover1 710:b2e1a2660ec2 24 #include "GattCallbackParamTypes.h"
rgrover1 710:b2e1a2660ec2 25 #include "CallChainOfFunctionPointersWithContext.h"
rgrover1 710:b2e1a2660ec2 26
rgrover1 710:b2e1a2660ec2 27 class GattServer {
rgrover1 710:b2e1a2660ec2 28 public:
vcoubard 1052:b55e1ad3e1b3 29
rgrover1 710:b2e1a2660ec2 30 /* Event callback handlers. */
vcoubard 1052:b55e1ad3e1b3 31 typedef FunctionPointerWithContext<unsigned> DataSentCallback_t;
vcoubard 1052:b55e1ad3e1b3 32 typedef CallChainOfFunctionPointersWithContext<unsigned> DataSentCallbackChain_t;
vcoubard 1052:b55e1ad3e1b3 33
vcoubard 1052:b55e1ad3e1b3 34 typedef FunctionPointerWithContext<const GattWriteCallbackParams*> DataWrittenCallback_t;
vcoubard 1052:b55e1ad3e1b3 35 typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*> DataWrittenCallbackChain_t;
vcoubard 1052:b55e1ad3e1b3 36
vcoubard 1052:b55e1ad3e1b3 37 typedef FunctionPointerWithContext<const GattReadCallbackParams*> DataReadCallback_t;
vcoubard 1052:b55e1ad3e1b3 38 typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams *> DataReadCallbackChain_t;
vcoubard 1052:b55e1ad3e1b3 39
vcoubard 1052:b55e1ad3e1b3 40 typedef FunctionPointerWithContext<GattAttribute::Handle_t> EventCallback_t;
rgrover1 710:b2e1a2660ec2 41
rgrover1 710:b2e1a2660ec2 42 protected:
rgrover1 710:b2e1a2660ec2 43 GattServer() :
rgrover1 710:b2e1a2660ec2 44 serviceCount(0),
rgrover1 710:b2e1a2660ec2 45 characteristicCount(0),
rgrover1 710:b2e1a2660ec2 46 dataSentCallChain(),
rgrover1 710:b2e1a2660ec2 47 dataWrittenCallChain(),
rgrover1 710:b2e1a2660ec2 48 dataReadCallChain(),
rgrover1 710:b2e1a2660ec2 49 updatesEnabledCallback(NULL),
rgrover1 710:b2e1a2660ec2 50 updatesDisabledCallback(NULL),
rgrover1 710:b2e1a2660ec2 51 confirmationReceivedCallback(NULL) {
rgrover1 710:b2e1a2660ec2 52 /* empty */
rgrover1 710:b2e1a2660ec2 53 }
rgrover1 710:b2e1a2660ec2 54
rgrover1 710:b2e1a2660ec2 55 /*
rgrover1 710:b2e1a2660ec2 56 * The following functions are meant to be overridden in the platform-specific sub-class.
rgrover1 710:b2e1a2660ec2 57 */
rgrover1 710:b2e1a2660ec2 58 public:
rgrover1 710:b2e1a2660ec2 59
rgrover1 710:b2e1a2660ec2 60 /**
rgrover1 710:b2e1a2660ec2 61 * Add a service declaration to the local server ATT table. Also add the
rgrover1 710:b2e1a2660ec2 62 * characteristics contained within.
rgrover1 710:b2e1a2660ec2 63 */
rgrover1 734:4872b70437ce 64 virtual ble_error_t addService(GattService &service) {
vcoubard 1048:efb29faf12fc 65 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 66 (void)service;
rgrover1 734:4872b70437ce 67
vcoubard 1048:efb29faf12fc 68 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 69 }
rgrover1 710:b2e1a2660ec2 70
rgrover1 710:b2e1a2660ec2 71 /**
vcoubard 1048:efb29faf12fc 72 * Read the value of a characteristic from the local GATT server.
rgrover1 710:b2e1a2660ec2 73 * @param[in] attributeHandle
rgrover1 710:b2e1a2660ec2 74 * Attribute handle for the value attribute of the characteristic.
rgrover1 710:b2e1a2660ec2 75 * @param[out] buffer
rgrover1 710:b2e1a2660ec2 76 * A buffer to hold the value being read.
rgrover1 710:b2e1a2660ec2 77 * @param[in/out] lengthP
rgrover1 710:b2e1a2660ec2 78 * Length of the buffer being supplied. If the attribute
rgrover1 710:b2e1a2660ec2 79 * value is longer than the size of the supplied buffer,
rgrover1 710:b2e1a2660ec2 80 * this variable will hold upon return the total attribute value length
rgrover1 710:b2e1a2660ec2 81 * (excluding offset). The application may use this
rgrover1 710:b2e1a2660ec2 82 * information to allocate a suitable buffer size.
rgrover1 710:b2e1a2660ec2 83 *
rgrover1 710:b2e1a2660ec2 84 * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
rgrover1 710:b2e1a2660ec2 85 */
rgrover1 710:b2e1a2660ec2 86 virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) {
vcoubard 1048:efb29faf12fc 87 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 88 (void)attributeHandle;
rgrover1 734:4872b70437ce 89 (void)buffer;
rgrover1 734:4872b70437ce 90 (void)lengthP;
rgrover1 734:4872b70437ce 91
vcoubard 1048:efb29faf12fc 92 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 93 }
rgrover1 710:b2e1a2660ec2 94
rgrover1 710:b2e1a2660ec2 95 /**
vcoubard 1048:efb29faf12fc 96 * Read the value of a characteristic from the local GATT server.
rgrover1 710:b2e1a2660ec2 97 * @param[in] connectionHandle
vcoubard 1048:efb29faf12fc 98 * Connection handle.
rgrover1 710:b2e1a2660ec2 99 * @param[in] attributeHandle
rgrover1 710:b2e1a2660ec2 100 * Attribute handle for the value attribute of the characteristic.
rgrover1 710:b2e1a2660ec2 101 * @param[out] buffer
rgrover1 710:b2e1a2660ec2 102 * A buffer to hold the value being read.
rgrover1 710:b2e1a2660ec2 103 * @param[in/out] lengthP
rgrover1 710:b2e1a2660ec2 104 * Length of the buffer being supplied. If the attribute
rgrover1 710:b2e1a2660ec2 105 * value is longer than the size of the supplied buffer,
rgrover1 710:b2e1a2660ec2 106 * this variable will hold upon return the total attribute value length
rgrover1 710:b2e1a2660ec2 107 * (excluding offset). The application may use this
rgrover1 710:b2e1a2660ec2 108 * information to allocate a suitable buffer size.
rgrover1 710:b2e1a2660ec2 109 *
rgrover1 710:b2e1a2660ec2 110 * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
rgrover1 710:b2e1a2660ec2 111 *
vcoubard 1048:efb29faf12fc 112 * @note This API is a version of the above, with an additional connection handle
rgrover1 710:b2e1a2660ec2 113 * parameter to allow fetches for connection-specific multivalued
rgrover1 733:718a3566b4ce 114 * attributes (such as the CCCDs).
rgrover1 710:b2e1a2660ec2 115 */
rgrover1 710:b2e1a2660ec2 116 virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) {
vcoubard 1048:efb29faf12fc 117 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 118 (void)connectionHandle;
rgrover1 734:4872b70437ce 119 (void)attributeHandle;
rgrover1 734:4872b70437ce 120 (void)buffer;
rgrover1 734:4872b70437ce 121 (void)lengthP;
rgrover1 734:4872b70437ce 122
vcoubard 1048:efb29faf12fc 123 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 124 }
rgrover1 710:b2e1a2660ec2 125
rgrover1 710:b2e1a2660ec2 126 /**
vcoubard 1048:efb29faf12fc 127 * Update the value of a characteristic on the local GATT server.
rgrover1 710:b2e1a2660ec2 128 *
rgrover1 710:b2e1a2660ec2 129 * @param[in] attributeHandle
vcoubard 1048:efb29faf12fc 130 * Handle for the value attribute of the characteristic.
rgrover1 710:b2e1a2660ec2 131 * @param[in] value
vcoubard 1048:efb29faf12fc 132 * A pointer to a buffer holding the new value.
rgrover1 710:b2e1a2660ec2 133 * @param[in] size
rgrover1 710:b2e1a2660ec2 134 * Size of the new value (in bytes).
rgrover1 710:b2e1a2660ec2 135 * @param[in] localOnly
rgrover1 710:b2e1a2660ec2 136 * Should this update be kept on the local
vcoubard 1048:efb29faf12fc 137 * GATT server regardless of the state of the
rgrover1 710:b2e1a2660ec2 138 * notify/indicate flag in the CCCD for this
rgrover1 710:b2e1a2660ec2 139 * Characteristic? If set to true, no notification
rgrover1 710:b2e1a2660ec2 140 * or indication is generated.
rgrover1 710:b2e1a2660ec2 141 *
rgrover1 710:b2e1a2660ec2 142 * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
rgrover1 710:b2e1a2660ec2 143 */
rgrover1 734:4872b70437ce 144 virtual ble_error_t write(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false) {
vcoubard 1048:efb29faf12fc 145 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 146 (void)attributeHandle;
rgrover1 734:4872b70437ce 147 (void)value;
rgrover1 734:4872b70437ce 148 (void)size;
rgrover1 734:4872b70437ce 149 (void)localOnly;
rgrover1 734:4872b70437ce 150
vcoubard 1048:efb29faf12fc 151 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 152 }
rgrover1 710:b2e1a2660ec2 153
rgrover1 710:b2e1a2660ec2 154 /**
vcoubard 1048:efb29faf12fc 155 * Update the value of a characteristic on the local GATT server. A version
vcoubard 1048:efb29faf12fc 156 * of the same as the above, with a connection handle parameter to allow updates
rgrover1 733:718a3566b4ce 157 * for connection-specific multivalued attributes (such as the CCCDs).
rgrover1 710:b2e1a2660ec2 158 *
rgrover1 710:b2e1a2660ec2 159 * @param[in] connectionHandle
vcoubard 1048:efb29faf12fc 160 * Connection handle.
rgrover1 710:b2e1a2660ec2 161 * @param[in] attributeHandle
vcoubard 1048:efb29faf12fc 162 * Handle for the value attribute of the characteristic.
rgrover1 710:b2e1a2660ec2 163 * @param[in] value
vcoubard 1048:efb29faf12fc 164 * A pointer to a buffer holding the new value.
rgrover1 710:b2e1a2660ec2 165 * @param[in] size
rgrover1 710:b2e1a2660ec2 166 * Size of the new value (in bytes).
rgrover1 710:b2e1a2660ec2 167 * @param[in] localOnly
rgrover1 710:b2e1a2660ec2 168 * Should this update be kept on the local
rgrover1 710:b2e1a2660ec2 169 * GattServer regardless of the state of the
rgrover1 710:b2e1a2660ec2 170 * notify/indicate flag in the CCCD for this
rgrover1 710:b2e1a2660ec2 171 * Characteristic? If set to true, no notification
rgrover1 710:b2e1a2660ec2 172 * or indication is generated.
rgrover1 710:b2e1a2660ec2 173 *
rgrover1 710:b2e1a2660ec2 174 * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
rgrover1 710:b2e1a2660ec2 175 */
rgrover1 734:4872b70437ce 176 virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false) {
vcoubard 1048:efb29faf12fc 177 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 178 (void)connectionHandle;
rgrover1 734:4872b70437ce 179 (void)attributeHandle;
rgrover1 734:4872b70437ce 180 (void)value;
rgrover1 734:4872b70437ce 181 (void)size;
rgrover1 734:4872b70437ce 182 (void)localOnly;
rgrover1 734:4872b70437ce 183
vcoubard 1048:efb29faf12fc 184 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 728:997ba5e7b3b6 185 }
rgrover1 728:997ba5e7b3b6 186
rgrover1 728:997ba5e7b3b6 187 /**
vcoubard 1048:efb29faf12fc 188 * Determine the updates-enabled status (notification or indication) for the current connection from a characteristic's CCCD.
rgrover1 728:997ba5e7b3b6 189 *
rgrover1 728:997ba5e7b3b6 190 * @param characteristic
vcoubard 1048:efb29faf12fc 191 * The characteristic.
rgrover1 728:997ba5e7b3b6 192 * @param[out] enabledP
rgrover1 728:997ba5e7b3b6 193 * Upon return, *enabledP is true if updates are enabled, else false.
rgrover1 728:997ba5e7b3b6 194 *
vcoubard 1048:efb29faf12fc 195 * @return BLE_ERROR_NONE if the connection and handle are found. False otherwise.
rgrover1 728:997ba5e7b3b6 196 */
rgrover1 728:997ba5e7b3b6 197 virtual ble_error_t areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP) {
vcoubard 1048:efb29faf12fc 198 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 199 (void)characteristic;
rgrover1 734:4872b70437ce 200 (void)enabledP;
rgrover1 734:4872b70437ce 201
vcoubard 1048:efb29faf12fc 202 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 728:997ba5e7b3b6 203 }
rgrover1 728:997ba5e7b3b6 204
rgrover1 728:997ba5e7b3b6 205 /**
vcoubard 1048:efb29faf12fc 206 * Determine the connection-specific updates-enabled status (notification or indication) from a characteristic's CCCD.
rgrover1 728:997ba5e7b3b6 207 *
rgrover1 728:997ba5e7b3b6 208 * @param connectionHandle
vcoubard 1048:efb29faf12fc 209 * The connection handle.
rgrover1 728:997ba5e7b3b6 210 * @param[out] enabledP
rgrover1 728:997ba5e7b3b6 211 * Upon return, *enabledP is true if updates are enabled, else false.
rgrover1 728:997ba5e7b3b6 212 *
rgrover1 728:997ba5e7b3b6 213 * @param characteristic
vcoubard 1048:efb29faf12fc 214 * The characteristic.
rgrover1 728:997ba5e7b3b6 215 *
vcoubard 1048:efb29faf12fc 216 * @return BLE_ERROR_NONE if the connection and handle are found. False otherwise.
rgrover1 728:997ba5e7b3b6 217 */
rgrover1 728:997ba5e7b3b6 218 virtual ble_error_t areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP) {
vcoubard 1048:efb29faf12fc 219 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 220 (void)connectionHandle;
rgrover1 734:4872b70437ce 221 (void)characteristic;
rgrover1 734:4872b70437ce 222 (void)enabledP;
rgrover1 734:4872b70437ce 223
vcoubard 1048:efb29faf12fc 224 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 724:80e065731d70 225 }
rgrover1 724:80e065731d70 226
rgrover1 724:80e065731d70 227 /**
rgrover1 710:b2e1a2660ec2 228 * A virtual function to allow underlying stacks to indicate if they support
rgrover1 710:b2e1a2660ec2 229 * onDataRead(). It should be overridden to return true as applicable.
rgrover1 710:b2e1a2660ec2 230 */
rgrover1 710:b2e1a2660ec2 231 virtual bool isOnDataReadAvailable() const {
vcoubard 1048:efb29faf12fc 232 return false; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 233 }
rgrover1 710:b2e1a2660ec2 234
rgrover1 710:b2e1a2660ec2 235 /*
rgrover1 710:b2e1a2660ec2 236 * APIs with non-virtual implementations.
rgrover1 710:b2e1a2660ec2 237 */
rgrover1 710:b2e1a2660ec2 238 public:
rgrover1 710:b2e1a2660ec2 239 /**
rgrover1 710:b2e1a2660ec2 240 * Add a callback for the GATT event DATA_SENT (which is triggered when
rgrover1 710:b2e1a2660ec2 241 * updates are sent out by GATT in the form of notifications).
rgrover1 710:b2e1a2660ec2 242 *
vcoubard 1048:efb29faf12fc 243 * @Note: It is possible to chain together multiple onDataSent callbacks
rgrover1 710:b2e1a2660ec2 244 * (potentially from different modules of an application) to receive updates
rgrover1 710:b2e1a2660ec2 245 * to characteristics.
rgrover1 710:b2e1a2660ec2 246 *
vcoubard 1048:efb29faf12fc 247 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 248 * some object.
rgrover1 710:b2e1a2660ec2 249 */
vcoubard 1052:b55e1ad3e1b3 250 void onDataSent(const DataSentCallback_t& callback) {dataSentCallChain.add(callback);}
rgrover1 710:b2e1a2660ec2 251 template <typename T>
rgrover1 710:b2e1a2660ec2 252 void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) {
rgrover1 710:b2e1a2660ec2 253 dataSentCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 254 }
rgrover1 710:b2e1a2660ec2 255
rgrover1 710:b2e1a2660ec2 256 /**
vcoubard 1052:b55e1ad3e1b3 257 * @brief get the callback chain called when the event DATA_EVENT is triggered.
vcoubard 1052:b55e1ad3e1b3 258 */
vcoubard 1052:b55e1ad3e1b3 259 DataSentCallbackChain_t& onDataSent() {
vcoubard 1052:b55e1ad3e1b3 260 return dataSentCallChain;
vcoubard 1052:b55e1ad3e1b3 261 }
vcoubard 1052:b55e1ad3e1b3 262
vcoubard 1052:b55e1ad3e1b3 263 /**
vcoubard 1048:efb29faf12fc 264 * Set up a callback for when an attribute has its value updated by or at the
vcoubard 1048:efb29faf12fc 265 * connected peer. For a peripheral, this callback is triggered when the local
rgrover1 710:b2e1a2660ec2 266 * GATT server has an attribute updated by a write command from the peer.
vcoubard 1048:efb29faf12fc 267 * For a central, this callback is triggered when a response is received for
rgrover1 710:b2e1a2660ec2 268 * a write request.
rgrover1 710:b2e1a2660ec2 269 *
vcoubard 1048:efb29faf12fc 270 * @Note: It is possible to chain together multiple onDataWritten callbacks
rgrover1 710:b2e1a2660ec2 271 * (potentially from different modules of an application) to receive updates
vcoubard 1048:efb29faf12fc 272 * to characteristics. Many services, such as DFU and UART, add their own
rgrover1 710:b2e1a2660ec2 273 * onDataWritten callbacks behind the scenes to trap interesting events.
rgrover1 710:b2e1a2660ec2 274 *
vcoubard 1048:efb29faf12fc 275 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 276 * some object.
vcoubard 1052:b55e1ad3e1b3 277 *
vcoubard 1052:b55e1ad3e1b3 278 * @Note It is possible to unregister a callback using onDataWritten().detach(callback)
rgrover1 710:b2e1a2660ec2 279 */
vcoubard 1052:b55e1ad3e1b3 280 void onDataWritten(const DataWrittenCallback_t& callback) {dataWrittenCallChain.add(callback);}
rgrover1 710:b2e1a2660ec2 281 template <typename T>
rgrover1 710:b2e1a2660ec2 282 void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) {
rgrover1 710:b2e1a2660ec2 283 dataWrittenCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 284 }
rgrover1 710:b2e1a2660ec2 285
rgrover1 710:b2e1a2660ec2 286 /**
vcoubard 1052:b55e1ad3e1b3 287 * @brief provide access to the callchain of data written event callbacks
vcoubard 1052:b55e1ad3e1b3 288 * It is possible to register callbacks using onDataWritten().add(callback);
vcoubard 1052:b55e1ad3e1b3 289 * It is possible to unregister callbacks using onDataWritten().detach(callback)
vcoubard 1052:b55e1ad3e1b3 290 * @return The data written event callbacks chain
vcoubard 1052:b55e1ad3e1b3 291 */
vcoubard 1052:b55e1ad3e1b3 292 DataWrittenCallbackChain_t& onDataWritten() {
vcoubard 1052:b55e1ad3e1b3 293 return dataWrittenCallChain;
vcoubard 1052:b55e1ad3e1b3 294 }
vcoubard 1052:b55e1ad3e1b3 295
vcoubard 1052:b55e1ad3e1b3 296 /**
rgrover1 710:b2e1a2660ec2 297 * Setup a callback to be invoked on the peripheral when an attribute is
rgrover1 710:b2e1a2660ec2 298 * being read by a remote client.
rgrover1 710:b2e1a2660ec2 299 *
vcoubard 1048:efb29faf12fc 300 * @Note: This functionality may not be available on all underlying stacks.
rgrover1 710:b2e1a2660ec2 301 * You could use GattCharacteristic::setReadAuthorizationCallback() as an
rgrover1 826:00415ff9e2a7 302 * alternative. Refer to isOnDataReadAvailable().
rgrover1 710:b2e1a2660ec2 303 *
vcoubard 1048:efb29faf12fc 304 * @Note: It is possible to chain together multiple onDataRead callbacks
rgrover1 710:b2e1a2660ec2 305 * (potentially from different modules of an application) to receive updates
rgrover1 710:b2e1a2660ec2 306 * to characteristics. Services may add their own onDataRead callbacks
rgrover1 710:b2e1a2660ec2 307 * behind the scenes to trap interesting events.
rgrover1 710:b2e1a2660ec2 308 *
vcoubard 1048:efb29faf12fc 309 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 310 * some object.
rgrover1 710:b2e1a2660ec2 311 *
vcoubard 1052:b55e1ad3e1b3 312 * @Note It is possible to unregister a callback using onDataRead().detach(callback)
vcoubard 1052:b55e1ad3e1b3 313 *
rgrover1 710:b2e1a2660ec2 314 * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available;
rgrover1 710:b2e1a2660ec2 315 * else BLE_ERROR_NONE.
rgrover1 710:b2e1a2660ec2 316 */
vcoubard 1052:b55e1ad3e1b3 317 ble_error_t onDataRead(const DataReadCallback_t& callback) {
rgrover1 710:b2e1a2660ec2 318 if (!isOnDataReadAvailable()) {
rgrover1 710:b2e1a2660ec2 319 return BLE_ERROR_NOT_IMPLEMENTED;
rgrover1 710:b2e1a2660ec2 320 }
rgrover1 710:b2e1a2660ec2 321
rgrover1 710:b2e1a2660ec2 322 dataReadCallChain.add(callback);
rgrover1 710:b2e1a2660ec2 323 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 324 }
rgrover1 710:b2e1a2660ec2 325 template <typename T>
rgrover1 710:b2e1a2660ec2 326 ble_error_t onDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) {
rgrover1 710:b2e1a2660ec2 327 if (!isOnDataReadAvailable()) {
rgrover1 710:b2e1a2660ec2 328 return BLE_ERROR_NOT_IMPLEMENTED;
rgrover1 710:b2e1a2660ec2 329 }
rgrover1 710:b2e1a2660ec2 330
rgrover1 710:b2e1a2660ec2 331 dataReadCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 332 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 333 }
rgrover1 710:b2e1a2660ec2 334
rgrover1 710:b2e1a2660ec2 335 /**
vcoubard 1052:b55e1ad3e1b3 336 * @brief provide access to the callchain of data read event callbacks
vcoubard 1052:b55e1ad3e1b3 337 * It is possible to register callbacks using onDataRead().add(callback);
vcoubard 1052:b55e1ad3e1b3 338 * It is possible to unregister callbacks using onDataRead().detach(callback)
vcoubard 1052:b55e1ad3e1b3 339 * @return The data read event callbacks chain
vcoubard 1052:b55e1ad3e1b3 340 */
vcoubard 1052:b55e1ad3e1b3 341 DataReadCallbackChain_t& onDataRead() {
vcoubard 1052:b55e1ad3e1b3 342 return dataReadCallChain;
vcoubard 1052:b55e1ad3e1b3 343 }
vcoubard 1052:b55e1ad3e1b3 344
vcoubard 1052:b55e1ad3e1b3 345 /**
vcoubard 1048:efb29faf12fc 346 * Set up a callback for when notifications or indications are enabled for a
vcoubard 1048:efb29faf12fc 347 * characteristic on the local GATT server.
rgrover1 710:b2e1a2660ec2 348 */
rgrover1 710:b2e1a2660ec2 349 void onUpdatesEnabled(EventCallback_t callback) {updatesEnabledCallback = callback;}
rgrover1 710:b2e1a2660ec2 350
rgrover1 710:b2e1a2660ec2 351 /**
vcoubard 1048:efb29faf12fc 352 * Set up a callback for when notifications or indications are disabled for a
vcoubard 1048:efb29faf12fc 353 * characteristic on the local GATT server.
rgrover1 710:b2e1a2660ec2 354 */
rgrover1 710:b2e1a2660ec2 355 void onUpdatesDisabled(EventCallback_t callback) {updatesDisabledCallback = callback;}
rgrover1 710:b2e1a2660ec2 356
rgrover1 710:b2e1a2660ec2 357 /**
vcoubard 1048:efb29faf12fc 358 * Set up a callback for when the GATT server receives a response for an
rgrover1 710:b2e1a2660ec2 359 * indication event sent previously.
rgrover1 710:b2e1a2660ec2 360 */
rgrover1 710:b2e1a2660ec2 361 void onConfirmationReceived(EventCallback_t callback) {confirmationReceivedCallback = callback;}
rgrover1 710:b2e1a2660ec2 362
rgrover1 710:b2e1a2660ec2 363 /* Entry points for the underlying stack to report events back to the user. */
rgrover1 710:b2e1a2660ec2 364 protected:
rgrover1 710:b2e1a2660ec2 365 void handleDataWrittenEvent(const GattWriteCallbackParams *params) {
vcoubard 1052:b55e1ad3e1b3 366 dataWrittenCallChain.call(params);
rgrover1 710:b2e1a2660ec2 367 }
rgrover1 710:b2e1a2660ec2 368
rgrover1 710:b2e1a2660ec2 369 void handleDataReadEvent(const GattReadCallbackParams *params) {
vcoubard 1052:b55e1ad3e1b3 370 dataReadCallChain.call(params);
rgrover1 710:b2e1a2660ec2 371 }
rgrover1 710:b2e1a2660ec2 372
rgrover1 728:997ba5e7b3b6 373 void handleEvent(GattServerEvents::gattEvent_e type, GattAttribute::Handle_t attributeHandle) {
rgrover1 710:b2e1a2660ec2 374 switch (type) {
rgrover1 710:b2e1a2660ec2 375 case GattServerEvents::GATT_EVENT_UPDATES_ENABLED:
rgrover1 710:b2e1a2660ec2 376 if (updatesEnabledCallback) {
rgrover1 728:997ba5e7b3b6 377 updatesEnabledCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 378 }
rgrover1 710:b2e1a2660ec2 379 break;
rgrover1 710:b2e1a2660ec2 380 case GattServerEvents::GATT_EVENT_UPDATES_DISABLED:
rgrover1 710:b2e1a2660ec2 381 if (updatesDisabledCallback) {
rgrover1 728:997ba5e7b3b6 382 updatesDisabledCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 383 }
rgrover1 710:b2e1a2660ec2 384 break;
rgrover1 710:b2e1a2660ec2 385 case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED:
rgrover1 710:b2e1a2660ec2 386 if (confirmationReceivedCallback) {
rgrover1 728:997ba5e7b3b6 387 confirmationReceivedCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 388 }
rgrover1 710:b2e1a2660ec2 389 break;
rgrover1 710:b2e1a2660ec2 390 default:
rgrover1 710:b2e1a2660ec2 391 break;
rgrover1 710:b2e1a2660ec2 392 }
rgrover1 710:b2e1a2660ec2 393 }
rgrover1 710:b2e1a2660ec2 394
rgrover1 710:b2e1a2660ec2 395 void handleDataSentEvent(unsigned count) {
vcoubard 1052:b55e1ad3e1b3 396 dataSentCallChain.call(count);
rgrover1 710:b2e1a2660ec2 397 }
rgrover1 710:b2e1a2660ec2 398
rgrover1 710:b2e1a2660ec2 399 protected:
vcoubard 1062:a3fd424b73ca 400 /**
vcoubard 1062:a3fd424b73ca 401 * Clear all GattServer state of the associated object.
vcoubard 1062:a3fd424b73ca 402 *
vcoubard 1062:a3fd424b73ca 403 * This function is meant to be overridden in the platform-specific
vcoubard 1062:a3fd424b73ca 404 * sub-class. Nevertheless, the sub-class is only expected to clean up its
vcoubard 1062:a3fd424b73ca 405 * state and not the data held in GattServer members. This shall be achieved
vcoubard 1062:a3fd424b73ca 406 * by a call to GattServer::cleanup() from the sub-class' cleanup()
vcoubard 1062:a3fd424b73ca 407 * implementation.
vcoubard 1062:a3fd424b73ca 408 *
vcoubard 1062:a3fd424b73ca 409 * @return BLE_ERROR_NONE on success.
vcoubard 1062:a3fd424b73ca 410 */
vcoubard 1062:a3fd424b73ca 411 virtual ble_error_t cleanup(void) {
vcoubard 1062:a3fd424b73ca 412 serviceCount = 0;
vcoubard 1062:a3fd424b73ca 413 characteristicCount = 0;
vcoubard 1062:a3fd424b73ca 414
vcoubard 1062:a3fd424b73ca 415 dataSentCallChain.clear();
vcoubard 1062:a3fd424b73ca 416 dataWrittenCallChain.clear();
vcoubard 1062:a3fd424b73ca 417 dataReadCallChain.clear();
vcoubard 1062:a3fd424b73ca 418 updatesEnabledCallback = NULL;
vcoubard 1062:a3fd424b73ca 419 updatesDisabledCallback = NULL;
vcoubard 1062:a3fd424b73ca 420 confirmationReceivedCallback = NULL;
vcoubard 1062:a3fd424b73ca 421
vcoubard 1062:a3fd424b73ca 422 return BLE_ERROR_NONE;
vcoubard 1062:a3fd424b73ca 423 }
vcoubard 1062:a3fd424b73ca 424
vcoubard 1062:a3fd424b73ca 425 public:
vcoubard 1062:a3fd424b73ca 426 /**
vcoubard 1062:a3fd424b73ca 427 * Clear all GattServer state of the object pointed to by
vcoubard 1062:a3fd424b73ca 428 * gattServerInstance.
vcoubard 1062:a3fd424b73ca 429 *
vcoubard 1062:a3fd424b73ca 430 * This function is meant to be called by the overridden BLE::shutdown()
vcoubard 1062:a3fd424b73ca 431 * in the platform-specific sub-class.
vcoubard 1062:a3fd424b73ca 432 *
vcoubard 1062:a3fd424b73ca 433 * @return BLE_ERROR_NONE on success.
vcoubard 1062:a3fd424b73ca 434 *
vcoubard 1062:a3fd424b73ca 435 * @note: If gattServerInstance is NULL then it is assumed that Gap has not
vcoubard 1062:a3fd424b73ca 436 * been instantiated and a call to GattServer::shutdown() will succeed.
vcoubard 1062:a3fd424b73ca 437 */
vcoubard 1062:a3fd424b73ca 438 static ble_error_t shutdown(void) {
vcoubard 1062:a3fd424b73ca 439 if (gattServerInstance) {
vcoubard 1062:a3fd424b73ca 440 return gattServerInstance->cleanup();
vcoubard 1062:a3fd424b73ca 441 }
vcoubard 1062:a3fd424b73ca 442 return BLE_ERROR_NONE;
vcoubard 1062:a3fd424b73ca 443 }
vcoubard 1062:a3fd424b73ca 444
vcoubard 1062:a3fd424b73ca 445 protected:
rgrover1 710:b2e1a2660ec2 446 uint8_t serviceCount;
rgrover1 710:b2e1a2660ec2 447 uint8_t characteristicCount;
rgrover1 710:b2e1a2660ec2 448
vcoubard 1062:a3fd424b73ca 449 protected:
vcoubard 1062:a3fd424b73ca 450 static GattServer *gattServerInstance; /**< Pointer to the GattServer object instance.
vcoubard 1062:a3fd424b73ca 451 * If NULL, then GattServer has not been initialized. */
vcoubard 1062:a3fd424b73ca 452
rgrover1 710:b2e1a2660ec2 453 private:
vcoubard 1052:b55e1ad3e1b3 454 DataSentCallbackChain_t dataSentCallChain;
vcoubard 1052:b55e1ad3e1b3 455 DataWrittenCallbackChain_t dataWrittenCallChain;
vcoubard 1052:b55e1ad3e1b3 456 DataReadCallbackChain_t dataReadCallChain;
vcoubard 1052:b55e1ad3e1b3 457 EventCallback_t updatesEnabledCallback;
vcoubard 1052:b55e1ad3e1b3 458 EventCallback_t updatesDisabledCallback;
vcoubard 1052:b55e1ad3e1b3 459 EventCallback_t confirmationReceivedCallback;
rgrover1 710:b2e1a2660ec2 460
rgrover1 710:b2e1a2660ec2 461 private:
vcoubard 1048:efb29faf12fc 462 /* Disallow copy and assignment. */
rgrover1 710:b2e1a2660ec2 463 GattServer(const GattServer &);
rgrover1 710:b2e1a2660ec2 464 GattServer& operator=(const GattServer &);
rgrover1 710:b2e1a2660ec2 465 };
rgrover1 710:b2e1a2660ec2 466
rgrover1 710:b2e1a2660ec2 467 #endif // ifndef __GATT_SERVER_H__