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
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 typedef FunctionPointerWithContext<const GattReadCallbackParams*> ReadCallback_t; 00032 typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams*> ReadCallbackChain_t; 00033 00034 enum WriteOp_t { 00035 GATT_OP_WRITE_REQ = 0x01, /**< Write request. */ 00036 GATT_OP_WRITE_CMD = 0x02, /**< Write command. */ 00037 }; 00038 00039 typedef FunctionPointerWithContext<const GattWriteCallbackParams*> WriteCallback_t; 00040 typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*> WriteCallbackChain_t; 00041 00042 typedef FunctionPointerWithContext<const GattHVXCallbackParams*> HVXCallback_t; 00043 typedef CallChainOfFunctionPointersWithContext<const GattHVXCallbackParams*> HVXCallbackChain_t; 00044 00045 typedef FunctionPointerWithContext<const GattClient *> GattClientShutdownCallback_t; 00046 typedef CallChainOfFunctionPointersWithContext<const GattClient *> GattClientShutdownCallbackChain_t; 00047 00048 /* 00049 * The following functions are meant to be overridden in the platform-specific sub-class. 00050 */ 00051 public: 00052 /** 00053 * Launch service discovery. Once launched, application callbacks will be 00054 * invoked for matching services or characteristics. isServiceDiscoveryActive() 00055 * can be used to determine status, and a termination callback (if one was set up) 00056 * will be invoked at the end. Service discovery can be terminated prematurely, 00057 * if needed, using terminateServiceDiscovery(). 00058 * 00059 * @param connectionHandle 00060 * Handle for the connection with the peer. 00061 * @param sc 00062 * This is the application callback for a matching service. Taken as 00063 * NULL by default. Note: service discovery may still be active 00064 * when this callback is issued; calling asynchronous BLE-stack 00065 * APIs from within this application callback might cause the 00066 * stack to abort service discovery. If this becomes an issue, it 00067 * may be better to make a local copy of the discoveredService and 00068 * wait for service discovery to terminate before operating on the 00069 * service. 00070 * @param cc 00071 * This is the application callback for a matching characteristic. 00072 * Taken as NULL by default. Note: service discovery may still be 00073 * active when this callback is issued; calling asynchronous 00074 * BLE-stack APIs from within this application callback might cause 00075 * the stack to abort service discovery. If this becomes an issue, 00076 * it may be better to make a local copy of the discoveredCharacteristic 00077 * and wait for service discovery to terminate before operating on the 00078 * characteristic. 00079 * @param matchingServiceUUID 00080 * UUID-based filter for specifying a service in which the application is 00081 * interested. By default it is set as the wildcard UUID_UNKNOWN, 00082 * in which case it matches all services. If characteristic-UUID 00083 * filter (below) is set to the wildcard value, then a service 00084 * callback will be invoked for the matching service (or for every 00085 * service if the service filter is a wildcard). 00086 * @param matchingCharacteristicUUIDIn 00087 * UUID-based filter for specifying characteristic in which the application 00088 * is interested. By default it is set as the wildcard UUID_UKNOWN 00089 * to match against any characteristic. If both service-UUID 00090 * filter and characteristic-UUID filter are used with non-wildcard 00091 * values, then only a single characteristic callback is 00092 * invoked for the matching characteristic. 00093 * 00094 * @note Using wildcard values for both service-UUID and characteristic- 00095 * UUID will result in complete service discovery: callbacks being 00096 * called for every service and characteristic. 00097 * 00098 * @note Providing NULL for the characteristic callback will result in 00099 * characteristic discovery being skipped for each matching 00100 * service. This allows for an inexpensive method to discover only 00101 * services. 00102 * 00103 * @return 00104 * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. 00105 */ 00106 virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, 00107 ServiceDiscovery::ServiceCallback_t sc = NULL, 00108 ServiceDiscovery::CharacteristicCallback_t cc = NULL, 00109 const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), 00110 const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) { 00111 /* Avoid compiler warnings about unused variables. */ 00112 (void)connectionHandle; 00113 (void)sc; 00114 (void)cc; 00115 (void)matchingServiceUUID; 00116 (void)matchingCharacteristicUUIDIn; 00117 00118 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00119 } 00120 00121 /** 00122 * Launch service discovery for services. Once launched, service discovery will remain 00123 * active with service-callbacks being issued back into the application for matching 00124 * services. isServiceDiscoveryActive() can be used to 00125 * determine status, and a termination callback (if set up) will be invoked 00126 * at the end. Service discovery can be terminated prematurely, if needed, 00127 * using terminateServiceDiscovery(). 00128 * 00129 * @param connectionHandle 00130 * Handle for the connection with the peer. 00131 * @param sc 00132 * This is the application callback for a matching service. Note: service discovery may still be active 00133 * when this callback is issued; calling asynchronous BLE-stack 00134 * APIs from within this application callback might cause the 00135 * stack to abort service discovery. If this becomes an issue, it 00136 * may be better to make a local copy of the discoveredService and 00137 * wait for service discovery to terminate before operating on the 00138 * service. 00139 * @param matchingServiceUUID 00140 * UUID-based filter for specifying a service in which the application is 00141 * interested. By default it is set as the wildcard UUID_UNKNOWN, 00142 * in which case it matches all services. 00143 * 00144 * @return 00145 * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. 00146 */ 00147 virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, 00148 ServiceDiscovery::ServiceCallback_t callback, 00149 const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) { 00150 return launchServiceDiscovery(connectionHandle, callback, NULL, matchingServiceUUID); /* We take advantage of the property 00151 * that providing NULL for the characteristic callback will result in 00152 * characteristic discovery being skipped for each matching 00153 * service. This allows for an inexpensive method to discover only 00154 * services. Porters are free to override this. */ 00155 } 00156 00157 /** 00158 * Launch service discovery for services. Once launched, service discovery will remain 00159 * active with service-callbacks being issued back into the application for matching 00160 * services. isServiceDiscoveryActive() can be used to 00161 * determine status, and a termination callback (if set up) will be invoked 00162 * at the end. Service discovery can be terminated prematurely, if needed, 00163 * using terminateServiceDiscovery(). 00164 * 00165 * @param connectionHandle 00166 * Handle for the connection with the peer. 00167 * @param sc 00168 * This is the application callback for a matching service. Note: service discovery may still be active 00169 * when this callback is issued; calling asynchronous BLE-stack 00170 * APIs from within this application callback might cause the 00171 * stack to abort service discovery. If this becomes an issue, it 00172 * may be better to make a local copy of the discoveredService and 00173 * wait for service discovery to terminate before operating on the 00174 * service. 00175 * @param startHandle, endHandle 00176 * Handle range within which to limit the search. 00177 * 00178 * @return 00179 * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. 00180 */ 00181 virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, 00182 ServiceDiscovery::ServiceCallback_t callback, 00183 GattAttribute::Handle_t startHandle, 00184 GattAttribute::Handle_t endHandle) { 00185 /* Avoid compiler warnings about unused variables. */ 00186 (void)connectionHandle; 00187 (void)callback; 00188 (void)startHandle; 00189 (void)endHandle; 00190 00191 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00192 } 00193 00194 /** 00195 * Is service-discovery currently active? 00196 */ 00197 virtual bool isServiceDiscoveryActive(void) const { 00198 return false; /* Requesting action from porters: override this API if this capability is supported. */ 00199 } 00200 00201 /** 00202 * Terminate an ongoing service discovery. This should result in an 00203 * invocation of TerminationCallback if service-discovery is active. 00204 */ 00205 virtual void terminateServiceDiscovery(void) { 00206 /* Requesting action from porters: override this API if this capability is supported. */ 00207 } 00208 00209 /* Initiate a GATT Client read procedure by attribute-handle. */ 00210 virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const { 00211 /* Avoid compiler warnings about unused variables. */ 00212 (void)connHandle; 00213 (void)attributeHandle; 00214 (void)offset; 00215 00216 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00217 } 00218 00219 /** 00220 * Initiate a GATT Client write procedure. 00221 * 00222 * @param[in] cmd 00223 * Command can be either a write-request (which generates a 00224 * matching response from the peripheral), or a write-command 00225 * (which doesn't require the connected peer to respond). 00226 * @param[in] connHandle 00227 * Connection handle. 00228 * @param[in] attributeHandle 00229 * Handle for the target attribtue on the remote GATT server. 00230 * @param[in] length 00231 * Length of the new value. 00232 * @param[in] value 00233 * New value being written. 00234 */ 00235 virtual ble_error_t write(GattClient::WriteOp_t cmd, 00236 Gap::Handle_t connHandle, 00237 GattAttribute::Handle_t attributeHandle, 00238 size_t length, 00239 const uint8_t *value) const { 00240 /* Avoid compiler warnings about unused variables. */ 00241 (void)cmd; 00242 (void)connHandle; 00243 (void)attributeHandle; 00244 (void)length; 00245 (void)value; 00246 00247 return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ 00248 } 00249 00250 /* Event callback handlers. */ 00251 public: 00252 /** 00253 * Set up a callback for read response events. 00254 * It is possible to remove registered callbacks using 00255 * onDataRead().detach(callbackToRemove) 00256 */ 00257 void onDataRead(ReadCallback_t callback) { 00258 onDataReadCallbackChain.add(callback); 00259 } 00260 00261 /** 00262 * @brief provide access to the callchain of read callbacks 00263 * It is possible to register callbacks using onDataRead().add(callback); 00264 * It is possible to unregister callbacks using onDataRead().detach(callback) 00265 * @return The read callbacks chain 00266 */ 00267 ReadCallbackChain_t& onDataRead() { 00268 return onDataReadCallbackChain; 00269 } 00270 00271 /** 00272 * Set up a callback for write response events. 00273 * It is possible to remove registered callbacks using 00274 * onDataWritten().detach(callbackToRemove). 00275 * @Note: Write commands (issued using writeWoResponse) don't generate a response. 00276 */ 00277 void onDataWritten(WriteCallback_t callback) { 00278 onDataWriteCallbackChain.add(callback); 00279 } 00280 00281 /** 00282 * @brief provide access to the callchain of data written callbacks 00283 * It is possible to register callbacks using onDataWritten().add(callback); 00284 * It is possible to unregister callbacks using onDataWritten().detach(callback) 00285 * @return The data written callbacks chain 00286 */ 00287 WriteCallbackChain_t& onDataWritten() { 00288 return onDataWriteCallbackChain; 00289 } 00290 00291 /** 00292 * Set up a callback for write response events. 00293 * @Note: Write commands (issued using writeWoResponse) don't generate a response. 00294 * 00295 * @note: This API is now *deprecated* and will be dropped in the future. 00296 * Please use onDataWritten() instead. 00297 */ 00298 void onDataWrite(WriteCallback_t callback) { 00299 onDataWritten(callback); 00300 } 00301 00302 /** 00303 * Set up a callback for when serviceDiscovery terminates. 00304 */ 00305 virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { 00306 (void)callback; /* Avoid compiler warnings about ununsed variables. */ 00307 00308 /* Requesting action from porters: override this API if this capability is supported. */ 00309 } 00310 00311 /** 00312 * @brief launch discovery of descriptors for a given characteristic 00313 * @details This function will discover all descriptors available for a 00314 * specific characteristic. 00315 * 00316 * @param characteristic[in] The characteristic targeted by this discovery 00317 * procedure 00318 * @param discoveryCallback[in] User function called each time a descriptor 00319 * is found during the procedure. 00320 * @param terminationCallback[in] User provided function which will be called 00321 * once the discovery procedure is terminating. This will get called when all 00322 * the descriptors have been discovered or if an error occur during the discovery 00323 * procedure. 00324 * 00325 * @return 00326 * BLE_ERROR_NONE if characteristic descriptor discovery is launched 00327 * successfully; else an appropriate error. 00328 */ 00329 virtual ble_error_t discoverCharacteristicDescriptors( 00330 const DiscoveredCharacteristic& characteristic, 00331 const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, 00332 const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { 00333 (void) characteristic; 00334 (void) discoveryCallback; 00335 (void) terminationCallback; 00336 /* Requesting action from porter(s): override this API if this capability is supported. */ 00337 return BLE_ERROR_NOT_IMPLEMENTED; 00338 } 00339 00340 /** 00341 * @brief Indicate if the discovery of characteristic descriptors is active for a given characteristic 00342 * or not. 00343 * @param characteristic[in] The characteristic concerned by the descriptors discovery. 00344 * @return true if a descriptors discovery is active for the characteristic in input; otherwise false. 00345 */ 00346 virtual bool isCharacteristicDescriptorDiscoveryActive(const DiscoveredCharacteristic& characteristic) const 00347 { 00348 (void) characteristic; 00349 return false; /* Requesting action from porter(s): override this API if this capability is supported. */ 00350 } 00351 00352 /** 00353 * @brief Terminate an ongoing characteristic descriptor discovery. 00354 * @detail This should result in an invocation of the TerminationCallback if 00355 * the characteristic descriptor discovery is active. 00356 * @param characteristic[in] The characteristic on which the running descriptors 00357 * discovery should be stopped. 00358 */ 00359 virtual void terminateCharacteristicDescriptorDiscovery(const DiscoveredCharacteristic& characteristic) { 00360 /* Requesting action from porter(s): override this API if this capability is supported. */ 00361 (void) characteristic; 00362 } 00363 00364 /** 00365 * Set up a callback for when the GATT client receives an update event 00366 * corresponding to a change in the value of a characteristic on the remote 00367 * GATT server. 00368 * It is possible to remove registered callbacks using onHVX().detach(callbackToRemove). 00369 */ 00370 void onHVX(HVXCallback_t callback) { 00371 onHVXCallbackChain.add(callback); 00372 } 00373 00374 /** 00375 * Setup a callback to be invoked to notify the user application that the 00376 * GattClient instance is about to shutdown (possibly as a result of a call 00377 * to BLE::shutdown()). 00378 * 00379 * @Note: It is possible to chain together multiple onShutdown callbacks 00380 * (potentially from different modules of an application) to be notified 00381 * before the GattClient is shutdown. 00382 * 00383 * @Note: It is also possible to set up a callback into a member function of 00384 * some object. 00385 * 00386 * @Note It is possible to unregister a callback using onShutdown().detach(callback) 00387 */ 00388 void onShutdown(const GattClientShutdownCallback_t& callback) { 00389 shutdownCallChain.add(callback); 00390 } 00391 template <typename T> 00392 void onShutdown(T *objPtr, void (T::*memberPtr)(void)) { 00393 shutdownCallChain.add(objPtr, memberPtr); 00394 } 00395 00396 /** 00397 * @brief provide access to the callchain of shutdown event callbacks 00398 * It is possible to register callbacks using onShutdown().add(callback); 00399 * It is possible to unregister callbacks using onShutdown().detach(callback) 00400 * @return The shutdown event callbacks chain 00401 */ 00402 GattClientShutdownCallbackChain_t& onShutdown() { 00403 return shutdownCallChain; 00404 } 00405 00406 /** 00407 * @brief provide access to the callchain of HVX callbacks 00408 * It is possible to register callbacks using onHVX().add(callback); 00409 * It is possible to unregister callbacks using onHVX().detach(callback) 00410 * @return The HVX callbacks chain 00411 */ 00412 HVXCallbackChain_t& onHVX() { 00413 return onHVXCallbackChain; 00414 } 00415 00416 public: 00417 /** 00418 * Notify all registered onShutdown callbacks that the GattClient is 00419 * about to be shutdown and clear all GattClient state of the 00420 * associated object. 00421 * 00422 * This function is meant to be overridden in the platform-specific 00423 * sub-class. Nevertheless, the sub-class is only expected to reset its 00424 * state and not the data held in GattClient members. This shall be achieved 00425 * by a call to GattClient::reset() from the sub-class' reset() 00426 * implementation. 00427 * 00428 * @return BLE_ERROR_NONE on success. 00429 */ 00430 virtual ble_error_t reset(void) { 00431 /* Notify that the instance is about to shutdown */ 00432 shutdownCallChain.call(this); 00433 shutdownCallChain.clear(); 00434 00435 onDataReadCallbackChain.clear(); 00436 onDataWriteCallbackChain.clear(); 00437 onHVXCallbackChain.clear(); 00438 00439 return BLE_ERROR_NONE; 00440 } 00441 00442 protected: 00443 GattClient() { 00444 /* Empty */ 00445 } 00446 00447 /* Entry points for the underlying stack to report events back to the user. */ 00448 public: 00449 void processReadResponse(const GattReadCallbackParams *params) { 00450 onDataReadCallbackChain(params); 00451 } 00452 00453 void processWriteResponse(const GattWriteCallbackParams *params) { 00454 onDataWriteCallbackChain(params); 00455 } 00456 00457 void processHVXEvent(const GattHVXCallbackParams *params) { 00458 if (onHVXCallbackChain) { 00459 onHVXCallbackChain(params); 00460 } 00461 } 00462 00463 protected: 00464 ReadCallbackChain_t onDataReadCallbackChain; 00465 WriteCallbackChain_t onDataWriteCallbackChain; 00466 HVXCallbackChain_t onHVXCallbackChain; 00467 GattClientShutdownCallbackChain_t shutdownCallChain; 00468 00469 private: 00470 /* Disallow copy and assignment. */ 00471 GattClient(const GattClient &); 00472 GattClient& operator=(const GattClient &); 00473 }; 00474 00475 #endif // ifndef __GATT_CLIENT_H__
Generated on Tue Jul 12 2022 17:17:58 by 1.7.2