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
GattServer.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef __GATT_SERVER_H__ 00018 #define __GATT_SERVER_H__ 00019 00020 #include "Gap.h" 00021 #include "GattService.h" 00022 #include "GattAttribute.h" 00023 #include "GattServerEvents.h" 00024 #include "GattCallbackParamTypes.h" 00025 #include "CallChainOfFunctionPointersWithContext.h" 00026 00027 class GattServer { 00028 public: 00029 /* Event callback handlers. */ 00030 typedef FunctionPointerWithContext<unsigned> DataSentCallback_t; 00031 typedef CallChainOfFunctionPointersWithContext<unsigned> DataSentCallbackChain_t; 00032 00033 typedef FunctionPointerWithContext<const GattWriteCallbackParams*> DataWrittenCallback_t; 00034 typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*> DataWrittenCallbackChain_t; 00035 00036 typedef FunctionPointerWithContext<const GattReadCallbackParams*> DataReadCallback_t; 00037 typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams *> DataReadCallbackChain_t; 00038 00039 typedef FunctionPointerWithContext<const GattServer *> GattServerShutdownCallback_t; 00040 typedef CallChainOfFunctionPointersWithContext<const GattServer *> GattServerShutdownCallbackChain_t; 00041 00042 typedef FunctionPointerWithContext<const GattSysAttrMissingCallbackParams*> SysAttrMissingCallback_t; 00043 typedef CallChainOfFunctionPointersWithContext<const GattSysAttrMissingCallbackParams*> SysAttrMissingCallbackChain_t; 00044 00045 typedef FunctionPointerWithContext<GattAttribute::Handle_t> EventCallback_t; 00046 00047 protected: 00048 GattServer() : 00049 serviceCount(0), 00050 characteristicCount(0), 00051 dataSentCallChain(), 00052 dataWrittenCallChain(), 00053 dataReadCallChain(), 00054 sysAttrMissingCallChain(), 00055 updatesEnabledCallback(NULL), 00056 updatesDisabledCallback(NULL), 00057 confirmationReceivedCallback(NULL) { 00058 /* empty */ 00059 } 00060 00061 /* 00062 * The following functions are meant to be overridden in the platform-specific sub-class. 00063 */ 00064 public: 00065 00066 /** 00067 * Add a service declaration to the local server ATT table. Also add the 00068 * characteristics contained within. 00069 */ 00070 virtual ble_error_t addService(GattService &service) { 00071 /* Avoid compiler warnings about unused variables. */ 00072 (void)service; 00073 00074 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00075 } 00076 00077 /** 00078 * Read the value of a characteristic from the local GATT server. 00079 * @param[in] attributeHandle 00080 * Attribute handle for the value attribute of the characteristic. 00081 * @param[out] buffer 00082 * A buffer to hold the value being read. 00083 * @param[in/out] lengthP 00084 * Length of the buffer being supplied. If the attribute 00085 * value is longer than the size of the supplied buffer, 00086 * this variable will hold upon return the total attribute value length 00087 * (excluding offset). The application may use this 00088 * information to allocate a suitable buffer size. 00089 * 00090 * @return BLE_ERROR_NONE if a value was read successfully into the buffer. 00091 */ 00092 virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) { 00093 /* Avoid compiler warnings about unused variables. */ 00094 (void)attributeHandle; 00095 (void)buffer; 00096 (void)lengthP; 00097 00098 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00099 } 00100 00101 /** 00102 * Read the value of a characteristic from the local GATT server. 00103 * @param[in] connectionHandle 00104 * Connection handle. 00105 * @param[in] attributeHandle 00106 * Attribute handle for the value attribute of the characteristic. 00107 * @param[out] buffer 00108 * A buffer to hold the value being read. 00109 * @param[in/out] lengthP 00110 * Length of the buffer being supplied. If the attribute 00111 * value is longer than the size of the supplied buffer, 00112 * this variable will hold upon return the total attribute value length 00113 * (excluding offset). The application may use this 00114 * information to allocate a suitable buffer size. 00115 * 00116 * @return BLE_ERROR_NONE if a value was read successfully into the buffer. 00117 * 00118 * @note This API is a version of the above, with an additional connection handle 00119 * parameter to allow fetches for connection-specific multivalued 00120 * attributes (such as the CCCDs). 00121 */ 00122 virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) { 00123 /* Avoid compiler warnings about unused variables. */ 00124 (void)connectionHandle; 00125 (void)attributeHandle; 00126 (void)buffer; 00127 (void)lengthP; 00128 00129 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00130 } 00131 00132 /** 00133 * Update the value of a characteristic on the local GATT server. 00134 * 00135 * @param[in] attributeHandle 00136 * Handle for the value attribute of the characteristic. 00137 * @param[in] value 00138 * A pointer to a buffer holding the new value. 00139 * @param[in] size 00140 * Size of the new value (in bytes). 00141 * @param[in] localOnly 00142 * Should this update be kept on the local 00143 * GATT server regardless of the state of the 00144 * notify/indicate flag in the CCCD for this 00145 * Characteristic? If set to true, no notification 00146 * or indication is generated. 00147 * 00148 * @return BLE_ERROR_NONE if we have successfully set the value of the attribute. 00149 */ 00150 virtual ble_error_t write(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false) { 00151 /* Avoid compiler warnings about unused variables. */ 00152 (void)attributeHandle; 00153 (void)value; 00154 (void)size; 00155 (void)localOnly; 00156 00157 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00158 } 00159 00160 /** 00161 * Update the value of a characteristic on the local GATT server. A version 00162 * of the same as the above, with a connection handle parameter to allow updates 00163 * for connection-specific multivalued attributes (such as the CCCDs). 00164 * 00165 * @param[in] connectionHandle 00166 * Connection handle. 00167 * @param[in] attributeHandle 00168 * Handle for the value attribute of the characteristic. 00169 * @param[in] value 00170 * A pointer to a buffer holding the new value. 00171 * @param[in] size 00172 * Size of the new value (in bytes). 00173 * @param[in] localOnly 00174 * Should this update be kept on the local 00175 * GattServer regardless of the state of the 00176 * notify/indicate flag in the CCCD for this 00177 * Characteristic? If set to true, no notification 00178 * or indication is generated. 00179 * 00180 * @return BLE_ERROR_NONE if we have successfully set the value of the attribute. 00181 */ 00182 virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false) { 00183 /* Avoid compiler warnings about unused variables. */ 00184 (void)connectionHandle; 00185 (void)attributeHandle; 00186 (void)value; 00187 (void)size; 00188 (void)localOnly; 00189 00190 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00191 } 00192 00193 /** 00194 * Perform an explicit BLE notification of a given attribute. 00195 * 00196 * @param[in] attributeHandle 00197 * Handle for the value attribute of the Characteristic. 00198 * @param[in] value 00199 * A pointer to a buffer holding the new value 00200 * @param[in] size 00201 * Size of the new value (in bytes). 00202 * 00203 * @return BLE_ERROR_NONE if we have successfully set the value of the attribute. 00204 */ 00205 virtual ble_error_t notify(GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size) 00206 { 00207 (void)attributeHandle; 00208 (void)value; 00209 (void)size; 00210 00211 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porter(s): override this API if this capability is supported. */ 00212 } 00213 00214 /** 00215 * Determine the updates-enabled status (notification or indication) for the current connection from a characteristic's CCCD. 00216 * 00217 * @param characteristic 00218 * The characteristic. 00219 * @param[out] enabledP 00220 * Upon return, *enabledP is true if updates are enabled, else false. 00221 * 00222 * @return BLE_ERROR_NONE if the connection and handle are found. False otherwise. 00223 */ 00224 virtual ble_error_t areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP) { 00225 /* Avoid compiler warnings about unused variables. */ 00226 (void)characteristic; 00227 (void)enabledP; 00228 00229 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00230 } 00231 00232 /** 00233 * Determine the connection-specific updates-enabled status (notification or indication) from a characteristic's CCCD. 00234 * 00235 * @param connectionHandle 00236 * The connection handle. 00237 * @param[out] enabledP 00238 * Upon return, *enabledP is true if updates are enabled, else false. 00239 * 00240 * @param characteristic 00241 * The characteristic. 00242 * 00243 * @return BLE_ERROR_NONE if the connection and handle are found. False otherwise. 00244 */ 00245 virtual ble_error_t areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP) { 00246 /* Avoid compiler warnings about unused variables. */ 00247 (void)connectionHandle; 00248 (void)characteristic; 00249 (void)enabledP; 00250 00251 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00252 } 00253 00254 /** 00255 * A virtual function to allow underlying stacks to indicate if they support 00256 * onDataRead(). It should be overridden to return true as applicable. 00257 */ 00258 virtual bool isOnDataReadAvailable() const { 00259 return false; /* Requesting action from porters: override this API if this capability is supported. */ 00260 } 00261 00262 /* 00263 * APIs with non-virtual implementations. 00264 */ 00265 public: 00266 /** 00267 * Add a callback for the GATT event DATA_SENT (which is triggered when 00268 * updates are sent out by GATT in the form of notifications). 00269 * 00270 * @Note: It is possible to chain together multiple onDataSent callbacks 00271 * (potentially from different modules of an application) to receive updates 00272 * to characteristics. 00273 * 00274 * @Note: It is also possible to set up a callback into a member function of 00275 * some object. 00276 */ 00277 void onDataSent(const DataSentCallback_t& callback) {dataSentCallChain.add(callback);} 00278 template <typename T> 00279 void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) { 00280 dataSentCallChain.add(objPtr, memberPtr); 00281 } 00282 00283 /** 00284 * @brief get the callback chain called when the event DATA_EVENT is triggered. 00285 */ 00286 DataSentCallbackChain_t& onDataSent() { 00287 return dataSentCallChain; 00288 } 00289 00290 /** 00291 * Set up a callback for when an attribute has its value updated by or at the 00292 * connected peer. For a peripheral, this callback is triggered when the local 00293 * GATT server has an attribute updated by a write command from the peer. 00294 * For a central, this callback is triggered when a response is received for 00295 * a write request. 00296 * 00297 * @Note: It is possible to chain together multiple onDataWritten callbacks 00298 * (potentially from different modules of an application) to receive updates 00299 * to characteristics. Many services, such as DFU and UART, add their own 00300 * onDataWritten callbacks behind the scenes to trap interesting events. 00301 * 00302 * @Note: It is also possible to set up a callback into a member function of 00303 * some object. 00304 * 00305 * @Note It is possible to unregister a callback using onDataWritten().detach(callback) 00306 */ 00307 void onDataWritten(const DataWrittenCallback_t& callback) {dataWrittenCallChain.add(callback);} 00308 template <typename T> 00309 void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) { 00310 dataWrittenCallChain.add(objPtr, memberPtr); 00311 } 00312 00313 /** 00314 * @brief provide access to the callchain of data written event callbacks 00315 * It is possible to register callbacks using onDataWritten().add(callback); 00316 * It is possible to unregister callbacks using onDataWritten().detach(callback) 00317 * @return The data written event callbacks chain 00318 */ 00319 DataWrittenCallbackChain_t& onDataWritten() { 00320 return dataWrittenCallChain; 00321 } 00322 00323 /** 00324 * Set up a callback for when asystem descriptor (CCCD) is missing. 00325 * This may be raised in response to a BLE profile change om a bonded connection. 00326 * This callback provides the opportunity for user applications to restore 00327 * CCCD state at the appropriate time. 00328 * 00329 * @Note: It is possible to chain together multiple onSysAttrMissing callbacks 00330 * (potentially from different modules of an application), although it is unlikely 00331 * that this will be beneficial. 00332 * 00333 * @Note: It is also possible to set up a callback into a member function of 00334 * some object. 00335 * 00336 * @Note It is possible to unregister a callback using onSysAttrMissing().detach(callback) 00337 */ 00338 void onSysAttrMissing(const SysAttrMissingCallback_t& callback) {sysAttrMissingCallChain.add(callback);} 00339 template <typename T> 00340 void onSysAttrMissing(T *objPtr, void (T::*memberPtr)(const GattSysAttrMissingCallbackParams* connectionHandle)) { 00341 sysAttrMissingCallChain.add(objPtr, memberPtr); 00342 } 00343 00344 /** 00345 * @brief provide access to the callchain of data written event callbacks 00346 * It is possible to register callbacks using onDataWritten().add(callback); 00347 * It is possible to unregister callbacks using onDataWritten().detach(callback) 00348 * @return The data written event callbacks chain 00349 */ 00350 SysAttrMissingCallbackChain_t& onSysAttrMissing() { 00351 return sysAttrMissingCallChain; 00352 } 00353 /** 00354 * Setup a callback to be invoked on the peripheral when an attribute is 00355 * being read by a remote client. 00356 * 00357 * @Note: This functionality may not be available on all underlying stacks. 00358 * You could use GattCharacteristic::setReadAuthorizationCallback() as an 00359 * alternative. Refer to isOnDataReadAvailable(). 00360 * 00361 * @Note: It is possible to chain together multiple onDataRead callbacks 00362 * (potentially from different modules of an application) to receive updates 00363 * to characteristics. Services may add their own onDataRead callbacks 00364 * behind the scenes to trap interesting events. 00365 * 00366 * @Note: It is also possible to set up a callback into a member function of 00367 * some object. 00368 * 00369 * @Note It is possible to unregister a callback using onDataRead().detach(callback) 00370 * 00371 * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available; 00372 * else BLE_ERROR_NONE. 00373 */ 00374 ble_error_t onDataRead(const DataReadCallback_t& callback) { 00375 if (!isOnDataReadAvailable()) { 00376 return BLE_ERROR_NOT_IMPLEMENTED; 00377 } 00378 00379 dataReadCallChain.add(callback); 00380 return BLE_ERROR_NONE; 00381 } 00382 template <typename T> 00383 ble_error_t onDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) { 00384 if (!isOnDataReadAvailable()) { 00385 return BLE_ERROR_NOT_IMPLEMENTED; 00386 } 00387 00388 dataReadCallChain.add(objPtr, memberPtr); 00389 return BLE_ERROR_NONE; 00390 } 00391 00392 /** 00393 * @brief provide access to the callchain of data read event callbacks 00394 * It is possible to register callbacks using onDataRead().add(callback); 00395 * It is possible to unregister callbacks using onDataRead().detach(callback) 00396 * @return The data read event callbacks chain 00397 */ 00398 DataReadCallbackChain_t& onDataRead() { 00399 return dataReadCallChain; 00400 } 00401 00402 /** 00403 * Setup a callback to be invoked to notify the user application that the 00404 * GattServer instance is about to shutdown (possibly as a result of a call 00405 * to BLE::shutdown()). 00406 * 00407 * @Note: It is possible to chain together multiple onShutdown callbacks 00408 * (potentially from different modules of an application) to be notified 00409 * before the GattServer is shutdown. 00410 * 00411 * @Note: It is also possible to set up a callback into a member function of 00412 * some object. 00413 * 00414 * @Note It is possible to unregister a callback using onShutdown().detach(callback) 00415 */ 00416 void onShutdown(const GattServerShutdownCallback_t& callback) { 00417 shutdownCallChain.add(callback); 00418 } 00419 template <typename T> 00420 void onShutdown(T *objPtr, void (T::*memberPtr)(void)) { 00421 shutdownCallChain.add(objPtr, memberPtr); 00422 } 00423 00424 /** 00425 * @brief provide access to the callchain of shutdown event callbacks 00426 * It is possible to register callbacks using onShutdown().add(callback); 00427 * It is possible to unregister callbacks using onShutdown().detach(callback) 00428 * @return The shutdown event callbacks chain 00429 */ 00430 GattServerShutdownCallbackChain_t& onShutdown() { 00431 return shutdownCallChain; 00432 } 00433 00434 /** 00435 * Set up a callback for when notifications or indications are enabled for a 00436 * characteristic on the local GATT server. 00437 */ 00438 void onUpdatesEnabled(EventCallback_t callback) {updatesEnabledCallback = callback;} 00439 00440 /** 00441 * Set up a callback for when notifications or indications are disabled for a 00442 * characteristic on the local GATT server. 00443 */ 00444 void onUpdatesDisabled(EventCallback_t callback) {updatesDisabledCallback = callback;} 00445 00446 /** 00447 * Set up a callback for when the GATT server receives a response for an 00448 * indication event sent previously. 00449 */ 00450 void onConfirmationReceived(EventCallback_t callback) {confirmationReceivedCallback = callback;} 00451 00452 /* Entry points for the underlying stack to report events back to the user. */ 00453 protected: 00454 void handleSysAttrMissingEvent(const GattSysAttrMissingCallbackParams *params) { 00455 sysAttrMissingCallChain.call(params); 00456 } 00457 00458 void handleDataWrittenEvent(const GattWriteCallbackParams *params) { 00459 dataWrittenCallChain.call(params); 00460 } 00461 00462 void handleDataReadEvent(const GattReadCallbackParams *params) { 00463 dataReadCallChain.call(params); 00464 } 00465 00466 void handleEvent(GattServerEvents::gattEvent_e type, GattAttribute::Handle_t attributeHandle) { 00467 switch (type) { 00468 case GattServerEvents::GATT_EVENT_UPDATES_ENABLED: 00469 if (updatesEnabledCallback) { 00470 updatesEnabledCallback(attributeHandle); 00471 } 00472 break; 00473 case GattServerEvents::GATT_EVENT_UPDATES_DISABLED: 00474 if (updatesDisabledCallback) { 00475 updatesDisabledCallback(attributeHandle); 00476 } 00477 break; 00478 case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED: 00479 if (confirmationReceivedCallback) { 00480 confirmationReceivedCallback(attributeHandle); 00481 } 00482 break; 00483 default: 00484 break; 00485 } 00486 } 00487 00488 void handleDataSentEvent(unsigned count) { 00489 dataSentCallChain.call(count); 00490 } 00491 00492 public: 00493 /** 00494 * Notify all registered onShutdown callbacks that the GattServer is 00495 * about to be shutdown and clear all GattServer state of the 00496 * associated object. 00497 * 00498 * This function is meant to be overridden in the platform-specific 00499 * sub-class. Nevertheless, the sub-class is only expected to reset its 00500 * state and not the data held in GattServer members. This shall be achieved 00501 * by a call to GattServer::reset() from the sub-class' reset() 00502 * implementation. 00503 * 00504 * @return BLE_ERROR_NONE on success. 00505 */ 00506 virtual ble_error_t reset(void) { 00507 /* Notify that the instance is about to shutdown */ 00508 shutdownCallChain.call(this); 00509 shutdownCallChain.clear(); 00510 00511 serviceCount = 0; 00512 characteristicCount = 0; 00513 00514 dataSentCallChain.clear(); 00515 dataWrittenCallChain.clear(); 00516 dataReadCallChain.clear(); 00517 sysAttrMissingCallChain.clear(); 00518 updatesEnabledCallback = NULL; 00519 updatesDisabledCallback = NULL; 00520 confirmationReceivedCallback = NULL; 00521 00522 return BLE_ERROR_NONE; 00523 } 00524 00525 protected: 00526 uint8_t serviceCount; 00527 uint8_t characteristicCount; 00528 00529 private: 00530 DataSentCallbackChain_t dataSentCallChain; 00531 DataWrittenCallbackChain_t dataWrittenCallChain; 00532 DataReadCallbackChain_t dataReadCallChain; 00533 SysAttrMissingCallbackChain_t sysAttrMissingCallChain; 00534 GattServerShutdownCallbackChain_t shutdownCallChain; 00535 EventCallback_t updatesEnabledCallback; 00536 EventCallback_t updatesDisabledCallback; 00537 EventCallback_t confirmationReceivedCallback; 00538 00539 private: 00540 /* Disallow copy and assignment. */ 00541 GattServer(const GattServer &); 00542 GattServer& operator=(const GattServer &); 00543 }; 00544 00545 #endif // ifndef __GATT_SERVER_H__
Generated on Tue Jul 12 2022 17:17:58 by 1.7.2