mbed os with nrf51 internal bandgap enabled to read battery level

Dependents:   BLE_file_test BLE_Blink ExternalEncoder

Committer:
elessair
Date:
Sun Oct 23 15:10:02 2016 +0000
Revision:
0:f269e3021894
Initial commit

Who changed what in which revision?

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