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:
Thu Nov 26 12:52:35 2015 +0000
Revision:
969:61f13bc8edbf
Parent:
966:9451b90bbb66
Child:
970:b3e45745026d
Synchronized with git rev 184d29c3
Author: Vincent Coubard
Various enhancement:

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

CallChainOfFunctionPointerswithContext:
- unify syntax of add
- detach function now return true if a function has been detached and
false otherwise
- Explanations about function call operator
- use safe bool idiom
- explanations about iterator and why it is mutable

FunctionPointerWithContext:
- fix call propagation
- use safe bool idiom

Gap:
- add documentation
- onRadioNotification does mot call initRadioNotification anymore

GattClient:
- documentation

GattServer:
- documentation

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 969:61f13bc8edbf 29
rgrover1 710:b2e1a2660ec2 30 /* Event callback handlers. */
rgrover1 969:61f13bc8edbf 31 typedef FunctionPointerWithContext<unsigned> DataSentCallback_t;
rgrover1 969:61f13bc8edbf 32 typedef CallChainOfFunctionPointersWithContext<unsigned> DataSentCallbackChain_t;
rgrover1 969:61f13bc8edbf 33
rgrover1 969:61f13bc8edbf 34 typedef FunctionPointerWithContext<const GattWriteCallbackParams*> DataWrittenCallback_t;
rgrover1 969:61f13bc8edbf 35 typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*> DataWrittenCallbackChain_t;
rgrover1 969:61f13bc8edbf 36
rgrover1 969:61f13bc8edbf 37 typedef FunctionPointerWithContext<const GattReadCallbackParams*> DataReadCallback_t;
rgrover1 969:61f13bc8edbf 38 typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams *> DataReadCallbackChain_t;
rgrover1 969:61f13bc8edbf 39
rgrover1 969:61f13bc8edbf 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 969:61f13bc8edbf 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 969:61f13bc8edbf 257 * @brief get the callback chain called when the event DATA_EVENT is triggered.
rgrover1 969:61f13bc8edbf 258 */
rgrover1 969:61f13bc8edbf 259 DataSentCallbackChain_t& onDataSent() {
rgrover1 969:61f13bc8edbf 260 return dataSentCallChain;
rgrover1 969:61f13bc8edbf 261 }
rgrover1 969:61f13bc8edbf 262
rgrover1 969:61f13bc8edbf 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 969:61f13bc8edbf 277 *
rgrover1 969:61f13bc8edbf 278 * @Note It is possible to unregister a callback using onDataWritten().detach(callback)
rgrover1 710:b2e1a2660ec2 279 */
rgrover1 969:61f13bc8edbf 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 969:61f13bc8edbf 287 * @brief provide access to the callchain of data written event callbacks
rgrover1 969:61f13bc8edbf 288 * It is possible to register callbacks using onDataWritten().add(callback);
rgrover1 969:61f13bc8edbf 289 * It is possible to unregister callbacks using onDataWritten().detach(callback)
rgrover1 969:61f13bc8edbf 290 * @return The data written event callbacks chain
rgrover1 969:61f13bc8edbf 291 */
rgrover1 969:61f13bc8edbf 292 DataWrittenCallbackChain_t& onDataWritten() {
rgrover1 969:61f13bc8edbf 293 return dataWrittenCallChain;
rgrover1 969:61f13bc8edbf 294 }
rgrover1 969:61f13bc8edbf 295
rgrover1 969:61f13bc8edbf 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 937:4932e700daf2 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 937:4932e700daf2 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 937:4932e700daf2 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 969:61f13bc8edbf 312 * @Note It is possible to unregister a callback using onDataRead().detach(callback)
rgrover1 969:61f13bc8edbf 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 969:61f13bc8edbf 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 969:61f13bc8edbf 336 * @brief provide access to the callchain of data read event callbacks
rgrover1 969:61f13bc8edbf 337 * It is possible to register callbacks using onDataRead().add(callback);
rgrover1 969:61f13bc8edbf 338 * It is possible to unregister callbacks using onDataRead().detach(callback)
rgrover1 969:61f13bc8edbf 339 * @return The data read event callbacks chain
rgrover1 969:61f13bc8edbf 340 */
rgrover1 969:61f13bc8edbf 341 DataReadCallbackChain_t& onDataRead() {
rgrover1 969:61f13bc8edbf 342 return dataReadCallChain;
rgrover1 969:61f13bc8edbf 343 }
rgrover1 969:61f13bc8edbf 344
rgrover1 969:61f13bc8edbf 345 /**
rgrover1 937:4932e700daf2 346 * Set up a callback for when notifications or indications are enabled for a
rgrover1 937:4932e700daf2 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 937:4932e700daf2 352 * Set up a callback for when notifications or indications are disabled for a
rgrover1 937:4932e700daf2 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 937:4932e700daf2 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 969:61f13bc8edbf 366 dataWrittenCallChain.call(params);
rgrover1 710:b2e1a2660ec2 367 }
rgrover1 710:b2e1a2660ec2 368
rgrover1 710:b2e1a2660ec2 369 void handleDataReadEvent(const GattReadCallbackParams *params) {
rgrover1 969:61f13bc8edbf 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 969:61f13bc8edbf 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 969:61f13bc8edbf 404 DataSentCallbackChain_t dataSentCallChain;
rgrover1 969:61f13bc8edbf 405 DataWrittenCallbackChain_t dataWrittenCallChain;
rgrover1 969:61f13bc8edbf 406 DataReadCallbackChain_t dataReadCallChain;
rgrover1 969:61f13bc8edbf 407 EventCallback_t updatesEnabledCallback;
rgrover1 969:61f13bc8edbf 408 EventCallback_t updatesDisabledCallback;
rgrover1 969:61f13bc8edbf 409 EventCallback_t confirmationReceivedCallback;
rgrover1 710:b2e1a2660ec2 410
rgrover1 710:b2e1a2660ec2 411 private:
rgrover1 937:4932e700daf2 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__