just a fork
Fork of BLE_API by
ble/GattServer.h@1062:a3fd424b73ca, 2016-01-11 (annotated)
- Committer:
- vcoubard
- Date:
- Mon Jan 11 08:51:37 2016 +0000
- Revision:
- 1062:a3fd424b73ca
- Parent:
- 1052:b55e1ad3e1b3
- Child:
- 1063:187f9929cb60
Synchronized with git rev b817cf3e
Author: Andres Amaya Garcia
Improve API to facilitate full shutdown procedure
The BLE API exposes a shutdown() function in BLE.h. This function is meant to
be overwridden by platform-specific sub-classes to clear all GAP and GATT
state. However, from the platform-specific implementation it is dificult to
achieve this because the Gap, GattClient, GattServer and SecurityManager
components of the API do not expose any functionality to shutdown.
This commit introduces the following changes:
* Add a static member pointer to Gap, GattClient, GattServer and
SecurityManager that is used to keep track of the initialized objects.
* Add a function member cleanup() to Gap, GattClient, GattServer and
SecurityManager to allow easy reset of the instance's state. This function
is meant to be overriden and called from the derived classes to fully clear the
state of the BLE API and the platform-specific implementation.
* Add a static member function shutdown() to Gap, GattClient, GattServer and
SecurityManager. This function shall be called from the shutdown()
overriding BLE::shutdown() for Gap, GattClient, GattServer and SecurityManager
that will in-turn clear the state of each of the components.
**NOTE:** Platform-specific implementations of this API must be modified to
this changes into account.
Who changed what in which revision?
User | Revision | Line number | New 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: |
vcoubard | 1052:b55e1ad3e1b3 | 29 | |
rgrover1 | 710:b2e1a2660ec2 | 30 | /* Event callback handlers. */ |
vcoubard | 1052:b55e1ad3e1b3 | 31 | typedef FunctionPointerWithContext<unsigned> DataSentCallback_t; |
vcoubard | 1052:b55e1ad3e1b3 | 32 | typedef CallChainOfFunctionPointersWithContext<unsigned> DataSentCallbackChain_t; |
vcoubard | 1052:b55e1ad3e1b3 | 33 | |
vcoubard | 1052:b55e1ad3e1b3 | 34 | typedef FunctionPointerWithContext<const GattWriteCallbackParams*> DataWrittenCallback_t; |
vcoubard | 1052:b55e1ad3e1b3 | 35 | typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*> DataWrittenCallbackChain_t; |
vcoubard | 1052:b55e1ad3e1b3 | 36 | |
vcoubard | 1052:b55e1ad3e1b3 | 37 | typedef FunctionPointerWithContext<const GattReadCallbackParams*> DataReadCallback_t; |
vcoubard | 1052:b55e1ad3e1b3 | 38 | typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams *> DataReadCallbackChain_t; |
vcoubard | 1052:b55e1ad3e1b3 | 39 | |
vcoubard | 1052:b55e1ad3e1b3 | 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) { |
vcoubard | 1048:efb29faf12fc | 65 | /* Avoid compiler warnings about unused variables. */ |
rgrover1 | 734:4872b70437ce | 66 | (void)service; |
rgrover1 | 734:4872b70437ce | 67 | |
vcoubard | 1048:efb29faf12fc | 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 | /** |
vcoubard | 1048:efb29faf12fc | 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) { |
vcoubard | 1048:efb29faf12fc | 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 | |
vcoubard | 1048:efb29faf12fc | 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 | /** |
vcoubard | 1048:efb29faf12fc | 96 | * Read the value of a characteristic from the local GATT server. |
rgrover1 | 710:b2e1a2660ec2 | 97 | * @param[in] connectionHandle |
vcoubard | 1048:efb29faf12fc | 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 | * |
vcoubard | 1048:efb29faf12fc | 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) { |
vcoubard | 1048:efb29faf12fc | 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 | |
vcoubard | 1048:efb29faf12fc | 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 | /** |
vcoubard | 1048:efb29faf12fc | 127 | * Update the value of a characteristic on the local GATT server. |
rgrover1 | 710:b2e1a2660ec2 | 128 | * |
rgrover1 | 710:b2e1a2660ec2 | 129 | * @param[in] attributeHandle |
vcoubard | 1048:efb29faf12fc | 130 | * Handle for the value attribute of the characteristic. |
rgrover1 | 710:b2e1a2660ec2 | 131 | * @param[in] value |
vcoubard | 1048:efb29faf12fc | 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 |
vcoubard | 1048:efb29faf12fc | 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) { |
vcoubard | 1048:efb29faf12fc | 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 | |
vcoubard | 1048:efb29faf12fc | 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 | /** |
vcoubard | 1048:efb29faf12fc | 155 | * Update the value of a characteristic on the local GATT server. A version |
vcoubard | 1048:efb29faf12fc | 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 |
vcoubard | 1048:efb29faf12fc | 160 | * Connection handle. |
rgrover1 | 710:b2e1a2660ec2 | 161 | * @param[in] attributeHandle |
vcoubard | 1048:efb29faf12fc | 162 | * Handle for the value attribute of the characteristic. |
rgrover1 | 710:b2e1a2660ec2 | 163 | * @param[in] value |
vcoubard | 1048:efb29faf12fc | 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) { |
vcoubard | 1048:efb29faf12fc | 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 | |
vcoubard | 1048:efb29faf12fc | 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 | /** |
vcoubard | 1048:efb29faf12fc | 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 |
vcoubard | 1048:efb29faf12fc | 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 | * |
vcoubard | 1048:efb29faf12fc | 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) { |
vcoubard | 1048:efb29faf12fc | 198 | /* Avoid compiler warnings about unused variables. */ |
rgrover1 | 734:4872b70437ce | 199 | (void)characteristic; |
rgrover1 | 734:4872b70437ce | 200 | (void)enabledP; |
rgrover1 | 734:4872b70437ce | 201 | |
vcoubard | 1048:efb29faf12fc | 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 | /** |
vcoubard | 1048:efb29faf12fc | 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 |
vcoubard | 1048:efb29faf12fc | 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 |
vcoubard | 1048:efb29faf12fc | 214 | * The characteristic. |
rgrover1 | 728:997ba5e7b3b6 | 215 | * |
vcoubard | 1048:efb29faf12fc | 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) { |
vcoubard | 1048:efb29faf12fc | 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 | |
vcoubard | 1048:efb29faf12fc | 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 { |
vcoubard | 1048:efb29faf12fc | 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 | * |
vcoubard | 1048:efb29faf12fc | 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 | * |
vcoubard | 1048:efb29faf12fc | 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 | */ |
vcoubard | 1052:b55e1ad3e1b3 | 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 | /** |
vcoubard | 1052:b55e1ad3e1b3 | 257 | * @brief get the callback chain called when the event DATA_EVENT is triggered. |
vcoubard | 1052:b55e1ad3e1b3 | 258 | */ |
vcoubard | 1052:b55e1ad3e1b3 | 259 | DataSentCallbackChain_t& onDataSent() { |
vcoubard | 1052:b55e1ad3e1b3 | 260 | return dataSentCallChain; |
vcoubard | 1052:b55e1ad3e1b3 | 261 | } |
vcoubard | 1052:b55e1ad3e1b3 | 262 | |
vcoubard | 1052:b55e1ad3e1b3 | 263 | /** |
vcoubard | 1048:efb29faf12fc | 264 | * Set up a callback for when an attribute has its value updated by or at the |
vcoubard | 1048:efb29faf12fc | 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. |
vcoubard | 1048:efb29faf12fc | 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 | * |
vcoubard | 1048:efb29faf12fc | 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 |
vcoubard | 1048:efb29faf12fc | 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 | * |
vcoubard | 1048:efb29faf12fc | 275 | * @Note: It is also possible to set up a callback into a member function of |
rgrover1 | 710:b2e1a2660ec2 | 276 | * some object. |
vcoubard | 1052:b55e1ad3e1b3 | 277 | * |
vcoubard | 1052:b55e1ad3e1b3 | 278 | * @Note It is possible to unregister a callback using onDataWritten().detach(callback) |
rgrover1 | 710:b2e1a2660ec2 | 279 | */ |
vcoubard | 1052:b55e1ad3e1b3 | 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 | /** |
vcoubard | 1052:b55e1ad3e1b3 | 287 | * @brief provide access to the callchain of data written event callbacks |
vcoubard | 1052:b55e1ad3e1b3 | 288 | * It is possible to register callbacks using onDataWritten().add(callback); |
vcoubard | 1052:b55e1ad3e1b3 | 289 | * It is possible to unregister callbacks using onDataWritten().detach(callback) |
vcoubard | 1052:b55e1ad3e1b3 | 290 | * @return The data written event callbacks chain |
vcoubard | 1052:b55e1ad3e1b3 | 291 | */ |
vcoubard | 1052:b55e1ad3e1b3 | 292 | DataWrittenCallbackChain_t& onDataWritten() { |
vcoubard | 1052:b55e1ad3e1b3 | 293 | return dataWrittenCallChain; |
vcoubard | 1052:b55e1ad3e1b3 | 294 | } |
vcoubard | 1052:b55e1ad3e1b3 | 295 | |
vcoubard | 1052:b55e1ad3e1b3 | 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 | * |
vcoubard | 1048:efb29faf12fc | 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 | * |
vcoubard | 1048:efb29faf12fc | 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 | * |
vcoubard | 1048:efb29faf12fc | 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 | * |
vcoubard | 1052:b55e1ad3e1b3 | 312 | * @Note It is possible to unregister a callback using onDataRead().detach(callback) |
vcoubard | 1052:b55e1ad3e1b3 | 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 | */ |
vcoubard | 1052:b55e1ad3e1b3 | 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 | /** |
vcoubard | 1052:b55e1ad3e1b3 | 336 | * @brief provide access to the callchain of data read event callbacks |
vcoubard | 1052:b55e1ad3e1b3 | 337 | * It is possible to register callbacks using onDataRead().add(callback); |
vcoubard | 1052:b55e1ad3e1b3 | 338 | * It is possible to unregister callbacks using onDataRead().detach(callback) |
vcoubard | 1052:b55e1ad3e1b3 | 339 | * @return The data read event callbacks chain |
vcoubard | 1052:b55e1ad3e1b3 | 340 | */ |
vcoubard | 1052:b55e1ad3e1b3 | 341 | DataReadCallbackChain_t& onDataRead() { |
vcoubard | 1052:b55e1ad3e1b3 | 342 | return dataReadCallChain; |
vcoubard | 1052:b55e1ad3e1b3 | 343 | } |
vcoubard | 1052:b55e1ad3e1b3 | 344 | |
vcoubard | 1052:b55e1ad3e1b3 | 345 | /** |
vcoubard | 1048:efb29faf12fc | 346 | * Set up a callback for when notifications or indications are enabled for a |
vcoubard | 1048:efb29faf12fc | 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 | /** |
vcoubard | 1048:efb29faf12fc | 352 | * Set up a callback for when notifications or indications are disabled for a |
vcoubard | 1048:efb29faf12fc | 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 | /** |
vcoubard | 1048:efb29faf12fc | 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) { |
vcoubard | 1052:b55e1ad3e1b3 | 366 | dataWrittenCallChain.call(params); |
rgrover1 | 710:b2e1a2660ec2 | 367 | } |
rgrover1 | 710:b2e1a2660ec2 | 368 | |
rgrover1 | 710:b2e1a2660ec2 | 369 | void handleDataReadEvent(const GattReadCallbackParams *params) { |
vcoubard | 1052:b55e1ad3e1b3 | 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) { |
vcoubard | 1052:b55e1ad3e1b3 | 396 | dataSentCallChain.call(count); |
rgrover1 | 710:b2e1a2660ec2 | 397 | } |
rgrover1 | 710:b2e1a2660ec2 | 398 | |
rgrover1 | 710:b2e1a2660ec2 | 399 | protected: |
vcoubard | 1062:a3fd424b73ca | 400 | /** |
vcoubard | 1062:a3fd424b73ca | 401 | * Clear all GattServer state of the associated object. |
vcoubard | 1062:a3fd424b73ca | 402 | * |
vcoubard | 1062:a3fd424b73ca | 403 | * This function is meant to be overridden in the platform-specific |
vcoubard | 1062:a3fd424b73ca | 404 | * sub-class. Nevertheless, the sub-class is only expected to clean up its |
vcoubard | 1062:a3fd424b73ca | 405 | * state and not the data held in GattServer members. This shall be achieved |
vcoubard | 1062:a3fd424b73ca | 406 | * by a call to GattServer::cleanup() from the sub-class' cleanup() |
vcoubard | 1062:a3fd424b73ca | 407 | * implementation. |
vcoubard | 1062:a3fd424b73ca | 408 | * |
vcoubard | 1062:a3fd424b73ca | 409 | * @return BLE_ERROR_NONE on success. |
vcoubard | 1062:a3fd424b73ca | 410 | */ |
vcoubard | 1062:a3fd424b73ca | 411 | virtual ble_error_t cleanup(void) { |
vcoubard | 1062:a3fd424b73ca | 412 | serviceCount = 0; |
vcoubard | 1062:a3fd424b73ca | 413 | characteristicCount = 0; |
vcoubard | 1062:a3fd424b73ca | 414 | |
vcoubard | 1062:a3fd424b73ca | 415 | dataSentCallChain.clear(); |
vcoubard | 1062:a3fd424b73ca | 416 | dataWrittenCallChain.clear(); |
vcoubard | 1062:a3fd424b73ca | 417 | dataReadCallChain.clear(); |
vcoubard | 1062:a3fd424b73ca | 418 | updatesEnabledCallback = NULL; |
vcoubard | 1062:a3fd424b73ca | 419 | updatesDisabledCallback = NULL; |
vcoubard | 1062:a3fd424b73ca | 420 | confirmationReceivedCallback = NULL; |
vcoubard | 1062:a3fd424b73ca | 421 | |
vcoubard | 1062:a3fd424b73ca | 422 | return BLE_ERROR_NONE; |
vcoubard | 1062:a3fd424b73ca | 423 | } |
vcoubard | 1062:a3fd424b73ca | 424 | |
vcoubard | 1062:a3fd424b73ca | 425 | public: |
vcoubard | 1062:a3fd424b73ca | 426 | /** |
vcoubard | 1062:a3fd424b73ca | 427 | * Clear all GattServer state of the object pointed to by |
vcoubard | 1062:a3fd424b73ca | 428 | * gattServerInstance. |
vcoubard | 1062:a3fd424b73ca | 429 | * |
vcoubard | 1062:a3fd424b73ca | 430 | * This function is meant to be called by the overridden BLE::shutdown() |
vcoubard | 1062:a3fd424b73ca | 431 | * in the platform-specific sub-class. |
vcoubard | 1062:a3fd424b73ca | 432 | * |
vcoubard | 1062:a3fd424b73ca | 433 | * @return BLE_ERROR_NONE on success. |
vcoubard | 1062:a3fd424b73ca | 434 | * |
vcoubard | 1062:a3fd424b73ca | 435 | * @note: If gattServerInstance is NULL then it is assumed that Gap has not |
vcoubard | 1062:a3fd424b73ca | 436 | * been instantiated and a call to GattServer::shutdown() will succeed. |
vcoubard | 1062:a3fd424b73ca | 437 | */ |
vcoubard | 1062:a3fd424b73ca | 438 | static ble_error_t shutdown(void) { |
vcoubard | 1062:a3fd424b73ca | 439 | if (gattServerInstance) { |
vcoubard | 1062:a3fd424b73ca | 440 | return gattServerInstance->cleanup(); |
vcoubard | 1062:a3fd424b73ca | 441 | } |
vcoubard | 1062:a3fd424b73ca | 442 | return BLE_ERROR_NONE; |
vcoubard | 1062:a3fd424b73ca | 443 | } |
vcoubard | 1062:a3fd424b73ca | 444 | |
vcoubard | 1062:a3fd424b73ca | 445 | protected: |
rgrover1 | 710:b2e1a2660ec2 | 446 | uint8_t serviceCount; |
rgrover1 | 710:b2e1a2660ec2 | 447 | uint8_t characteristicCount; |
rgrover1 | 710:b2e1a2660ec2 | 448 | |
vcoubard | 1062:a3fd424b73ca | 449 | protected: |
vcoubard | 1062:a3fd424b73ca | 450 | static GattServer *gattServerInstance; /**< Pointer to the GattServer object instance. |
vcoubard | 1062:a3fd424b73ca | 451 | * If NULL, then GattServer has not been initialized. */ |
vcoubard | 1062:a3fd424b73ca | 452 | |
rgrover1 | 710:b2e1a2660ec2 | 453 | private: |
vcoubard | 1052:b55e1ad3e1b3 | 454 | DataSentCallbackChain_t dataSentCallChain; |
vcoubard | 1052:b55e1ad3e1b3 | 455 | DataWrittenCallbackChain_t dataWrittenCallChain; |
vcoubard | 1052:b55e1ad3e1b3 | 456 | DataReadCallbackChain_t dataReadCallChain; |
vcoubard | 1052:b55e1ad3e1b3 | 457 | EventCallback_t updatesEnabledCallback; |
vcoubard | 1052:b55e1ad3e1b3 | 458 | EventCallback_t updatesDisabledCallback; |
vcoubard | 1052:b55e1ad3e1b3 | 459 | EventCallback_t confirmationReceivedCallback; |
rgrover1 | 710:b2e1a2660ec2 | 460 | |
rgrover1 | 710:b2e1a2660ec2 | 461 | private: |
vcoubard | 1048:efb29faf12fc | 462 | /* Disallow copy and assignment. */ |
rgrover1 | 710:b2e1a2660ec2 | 463 | GattServer(const GattServer &); |
rgrover1 | 710:b2e1a2660ec2 | 464 | GattServer& operator=(const GattServer &); |
rgrover1 | 710:b2e1a2660ec2 | 465 | }; |
rgrover1 | 710:b2e1a2660ec2 | 466 | |
rgrover1 | 710:b2e1a2660ec2 | 467 | #endif // ifndef __GATT_SERVER_H__ |