Lancaster University's fork of the mbed BLE API. Lives on github, https://github.com/lancaster-university/BLE_API

Dependents:   microbit-dal microbit-dal microbit-ble-open microbit-dal ... more

Fork of BLE_API by Bluetooth Low Energy

Committer:
LancasterUniversity
Date:
Wed Apr 06 18:40:37 2016 +0100
Revision:
1138:6aabbb5f81e6
Parent:
1137:290d499dd0e8
Child:
1140:dd2f69fad8c6
Synchronized with git rev 33067370
Author: Joe Finney
microbit: Added support for explicit notification

Introduce abality to explicitly perform a notify/indicate opertion on a characteristic.
This brings benefits of a reduce RAM footprint for storing GattCharacterisitics.

n.b. temporary measure until ARM mbed integrate more generic optimisations.

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;
LancasterUniversity 1137:290d499dd0e8 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
LancasterUniversity 1137:290d499dd0e8 39 typedef FunctionPointerWithContext<const GattServer *> GattServerShutdownCallback_t;
LancasterUniversity 1137:290d499dd0e8 40 typedef CallChainOfFunctionPointersWithContext<const GattServer *> GattServerShutdownCallbackChain_t;
LancasterUniversity 1137:290d499dd0e8 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 /**
LancasterUniversity 1138:6aabbb5f81e6 190 * Perform an explicit BLE notification of a given attribute.
LancasterUniversity 1138:6aabbb5f81e6 191 *
LancasterUniversity 1138:6aabbb5f81e6 192 * @param[in] attributeHandle
LancasterUniversity 1138:6aabbb5f81e6 193 * Handle for the value attribute of the Characteristic.
LancasterUniversity 1138:6aabbb5f81e6 194 * @param[in] value
LancasterUniversity 1138:6aabbb5f81e6 195 * A pointer to a buffer holding the new value
LancasterUniversity 1138:6aabbb5f81e6 196 * @param[in] size
LancasterUniversity 1138:6aabbb5f81e6 197 * Size of the new value (in bytes).
LancasterUniversity 1138:6aabbb5f81e6 198 *
LancasterUniversity 1138:6aabbb5f81e6 199 * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
LancasterUniversity 1138:6aabbb5f81e6 200 */
LancasterUniversity 1138:6aabbb5f81e6 201 virtual ble_error_t notify(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size)
LancasterUniversity 1138:6aabbb5f81e6 202 {
LancasterUniversity 1138:6aabbb5f81e6 203 (void)attributeHandle;
LancasterUniversity 1138:6aabbb5f81e6 204 (void)value;
LancasterUniversity 1138:6aabbb5f81e6 205 (void)size;
LancasterUniversity 1138:6aabbb5f81e6 206
LancasterUniversity 1138:6aabbb5f81e6 207 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
LancasterUniversity 1138:6aabbb5f81e6 208 }
LancasterUniversity 1138:6aabbb5f81e6 209
LancasterUniversity 1138:6aabbb5f81e6 210 /**
vcoubard 1048:efb29faf12fc 211 * Determine the updates-enabled status (notification or indication) for the current connection from a characteristic's CCCD.
rgrover1 728:997ba5e7b3b6 212 *
rgrover1 728:997ba5e7b3b6 213 * @param characteristic
vcoubard 1048:efb29faf12fc 214 * The characteristic.
rgrover1 728:997ba5e7b3b6 215 * @param[out] enabledP
rgrover1 728:997ba5e7b3b6 216 * Upon return, *enabledP is true if updates are enabled, else false.
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(const GattCharacteristic &characteristic, bool *enabledP) {
vcoubard 1048:efb29faf12fc 221 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 222 (void)characteristic;
rgrover1 734:4872b70437ce 223 (void)enabledP;
rgrover1 734:4872b70437ce 224
vcoubard 1048:efb29faf12fc 225 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 728:997ba5e7b3b6 226 }
rgrover1 728:997ba5e7b3b6 227
rgrover1 728:997ba5e7b3b6 228 /**
vcoubard 1048:efb29faf12fc 229 * Determine the connection-specific updates-enabled status (notification or indication) from a characteristic's CCCD.
rgrover1 728:997ba5e7b3b6 230 *
rgrover1 728:997ba5e7b3b6 231 * @param connectionHandle
vcoubard 1048:efb29faf12fc 232 * The connection handle.
rgrover1 728:997ba5e7b3b6 233 * @param[out] enabledP
rgrover1 728:997ba5e7b3b6 234 * Upon return, *enabledP is true if updates are enabled, else false.
rgrover1 728:997ba5e7b3b6 235 *
rgrover1 728:997ba5e7b3b6 236 * @param characteristic
vcoubard 1048:efb29faf12fc 237 * The characteristic.
rgrover1 728:997ba5e7b3b6 238 *
vcoubard 1048:efb29faf12fc 239 * @return BLE_ERROR_NONE if the connection and handle are found. False otherwise.
rgrover1 728:997ba5e7b3b6 240 */
rgrover1 728:997ba5e7b3b6 241 virtual ble_error_t areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP) {
vcoubard 1048:efb29faf12fc 242 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 243 (void)connectionHandle;
rgrover1 734:4872b70437ce 244 (void)characteristic;
rgrover1 734:4872b70437ce 245 (void)enabledP;
rgrover1 734:4872b70437ce 246
vcoubard 1048:efb29faf12fc 247 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 724:80e065731d70 248 }
rgrover1 724:80e065731d70 249
rgrover1 724:80e065731d70 250 /**
rgrover1 710:b2e1a2660ec2 251 * A virtual function to allow underlying stacks to indicate if they support
rgrover1 710:b2e1a2660ec2 252 * onDataRead(). It should be overridden to return true as applicable.
rgrover1 710:b2e1a2660ec2 253 */
rgrover1 710:b2e1a2660ec2 254 virtual bool isOnDataReadAvailable() const {
vcoubard 1048:efb29faf12fc 255 return false; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 256 }
rgrover1 710:b2e1a2660ec2 257
rgrover1 710:b2e1a2660ec2 258 /*
rgrover1 710:b2e1a2660ec2 259 * APIs with non-virtual implementations.
rgrover1 710:b2e1a2660ec2 260 */
rgrover1 710:b2e1a2660ec2 261 public:
rgrover1 710:b2e1a2660ec2 262 /**
rgrover1 710:b2e1a2660ec2 263 * Add a callback for the GATT event DATA_SENT (which is triggered when
rgrover1 710:b2e1a2660ec2 264 * updates are sent out by GATT in the form of notifications).
rgrover1 710:b2e1a2660ec2 265 *
vcoubard 1048:efb29faf12fc 266 * @Note: It is possible to chain together multiple onDataSent callbacks
rgrover1 710:b2e1a2660ec2 267 * (potentially from different modules of an application) to receive updates
rgrover1 710:b2e1a2660ec2 268 * to characteristics.
rgrover1 710:b2e1a2660ec2 269 *
vcoubard 1048:efb29faf12fc 270 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 271 * some object.
rgrover1 710:b2e1a2660ec2 272 */
vcoubard 1052:b55e1ad3e1b3 273 void onDataSent(const DataSentCallback_t& callback) {dataSentCallChain.add(callback);}
rgrover1 710:b2e1a2660ec2 274 template <typename T>
rgrover1 710:b2e1a2660ec2 275 void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) {
rgrover1 710:b2e1a2660ec2 276 dataSentCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 277 }
rgrover1 710:b2e1a2660ec2 278
rgrover1 710:b2e1a2660ec2 279 /**
LancasterUniversity 1137:290d499dd0e8 280 * @brief get the callback chain called when the event DATA_EVENT is triggered.
vcoubard 1052:b55e1ad3e1b3 281 */
LancasterUniversity 1137:290d499dd0e8 282 DataSentCallbackChain_t& onDataSent() {
vcoubard 1052:b55e1ad3e1b3 283 return dataSentCallChain;
vcoubard 1052:b55e1ad3e1b3 284 }
vcoubard 1052:b55e1ad3e1b3 285
vcoubard 1052:b55e1ad3e1b3 286 /**
vcoubard 1048:efb29faf12fc 287 * Set up a callback for when an attribute has its value updated by or at the
vcoubard 1048:efb29faf12fc 288 * connected peer. For a peripheral, this callback is triggered when the local
rgrover1 710:b2e1a2660ec2 289 * GATT server has an attribute updated by a write command from the peer.
vcoubard 1048:efb29faf12fc 290 * For a central, this callback is triggered when a response is received for
rgrover1 710:b2e1a2660ec2 291 * a write request.
rgrover1 710:b2e1a2660ec2 292 *
vcoubard 1048:efb29faf12fc 293 * @Note: It is possible to chain together multiple onDataWritten callbacks
rgrover1 710:b2e1a2660ec2 294 * (potentially from different modules of an application) to receive updates
vcoubard 1048:efb29faf12fc 295 * to characteristics. Many services, such as DFU and UART, add their own
rgrover1 710:b2e1a2660ec2 296 * onDataWritten callbacks behind the scenes to trap interesting events.
rgrover1 710:b2e1a2660ec2 297 *
vcoubard 1048:efb29faf12fc 298 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 299 * some object.
LancasterUniversity 1137:290d499dd0e8 300 *
vcoubard 1052:b55e1ad3e1b3 301 * @Note It is possible to unregister a callback using onDataWritten().detach(callback)
rgrover1 710:b2e1a2660ec2 302 */
vcoubard 1052:b55e1ad3e1b3 303 void onDataWritten(const DataWrittenCallback_t& callback) {dataWrittenCallChain.add(callback);}
rgrover1 710:b2e1a2660ec2 304 template <typename T>
rgrover1 710:b2e1a2660ec2 305 void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) {
rgrover1 710:b2e1a2660ec2 306 dataWrittenCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 307 }
rgrover1 710:b2e1a2660ec2 308
rgrover1 710:b2e1a2660ec2 309 /**
vcoubard 1052:b55e1ad3e1b3 310 * @brief provide access to the callchain of data written event callbacks
vcoubard 1052:b55e1ad3e1b3 311 * It is possible to register callbacks using onDataWritten().add(callback);
LancasterUniversity 1137:290d499dd0e8 312 * It is possible to unregister callbacks using onDataWritten().detach(callback)
vcoubard 1052:b55e1ad3e1b3 313 * @return The data written event callbacks chain
LancasterUniversity 1137:290d499dd0e8 314 */
vcoubard 1052:b55e1ad3e1b3 315 DataWrittenCallbackChain_t& onDataWritten() {
vcoubard 1052:b55e1ad3e1b3 316 return dataWrittenCallChain;
vcoubard 1052:b55e1ad3e1b3 317 }
vcoubard 1052:b55e1ad3e1b3 318
vcoubard 1052:b55e1ad3e1b3 319 /**
rgrover1 710:b2e1a2660ec2 320 * Setup a callback to be invoked on the peripheral when an attribute is
rgrover1 710:b2e1a2660ec2 321 * being read by a remote client.
rgrover1 710:b2e1a2660ec2 322 *
vcoubard 1048:efb29faf12fc 323 * @Note: This functionality may not be available on all underlying stacks.
rgrover1 710:b2e1a2660ec2 324 * You could use GattCharacteristic::setReadAuthorizationCallback() as an
rgrover1 826:00415ff9e2a7 325 * alternative. Refer to isOnDataReadAvailable().
rgrover1 710:b2e1a2660ec2 326 *
vcoubard 1048:efb29faf12fc 327 * @Note: It is possible to chain together multiple onDataRead callbacks
rgrover1 710:b2e1a2660ec2 328 * (potentially from different modules of an application) to receive updates
rgrover1 710:b2e1a2660ec2 329 * to characteristics. Services may add their own onDataRead callbacks
rgrover1 710:b2e1a2660ec2 330 * behind the scenes to trap interesting events.
rgrover1 710:b2e1a2660ec2 331 *
vcoubard 1048:efb29faf12fc 332 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 333 * some object.
rgrover1 710:b2e1a2660ec2 334 *
vcoubard 1052:b55e1ad3e1b3 335 * @Note It is possible to unregister a callback using onDataRead().detach(callback)
vcoubard 1052:b55e1ad3e1b3 336 *
rgrover1 710:b2e1a2660ec2 337 * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available;
rgrover1 710:b2e1a2660ec2 338 * else BLE_ERROR_NONE.
rgrover1 710:b2e1a2660ec2 339 */
vcoubard 1052:b55e1ad3e1b3 340 ble_error_t onDataRead(const DataReadCallback_t& callback) {
rgrover1 710:b2e1a2660ec2 341 if (!isOnDataReadAvailable()) {
rgrover1 710:b2e1a2660ec2 342 return BLE_ERROR_NOT_IMPLEMENTED;
rgrover1 710:b2e1a2660ec2 343 }
rgrover1 710:b2e1a2660ec2 344
rgrover1 710:b2e1a2660ec2 345 dataReadCallChain.add(callback);
rgrover1 710:b2e1a2660ec2 346 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 347 }
rgrover1 710:b2e1a2660ec2 348 template <typename T>
rgrover1 710:b2e1a2660ec2 349 ble_error_t onDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) {
rgrover1 710:b2e1a2660ec2 350 if (!isOnDataReadAvailable()) {
rgrover1 710:b2e1a2660ec2 351 return BLE_ERROR_NOT_IMPLEMENTED;
rgrover1 710:b2e1a2660ec2 352 }
rgrover1 710:b2e1a2660ec2 353
rgrover1 710:b2e1a2660ec2 354 dataReadCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 355 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 356 }
rgrover1 710:b2e1a2660ec2 357
rgrover1 710:b2e1a2660ec2 358 /**
vcoubard 1052:b55e1ad3e1b3 359 * @brief provide access to the callchain of data read event callbacks
vcoubard 1052:b55e1ad3e1b3 360 * It is possible to register callbacks using onDataRead().add(callback);
LancasterUniversity 1137:290d499dd0e8 361 * It is possible to unregister callbacks using onDataRead().detach(callback)
vcoubard 1052:b55e1ad3e1b3 362 * @return The data read event callbacks chain
vcoubard 1052:b55e1ad3e1b3 363 */
vcoubard 1052:b55e1ad3e1b3 364 DataReadCallbackChain_t& onDataRead() {
vcoubard 1052:b55e1ad3e1b3 365 return dataReadCallChain;
vcoubard 1052:b55e1ad3e1b3 366 }
vcoubard 1052:b55e1ad3e1b3 367
vcoubard 1052:b55e1ad3e1b3 368 /**
LancasterUniversity 1137:290d499dd0e8 369 * Setup a callback to be invoked to notify the user application that the
LancasterUniversity 1137:290d499dd0e8 370 * GattServer instance is about to shutdown (possibly as a result of a call
LancasterUniversity 1137:290d499dd0e8 371 * to BLE::shutdown()).
LancasterUniversity 1137:290d499dd0e8 372 *
LancasterUniversity 1137:290d499dd0e8 373 * @Note: It is possible to chain together multiple onShutdown callbacks
LancasterUniversity 1137:290d499dd0e8 374 * (potentially from different modules of an application) to be notified
LancasterUniversity 1137:290d499dd0e8 375 * before the GattServer is shutdown.
LancasterUniversity 1137:290d499dd0e8 376 *
LancasterUniversity 1137:290d499dd0e8 377 * @Note: It is also possible to set up a callback into a member function of
LancasterUniversity 1137:290d499dd0e8 378 * some object.
LancasterUniversity 1137:290d499dd0e8 379 *
LancasterUniversity 1137:290d499dd0e8 380 * @Note It is possible to unregister a callback using onShutdown().detach(callback)
LancasterUniversity 1137:290d499dd0e8 381 */
LancasterUniversity 1137:290d499dd0e8 382 void onShutdown(const GattServerShutdownCallback_t& callback) {
LancasterUniversity 1137:290d499dd0e8 383 shutdownCallChain.add(callback);
LancasterUniversity 1137:290d499dd0e8 384 }
LancasterUniversity 1137:290d499dd0e8 385 template <typename T>
LancasterUniversity 1137:290d499dd0e8 386 void onShutdown(T *objPtr, void (T::*memberPtr)(void)) {
LancasterUniversity 1137:290d499dd0e8 387 shutdownCallChain.add(objPtr, memberPtr);
LancasterUniversity 1137:290d499dd0e8 388 }
LancasterUniversity 1137:290d499dd0e8 389
LancasterUniversity 1137:290d499dd0e8 390 /**
LancasterUniversity 1137:290d499dd0e8 391 * @brief provide access to the callchain of shutdown event callbacks
LancasterUniversity 1137:290d499dd0e8 392 * It is possible to register callbacks using onShutdown().add(callback);
LancasterUniversity 1137:290d499dd0e8 393 * It is possible to unregister callbacks using onShutdown().detach(callback)
LancasterUniversity 1137:290d499dd0e8 394 * @return The shutdown event callbacks chain
LancasterUniversity 1137:290d499dd0e8 395 */
LancasterUniversity 1137:290d499dd0e8 396 GattServerShutdownCallbackChain_t& onShutdown() {
LancasterUniversity 1137:290d499dd0e8 397 return shutdownCallChain;
LancasterUniversity 1137:290d499dd0e8 398 }
LancasterUniversity 1137:290d499dd0e8 399
LancasterUniversity 1137:290d499dd0e8 400 /**
vcoubard 1048:efb29faf12fc 401 * Set up a callback for when notifications or indications are enabled for a
vcoubard 1048:efb29faf12fc 402 * characteristic on the local GATT server.
rgrover1 710:b2e1a2660ec2 403 */
rgrover1 710:b2e1a2660ec2 404 void onUpdatesEnabled(EventCallback_t callback) {updatesEnabledCallback = callback;}
rgrover1 710:b2e1a2660ec2 405
rgrover1 710:b2e1a2660ec2 406 /**
vcoubard 1048:efb29faf12fc 407 * Set up a callback for when notifications or indications are disabled for a
vcoubard 1048:efb29faf12fc 408 * characteristic on the local GATT server.
rgrover1 710:b2e1a2660ec2 409 */
rgrover1 710:b2e1a2660ec2 410 void onUpdatesDisabled(EventCallback_t callback) {updatesDisabledCallback = callback;}
rgrover1 710:b2e1a2660ec2 411
rgrover1 710:b2e1a2660ec2 412 /**
vcoubard 1048:efb29faf12fc 413 * Set up a callback for when the GATT server receives a response for an
rgrover1 710:b2e1a2660ec2 414 * indication event sent previously.
rgrover1 710:b2e1a2660ec2 415 */
rgrover1 710:b2e1a2660ec2 416 void onConfirmationReceived(EventCallback_t callback) {confirmationReceivedCallback = callback;}
rgrover1 710:b2e1a2660ec2 417
rgrover1 710:b2e1a2660ec2 418 /* Entry points for the underlying stack to report events back to the user. */
rgrover1 710:b2e1a2660ec2 419 protected:
rgrover1 710:b2e1a2660ec2 420 void handleDataWrittenEvent(const GattWriteCallbackParams *params) {
vcoubard 1052:b55e1ad3e1b3 421 dataWrittenCallChain.call(params);
rgrover1 710:b2e1a2660ec2 422 }
rgrover1 710:b2e1a2660ec2 423
rgrover1 710:b2e1a2660ec2 424 void handleDataReadEvent(const GattReadCallbackParams *params) {
vcoubard 1052:b55e1ad3e1b3 425 dataReadCallChain.call(params);
rgrover1 710:b2e1a2660ec2 426 }
rgrover1 710:b2e1a2660ec2 427
rgrover1 728:997ba5e7b3b6 428 void handleEvent(GattServerEvents::gattEvent_e type, GattAttribute::Handle_t attributeHandle) {
rgrover1 710:b2e1a2660ec2 429 switch (type) {
rgrover1 710:b2e1a2660ec2 430 case GattServerEvents::GATT_EVENT_UPDATES_ENABLED:
rgrover1 710:b2e1a2660ec2 431 if (updatesEnabledCallback) {
rgrover1 728:997ba5e7b3b6 432 updatesEnabledCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 433 }
rgrover1 710:b2e1a2660ec2 434 break;
rgrover1 710:b2e1a2660ec2 435 case GattServerEvents::GATT_EVENT_UPDATES_DISABLED:
rgrover1 710:b2e1a2660ec2 436 if (updatesDisabledCallback) {
rgrover1 728:997ba5e7b3b6 437 updatesDisabledCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 438 }
rgrover1 710:b2e1a2660ec2 439 break;
rgrover1 710:b2e1a2660ec2 440 case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED:
rgrover1 710:b2e1a2660ec2 441 if (confirmationReceivedCallback) {
rgrover1 728:997ba5e7b3b6 442 confirmationReceivedCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 443 }
rgrover1 710:b2e1a2660ec2 444 break;
rgrover1 710:b2e1a2660ec2 445 default:
rgrover1 710:b2e1a2660ec2 446 break;
rgrover1 710:b2e1a2660ec2 447 }
rgrover1 710:b2e1a2660ec2 448 }
rgrover1 710:b2e1a2660ec2 449
rgrover1 710:b2e1a2660ec2 450 void handleDataSentEvent(unsigned count) {
vcoubard 1052:b55e1ad3e1b3 451 dataSentCallChain.call(count);
rgrover1 710:b2e1a2660ec2 452 }
rgrover1 710:b2e1a2660ec2 453
LancasterUniversity 1137:290d499dd0e8 454 public:
LancasterUniversity 1137:290d499dd0e8 455 /**
LancasterUniversity 1137:290d499dd0e8 456 * Notify all registered onShutdown callbacks that the GattServer is
LancasterUniversity 1137:290d499dd0e8 457 * about to be shutdown and clear all GattServer state of the
LancasterUniversity 1137:290d499dd0e8 458 * associated object.
LancasterUniversity 1137:290d499dd0e8 459 *
LancasterUniversity 1137:290d499dd0e8 460 * This function is meant to be overridden in the platform-specific
LancasterUniversity 1137:290d499dd0e8 461 * sub-class. Nevertheless, the sub-class is only expected to reset its
LancasterUniversity 1137:290d499dd0e8 462 * state and not the data held in GattServer members. This shall be achieved
LancasterUniversity 1137:290d499dd0e8 463 * by a call to GattServer::reset() from the sub-class' reset()
LancasterUniversity 1137:290d499dd0e8 464 * implementation.
LancasterUniversity 1137:290d499dd0e8 465 *
LancasterUniversity 1137:290d499dd0e8 466 * @return BLE_ERROR_NONE on success.
LancasterUniversity 1137:290d499dd0e8 467 */
LancasterUniversity 1137:290d499dd0e8 468 virtual ble_error_t reset(void) {
LancasterUniversity 1137:290d499dd0e8 469 /* Notify that the instance is about to shutdown */
LancasterUniversity 1137:290d499dd0e8 470 shutdownCallChain.call(this);
LancasterUniversity 1137:290d499dd0e8 471 shutdownCallChain.clear();
LancasterUniversity 1137:290d499dd0e8 472
LancasterUniversity 1137:290d499dd0e8 473 serviceCount = 0;
LancasterUniversity 1137:290d499dd0e8 474 characteristicCount = 0;
LancasterUniversity 1137:290d499dd0e8 475
LancasterUniversity 1137:290d499dd0e8 476 dataSentCallChain.clear();
LancasterUniversity 1137:290d499dd0e8 477 dataWrittenCallChain.clear();
LancasterUniversity 1137:290d499dd0e8 478 dataReadCallChain.clear();
LancasterUniversity 1137:290d499dd0e8 479 updatesEnabledCallback = NULL;
LancasterUniversity 1137:290d499dd0e8 480 updatesDisabledCallback = NULL;
LancasterUniversity 1137:290d499dd0e8 481 confirmationReceivedCallback = NULL;
LancasterUniversity 1137:290d499dd0e8 482
LancasterUniversity 1137:290d499dd0e8 483 return BLE_ERROR_NONE;
LancasterUniversity 1137:290d499dd0e8 484 }
LancasterUniversity 1137:290d499dd0e8 485
rgrover1 710:b2e1a2660ec2 486 protected:
rgrover1 710:b2e1a2660ec2 487 uint8_t serviceCount;
rgrover1 710:b2e1a2660ec2 488 uint8_t characteristicCount;
rgrover1 710:b2e1a2660ec2 489
rgrover1 710:b2e1a2660ec2 490 private:
LancasterUniversity 1137:290d499dd0e8 491 DataSentCallbackChain_t dataSentCallChain;
LancasterUniversity 1137:290d499dd0e8 492 DataWrittenCallbackChain_t dataWrittenCallChain;
LancasterUniversity 1137:290d499dd0e8 493 DataReadCallbackChain_t dataReadCallChain;
LancasterUniversity 1137:290d499dd0e8 494 GattServerShutdownCallbackChain_t shutdownCallChain;
LancasterUniversity 1137:290d499dd0e8 495 EventCallback_t updatesEnabledCallback;
LancasterUniversity 1137:290d499dd0e8 496 EventCallback_t updatesDisabledCallback;
LancasterUniversity 1137:290d499dd0e8 497 EventCallback_t confirmationReceivedCallback;
rgrover1 710:b2e1a2660ec2 498
rgrover1 710:b2e1a2660ec2 499 private:
vcoubard 1048:efb29faf12fc 500 /* Disallow copy and assignment. */
rgrover1 710:b2e1a2660ec2 501 GattServer(const GattServer &);
rgrover1 710:b2e1a2660ec2 502 GattServer& operator=(const GattServer &);
rgrover1 710:b2e1a2660ec2 503 };
rgrover1 710:b2e1a2660ec2 504
rgrover1 710:b2e1a2660ec2 505 #endif // ifndef __GATT_SERVER_H__