d

Fork of BLE_API by Bluetooth Low Energy

Committer:
didierlauwerys
Date:
Sun May 28 16:24:51 2017 +0000
Revision:
1209:d3985c47e5c9
Parent:
993:4d62b7967c11
finished project;

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 993:4d62b7967c11 29
rgrover1 710:b2e1a2660ec2 30 /* Event callback handlers. */
rgrover1 993:4d62b7967c11 31 typedef FunctionPointerWithContext<unsigned> DataSentCallback_t;
rgrover1 993:4d62b7967c11 32 typedef CallChainOfFunctionPointersWithContext<unsigned> DataSentCallbackChain_t;
rgrover1 993:4d62b7967c11 33
rgrover1 993:4d62b7967c11 34 typedef FunctionPointerWithContext<const GattWriteCallbackParams*> DataWrittenCallback_t;
rgrover1 993:4d62b7967c11 35 typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*> DataWrittenCallbackChain_t;
rgrover1 993:4d62b7967c11 36
rgrover1 993:4d62b7967c11 37 typedef FunctionPointerWithContext<const GattReadCallbackParams*> DataReadCallback_t;
rgrover1 993:4d62b7967c11 38 typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams *> DataReadCallbackChain_t;
rgrover1 993:4d62b7967c11 39
rgrover1 993:4d62b7967c11 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) {
rgrover1 993:4d62b7967c11 65 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 66 (void)service;
rgrover1 734:4872b70437ce 67
rgrover1 993:4d62b7967c11 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 /**
rgrover1 993:4d62b7967c11 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) {
rgrover1 993:4d62b7967c11 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
rgrover1 993:4d62b7967c11 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 /**
rgrover1 993:4d62b7967c11 96 * Read the value of a characteristic from the local GATT server.
rgrover1 710:b2e1a2660ec2 97 * @param[in] connectionHandle
rgrover1 993:4d62b7967c11 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 *
rgrover1 993:4d62b7967c11 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) {
rgrover1 993:4d62b7967c11 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
rgrover1 993:4d62b7967c11 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 /**
rgrover1 993:4d62b7967c11 127 * Update the value of a characteristic on the local GATT server.
rgrover1 710:b2e1a2660ec2 128 *
rgrover1 710:b2e1a2660ec2 129 * @param[in] attributeHandle
rgrover1 993:4d62b7967c11 130 * Handle for the value attribute of the characteristic.
rgrover1 710:b2e1a2660ec2 131 * @param[in] value
rgrover1 993:4d62b7967c11 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
rgrover1 993:4d62b7967c11 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) {
rgrover1 993:4d62b7967c11 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
rgrover1 993:4d62b7967c11 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 /**
rgrover1 993:4d62b7967c11 155 * Update the value of a characteristic on the local GATT server. A version
rgrover1 993:4d62b7967c11 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
rgrover1 993:4d62b7967c11 160 * Connection handle.
rgrover1 710:b2e1a2660ec2 161 * @param[in] attributeHandle
rgrover1 993:4d62b7967c11 162 * Handle for the value attribute of the characteristic.
rgrover1 710:b2e1a2660ec2 163 * @param[in] value
rgrover1 993:4d62b7967c11 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) {
rgrover1 993:4d62b7967c11 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
rgrover1 993:4d62b7967c11 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 /**
rgrover1 993:4d62b7967c11 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
rgrover1 993:4d62b7967c11 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 *
rgrover1 993:4d62b7967c11 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) {
rgrover1 993:4d62b7967c11 198 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 199 (void)characteristic;
rgrover1 734:4872b70437ce 200 (void)enabledP;
rgrover1 734:4872b70437ce 201
rgrover1 993:4d62b7967c11 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 /**
rgrover1 993:4d62b7967c11 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
rgrover1 993:4d62b7967c11 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
rgrover1 993:4d62b7967c11 214 * The characteristic.
rgrover1 728:997ba5e7b3b6 215 *
rgrover1 993:4d62b7967c11 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) {
rgrover1 993:4d62b7967c11 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
rgrover1 993:4d62b7967c11 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 {
rgrover1 993:4d62b7967c11 232 return false; /* Requesting action from porters: override this API if this capability is supported. */
didierlauwerys 1209:d3985c47e5c9 233 //return true;
rgrover1 710:b2e1a2660ec2 234 }
rgrover1 710:b2e1a2660ec2 235
rgrover1 710:b2e1a2660ec2 236 /*
rgrover1 710:b2e1a2660ec2 237 * APIs with non-virtual implementations.
rgrover1 710:b2e1a2660ec2 238 */
rgrover1 710:b2e1a2660ec2 239 public:
rgrover1 710:b2e1a2660ec2 240 /**
rgrover1 710:b2e1a2660ec2 241 * Add a callback for the GATT event DATA_SENT (which is triggered when
rgrover1 710:b2e1a2660ec2 242 * updates are sent out by GATT in the form of notifications).
rgrover1 710:b2e1a2660ec2 243 *
rgrover1 993:4d62b7967c11 244 * @Note: It is possible to chain together multiple onDataSent callbacks
rgrover1 710:b2e1a2660ec2 245 * (potentially from different modules of an application) to receive updates
rgrover1 710:b2e1a2660ec2 246 * to characteristics.
rgrover1 710:b2e1a2660ec2 247 *
rgrover1 993:4d62b7967c11 248 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 249 * some object.
rgrover1 710:b2e1a2660ec2 250 */
rgrover1 993:4d62b7967c11 251 void onDataSent(const DataSentCallback_t& callback) {dataSentCallChain.add(callback);}
rgrover1 710:b2e1a2660ec2 252 template <typename T>
rgrover1 710:b2e1a2660ec2 253 void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) {
rgrover1 710:b2e1a2660ec2 254 dataSentCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 255 }
rgrover1 710:b2e1a2660ec2 256
rgrover1 710:b2e1a2660ec2 257 /**
rgrover1 993:4d62b7967c11 258 * @brief get the callback chain called when the event DATA_EVENT is triggered.
rgrover1 993:4d62b7967c11 259 */
rgrover1 993:4d62b7967c11 260 DataSentCallbackChain_t& onDataSent() {
rgrover1 993:4d62b7967c11 261 return dataSentCallChain;
rgrover1 993:4d62b7967c11 262 }
rgrover1 993:4d62b7967c11 263
rgrover1 993:4d62b7967c11 264 /**
rgrover1 993:4d62b7967c11 265 * Set up a callback for when an attribute has its value updated by or at the
rgrover1 993:4d62b7967c11 266 * connected peer. For a peripheral, this callback is triggered when the local
rgrover1 710:b2e1a2660ec2 267 * GATT server has an attribute updated by a write command from the peer.
rgrover1 993:4d62b7967c11 268 * For a central, this callback is triggered when a response is received for
rgrover1 710:b2e1a2660ec2 269 * a write request.
rgrover1 710:b2e1a2660ec2 270 *
rgrover1 993:4d62b7967c11 271 * @Note: It is possible to chain together multiple onDataWritten callbacks
rgrover1 710:b2e1a2660ec2 272 * (potentially from different modules of an application) to receive updates
rgrover1 993:4d62b7967c11 273 * to characteristics. Many services, such as DFU and UART, add their own
rgrover1 710:b2e1a2660ec2 274 * onDataWritten callbacks behind the scenes to trap interesting events.
rgrover1 710:b2e1a2660ec2 275 *
rgrover1 993:4d62b7967c11 276 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 277 * some object.
rgrover1 993:4d62b7967c11 278 *
rgrover1 993:4d62b7967c11 279 * @Note It is possible to unregister a callback using onDataWritten().detach(callback)
rgrover1 710:b2e1a2660ec2 280 */
rgrover1 993:4d62b7967c11 281 void onDataWritten(const DataWrittenCallback_t& callback) {dataWrittenCallChain.add(callback);}
rgrover1 710:b2e1a2660ec2 282 template <typename T>
rgrover1 710:b2e1a2660ec2 283 void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) {
rgrover1 710:b2e1a2660ec2 284 dataWrittenCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 285 }
rgrover1 710:b2e1a2660ec2 286
rgrover1 710:b2e1a2660ec2 287 /**
rgrover1 993:4d62b7967c11 288 * @brief provide access to the callchain of data written event callbacks
rgrover1 993:4d62b7967c11 289 * It is possible to register callbacks using onDataWritten().add(callback);
rgrover1 993:4d62b7967c11 290 * It is possible to unregister callbacks using onDataWritten().detach(callback)
rgrover1 993:4d62b7967c11 291 * @return The data written event callbacks chain
rgrover1 993:4d62b7967c11 292 */
rgrover1 993:4d62b7967c11 293 DataWrittenCallbackChain_t& onDataWritten() {
rgrover1 993:4d62b7967c11 294 return dataWrittenCallChain;
rgrover1 993:4d62b7967c11 295 }
rgrover1 993:4d62b7967c11 296
rgrover1 993:4d62b7967c11 297 /**
rgrover1 710:b2e1a2660ec2 298 * Setup a callback to be invoked on the peripheral when an attribute is
rgrover1 710:b2e1a2660ec2 299 * being read by a remote client.
rgrover1 710:b2e1a2660ec2 300 *
rgrover1 993:4d62b7967c11 301 * @Note: This functionality may not be available on all underlying stacks.
rgrover1 710:b2e1a2660ec2 302 * You could use GattCharacteristic::setReadAuthorizationCallback() as an
rgrover1 826:00415ff9e2a7 303 * alternative. Refer to isOnDataReadAvailable().
rgrover1 710:b2e1a2660ec2 304 *
rgrover1 993:4d62b7967c11 305 * @Note: It is possible to chain together multiple onDataRead callbacks
rgrover1 710:b2e1a2660ec2 306 * (potentially from different modules of an application) to receive updates
rgrover1 710:b2e1a2660ec2 307 * to characteristics. Services may add their own onDataRead callbacks
rgrover1 710:b2e1a2660ec2 308 * behind the scenes to trap interesting events.
rgrover1 710:b2e1a2660ec2 309 *
rgrover1 993:4d62b7967c11 310 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 311 * some object.
rgrover1 710:b2e1a2660ec2 312 *
rgrover1 993:4d62b7967c11 313 * @Note It is possible to unregister a callback using onDataRead().detach(callback)
rgrover1 993:4d62b7967c11 314 *
rgrover1 710:b2e1a2660ec2 315 * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available;
rgrover1 710:b2e1a2660ec2 316 * else BLE_ERROR_NONE.
rgrover1 710:b2e1a2660ec2 317 */
rgrover1 993:4d62b7967c11 318 ble_error_t onDataRead(const DataReadCallback_t& callback) {
rgrover1 710:b2e1a2660ec2 319 if (!isOnDataReadAvailable()) {
rgrover1 710:b2e1a2660ec2 320 return BLE_ERROR_NOT_IMPLEMENTED;
rgrover1 710:b2e1a2660ec2 321 }
rgrover1 710:b2e1a2660ec2 322
rgrover1 710:b2e1a2660ec2 323 dataReadCallChain.add(callback);
rgrover1 710:b2e1a2660ec2 324 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 325 }
rgrover1 710:b2e1a2660ec2 326 template <typename T>
rgrover1 710:b2e1a2660ec2 327 ble_error_t onDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) {
rgrover1 710:b2e1a2660ec2 328 if (!isOnDataReadAvailable()) {
rgrover1 710:b2e1a2660ec2 329 return BLE_ERROR_NOT_IMPLEMENTED;
rgrover1 710:b2e1a2660ec2 330 }
rgrover1 710:b2e1a2660ec2 331
rgrover1 710:b2e1a2660ec2 332 dataReadCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 333 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 334 }
rgrover1 710:b2e1a2660ec2 335
rgrover1 710:b2e1a2660ec2 336 /**
rgrover1 993:4d62b7967c11 337 * @brief provide access to the callchain of data read event callbacks
rgrover1 993:4d62b7967c11 338 * It is possible to register callbacks using onDataRead().add(callback);
rgrover1 993:4d62b7967c11 339 * It is possible to unregister callbacks using onDataRead().detach(callback)
rgrover1 993:4d62b7967c11 340 * @return The data read event callbacks chain
rgrover1 993:4d62b7967c11 341 */
rgrover1 993:4d62b7967c11 342 DataReadCallbackChain_t& onDataRead() {
rgrover1 993:4d62b7967c11 343 return dataReadCallChain;
rgrover1 993:4d62b7967c11 344 }
rgrover1 993:4d62b7967c11 345
rgrover1 993:4d62b7967c11 346 /**
rgrover1 993:4d62b7967c11 347 * Set up a callback for when notifications or indications are enabled for a
rgrover1 993:4d62b7967c11 348 * characteristic on the local GATT server.
rgrover1 710:b2e1a2660ec2 349 */
rgrover1 710:b2e1a2660ec2 350 void onUpdatesEnabled(EventCallback_t callback) {updatesEnabledCallback = callback;}
rgrover1 710:b2e1a2660ec2 351
rgrover1 710:b2e1a2660ec2 352 /**
rgrover1 993:4d62b7967c11 353 * Set up a callback for when notifications or indications are disabled for a
rgrover1 993:4d62b7967c11 354 * characteristic on the local GATT server.
rgrover1 710:b2e1a2660ec2 355 */
rgrover1 710:b2e1a2660ec2 356 void onUpdatesDisabled(EventCallback_t callback) {updatesDisabledCallback = callback;}
rgrover1 710:b2e1a2660ec2 357
rgrover1 710:b2e1a2660ec2 358 /**
rgrover1 993:4d62b7967c11 359 * Set up a callback for when the GATT server receives a response for an
rgrover1 710:b2e1a2660ec2 360 * indication event sent previously.
rgrover1 710:b2e1a2660ec2 361 */
rgrover1 710:b2e1a2660ec2 362 void onConfirmationReceived(EventCallback_t callback) {confirmationReceivedCallback = callback;}
rgrover1 710:b2e1a2660ec2 363
rgrover1 710:b2e1a2660ec2 364 /* Entry points for the underlying stack to report events back to the user. */
rgrover1 710:b2e1a2660ec2 365 protected:
rgrover1 710:b2e1a2660ec2 366 void handleDataWrittenEvent(const GattWriteCallbackParams *params) {
rgrover1 993:4d62b7967c11 367 dataWrittenCallChain.call(params);
rgrover1 710:b2e1a2660ec2 368 }
rgrover1 710:b2e1a2660ec2 369
rgrover1 710:b2e1a2660ec2 370 void handleDataReadEvent(const GattReadCallbackParams *params) {
rgrover1 993:4d62b7967c11 371 dataReadCallChain.call(params);
rgrover1 710:b2e1a2660ec2 372 }
rgrover1 710:b2e1a2660ec2 373
rgrover1 728:997ba5e7b3b6 374 void handleEvent(GattServerEvents::gattEvent_e type, GattAttribute::Handle_t attributeHandle) {
rgrover1 710:b2e1a2660ec2 375 switch (type) {
rgrover1 710:b2e1a2660ec2 376 case GattServerEvents::GATT_EVENT_UPDATES_ENABLED:
rgrover1 710:b2e1a2660ec2 377 if (updatesEnabledCallback) {
rgrover1 728:997ba5e7b3b6 378 updatesEnabledCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 379 }
rgrover1 710:b2e1a2660ec2 380 break;
rgrover1 710:b2e1a2660ec2 381 case GattServerEvents::GATT_EVENT_UPDATES_DISABLED:
rgrover1 710:b2e1a2660ec2 382 if (updatesDisabledCallback) {
rgrover1 728:997ba5e7b3b6 383 updatesDisabledCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 384 }
rgrover1 710:b2e1a2660ec2 385 break;
rgrover1 710:b2e1a2660ec2 386 case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED:
rgrover1 710:b2e1a2660ec2 387 if (confirmationReceivedCallback) {
rgrover1 728:997ba5e7b3b6 388 confirmationReceivedCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 389 }
rgrover1 710:b2e1a2660ec2 390 break;
rgrover1 710:b2e1a2660ec2 391 default:
rgrover1 710:b2e1a2660ec2 392 break;
rgrover1 710:b2e1a2660ec2 393 }
rgrover1 710:b2e1a2660ec2 394 }
rgrover1 710:b2e1a2660ec2 395
rgrover1 710:b2e1a2660ec2 396 void handleDataSentEvent(unsigned count) {
rgrover1 993:4d62b7967c11 397 dataSentCallChain.call(count);
rgrover1 710:b2e1a2660ec2 398 }
rgrover1 710:b2e1a2660ec2 399
rgrover1 710:b2e1a2660ec2 400 protected:
rgrover1 710:b2e1a2660ec2 401 uint8_t serviceCount;
rgrover1 710:b2e1a2660ec2 402 uint8_t characteristicCount;
rgrover1 710:b2e1a2660ec2 403
rgrover1 710:b2e1a2660ec2 404 private:
rgrover1 993:4d62b7967c11 405 DataSentCallbackChain_t dataSentCallChain;
rgrover1 993:4d62b7967c11 406 DataWrittenCallbackChain_t dataWrittenCallChain;
rgrover1 993:4d62b7967c11 407 DataReadCallbackChain_t dataReadCallChain;
rgrover1 993:4d62b7967c11 408 EventCallback_t updatesEnabledCallback;
rgrover1 993:4d62b7967c11 409 EventCallback_t updatesDisabledCallback;
rgrover1 993:4d62b7967c11 410 EventCallback_t confirmationReceivedCallback;
rgrover1 710:b2e1a2660ec2 411
rgrover1 710:b2e1a2660ec2 412 private:
rgrover1 993:4d62b7967c11 413 /* Disallow copy and assignment. */
rgrover1 710:b2e1a2660ec2 414 GattServer(const GattServer &);
rgrover1 710:b2e1a2660ec2 415 GattServer& operator=(const GattServer &);
rgrover1 710:b2e1a2660ec2 416 };
rgrover1 710:b2e1a2660ec2 417
rgrover1 710:b2e1a2660ec2 418 #endif // ifndef __GATT_SERVER_H__