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

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

Fork of BLE_API by Bluetooth Low Energy

Committer:
LancasterUniversity
Date:
Wed Apr 06 18:40:40 2016 +0100
Revision:
1140:dd2f69fad8c6
Parent:
1138:6aabbb5f81e6
Synchronized with git rev bbc2dc58
Author: Joe Finney
microbit: Additional callback to indicate to applications when System
Attributes require initialisation from persistent storage.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 710:b2e1a2660ec2 1 /* mbed Microcontroller Library
rgrover1 710:b2e1a2660ec2 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 710:b2e1a2660ec2 3 *
rgrover1 710:b2e1a2660ec2 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 710:b2e1a2660ec2 5 * you may not use this file except in compliance with the License.
rgrover1 710:b2e1a2660ec2 6 * You may obtain a copy of the License at
rgrover1 710:b2e1a2660ec2 7 *
rgrover1 710:b2e1a2660ec2 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 710:b2e1a2660ec2 9 *
rgrover1 710:b2e1a2660ec2 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 710:b2e1a2660ec2 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 710:b2e1a2660ec2 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 710:b2e1a2660ec2 13 * See the License for the specific language governing permissions and
rgrover1 710:b2e1a2660ec2 14 * limitations under the License.
rgrover1 710:b2e1a2660ec2 15 */
rgrover1 710:b2e1a2660ec2 16
rgrover1 710:b2e1a2660ec2 17 #ifndef __GATT_SERVER_H__
rgrover1 710:b2e1a2660ec2 18 #define __GATT_SERVER_H__
rgrover1 710:b2e1a2660ec2 19
rgrover1 710:b2e1a2660ec2 20 #include "Gap.h"
rgrover1 710:b2e1a2660ec2 21 #include "GattService.h"
rgrover1 710:b2e1a2660ec2 22 #include "GattAttribute.h"
rgrover1 710:b2e1a2660ec2 23 #include "GattServerEvents.h"
rgrover1 710:b2e1a2660ec2 24 #include "GattCallbackParamTypes.h"
rgrover1 710:b2e1a2660ec2 25 #include "CallChainOfFunctionPointersWithContext.h"
rgrover1 710:b2e1a2660ec2 26
rgrover1 710:b2e1a2660ec2 27 class GattServer {
rgrover1 710:b2e1a2660ec2 28 public:
rgrover1 710:b2e1a2660ec2 29 /* Event callback handlers. */
vcoubard 1052:b55e1ad3e1b3 30 typedef FunctionPointerWithContext<unsigned> DataSentCallback_t;
vcoubard 1052:b55e1ad3e1b3 31 typedef CallChainOfFunctionPointersWithContext<unsigned> DataSentCallbackChain_t;
vcoubard 1052:b55e1ad3e1b3 32
vcoubard 1052:b55e1ad3e1b3 33 typedef FunctionPointerWithContext<const GattWriteCallbackParams*> DataWrittenCallback_t;
LancasterUniversity 1137:290d499dd0e8 34 typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*> DataWrittenCallbackChain_t;
vcoubard 1052:b55e1ad3e1b3 35
vcoubard 1052:b55e1ad3e1b3 36 typedef FunctionPointerWithContext<const GattReadCallbackParams*> DataReadCallback_t;
vcoubard 1052:b55e1ad3e1b3 37 typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams *> DataReadCallbackChain_t;
vcoubard 1052:b55e1ad3e1b3 38
LancasterUniversity 1137:290d499dd0e8 39 typedef FunctionPointerWithContext<const GattServer *> GattServerShutdownCallback_t;
LancasterUniversity 1137:290d499dd0e8 40 typedef CallChainOfFunctionPointersWithContext<const GattServer *> GattServerShutdownCallbackChain_t;
LancasterUniversity 1137:290d499dd0e8 41
LancasterUniversity 1140:dd2f69fad8c6 42 typedef FunctionPointerWithContext<const GattSysAttrMissingCallbackParams*> SysAttrMissingCallback_t;
LancasterUniversity 1140:dd2f69fad8c6 43 typedef CallChainOfFunctionPointersWithContext<const GattSysAttrMissingCallbackParams*> SysAttrMissingCallbackChain_t;
LancasterUniversity 1140:dd2f69fad8c6 44
vcoubard 1052:b55e1ad3e1b3 45 typedef FunctionPointerWithContext<GattAttribute::Handle_t> EventCallback_t;
rgrover1 710:b2e1a2660ec2 46
rgrover1 710:b2e1a2660ec2 47 protected:
rgrover1 710:b2e1a2660ec2 48 GattServer() :
rgrover1 710:b2e1a2660ec2 49 serviceCount(0),
rgrover1 710:b2e1a2660ec2 50 characteristicCount(0),
rgrover1 710:b2e1a2660ec2 51 dataSentCallChain(),
rgrover1 710:b2e1a2660ec2 52 dataWrittenCallChain(),
rgrover1 710:b2e1a2660ec2 53 dataReadCallChain(),
LancasterUniversity 1140:dd2f69fad8c6 54 sysAttrMissingCallChain(),
rgrover1 710:b2e1a2660ec2 55 updatesEnabledCallback(NULL),
rgrover1 710:b2e1a2660ec2 56 updatesDisabledCallback(NULL),
rgrover1 710:b2e1a2660ec2 57 confirmationReceivedCallback(NULL) {
rgrover1 710:b2e1a2660ec2 58 /* empty */
rgrover1 710:b2e1a2660ec2 59 }
rgrover1 710:b2e1a2660ec2 60
rgrover1 710:b2e1a2660ec2 61 /*
rgrover1 710:b2e1a2660ec2 62 * The following functions are meant to be overridden in the platform-specific sub-class.
rgrover1 710:b2e1a2660ec2 63 */
rgrover1 710:b2e1a2660ec2 64 public:
rgrover1 710:b2e1a2660ec2 65
rgrover1 710:b2e1a2660ec2 66 /**
rgrover1 710:b2e1a2660ec2 67 * Add a service declaration to the local server ATT table. Also add the
rgrover1 710:b2e1a2660ec2 68 * characteristics contained within.
rgrover1 710:b2e1a2660ec2 69 */
rgrover1 734:4872b70437ce 70 virtual ble_error_t addService(GattService &service) {
vcoubard 1048:efb29faf12fc 71 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 72 (void)service;
rgrover1 734:4872b70437ce 73
vcoubard 1048:efb29faf12fc 74 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 75 }
rgrover1 710:b2e1a2660ec2 76
rgrover1 710:b2e1a2660ec2 77 /**
vcoubard 1048:efb29faf12fc 78 * Read the value of a characteristic from the local GATT server.
rgrover1 710:b2e1a2660ec2 79 * @param[in] attributeHandle
rgrover1 710:b2e1a2660ec2 80 * Attribute handle for the value attribute of the characteristic.
rgrover1 710:b2e1a2660ec2 81 * @param[out] buffer
rgrover1 710:b2e1a2660ec2 82 * A buffer to hold the value being read.
rgrover1 710:b2e1a2660ec2 83 * @param[in/out] lengthP
rgrover1 710:b2e1a2660ec2 84 * Length of the buffer being supplied. If the attribute
rgrover1 710:b2e1a2660ec2 85 * value is longer than the size of the supplied buffer,
rgrover1 710:b2e1a2660ec2 86 * this variable will hold upon return the total attribute value length
rgrover1 710:b2e1a2660ec2 87 * (excluding offset). The application may use this
rgrover1 710:b2e1a2660ec2 88 * information to allocate a suitable buffer size.
rgrover1 710:b2e1a2660ec2 89 *
rgrover1 710:b2e1a2660ec2 90 * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
rgrover1 710:b2e1a2660ec2 91 */
rgrover1 710:b2e1a2660ec2 92 virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) {
vcoubard 1048:efb29faf12fc 93 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 94 (void)attributeHandle;
rgrover1 734:4872b70437ce 95 (void)buffer;
rgrover1 734:4872b70437ce 96 (void)lengthP;
rgrover1 734:4872b70437ce 97
vcoubard 1048:efb29faf12fc 98 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 99 }
rgrover1 710:b2e1a2660ec2 100
rgrover1 710:b2e1a2660ec2 101 /**
vcoubard 1048:efb29faf12fc 102 * Read the value of a characteristic from the local GATT server.
rgrover1 710:b2e1a2660ec2 103 * @param[in] connectionHandle
vcoubard 1048:efb29faf12fc 104 * Connection handle.
rgrover1 710:b2e1a2660ec2 105 * @param[in] attributeHandle
rgrover1 710:b2e1a2660ec2 106 * Attribute handle for the value attribute of the characteristic.
rgrover1 710:b2e1a2660ec2 107 * @param[out] buffer
rgrover1 710:b2e1a2660ec2 108 * A buffer to hold the value being read.
rgrover1 710:b2e1a2660ec2 109 * @param[in/out] lengthP
rgrover1 710:b2e1a2660ec2 110 * Length of the buffer being supplied. If the attribute
rgrover1 710:b2e1a2660ec2 111 * value is longer than the size of the supplied buffer,
rgrover1 710:b2e1a2660ec2 112 * this variable will hold upon return the total attribute value length
rgrover1 710:b2e1a2660ec2 113 * (excluding offset). The application may use this
rgrover1 710:b2e1a2660ec2 114 * information to allocate a suitable buffer size.
rgrover1 710:b2e1a2660ec2 115 *
rgrover1 710:b2e1a2660ec2 116 * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
rgrover1 710:b2e1a2660ec2 117 *
vcoubard 1048:efb29faf12fc 118 * @note This API is a version of the above, with an additional connection handle
rgrover1 710:b2e1a2660ec2 119 * parameter to allow fetches for connection-specific multivalued
rgrover1 733:718a3566b4ce 120 * attributes (such as the CCCDs).
rgrover1 710:b2e1a2660ec2 121 */
rgrover1 710:b2e1a2660ec2 122 virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) {
vcoubard 1048:efb29faf12fc 123 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 124 (void)connectionHandle;
rgrover1 734:4872b70437ce 125 (void)attributeHandle;
rgrover1 734:4872b70437ce 126 (void)buffer;
rgrover1 734:4872b70437ce 127 (void)lengthP;
rgrover1 734:4872b70437ce 128
vcoubard 1048:efb29faf12fc 129 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 130 }
rgrover1 710:b2e1a2660ec2 131
rgrover1 710:b2e1a2660ec2 132 /**
vcoubard 1048:efb29faf12fc 133 * Update the value of a characteristic on the local GATT server.
rgrover1 710:b2e1a2660ec2 134 *
rgrover1 710:b2e1a2660ec2 135 * @param[in] attributeHandle
vcoubard 1048:efb29faf12fc 136 * Handle for the value attribute of the characteristic.
rgrover1 710:b2e1a2660ec2 137 * @param[in] value
vcoubard 1048:efb29faf12fc 138 * A pointer to a buffer holding the new value.
rgrover1 710:b2e1a2660ec2 139 * @param[in] size
rgrover1 710:b2e1a2660ec2 140 * Size of the new value (in bytes).
rgrover1 710:b2e1a2660ec2 141 * @param[in] localOnly
rgrover1 710:b2e1a2660ec2 142 * Should this update be kept on the local
vcoubard 1048:efb29faf12fc 143 * GATT server regardless of the state of the
rgrover1 710:b2e1a2660ec2 144 * notify/indicate flag in the CCCD for this
rgrover1 710:b2e1a2660ec2 145 * Characteristic? If set to true, no notification
rgrover1 710:b2e1a2660ec2 146 * or indication is generated.
rgrover1 710:b2e1a2660ec2 147 *
rgrover1 710:b2e1a2660ec2 148 * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
rgrover1 710:b2e1a2660ec2 149 */
rgrover1 734:4872b70437ce 150 virtual ble_error_t write(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false) {
vcoubard 1048:efb29faf12fc 151 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 152 (void)attributeHandle;
rgrover1 734:4872b70437ce 153 (void)value;
rgrover1 734:4872b70437ce 154 (void)size;
rgrover1 734:4872b70437ce 155 (void)localOnly;
rgrover1 734:4872b70437ce 156
vcoubard 1048:efb29faf12fc 157 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 158 }
rgrover1 710:b2e1a2660ec2 159
rgrover1 710:b2e1a2660ec2 160 /**
vcoubard 1048:efb29faf12fc 161 * Update the value of a characteristic on the local GATT server. A version
vcoubard 1048:efb29faf12fc 162 * of the same as the above, with a connection handle parameter to allow updates
rgrover1 733:718a3566b4ce 163 * for connection-specific multivalued attributes (such as the CCCDs).
rgrover1 710:b2e1a2660ec2 164 *
rgrover1 710:b2e1a2660ec2 165 * @param[in] connectionHandle
vcoubard 1048:efb29faf12fc 166 * Connection handle.
rgrover1 710:b2e1a2660ec2 167 * @param[in] attributeHandle
vcoubard 1048:efb29faf12fc 168 * Handle for the value attribute of the characteristic.
rgrover1 710:b2e1a2660ec2 169 * @param[in] value
vcoubard 1048:efb29faf12fc 170 * A pointer to a buffer holding the new value.
rgrover1 710:b2e1a2660ec2 171 * @param[in] size
rgrover1 710:b2e1a2660ec2 172 * Size of the new value (in bytes).
rgrover1 710:b2e1a2660ec2 173 * @param[in] localOnly
rgrover1 710:b2e1a2660ec2 174 * Should this update be kept on the local
rgrover1 710:b2e1a2660ec2 175 * GattServer regardless of the state of the
rgrover1 710:b2e1a2660ec2 176 * notify/indicate flag in the CCCD for this
rgrover1 710:b2e1a2660ec2 177 * Characteristic? If set to true, no notification
rgrover1 710:b2e1a2660ec2 178 * or indication is generated.
rgrover1 710:b2e1a2660ec2 179 *
rgrover1 710:b2e1a2660ec2 180 * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
rgrover1 710:b2e1a2660ec2 181 */
rgrover1 734:4872b70437ce 182 virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false) {
vcoubard 1048:efb29faf12fc 183 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 184 (void)connectionHandle;
rgrover1 734:4872b70437ce 185 (void)attributeHandle;
rgrover1 734:4872b70437ce 186 (void)value;
rgrover1 734:4872b70437ce 187 (void)size;
rgrover1 734:4872b70437ce 188 (void)localOnly;
rgrover1 734:4872b70437ce 189
vcoubard 1048:efb29faf12fc 190 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 728:997ba5e7b3b6 191 }
rgrover1 728:997ba5e7b3b6 192
rgrover1 728:997ba5e7b3b6 193 /**
LancasterUniversity 1138:6aabbb5f81e6 194 * Perform an explicit BLE notification of a given attribute.
LancasterUniversity 1138:6aabbb5f81e6 195 *
LancasterUniversity 1138:6aabbb5f81e6 196 * @param[in] attributeHandle
LancasterUniversity 1138:6aabbb5f81e6 197 * Handle for the value attribute of the Characteristic.
LancasterUniversity 1138:6aabbb5f81e6 198 * @param[in] value
LancasterUniversity 1138:6aabbb5f81e6 199 * A pointer to a buffer holding the new value
LancasterUniversity 1138:6aabbb5f81e6 200 * @param[in] size
LancasterUniversity 1138:6aabbb5f81e6 201 * Size of the new value (in bytes).
LancasterUniversity 1138:6aabbb5f81e6 202 *
LancasterUniversity 1138:6aabbb5f81e6 203 * @return BLE_ERROR_NONE if we have successfully set the value of the attribute.
LancasterUniversity 1138:6aabbb5f81e6 204 */
LancasterUniversity 1138:6aabbb5f81e6 205 virtual ble_error_t notify(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size)
LancasterUniversity 1138:6aabbb5f81e6 206 {
LancasterUniversity 1138:6aabbb5f81e6 207 (void)attributeHandle;
LancasterUniversity 1138:6aabbb5f81e6 208 (void)value;
LancasterUniversity 1138:6aabbb5f81e6 209 (void)size;
LancasterUniversity 1138:6aabbb5f81e6 210
LancasterUniversity 1138:6aabbb5f81e6 211 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */
LancasterUniversity 1138:6aabbb5f81e6 212 }
LancasterUniversity 1138:6aabbb5f81e6 213
LancasterUniversity 1138:6aabbb5f81e6 214 /**
vcoubard 1048:efb29faf12fc 215 * Determine the updates-enabled status (notification or indication) for the current connection from a characteristic's CCCD.
rgrover1 728:997ba5e7b3b6 216 *
rgrover1 728:997ba5e7b3b6 217 * @param characteristic
vcoubard 1048:efb29faf12fc 218 * The characteristic.
rgrover1 728:997ba5e7b3b6 219 * @param[out] enabledP
rgrover1 728:997ba5e7b3b6 220 * Upon return, *enabledP is true if updates are enabled, else false.
rgrover1 728:997ba5e7b3b6 221 *
vcoubard 1048:efb29faf12fc 222 * @return BLE_ERROR_NONE if the connection and handle are found. False otherwise.
rgrover1 728:997ba5e7b3b6 223 */
rgrover1 728:997ba5e7b3b6 224 virtual ble_error_t areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP) {
vcoubard 1048:efb29faf12fc 225 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 226 (void)characteristic;
rgrover1 734:4872b70437ce 227 (void)enabledP;
rgrover1 734:4872b70437ce 228
vcoubard 1048:efb29faf12fc 229 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 728:997ba5e7b3b6 230 }
rgrover1 728:997ba5e7b3b6 231
rgrover1 728:997ba5e7b3b6 232 /**
vcoubard 1048:efb29faf12fc 233 * Determine the connection-specific updates-enabled status (notification or indication) from a characteristic's CCCD.
rgrover1 728:997ba5e7b3b6 234 *
rgrover1 728:997ba5e7b3b6 235 * @param connectionHandle
vcoubard 1048:efb29faf12fc 236 * The connection handle.
rgrover1 728:997ba5e7b3b6 237 * @param[out] enabledP
rgrover1 728:997ba5e7b3b6 238 * Upon return, *enabledP is true if updates are enabled, else false.
rgrover1 728:997ba5e7b3b6 239 *
rgrover1 728:997ba5e7b3b6 240 * @param characteristic
vcoubard 1048:efb29faf12fc 241 * The characteristic.
rgrover1 728:997ba5e7b3b6 242 *
vcoubard 1048:efb29faf12fc 243 * @return BLE_ERROR_NONE if the connection and handle are found. False otherwise.
rgrover1 728:997ba5e7b3b6 244 */
rgrover1 728:997ba5e7b3b6 245 virtual ble_error_t areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP) {
vcoubard 1048:efb29faf12fc 246 /* Avoid compiler warnings about unused variables. */
rgrover1 734:4872b70437ce 247 (void)connectionHandle;
rgrover1 734:4872b70437ce 248 (void)characteristic;
rgrover1 734:4872b70437ce 249 (void)enabledP;
rgrover1 734:4872b70437ce 250
vcoubard 1048:efb29faf12fc 251 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 724:80e065731d70 252 }
rgrover1 724:80e065731d70 253
rgrover1 724:80e065731d70 254 /**
rgrover1 710:b2e1a2660ec2 255 * A virtual function to allow underlying stacks to indicate if they support
rgrover1 710:b2e1a2660ec2 256 * onDataRead(). It should be overridden to return true as applicable.
rgrover1 710:b2e1a2660ec2 257 */
rgrover1 710:b2e1a2660ec2 258 virtual bool isOnDataReadAvailable() const {
vcoubard 1048:efb29faf12fc 259 return false; /* Requesting action from porters: override this API if this capability is supported. */
rgrover1 710:b2e1a2660ec2 260 }
rgrover1 710:b2e1a2660ec2 261
rgrover1 710:b2e1a2660ec2 262 /*
rgrover1 710:b2e1a2660ec2 263 * APIs with non-virtual implementations.
rgrover1 710:b2e1a2660ec2 264 */
rgrover1 710:b2e1a2660ec2 265 public:
rgrover1 710:b2e1a2660ec2 266 /**
rgrover1 710:b2e1a2660ec2 267 * Add a callback for the GATT event DATA_SENT (which is triggered when
rgrover1 710:b2e1a2660ec2 268 * updates are sent out by GATT in the form of notifications).
rgrover1 710:b2e1a2660ec2 269 *
vcoubard 1048:efb29faf12fc 270 * @Note: It is possible to chain together multiple onDataSent callbacks
rgrover1 710:b2e1a2660ec2 271 * (potentially from different modules of an application) to receive updates
rgrover1 710:b2e1a2660ec2 272 * to characteristics.
rgrover1 710:b2e1a2660ec2 273 *
vcoubard 1048:efb29faf12fc 274 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 275 * some object.
rgrover1 710:b2e1a2660ec2 276 */
vcoubard 1052:b55e1ad3e1b3 277 void onDataSent(const DataSentCallback_t& callback) {dataSentCallChain.add(callback);}
rgrover1 710:b2e1a2660ec2 278 template <typename T>
rgrover1 710:b2e1a2660ec2 279 void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) {
rgrover1 710:b2e1a2660ec2 280 dataSentCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 281 }
rgrover1 710:b2e1a2660ec2 282
rgrover1 710:b2e1a2660ec2 283 /**
LancasterUniversity 1137:290d499dd0e8 284 * @brief get the callback chain called when the event DATA_EVENT is triggered.
vcoubard 1052:b55e1ad3e1b3 285 */
LancasterUniversity 1137:290d499dd0e8 286 DataSentCallbackChain_t& onDataSent() {
vcoubard 1052:b55e1ad3e1b3 287 return dataSentCallChain;
vcoubard 1052:b55e1ad3e1b3 288 }
vcoubard 1052:b55e1ad3e1b3 289
vcoubard 1052:b55e1ad3e1b3 290 /**
vcoubard 1048:efb29faf12fc 291 * Set up a callback for when an attribute has its value updated by or at the
vcoubard 1048:efb29faf12fc 292 * connected peer. For a peripheral, this callback is triggered when the local
rgrover1 710:b2e1a2660ec2 293 * GATT server has an attribute updated by a write command from the peer.
vcoubard 1048:efb29faf12fc 294 * For a central, this callback is triggered when a response is received for
rgrover1 710:b2e1a2660ec2 295 * a write request.
rgrover1 710:b2e1a2660ec2 296 *
vcoubard 1048:efb29faf12fc 297 * @Note: It is possible to chain together multiple onDataWritten callbacks
rgrover1 710:b2e1a2660ec2 298 * (potentially from different modules of an application) to receive updates
vcoubard 1048:efb29faf12fc 299 * to characteristics. Many services, such as DFU and UART, add their own
rgrover1 710:b2e1a2660ec2 300 * onDataWritten callbacks behind the scenes to trap interesting events.
rgrover1 710:b2e1a2660ec2 301 *
vcoubard 1048:efb29faf12fc 302 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 303 * some object.
LancasterUniversity 1137:290d499dd0e8 304 *
vcoubard 1052:b55e1ad3e1b3 305 * @Note It is possible to unregister a callback using onDataWritten().detach(callback)
rgrover1 710:b2e1a2660ec2 306 */
vcoubard 1052:b55e1ad3e1b3 307 void onDataWritten(const DataWrittenCallback_t& callback) {dataWrittenCallChain.add(callback);}
rgrover1 710:b2e1a2660ec2 308 template <typename T>
rgrover1 710:b2e1a2660ec2 309 void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) {
rgrover1 710:b2e1a2660ec2 310 dataWrittenCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 311 }
rgrover1 710:b2e1a2660ec2 312
rgrover1 710:b2e1a2660ec2 313 /**
vcoubard 1052:b55e1ad3e1b3 314 * @brief provide access to the callchain of data written event callbacks
vcoubard 1052:b55e1ad3e1b3 315 * It is possible to register callbacks using onDataWritten().add(callback);
LancasterUniversity 1137:290d499dd0e8 316 * It is possible to unregister callbacks using onDataWritten().detach(callback)
vcoubard 1052:b55e1ad3e1b3 317 * @return The data written event callbacks chain
LancasterUniversity 1137:290d499dd0e8 318 */
vcoubard 1052:b55e1ad3e1b3 319 DataWrittenCallbackChain_t& onDataWritten() {
vcoubard 1052:b55e1ad3e1b3 320 return dataWrittenCallChain;
vcoubard 1052:b55e1ad3e1b3 321 }
vcoubard 1052:b55e1ad3e1b3 322
vcoubard 1052:b55e1ad3e1b3 323 /**
LancasterUniversity 1140:dd2f69fad8c6 324 * Set up a callback for when asystem descriptor (CCCD) is missing.
LancasterUniversity 1140:dd2f69fad8c6 325 * This may be raised in response to a BLE profile change om a bonded connection.
LancasterUniversity 1140:dd2f69fad8c6 326 * This callback provides the opportunity for user applications to restore
LancasterUniversity 1140:dd2f69fad8c6 327 * CCCD state at the appropriate time.
LancasterUniversity 1140:dd2f69fad8c6 328 *
LancasterUniversity 1140:dd2f69fad8c6 329 * @Note: It is possible to chain together multiple onSysAttrMissing callbacks
LancasterUniversity 1140:dd2f69fad8c6 330 * (potentially from different modules of an application), although it is unlikely
LancasterUniversity 1140:dd2f69fad8c6 331 * that this will be beneficial.
LancasterUniversity 1140:dd2f69fad8c6 332 *
LancasterUniversity 1140:dd2f69fad8c6 333 * @Note: It is also possible to set up a callback into a member function of
LancasterUniversity 1140:dd2f69fad8c6 334 * some object.
LancasterUniversity 1140:dd2f69fad8c6 335 *
LancasterUniversity 1140:dd2f69fad8c6 336 * @Note It is possible to unregister a callback using onSysAttrMissing().detach(callback)
LancasterUniversity 1140:dd2f69fad8c6 337 */
LancasterUniversity 1140:dd2f69fad8c6 338 void onSysAttrMissing(const SysAttrMissingCallback_t& callback) {sysAttrMissingCallChain.add(callback);}
LancasterUniversity 1140:dd2f69fad8c6 339 template <typename T>
LancasterUniversity 1140:dd2f69fad8c6 340 void onSysAttrMissing(T *objPtr, void (T::*memberPtr)(const GattSysAttrMissingCallbackParams* connectionHandle)) {
LancasterUniversity 1140:dd2f69fad8c6 341 sysAttrMissingCallChain.add(objPtr, memberPtr);
LancasterUniversity 1140:dd2f69fad8c6 342 }
LancasterUniversity 1140:dd2f69fad8c6 343
LancasterUniversity 1140:dd2f69fad8c6 344 /**
LancasterUniversity 1140:dd2f69fad8c6 345 * @brief provide access to the callchain of data written event callbacks
LancasterUniversity 1140:dd2f69fad8c6 346 * It is possible to register callbacks using onDataWritten().add(callback);
LancasterUniversity 1140:dd2f69fad8c6 347 * It is possible to unregister callbacks using onDataWritten().detach(callback)
LancasterUniversity 1140:dd2f69fad8c6 348 * @return The data written event callbacks chain
LancasterUniversity 1140:dd2f69fad8c6 349 */
LancasterUniversity 1140:dd2f69fad8c6 350 SysAttrMissingCallbackChain_t& onSysAttrMissing() {
LancasterUniversity 1140:dd2f69fad8c6 351 return sysAttrMissingCallChain;
LancasterUniversity 1140:dd2f69fad8c6 352 }
LancasterUniversity 1140:dd2f69fad8c6 353 /**
rgrover1 710:b2e1a2660ec2 354 * Setup a callback to be invoked on the peripheral when an attribute is
rgrover1 710:b2e1a2660ec2 355 * being read by a remote client.
rgrover1 710:b2e1a2660ec2 356 *
vcoubard 1048:efb29faf12fc 357 * @Note: This functionality may not be available on all underlying stacks.
rgrover1 710:b2e1a2660ec2 358 * You could use GattCharacteristic::setReadAuthorizationCallback() as an
rgrover1 826:00415ff9e2a7 359 * alternative. Refer to isOnDataReadAvailable().
rgrover1 710:b2e1a2660ec2 360 *
vcoubard 1048:efb29faf12fc 361 * @Note: It is possible to chain together multiple onDataRead callbacks
rgrover1 710:b2e1a2660ec2 362 * (potentially from different modules of an application) to receive updates
rgrover1 710:b2e1a2660ec2 363 * to characteristics. Services may add their own onDataRead callbacks
rgrover1 710:b2e1a2660ec2 364 * behind the scenes to trap interesting events.
rgrover1 710:b2e1a2660ec2 365 *
vcoubard 1048:efb29faf12fc 366 * @Note: It is also possible to set up a callback into a member function of
rgrover1 710:b2e1a2660ec2 367 * some object.
rgrover1 710:b2e1a2660ec2 368 *
vcoubard 1052:b55e1ad3e1b3 369 * @Note It is possible to unregister a callback using onDataRead().detach(callback)
vcoubard 1052:b55e1ad3e1b3 370 *
rgrover1 710:b2e1a2660ec2 371 * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available;
rgrover1 710:b2e1a2660ec2 372 * else BLE_ERROR_NONE.
rgrover1 710:b2e1a2660ec2 373 */
vcoubard 1052:b55e1ad3e1b3 374 ble_error_t onDataRead(const DataReadCallback_t& callback) {
rgrover1 710:b2e1a2660ec2 375 if (!isOnDataReadAvailable()) {
rgrover1 710:b2e1a2660ec2 376 return BLE_ERROR_NOT_IMPLEMENTED;
rgrover1 710:b2e1a2660ec2 377 }
rgrover1 710:b2e1a2660ec2 378
rgrover1 710:b2e1a2660ec2 379 dataReadCallChain.add(callback);
rgrover1 710:b2e1a2660ec2 380 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 381 }
rgrover1 710:b2e1a2660ec2 382 template <typename T>
rgrover1 710:b2e1a2660ec2 383 ble_error_t onDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) {
rgrover1 710:b2e1a2660ec2 384 if (!isOnDataReadAvailable()) {
rgrover1 710:b2e1a2660ec2 385 return BLE_ERROR_NOT_IMPLEMENTED;
rgrover1 710:b2e1a2660ec2 386 }
rgrover1 710:b2e1a2660ec2 387
rgrover1 710:b2e1a2660ec2 388 dataReadCallChain.add(objPtr, memberPtr);
rgrover1 710:b2e1a2660ec2 389 return BLE_ERROR_NONE;
rgrover1 710:b2e1a2660ec2 390 }
rgrover1 710:b2e1a2660ec2 391
rgrover1 710:b2e1a2660ec2 392 /**
vcoubard 1052:b55e1ad3e1b3 393 * @brief provide access to the callchain of data read event callbacks
vcoubard 1052:b55e1ad3e1b3 394 * It is possible to register callbacks using onDataRead().add(callback);
LancasterUniversity 1137:290d499dd0e8 395 * It is possible to unregister callbacks using onDataRead().detach(callback)
vcoubard 1052:b55e1ad3e1b3 396 * @return The data read event callbacks chain
vcoubard 1052:b55e1ad3e1b3 397 */
vcoubard 1052:b55e1ad3e1b3 398 DataReadCallbackChain_t& onDataRead() {
vcoubard 1052:b55e1ad3e1b3 399 return dataReadCallChain;
vcoubard 1052:b55e1ad3e1b3 400 }
vcoubard 1052:b55e1ad3e1b3 401
vcoubard 1052:b55e1ad3e1b3 402 /**
LancasterUniversity 1137:290d499dd0e8 403 * Setup a callback to be invoked to notify the user application that the
LancasterUniversity 1137:290d499dd0e8 404 * GattServer instance is about to shutdown (possibly as a result of a call
LancasterUniversity 1137:290d499dd0e8 405 * to BLE::shutdown()).
LancasterUniversity 1137:290d499dd0e8 406 *
LancasterUniversity 1137:290d499dd0e8 407 * @Note: It is possible to chain together multiple onShutdown callbacks
LancasterUniversity 1137:290d499dd0e8 408 * (potentially from different modules of an application) to be notified
LancasterUniversity 1137:290d499dd0e8 409 * before the GattServer is shutdown.
LancasterUniversity 1137:290d499dd0e8 410 *
LancasterUniversity 1137:290d499dd0e8 411 * @Note: It is also possible to set up a callback into a member function of
LancasterUniversity 1137:290d499dd0e8 412 * some object.
LancasterUniversity 1137:290d499dd0e8 413 *
LancasterUniversity 1137:290d499dd0e8 414 * @Note It is possible to unregister a callback using onShutdown().detach(callback)
LancasterUniversity 1137:290d499dd0e8 415 */
LancasterUniversity 1137:290d499dd0e8 416 void onShutdown(const GattServerShutdownCallback_t& callback) {
LancasterUniversity 1137:290d499dd0e8 417 shutdownCallChain.add(callback);
LancasterUniversity 1137:290d499dd0e8 418 }
LancasterUniversity 1137:290d499dd0e8 419 template <typename T>
LancasterUniversity 1137:290d499dd0e8 420 void onShutdown(T *objPtr, void (T::*memberPtr)(void)) {
LancasterUniversity 1137:290d499dd0e8 421 shutdownCallChain.add(objPtr, memberPtr);
LancasterUniversity 1137:290d499dd0e8 422 }
LancasterUniversity 1137:290d499dd0e8 423
LancasterUniversity 1137:290d499dd0e8 424 /**
LancasterUniversity 1137:290d499dd0e8 425 * @brief provide access to the callchain of shutdown event callbacks
LancasterUniversity 1137:290d499dd0e8 426 * It is possible to register callbacks using onShutdown().add(callback);
LancasterUniversity 1137:290d499dd0e8 427 * It is possible to unregister callbacks using onShutdown().detach(callback)
LancasterUniversity 1137:290d499dd0e8 428 * @return The shutdown event callbacks chain
LancasterUniversity 1137:290d499dd0e8 429 */
LancasterUniversity 1137:290d499dd0e8 430 GattServerShutdownCallbackChain_t& onShutdown() {
LancasterUniversity 1137:290d499dd0e8 431 return shutdownCallChain;
LancasterUniversity 1137:290d499dd0e8 432 }
LancasterUniversity 1137:290d499dd0e8 433
LancasterUniversity 1137:290d499dd0e8 434 /**
vcoubard 1048:efb29faf12fc 435 * Set up a callback for when notifications or indications are enabled for a
vcoubard 1048:efb29faf12fc 436 * characteristic on the local GATT server.
rgrover1 710:b2e1a2660ec2 437 */
rgrover1 710:b2e1a2660ec2 438 void onUpdatesEnabled(EventCallback_t callback) {updatesEnabledCallback = callback;}
rgrover1 710:b2e1a2660ec2 439
rgrover1 710:b2e1a2660ec2 440 /**
vcoubard 1048:efb29faf12fc 441 * Set up a callback for when notifications or indications are disabled for a
vcoubard 1048:efb29faf12fc 442 * characteristic on the local GATT server.
rgrover1 710:b2e1a2660ec2 443 */
rgrover1 710:b2e1a2660ec2 444 void onUpdatesDisabled(EventCallback_t callback) {updatesDisabledCallback = callback;}
rgrover1 710:b2e1a2660ec2 445
rgrover1 710:b2e1a2660ec2 446 /**
vcoubard 1048:efb29faf12fc 447 * Set up a callback for when the GATT server receives a response for an
rgrover1 710:b2e1a2660ec2 448 * indication event sent previously.
rgrover1 710:b2e1a2660ec2 449 */
rgrover1 710:b2e1a2660ec2 450 void onConfirmationReceived(EventCallback_t callback) {confirmationReceivedCallback = callback;}
rgrover1 710:b2e1a2660ec2 451
rgrover1 710:b2e1a2660ec2 452 /* Entry points for the underlying stack to report events back to the user. */
rgrover1 710:b2e1a2660ec2 453 protected:
LancasterUniversity 1140:dd2f69fad8c6 454 void handleSysAttrMissingEvent(const GattSysAttrMissingCallbackParams *params) {
LancasterUniversity 1140:dd2f69fad8c6 455 sysAttrMissingCallChain.call(params);
LancasterUniversity 1140:dd2f69fad8c6 456 }
LancasterUniversity 1140:dd2f69fad8c6 457
rgrover1 710:b2e1a2660ec2 458 void handleDataWrittenEvent(const GattWriteCallbackParams *params) {
vcoubard 1052:b55e1ad3e1b3 459 dataWrittenCallChain.call(params);
rgrover1 710:b2e1a2660ec2 460 }
rgrover1 710:b2e1a2660ec2 461
rgrover1 710:b2e1a2660ec2 462 void handleDataReadEvent(const GattReadCallbackParams *params) {
vcoubard 1052:b55e1ad3e1b3 463 dataReadCallChain.call(params);
rgrover1 710:b2e1a2660ec2 464 }
rgrover1 710:b2e1a2660ec2 465
rgrover1 728:997ba5e7b3b6 466 void handleEvent(GattServerEvents::gattEvent_e type, GattAttribute::Handle_t attributeHandle) {
rgrover1 710:b2e1a2660ec2 467 switch (type) {
rgrover1 710:b2e1a2660ec2 468 case GattServerEvents::GATT_EVENT_UPDATES_ENABLED:
rgrover1 710:b2e1a2660ec2 469 if (updatesEnabledCallback) {
rgrover1 728:997ba5e7b3b6 470 updatesEnabledCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 471 }
rgrover1 710:b2e1a2660ec2 472 break;
rgrover1 710:b2e1a2660ec2 473 case GattServerEvents::GATT_EVENT_UPDATES_DISABLED:
rgrover1 710:b2e1a2660ec2 474 if (updatesDisabledCallback) {
rgrover1 728:997ba5e7b3b6 475 updatesDisabledCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 476 }
rgrover1 710:b2e1a2660ec2 477 break;
rgrover1 710:b2e1a2660ec2 478 case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED:
rgrover1 710:b2e1a2660ec2 479 if (confirmationReceivedCallback) {
rgrover1 728:997ba5e7b3b6 480 confirmationReceivedCallback(attributeHandle);
rgrover1 710:b2e1a2660ec2 481 }
rgrover1 710:b2e1a2660ec2 482 break;
rgrover1 710:b2e1a2660ec2 483 default:
rgrover1 710:b2e1a2660ec2 484 break;
rgrover1 710:b2e1a2660ec2 485 }
rgrover1 710:b2e1a2660ec2 486 }
rgrover1 710:b2e1a2660ec2 487
rgrover1 710:b2e1a2660ec2 488 void handleDataSentEvent(unsigned count) {
vcoubard 1052:b55e1ad3e1b3 489 dataSentCallChain.call(count);
rgrover1 710:b2e1a2660ec2 490 }
rgrover1 710:b2e1a2660ec2 491
LancasterUniversity 1137:290d499dd0e8 492 public:
LancasterUniversity 1137:290d499dd0e8 493 /**
LancasterUniversity 1137:290d499dd0e8 494 * Notify all registered onShutdown callbacks that the GattServer is
LancasterUniversity 1137:290d499dd0e8 495 * about to be shutdown and clear all GattServer state of the
LancasterUniversity 1137:290d499dd0e8 496 * associated object.
LancasterUniversity 1137:290d499dd0e8 497 *
LancasterUniversity 1137:290d499dd0e8 498 * This function is meant to be overridden in the platform-specific
LancasterUniversity 1137:290d499dd0e8 499 * sub-class. Nevertheless, the sub-class is only expected to reset its
LancasterUniversity 1137:290d499dd0e8 500 * state and not the data held in GattServer members. This shall be achieved
LancasterUniversity 1137:290d499dd0e8 501 * by a call to GattServer::reset() from the sub-class' reset()
LancasterUniversity 1137:290d499dd0e8 502 * implementation.
LancasterUniversity 1137:290d499dd0e8 503 *
LancasterUniversity 1137:290d499dd0e8 504 * @return BLE_ERROR_NONE on success.
LancasterUniversity 1137:290d499dd0e8 505 */
LancasterUniversity 1137:290d499dd0e8 506 virtual ble_error_t reset(void) {
LancasterUniversity 1137:290d499dd0e8 507 /* Notify that the instance is about to shutdown */
LancasterUniversity 1137:290d499dd0e8 508 shutdownCallChain.call(this);
LancasterUniversity 1137:290d499dd0e8 509 shutdownCallChain.clear();
LancasterUniversity 1137:290d499dd0e8 510
LancasterUniversity 1137:290d499dd0e8 511 serviceCount = 0;
LancasterUniversity 1137:290d499dd0e8 512 characteristicCount = 0;
LancasterUniversity 1137:290d499dd0e8 513
LancasterUniversity 1137:290d499dd0e8 514 dataSentCallChain.clear();
LancasterUniversity 1137:290d499dd0e8 515 dataWrittenCallChain.clear();
LancasterUniversity 1137:290d499dd0e8 516 dataReadCallChain.clear();
LancasterUniversity 1140:dd2f69fad8c6 517 sysAttrMissingCallChain.clear();
LancasterUniversity 1137:290d499dd0e8 518 updatesEnabledCallback = NULL;
LancasterUniversity 1137:290d499dd0e8 519 updatesDisabledCallback = NULL;
LancasterUniversity 1137:290d499dd0e8 520 confirmationReceivedCallback = NULL;
LancasterUniversity 1137:290d499dd0e8 521
LancasterUniversity 1137:290d499dd0e8 522 return BLE_ERROR_NONE;
LancasterUniversity 1137:290d499dd0e8 523 }
LancasterUniversity 1137:290d499dd0e8 524
rgrover1 710:b2e1a2660ec2 525 protected:
rgrover1 710:b2e1a2660ec2 526 uint8_t serviceCount;
rgrover1 710:b2e1a2660ec2 527 uint8_t characteristicCount;
rgrover1 710:b2e1a2660ec2 528
rgrover1 710:b2e1a2660ec2 529 private:
LancasterUniversity 1137:290d499dd0e8 530 DataSentCallbackChain_t dataSentCallChain;
LancasterUniversity 1137:290d499dd0e8 531 DataWrittenCallbackChain_t dataWrittenCallChain;
LancasterUniversity 1137:290d499dd0e8 532 DataReadCallbackChain_t dataReadCallChain;
LancasterUniversity 1140:dd2f69fad8c6 533 SysAttrMissingCallbackChain_t sysAttrMissingCallChain;
LancasterUniversity 1137:290d499dd0e8 534 GattServerShutdownCallbackChain_t shutdownCallChain;
LancasterUniversity 1137:290d499dd0e8 535 EventCallback_t updatesEnabledCallback;
LancasterUniversity 1137:290d499dd0e8 536 EventCallback_t updatesDisabledCallback;
LancasterUniversity 1137:290d499dd0e8 537 EventCallback_t confirmationReceivedCallback;
rgrover1 710:b2e1a2660ec2 538
rgrover1 710:b2e1a2660ec2 539 private:
vcoubard 1048:efb29faf12fc 540 /* Disallow copy and assignment. */
rgrover1 710:b2e1a2660ec2 541 GattServer(const GattServer &);
rgrover1 710:b2e1a2660ec2 542 GattServer& operator=(const GattServer &);
rgrover1 710:b2e1a2660ec2 543 };
rgrover1 710:b2e1a2660ec2 544
rgrover1 710:b2e1a2660ec2 545 #endif // ifndef __GATT_SERVER_H__