High level Bluetooth Low Energy API and radio abstraction layer

Dependencies:   nRF51822

Dependents:   LinkNode_LIS3DH

Fork of BLE_API by Bluetooth Low Energy

Committer:
vcoubard
Date:
Mon Jan 11 08:51:49 2016 +0000
Revision:
1088:709ebced28ab
Parent:
1084:40c1e518d6de
Child:
1089:8e810a8e083e
Synchronized with git rev 0781293b
Author: Andres Amaya Garcia
Add onShutdown to register callbacks

Add an onShutdown() function to Gap, GattClient, GattServer and
SecurityManager. The callbacks are added to a private callback chain in each of
the instances. The callbacks will be executed inside each object's reset()
function BEFORE the state of the instance is cleared. The developers of the
platform-specific implementation must call the parent class' reset() function
for the callbacks to be executed.

Finally, an onShutdown() function that returns the shutdown callchain is added
to allow detaching callbacks.

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