just a fork

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Thu Nov 26 12:52:34 2015 +0000
Revision:
959:d99a4565f872
Parent:
949:1902cbd0dd83
Child:
966:9451b90bbb66
Synchronized with git rev 57ad5334
Author: Vincent Coubard
Add typedef for FunctionPointerWithContext and CallChains.
Provide access to Callchains

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