High level Bluetooth Low Energy API and radio abstraction layer

Dependents:   BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate BLE_ANCS_SDAPI_IRC ... more

Overview

The BLE_API is a high level abstraction for using Bluetooth Low Energy on multiple platforms. For details and examples using the BLE_API please see the BLE_API Summary Page. Or click on the API Documentation tab above.

Supported Services

Supported services can be found in the BLE_API/services folder.

Committer:
rgrover1
Date:
Wed Dec 02 10:29:44 2015 +0000
Revision:
993:4d62b7967c11
Parent:
992:ca834f7ae8ed
Child:
1042:21a86ac7f5b1
Synchronized with git rev 12e27cd4
Author: Rohit Grover
Release 2.1.3
=============

* Improvements to CallChainOfFunctionPointerswithContext:
- add a `detach` function to be able to remove callbacks.
- detach function now return true if a function has been detached and
false otherwise.
- add a function call operator.
- use safe-bool idiom. see : http://www.artima.com/cppsource/safebool.html

* Add SafeBool class which allow to easily declare a safe bool operator in
c++03.

* Improvements to FunctionPointerWithContext:
- fix call propagation
- use safe bool idiom

* Add config file for generating Doxygen.

* Setup for onRadioNotification callback does not call initRadioNotification
anymore.

