Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-os by
GattClient.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_CLIENT_H__ 00018 #define __GATT_CLIENT_H__ 00019 00020 #include "Gap.h" 00021 #include "GattAttribute.h" 00022 #include "ServiceDiscovery.h" 00023 #include "CharacteristicDescriptorDiscovery.h" 00024 00025 #include "GattCallbackParamTypes.h" 00026 00027 #include "CallChainOfFunctionPointersWithContext.h" 00028 00029 class GattClient { 00030 public: 00031 /** 00032 * Type for the registered callbacks added to the data read callchain. 00033 * Refer to GattClient::onDataRead(). 00034 */ 00035 typedef FunctionPointerWithContext<const GattReadCallbackParams*> ReadCallback_t; 00036 /** 00037 * Type for the data read event callchain. Refer to GattClient::onDataRead(). 00038 */ 00039 typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams*> ReadCallbackChain_t; 00040 00041 /** 00042 * Enumerator for write operations. 00043 */ 00044 enum WriteOp_t { 00045 GATT_OP_WRITE_REQ = 0x01, /**< Write request. */ 00046 GATT_OP_WRITE_CMD = 0x02, /**< Write command. */ 00047 }; 00048 00049 /** 00050 * Type for the registered callbacks added to the data write callchain. 00051 * Refer to GattClient::onDataWrite(). 00052 */ 00053 typedef FunctionPointerWithContext<const GattWriteCallbackParams*> WriteCallback_t; 00054 /** 00055 * Type for the data write event callchain. Refer to GattClient::onDataWrite(). 00056 */ 00057 typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*> WriteCallbackChain_t; 00058 00059 /** 00060 * Type for the registered callbacks added to the update event callchain. 00061 * Refer to GattClient::onHVX(). 00062 */ 00063 typedef FunctionPointerWithContext<const GattHVXCallbackParams*> HVXCallback_t; 00064 /** 00065 * Type for the update event callchain. Refer to GattClient::onHVX(). 00066 */ 00067 typedef CallChainOfFunctionPointersWithContext<const GattHVXCallbackParams*> HVXCallbackChain_t; 00068 00069 /** 00070 * Type for the registered callbacks added to the shutdown callchain. 00071 * Refer to GattClient::onShutdown(). 00072 */ 00073 typedef FunctionPointerWithContext<const GattClient *> GattClientShutdownCallback_t; 00074 /** 00075 * Type for the shutdown event callchain. Refer to GattClient::onShutown(). 00076 */ 00077 typedef CallChainOfFunctionPointersWithContext<const GattClient *> GattClientShutdownCallbackChain_t; 00078 00079 /* 00080 * The following functions are meant to be overridden in the platform-specific sub-class. 00081 */ 00082 public: 00083 /** 00084 * Launch service discovery. Once launched, application callbacks will be 00085 * invoked for matching services or characteristics. isServiceDiscoveryActive() 00086 * can be used to determine status, and a termination callback (if one was set up) 00087 * will be invoked at the end. Service discovery can be terminated prematurely, 00088 * if needed, using terminateServiceDiscovery(). 00089 * 00090 * @param[in] connectionHandle 00091 * Handle for the connection with the peer. 00092 * @param[in] sc 00093 * This is the application callback for a matching service. Taken as 00094 * NULL by default. Note: service discovery may still be active 00095 * when this callback is issued; calling asynchronous BLE-stack 00096 * APIs from within this application callback might cause the 00097 * stack to abort service discovery. If this becomes an issue, it 00098 * may be better to make a local copy of the discoveredService and 00099 * wait for service discovery to terminate before operating on the 00100 * service. 00101 * @param[in] cc 00102 * This is the application callback for a matching characteristic. 00103 * Taken as NULL by default. Note: service discovery may still be 00104 * active when this callback is issued; calling asynchronous 00105 * BLE-stack APIs from within this application callback might cause 00106 * the stack to abort service discovery. If this becomes an issue, 00107 * it may be better to make a local copy of the discoveredCharacteristic 00108 * and wait for service discovery to terminate before operating on the 00109 * characteristic. 00110 * @param[in] matchingServiceUUID 00111 * UUID-based filter for specifying a service in which the application is 00112 * interested. By default it is set as the wildcard UUID_UNKNOWN, 00113 * in which case it matches all services. If characteristic-UUID 00114 * filter (below) is set to the wildcard value, then a service 00115 * callback will be invoked for the matching service (or for every 00116 * service if the service filter is a wildcard). 00117 * @param[in] matchingCharacteristicUUIDIn 00118 * UUID-based filter for specifying characteristic in which the application 00119 * is interested. By default it is set as the wildcard UUID_UKNOWN 00120 * to match against any characteristic. If both service-UUID 00121 * filter and characteristic-UUID filter are used with non-wildcard 00122 * values, then only a single characteristic callback is 00123 * invoked for the matching characteristic. 00124 * 00125 * @note Using wildcard values for both service-UUID and characteristic- 00126 * UUID will result in complete service discovery: callbacks being 00127 * called for every service and characteristic. 00128 * 00129 * @note Providing NULL for the characteristic callback will result in 00130 * characteristic discovery being skipped for each matching 00131 * service. This allows for an inexpensive method to discover only 00132 * services. 00133 * 00134 * @return 00135 * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. 00136 */ 00137 virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, 00138 ServiceDiscovery::ServiceCallback_t sc = NULL, 00139 ServiceDiscovery::CharacteristicCallback_t cc = NULL, 00140 const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), 00141 const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) { 00142 /* Avoid compiler warnings about unused variables. */ 00143 (void)connectionHandle; 00144 (void)sc; 00145 (void)cc; 00146 (void)matchingServiceUUID; 00147 (void)matchingCharacteristicUUIDIn; 00148 00149 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00150 } 00151 00152 /** 00153 * Launch service discovery for services. Once launched, service discovery will remain 00154 * active with service-callbacks being issued back into the application for matching 00155 * services. isServiceDiscoveryActive() can be used to 00156 * determine status, and a termination callback (if set up) will be invoked 00157 * at the end. Service discovery can be terminated prematurely, if needed, 00158 * using terminateServiceDiscovery(). 00159 * 00160 * @param[in] connectionHandle 00161 * Handle for the connection with the peer. 00162 * @param[in] callback 00163 * This is the application callback for a matching service. 00164 * Note: service discovery may still be active 00165 * when this callback is issued; calling asynchronous BLE-stack 00166 * APIs from within this application callback might cause the 00167 * stack to abort service discovery. If this becomes an issue, it 00168 * may be better to make a local copy of the discoveredService and 00169 * wait for service discovery to terminate before operating on the 00170 * service. 00171 * @param[in] matchingServiceUUID 00172 * UUID-based filter for specifying a service in which the application is 00173 * interested. By default it is set as the wildcard UUID_UNKNOWN, 00174 * in which case it matches all services. 00175 * 00176 * @return 00177 * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. 00178 */ 00179 virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, 00180 ServiceDiscovery::ServiceCallback_t callback, 00181 const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) { 00182 return launchServiceDiscovery(connectionHandle, callback, NULL, matchingServiceUUID); /* We take advantage of the property 00183 * that providing NULL for the characteristic callback will result in 00184 * characteristic discovery being skipped for each matching 00185 * service. This allows for an inexpensive method to discover only 00186 * services. Porters are free to override this. */ 00187 } 00188 00189 /** 00190 * Launch service discovery for services. Once launched, service discovery will remain 00191 * active with service-callbacks being issued back into the application for matching 00192 * services. isServiceDiscoveryActive() can be used to 00193 * determine status, and a termination callback (if set up) will be invoked 00194 * at the end. Service discovery can be terminated prematurely, if needed, 00195 * using terminateServiceDiscovery(). 00196 * 00197 * @param[in] connectionHandle 00198 * Handle for the connection with the peer. 00199 * @param[in] callback 00200 * This is the application callback for a matching service. 00201 * Note: service discovery may still be active 00202 * when this callback is issued; calling asynchronous BLE-stack 00203 * APIs from within this application callback might cause the 00204 * stack to abort service discovery. If this becomes an issue, it 00205 * may be better to make a local copy of the discoveredService and 00206 * wait for service discovery to terminate before operating on the 00207 * service. 00208 * @param[in] startHandle, endHandle 00209 * Handle range within which to limit the search. 00210 * 00211 * @return 00212 * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. 00213 */ 00214 virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, 00215 ServiceDiscovery::ServiceCallback_t callback, 00216 GattAttribute::Handle_t startHandle, 00217 GattAttribute::Handle_t endHandle) { 00218 /* Avoid compiler warnings about unused variables. */ 00219 (void)connectionHandle; 00220 (void)callback; 00221 (void)startHandle; 00222 (void)endHandle; 00223 00224 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00225 } 00226 00227 /** 00228 * Check if service-discovery is currently active. 00229 * 00230 * @return true if service-discovery is active, false otherwise. 00231 */ 00232 virtual bool isServiceDiscoveryActive(void) const { 00233 return false; /* Requesting action from porters: override this API if this capability is supported. */ 00234 } 00235 00236 /** 00237 * Terminate an ongoing service discovery. This should result in an 00238 * invocation of TerminationCallback if service-discovery is active. 00239 */ 00240 virtual void terminateServiceDiscovery(void) { 00241 /* Requesting action from porters: override this API if this capability is supported. */ 00242 } 00243 00244 /** 00245 * Initiate a GATT Client read procedure by attribute-handle. 00246 * 00247 * @param[in] connHandle 00248 * Handle for the connection with the peer. 00249 * @param[in] attributeHandle 00250 * Handle of the attribute to read data from. 00251 * @param[in] offset 00252 * The offset from the start of the attribute value to be read. 00253 * 00254 * @return 00255 * BLE_ERROR_NONE if read procedure was successfully started. 00256 */ 00257 virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const { 00258 /* Avoid compiler warnings about unused variables. */ 00259 (void)connHandle; 00260 (void)attributeHandle; 00261 (void)offset; 00262 00263 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00264 } 00265 00266 /** 00267 * Initiate a GATT Client write procedure. 00268 * 00269 * @param[in] cmd 00270 * Command can be either a write-request (which generates a 00271 * matching response from the peripheral), or a write-command 00272 * (which doesn't require the connected peer to respond). 00273 * @param[in] connHandle 00274 * Connection handle. 00275 * @param[in] attributeHandle 00276 * Handle for the target attribtue on the remote GATT server. 00277 * @param[in] length 00278 * Length of the new value. 00279 * @param[in] value 00280 * New value being written. 00281 * 00282 * @return 00283 * BLE_ERROR_NONE if write procedure was successfully started. 00284 */ 00285 virtual ble_error_t write(GattClient::WriteOp_t cmd, 00286 Gap::Handle_t connHandle, 00287 GattAttribute::Handle_t attributeHandle, 00288 size_t length, 00289 const uint8_t *value) const { 00290 /* Avoid compiler warnings about unused variables. */ 00291 (void)cmd; 00292 (void)connHandle; 00293 (void)attributeHandle; 00294 (void)length; 00295 (void)value; 00296 00297 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00298 } 00299 00300 /* Event callback handlers. */ 00301 public: 00302 /** 00303 * Set up a callback for read response events. 00304 * 00305 * @param[in] callback 00306 * Event handler being registered. 00307 * 00308 * @note It is possible to chain together multiple onDataRead callbacks 00309 * (potentially from different modules of an application). 00310 * 00311 * @note It is possible to unregister a callback using 00312 * onDataRead().detach(callbackToRemove). 00313 */ 00314 void onDataRead(ReadCallback_t callback) { 00315 onDataReadCallbackChain.add(callback); 00316 } 00317 00318 /** 00319 * @brief Provide access to the callchain of read event callbacks. 00320 * 00321 * @return A reference to the read event callback chain. 00322 * 00323 * @note It is possible to register callbacks using onDataRead().add(callback). 00324 * 00325 * @note It is possible to unregister callbacks using onDataRead().detach(callback). 00326 */ 00327 ReadCallbackChain_t& onDataRead() { 00328 return onDataReadCallbackChain; 00329 } 00330 00331 /** 00332 * Set up a callback for write response events. 00333 * 00334 * @param[in] callback 00335 * Event handler being registered. 00336 * 00337 * @note It is possible to remove registered callbacks using 00338 * onDataWritten().detach(callbackToRemove). 00339 * 00340 * @note Write commands (issued using writeWoResponse) don't generate a response. 00341 */ 00342 void onDataWritten(WriteCallback_t callback) { 00343 onDataWriteCallbackChain.add(callback); 00344 } 00345 00346 /** 00347 * @brief Provide access to the callchain of data written callbacks. 00348 * 00349 * @return A reference to the data written callbacks chain. 00350 * 00351 * @note It is possible to register callbacks using onDataWritten().add(callback). 00352 * 00353 * @note It is possible to unregister callbacks using onDataWritten().detach(callback). 00354 */ 00355 WriteCallbackChain_t& onDataWritten() { 00356 return onDataWriteCallbackChain; 00357 } 00358 00359 /** 00360 * Set up a callback for write response events. 00361 * 00362 * @param[in] callback 00363 * Event handler being registered. 00364 * 00365 * @note Write commands (issued using writeWoResponse) don't generate a response. 00366 * 00367 * @deprecated Please use GattServer::onDataWritten() instead. 00368 */ 00369 void onDataWrite(WriteCallback_t callback) { 00370 onDataWritten(callback); 00371 } 00372 00373 /** 00374 * Set up a callback for when serviceDiscovery terminates. 00375 * 00376 * @param[in] callback 00377 * Event handler being registered. 00378 */ 00379 virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { 00380 (void)callback; /* Avoid compiler warnings about ununsed variables. */ 00381 00382 /* Requesting action from porters: override this API if this capability is supported. */ 00383 } 00384 00385 /** 00386 * @brief Launch discovery of descriptors for a given characteristic. 00387 * 00388 * @details This function will discover all descriptors available for a 00389 * specific characteristic. 00390 * 00391 * @param[in] characteristic 00392 * The characteristic targeted by this discovery procedure. 00393 * @param[in] discoveryCallback 00394 * User function called each time a descriptor is found during 00395 * the procedure. 00396 * @param[in] terminationCallback 00397 * User provided function which will be called once the 00398 * discovery procedure is terminating. This will get called 00399 * when all the descriptors have been discovered or if an 00400 * error occur during the discovery procedure. 00401 * 00402 * @return 00403 * BLE_ERROR_NONE if characteristic descriptor discovery is launched 00404 * successfully; else an appropriate error. 00405 */ 00406 virtual ble_error_t discoverCharacteristicDescriptors( 00407 const DiscoveredCharacteristic& characteristic, 00408 const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, 00409 const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { 00410 (void) characteristic; 00411 (void) discoveryCallback; 00412 (void) terminationCallback; 00413 /* Requesting action from porter(s): override this API if this capability is supported. */ 00414 return BLE_ERROR_NOT_IMPLEMENTED; 00415 } 00416 00417 /** 00418 * @brief Indicate if the discovery of characteristic descriptors is active 00419 * for a given characteristic or not. 00420 * 00421 * @param[in] characteristic 00422 * The characteristic concerned by the descriptors discovery. 00423 * 00424 * @return true if a descriptors discovery is active for the characteristic 00425 * in input; otherwise false. 00426 */ 00427 virtual bool isCharacteristicDescriptorDiscoveryActive(const DiscoveredCharacteristic& characteristic) const 00428 { 00429 (void) characteristic; 00430 return false; /* Requesting action from porter(s): override this API if this capability is supported. */ 00431 } 00432 00433 /** 00434 * @brief Terminate an ongoing characteristic descriptor discovery. 00435 * 00436 * @details This should result in an invocation of the TerminationCallback if 00437 * the characteristic descriptor discovery is active. 00438 * 00439 * @param[in] characteristic 00440 * The characteristic on which the running descriptors 00441 * discovery should be stopped. 00442 */ 00443 virtual void terminateCharacteristicDescriptorDiscovery(const DiscoveredCharacteristic& characteristic) { 00444 /* Requesting action from porter(s): override this API if this capability is supported. */ 00445 (void) characteristic; 00446 } 00447 00448 /** 00449 * Set up a callback for when the GATT Client receives an update event 00450 * corresponding to a change in the value of a characteristic on the remote 00451 * GATT Server. 00452 * 00453 * @note It is possible to unregister callbacks using 00454 * onHVX().detach(callbackToRemove). 00455 */ 00456 void onHVX(HVXCallback_t callback) { 00457 onHVXCallbackChain.add(callback); 00458 } 00459 00460 /** 00461 * Setup a callback to be invoked to notify the user application that the 00462 * GattClient instance is about to shutdown (possibly as a result of a call 00463 * to BLE::shutdown()). 00464 * 00465 * @param[in] callback 00466 * Event handler being registered. 00467 * 00468 * @note It is possible to chain together multiple onShutdown callbacks 00469 * (potentially from different modules of an application) to be notified 00470 * before the GattClient is shutdown. 00471 * 00472 * @note It is also possible to set up a callback into a member function of 00473 * some object. 00474 * 00475 * @note It is possible to unregister a callback using onShutdown().detach(callback). 00476 */ 00477 void onShutdown(const GattClientShutdownCallback_t& callback) { 00478 shutdownCallChain.add(callback); 00479 } 00480 00481 /** 00482 * Same as GattClient::onShutdown(), but allows the possibility to add an object 00483 * reference and member function as handler for shutdown event 00484 * callbacks. 00485 * 00486 * @param[in] objPtr 00487 * Pointer to the object of a class defining the member callback 00488 * function (@p memberPtr). 00489 * @param[in] memberPtr 00490 * The member callback (within the context of an object) to be 00491 * invoked. 00492 */ 00493 template <typename T> 00494 void onShutdown(T *objPtr, void (T::*memberPtr)(const GattClient *)) { 00495 shutdownCallChain.add(objPtr, memberPtr); 00496 } 00497 00498 /** 00499 * @brief Provide access to the callchain of shutdown event callbacks. 00500 * 00501 * @return A reference to the shutdown event callbacks chain. 00502 * 00503 * @note It is possible to register callbacks using onShutdown().add(callback). 00504 * 00505 * @note It is possible to unregister callbacks using onShutdown().detach(callback). 00506 */ 00507 GattClientShutdownCallbackChain_t& onShutdown() { 00508 return shutdownCallChain; 00509 } 00510 00511 /** 00512 * @brief provide access to the callchain of HVX callbacks. 00513 * 00514 * @return A reference to the HVX callbacks chain. 00515 * 00516 * @note It is possible to register callbacks using onHVX().add(callback). 00517 * 00518 * @note It is possible to unregister callbacks using onHVX().detach(callback). 00519 */ 00520 HVXCallbackChain_t& onHVX() { 00521 return onHVXCallbackChain; 00522 } 00523 00524 public: 00525 /** 00526 * Notify all registered onShutdown callbacks that the GattClient is 00527 * about to be shutdown and clear all GattClient state of the 00528 * associated object. 00529 * 00530 * This function is meant to be overridden in the platform-specific 00531 * sub-class. Nevertheless, the sub-class is only expected to reset its 00532 * state and not the data held in GattClient members. This shall be achieved 00533 * by a call to GattClient::reset() from the sub-class' reset() 00534 * implementation. 00535 * 00536 * @return BLE_ERROR_NONE on success. 00537 */ 00538 virtual ble_error_t reset(void) { 00539 /* Notify that the instance is about to shutdown */ 00540 shutdownCallChain.call(this); 00541 shutdownCallChain.clear(); 00542 00543 onDataReadCallbackChain.clear(); 00544 onDataWriteCallbackChain.clear(); 00545 onHVXCallbackChain.clear(); 00546 00547 return BLE_ERROR_NONE; 00548 } 00549 00550 protected: 00551 GattClient() { 00552 /* Empty */ 00553 } 00554 00555 /* Entry points for the underlying stack to report events back to the user. */ 00556 public: 00557 /** 00558 * Helper function that notifies all registered handlers of an occurrence 00559 * of a data read event. This function is meant to be called from the 00560 * BLE stack specific implementation when a data read event occurs. 00561 * 00562 * @param[in] params 00563 * The data read parameters passed to the registered 00564 * handlers. 00565 */ 00566 void processReadResponse(const GattReadCallbackParams *params) { 00567 onDataReadCallbackChain(params); 00568 } 00569 00570 /** 00571 * Helper function that notifies all registered handlers of an occurrence 00572 * of a data written event. This function is meant to be called from the 00573 * BLE stack specific implementation when a data written event occurs. 00574 * 00575 * @param[in] params 00576 * The data written parameters passed to the registered 00577 * handlers. 00578 */ 00579 void processWriteResponse(const GattWriteCallbackParams *params) { 00580 onDataWriteCallbackChain(params); 00581 } 00582 00583 /** 00584 * Helper function that notifies all registered handlers of an occurrence 00585 * of an update event. This function is meant to be called from the 00586 * BLE stack specific implementation when an update event occurs. 00587 * 00588 * @param[in] params 00589 * The update event parameters passed to the registered 00590 * handlers. 00591 */ 00592 void processHVXEvent(const GattHVXCallbackParams *params) { 00593 if (onHVXCallbackChain) { 00594 onHVXCallbackChain(params); 00595 } 00596 } 00597 00598 protected: 00599 /** 00600 * Callchain containing all registered callback handlers for data read 00601 * events. 00602 */ 00603 ReadCallbackChain_t onDataReadCallbackChain; 00604 /** 00605 * Callchain containing all registered callback handlers for data write 00606 * events. 00607 */ 00608 WriteCallbackChain_t onDataWriteCallbackChain; 00609 /** 00610 * Callchain containing all registered callback handlers for update 00611 * events. 00612 */ 00613 HVXCallbackChain_t onHVXCallbackChain; 00614 /** 00615 * Callchain containing all registered callback handlers for shutdown 00616 * events. 00617 */ 00618 GattClientShutdownCallbackChain_t shutdownCallChain; 00619 00620 private: 00621 /* Disallow copy and assignment. */ 00622 GattClient(const GattClient &); 00623 GattClient& operator=(const GattClient &); 00624 }; 00625 00626 #endif /* ifndef __GATT_CLIENT_H__ */
Generated on Tue Jul 12 2022 13:15:50 by