* GapAdvertisementData now handles replacement and appending of data fields
based on type. Some fields can be replaced with new values, and others
require the payload to be appended.

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. */
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 993:4d62b7967c11 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 993:4d62b7967c11 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 993:4d62b7967c11 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 993:4d62b7967c11 257 * @brief get the callback chain called when the event DATA_EVENT is triggered.
rgrover1 993:4d62b7967c11 258 */
rgrover1 993:4d62b7967c11 259 DataSentCallbackChain_t& onDataSent() {
rgrover1 993:4d62b7967c11 260 return dataSentCallChain;
rgrover1 993:4d62b7967c11 261 }
rgrover1 993:4d62b7967c11 262
rgrover1 993:4d62b7967c11 263 /**
rgrover1 993:4d62b7967c11 264 * Set up a callback for when an attribute has its value updated by or at the
rgrover1 993:4d62b7967c11 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 993:4d62b7967c11 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 993:4d62b7967c11 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 993:4d62b7967c11 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 993:4d62b7967c11 275 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 276 * some object.
rgrover1 993:4d62b7967c11 277 *
rgrover1 993:4d62b7967c11 278 * @Note It is possible to unregister a callback using onDataWritten().detach(callback)
rgrover1 710:b2e1a2660ec2 279 */
rgrover1 993:4d62b7967c11 280 void onDataWritten(const DataWrittenCallback_t& callback) {dataWrittenCallChain.add(callback);}
rgrover1 710:b2e1a2660ec2 281 template <typename T>
rgrover1 710:b2e1a2660ec2 282 void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) {
rgrover1 710:b2e1a2660ec2 283 dataWrittenCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 284 }
rgrover1 710:b2e1a2660ec2 285
rgrover1 710:b2e1a2660ec2 286 /**
rgrover1 993:4d62b7967c11 287 * @brief provide access to the callchain of data written event callbacks
rgrover1 993:4d62b7967c11 288 * It is possible to register callbacks using onDataWritten().add(callback);
rgrover1 993:4d62b7967c11 289 * It is possible to unregister callbacks using onDataWritten().detach(callback)
rgrover1 993:4d62b7967c11 290 * @return The data written event callbacks chain
rgrover1 993:4d62b7967c11 291 */
rgrover1 993:4d62b7967c11 292 DataWrittenCallbackChain_t& onDataWritten() {
rgrover1 993:4d62b7967c11 293 return dataWrittenCallChain;
rgrover1 993:4d62b7967c11 294 }
rgrover1 993:4d62b7967c11 295
rgrover1 993:4d62b7967c11 296 /**
rgrover1 710:b2e1a2660ec2 297 * Setup a callback to be invoked on the peripheral when an attribute is
rgrover1 710:b2e1a2660ec2 298 * being read by a remote client.
rgrover1 710:b2e1a2660ec2 299 *
rgrover1 993:4d62b7967c11 300 * @Note: This functionality may not be available on all underlying stacks.
rgrover1 710:b2e1a2660ec2 301 * You could use GattCharacteristic::setReadAuthorizationCallback() as an
rgrover1 826:00415ff9e2a7 302 * alternative. Refer to isOnDataReadAvailable().
rgrover1 710:b2e1a2660ec2 303 *
rgrover1 993:4d62b7967c11 304 * @Note: It is possible to chain together multiple onDataRead callbacks
rgrover1 710:b2e1a2660ec2 305 * (potentially from different modules of an application) to receive updates
rgrover1 710:b2e1a2660ec2 306 * to characteristics. Services may add their own onDataRead callbacks
rgrover1 710:b2e1a2660ec2 307 * behind the scenes to trap interesting events.
rgrover1 710:b2e1a2660ec2 308 *
rgrover1 993:4d62b7967c11 309 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 310 * some object.
rgrover1 710:b2e1a2660ec2 311 *
rgrover1 993:4d62b7967c11 312 * @Note It is possible to unregister a callback using onDataRead().detach(callback)
rgrover1 993:4d62b7967c11 313 *
rgrover1 710:b2e1a2660ec2 314 * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available;
rgrover1 710:b2e1a2660ec2 315 * else BLE_ERROR_NONE.
rgrover1 710:b2e1a2660ec2 316 */
rgrover1 993:4d62b7967c11 317 ble_error_t onDataRead(const DataReadCallback_t& callback) {
rgrover1 710:b2e1a2660ec2 318 if (!isOnDataReadAvailable()) {
rgrover1 710:b2e1a2660ec2 319 return BLE_ERROR_NOT_IMPLEMENTED;
rgrover1 710:b2e1a2660ec2 320 }
rgrover1 710:b2e1a2660ec2 321
rgrover1 710:b2e1a2660ec2 322 dataReadCallChain.add(callback);
rgrover1 710:b2e1a2660ec2 323 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 324 }
rgrover1 710:b2e1a2660ec2 325 template <typename T>
rgrover1 710:b2e1a2660ec2 326 ble_error_t onDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) {
rgrover1 710:b2e1a2660ec2 327 if (!isOnDataReadAvailable()) {
rgrover1 710:b2e1a2660ec2 328 return BLE_ERROR_NOT_IMPLEMENTED;
rgrover1 710:b2e1a2660ec2 329 }
rgrover1 710:b2e1a2660ec2 330
rgrover1 710:b2e1a2660ec2 331 dataReadCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 332 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 333 }
rgrover1 710:b2e1a2660ec2 334
rgrover1 710:b2e1a2660ec2 335 /**
rgrover1 993:4d62b7967c11 336 * @brief provide access to the callchain of data read event callbacks
rgrover1 993:4d62b7967c11 337 * It is possible to register callbacks using onDataRead().add(callback);
rgrover1 993:4d62b7967c11 338 * It is possible to unregister callbacks using onDataRead().detach(callback)
rgrover1 993:4d62b7967c11 339 * @return The data read event callbacks chain
rgrover1 993:4d62b7967c11 340 */
rgrover1 993:4d62b7967c11 341 DataReadCallbackChain_t& onDataRead() {
rgrover1 993:4d62b7967c11 342 return dataReadCallChain;
rgrover1 993:4d62b7967c11 343 }
rgrover1 993:4d62b7967c11 344
rgrover1 993:4d62b7967c11 345 /**
rgrover1 993:4d62b7967c11 346 * Set up a callback for when notifications or indications are enabled for a
rgrover1 993:4d62b7967c11 347 * characteristic on the local GATT server.
rgrover1 710:b2e1a2660ec2 348 */
rgrover1 710:b2e1a2660ec2 349 void onUpdatesEnabled(EventCallback_t callback) {updatesEnabledCallback = callback;}
rgrover1 710:b2e1a2660ec2 350
rgrover1 710:b2e1a2660ec2 351 /**
rgrover1 993:4d62b7967c11 352 * Set up a callback for when notifications or indications are disabled for a
rgrover1 993:4d62b7967c11 353 * characteristic on the local GATT server.
rgrover1 710:b2e1a2660ec2 354 */
rgrover1 710:b2e1a2660ec2 355 void onUpdatesDisabled(EventCallback_t callback) {updatesDisabledCallback = callback;}
rgrover1 710:b2e1a2660ec2 356
rgrover1 710:b2e1a2660ec2 357 /**
rgrover1 993:4d62b7967c11 358 * Set up a callback for when the GATT server receives a response for an
rgrover1 710:b2e1a2660ec2 359 * indication event sent previously.
rgrover1 710:b2e1a2660ec2 360 */
rgrover1 710:b2e1a2660ec2 361 void onConfirmationReceived(EventCallback_t callback) {confirmationReceivedCallback = callback;}
rgrover1 710:b2e1a2660ec2 362
rgrover1 710:b2e1a2660ec2 363 /* Entry points for the underlying stack to report events back to the user. */
rgrover1 710:b2e1a2660ec2 364 protected:
rgrover1 710:b2e1a2660ec2 365 void handleDataWrittenEvent(const GattWriteCallbackParams *params) {
rgrover1 993:4d62b7967c11 366 dataWrittenCallChain.call(params);
rgrover1 710:b2e1a2660ec2 367 }
rgrover1 710:b2e1a2660ec2 368
rgrover1 710:b2e1a2660ec2 369 void handleDataReadEvent(const GattReadCallbackParams *params) {
rgrover1 993:4d62b7967c11 370 dataReadCallChain.call(params);
rgrover1 710:b2e1a2660ec2 371 }
rgrover1 710:b2e1a2660ec2 372
rgrover1 728:997ba5e7b3b6 373 void handleEvent(GattServerEvents::gattEvent_e type, GattAttribute::Handle_t attributeHandle) {
rgrover1 710:b2e1a2660ec2 374 switch (type) {
rgrover1 710:b2e1a2660ec2 375 case GattServerEvents::GATT_EVENT_UPDATES_ENABLED:
rgrover1 710:b2e1a2660ec2 376 if (updatesEnabledCallback) {
rgrover1 728:997ba5e7b3b6 377 updatesEnabledCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 378 }
rgrover1 710:b2e1a2660ec2 379 break;
rgrover1 710:b2e1a2660ec2 380 case GattServerEvents::GATT_EVENT_UPDATES_DISABLED:
rgrover1 710:b2e1a2660ec2 381 if (updatesDisabledCallback) {
rgrover1 728:997ba5e7b3b6 382 updatesDisabledCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 383 }
rgrover1 710:b2e1a2660ec2 384 break;
rgrover1 710:b2e1a2660ec2 385 case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED:
rgrover1 710:b2e1a2660ec2 386 if (confirmationReceivedCallback) {
rgrover1 728:997ba5e7b3b6 387 confirmationReceivedCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 388 }
rgrover1 710:b2e1a2660ec2 389 break;
rgrover1 710:b2e1a2660ec2 390 default:
rgrover1 710:b2e1a2660ec2 391 break;
rgrover1 710:b2e1a2660ec2 392 }
rgrover1 710:b2e1a2660ec2 393 }
rgrover1 710:b2e1a2660ec2 394
rgrover1 710:b2e1a2660ec2 395 void handleDataSentEvent(unsigned count) {
rgrover1 993:4d62b7967c11 396 dataSentCallChain.call(count);
rgrover1 710:b2e1a2660ec2 397 }
rgrover1 710:b2e1a2660ec2 398
rgrover1 710:b2e1a2660ec2 399 protected:
rgrover1 710:b2e1a2660ec2 400 uint8_t serviceCount;
rgrover1 710:b2e1a2660ec2 401 uint8_t characteristicCount;
rgrover1 710:b2e1a2660ec2 402
rgrover1 710:b2e1a2660ec2 403 private:
rgrover1 993:4d62b7967c11 404 DataSentCallbackChain_t dataSentCallChain;
rgrover1 993:4d62b7967c11 405 DataWrittenCallbackChain_t dataWrittenCallChain;
rgrover1 993:4d62b7967c11 406 DataReadCallbackChain_t dataReadCallChain;
rgrover1 993:4d62b7967c11 407 EventCallback_t updatesEnabledCallback;
rgrover1 993:4d62b7967c11 408 EventCallback_t updatesDisabledCallback;
rgrover1 993:4d62b7967c11 409 EventCallback_t confirmationReceivedCallback;
rgrover1 710:b2e1a2660ec2 410
rgrover1 710:b2e1a2660ec2 411 private:
rgrover1 993:4d62b7967c11 412 /* Disallow copy and assignment. */
rgrover1 710:b2e1a2660ec2 413 GattServer(const GattServer &);
rgrover1 710:b2e1a2660ec2 414 GattServer& operator=(const GattServer &);
rgrover1 710:b2e1a2660ec2 415 };
rgrover1 710:b2e1a2660ec2 416
rgrover1 710:b2e1a2660ec2 417 #endif // ifndef __GATT_SERVER_H__