From 1c2685c2ac1469ddd146917243a183670cf2be57 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Fri, 27 Oct 2017 11:39:05 -0500 Subject: [PATCH] BLE: Improve GattClient.h documentation. --- features/FEATURE_BLE/ble/GattClient.h | 828 ++++++++++++++++---------- 1 file changed, 512 insertions(+), 316 deletions(-) diff --git a/features/FEATURE_BLE/ble/GattClient.h b/features/FEATURE_BLE/ble/GattClient.h index 5f043ebb22..b441c8000c 100644 --- a/features/FEATURE_BLE/ble/GattClient.h +++ b/features/FEATURE_BLE/ble/GattClient.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef __GATT_CLIENT_H__ -#define __GATT_CLIENT_H__ +#ifndef MBED_GATT_CLIENT_H__ +#define MBED_GATT_CLIENT_H__ #include "Gap.h" #include "GattAttribute.h" @@ -26,122 +26,212 @@ #include "CallChainOfFunctionPointersWithContext.h" +/** + * @addtogroup ble + * @{ + * @addtogroup gatt + * @{ + * @addtogroup client + * @{ + */ + +/** + * Define procedures required for interracting with a distant GATT server. + * + * @par Discovery procedures + * + * A GATT server host a fixed set of services. These services are a logical + * composition of Characteristic which may be discovered, read, written or also + * broadcast their state to a connected client. These characteristics may also + * contain meta informations named characteristic descriptor. A characteristic + * descriptor may be used to indicate the unit used for a characteristic value, + * describe in a textual form the characterisic purpose or allow a client to + * register for notification of updates of the characteristic value. + * + * Prior to any interaction with server characteristic, a GATT client should + * discover the layout of the services and characteristics present on the + * server. + * + * The layout of the descriptors of a characteristic may also be issued to + * as an extra discovery step. + * + * @par Attribute manipulation + * + * As a result of the discovery process the client can start interracting with + * the characteristic discovered. Depending on the characteristic properties + * (acquired during discovery) a client can read or write the value of a given + * characteristic. + * + * mbed BLE abstract most read/write operation to offer a user a single API which + * can be use to read or write characteristics values. Application code do not + * have to handle the fragmentation/reassembly process necessary if the attribute + * value to transported cannot fit in a single data packet. + * + * @par Server Initiated events + * + * If a characteristic has the notify or indicate property set then a client may + * register to notification or indication from the characteristic. When the + * characteristic value is updated by the server, the server can forward the + * new value to the registered clients. The notification/indication mechanism + * prevents polling from the client and therefore minimize the transactons + * involved between a client and a server. + * + * Registration is made by writing the Client Characteristic Configuration + * Descriptor which shall be present in the characteristic if the notify or + * indicate properties are set. That descriptor shall be discovered by the client + * if it intends to register to server initiated events. + */ class GattClient { public: /** - * Type for the registered callbacks added to the data read callchain. - * Refer to GattClient::onDataRead(). + * Attribute read event handler. + * + * @see GattClient::onDataRead(). */ - typedef FunctionPointerWithContext ReadCallback_t; - /** - * Type for the data read event callchain. Refer to GattClient::onDataRead(). - */ - typedef CallChainOfFunctionPointersWithContext ReadCallbackChain_t; + typedef FunctionPointerWithContext + ReadCallback_t; /** - * Enumerator for write operations. + * Callchain of attribute read event handlers. + */ + typedef CallChainOfFunctionPointersWithContext + ReadCallbackChain_t; + + /** + * GATT write operations. */ enum WriteOp_t { - GATT_OP_WRITE_REQ = 0x01, /**< Write request. */ - GATT_OP_WRITE_CMD = 0x02, /**< Write command. */ + /** + * Write request. + * + * It is used to request the server to write the value of an attribute + * and acknowledge that this has been achieved in a Write Response. + */ + GATT_OP_WRITE_REQ = 0x01, + + /** + * Write command. + * + * It is is used to request the server to write the value of an attribute. + * The server does not acknowledge the status of the operation. + */ + GATT_OP_WRITE_CMD = 0x02, }; /** - * Type for the registered callbacks added to the data write callchain. - * Refer to GattClient::onDataWrite(). + * Attribute write event handler. + * + * @see GattClient::onDataWrite(). */ - typedef FunctionPointerWithContext WriteCallback_t; - /** - * Type for the data write event callchain. Refer to GattClient::onDataWrite(). - */ - typedef CallChainOfFunctionPointersWithContext WriteCallbackChain_t; + typedef FunctionPointerWithContext + WriteCallback_t; /** - * Type for the registered callbacks added to the update event callchain. - * Refer to GattClient::onHVX(). + * Callchain of attribute write event handlers. + * + * @see GattClient::onDataWrite(). */ - typedef FunctionPointerWithContext HVXCallback_t; - /** - * Type for the update event callchain. Refer to GattClient::onHVX(). - */ - typedef CallChainOfFunctionPointersWithContext HVXCallbackChain_t; + typedef CallChainOfFunctionPointersWithContext + WriteCallbackChain_t; /** - * Type for the registered callbacks added to the shutdown callchain. - * Refer to GattClient::onShutdown(). + * Handle value notification/indication event handler. + * + * @see to GattClient::onHVX(). */ - typedef FunctionPointerWithContext GattClientShutdownCallback_t; + typedef FunctionPointerWithContext + HVXCallback_t; + /** - * Type for the shutdown event callchain. Refer to GattClient::onShutown(). + * Callchain of handle value notification/indication event handlers. + * + * @see GattClient::onHVX(). */ - typedef CallChainOfFunctionPointersWithContext GattClientShutdownCallbackChain_t; + typedef CallChainOfFunctionPointersWithContext + HVXCallbackChain_t; + + /** + * Shutdown event handler. + * + * @see GattClient::onShutdown(). + */ + typedef FunctionPointerWithContext + GattClientShutdownCallback_t; + + + /** + * Callchain of shutdown event handlers. + * + * @see to GattClient::onShutown(). + */ + typedef CallChainOfFunctionPointersWithContext + GattClientShutdownCallbackChain_t; /* - * The following functions are meant to be overridden in the platform-specific sub-class. + * The following functions are meant to be overridden in the platform + * specific sub-class. */ public: virtual ~GattClient() { } /** - * Launch service discovery. Once launched, application callbacks will be - * invoked for matching services or characteristics. isServiceDiscoveryActive() - * can be used to determine status, and a termination callback (if one was set up) - * will be invoked at the end. Service discovery can be terminated prematurely, - * if needed, using terminateServiceDiscovery(). + * Launch the service and characteristic discovery procedure of a GATT server + * peer. * - * @param[in] connectionHandle - * Handle for the connection with the peer. - * @param[in] sc - * This is the application callback for a matching service. Taken as - * NULL by default. Note: service discovery may still be active - * when this callback is issued; calling asynchronous BLE-stack - * APIs from within this application callback might cause the - * stack to abort service discovery. If this becomes an issue, it - * may be better to make a local copy of the discoveredService and - * wait for service discovery to terminate before operating on the - * service. - * @param[in] cc - * This is the application callback for a matching characteristic. - * Taken as NULL by default. Note: service discovery may still be - * active when this callback is issued; calling asynchronous - * BLE-stack APIs from within this application callback might cause - * the stack to abort service discovery. If this becomes an issue, - * it may be better to make a local copy of the discoveredCharacteristic - * and wait for service discovery to terminate before operating on the - * characteristic. - * @param[in] matchingServiceUUID - * UUID-based filter for specifying a service in which the application is - * interested. By default it is set as the wildcard UUID_UNKNOWN, - * in which case it matches all services. If characteristic-UUID - * filter (below) is set to the wildcard value, then a service - * callback will be invoked for the matching service (or for every - * service if the service filter is a wildcard). - * @param[in] matchingCharacteristicUUIDIn - * UUID-based filter for specifying characteristic in which the application - * is interested. By default it is set as the wildcard UUID_UKNOWN - * to match against any characteristic. If both service-UUID - * filter and characteristic-UUID filter are used with non-wildcard - * values, then only a single characteristic callback is - * invoked for the matching characteristic. + * The procedure will invoke application callbacks for matching services or + * characteristics. The process ends after all the services and + * characteristics present on the distant GATT server have been discovered. + * Termination callbacks registered with onServiceDiscoveryTermination() are + * invoked to notify the application of the termination of the procedure. * - * @note Using wildcard values for both service-UUID and characteristic- - * UUID will result in complete service discovery: callbacks being - * called for every service and characteristic. + * Application code can track the status of the procedure by invoking the + * function isServiceDiscoveryActive() which will return true if the + * procedure is ongoing. * - * @note Providing NULL for the characteristic callback will result in - * characteristic discovery being skipped for each matching - * service. This allows for an inexpensive method to discover only - * services. + * At any point application code can terminate prematurely the discovery + * procedure by calling terminateServiceDiscovery(). * - * @return - * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. + * @param[in] connectionHandle Handle of the connection with the peer GATT + * server. + * @param[in] sc Service discovered event handler invoked when a matching + * service has been discovered. This parameter may be NULL. + * @param[in] cc Characteristic discovered event handler invoked when a + * matching characteristic has been found. This parameter may be NULL. + * @param[in] matchingServiceUUID UUID of the service the caller is + * interrested in. If a service discovered match this filter then @p sc is + * invoked with it. The special value BLE_UUID_UNKNOWN act is a wildcard + * which can be used to discover all services present on the peer GATT + * server. + * @param[in] matchingCharacteristicUUIDIn UUID of the characteristic the + * caller is interrested in. If a characteristic discovered match this + * filter then @p cc is invoked with it. The special value BLE_UUID_UNKNOWN + * act is a wildcard which can be used to discover all services present on + * the peer GATT server. + * + * @par Discovery procedure implementation detail + * + * It is recommended to implement several strategies based on the + * combination of callbacks and filters passed in input to efficiently + * realize the discovery procedure: + * - If @p sc and @p cc are NULL then it is not necessay to initiate any + * discovery and the termination handlers can be invoked immediately. + * - If @p matchingServiceUUID is set then the GATT discover services by + * service UUID procedure should be used otherwise the GATT discover primary + * services procedure should be used.. + * - If @p cc is NULL then the discovery process should end after the discovery + * of the services. + * + * @return BLE_ERROR_NONE if the discovery procedure has been successfully + * started and an appropriate error otherwise. */ - virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, - ServiceDiscovery::ServiceCallback_t sc = NULL, - ServiceDiscovery::CharacteristicCallback_t cc = NULL, - const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), - const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) { + virtual ble_error_t launchServiceDiscovery( + Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN) + ) { /* Avoid compiler warnings about unused variables. */ (void)connectionHandle; (void)sc; @@ -149,147 +239,213 @@ public: (void)matchingServiceUUID; (void)matchingCharacteristicUUIDIn; - return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ + /* Requesting action from porters: override this API if this capability + is supported. */ + return BLE_ERROR_NOT_IMPLEMENTED; } /** - * Launch service discovery for services. Once launched, service discovery will remain - * active with service-callbacks being issued back into the application for matching - * services. isServiceDiscoveryActive() can be used to - * determine status, and a termination callback (if set up) will be invoked - * at the end. Service discovery can be terminated prematurely, if needed, - * using terminateServiceDiscovery(). + * Launch the service discovery procedure of a GATT server peer. * - * @param[in] connectionHandle - * Handle for the connection with the peer. - * @param[in] callback - * This is the application callback for a matching service. - * Note: service discovery may still be active - * when this callback is issued; calling asynchronous BLE-stack - * APIs from within this application callback might cause the - * stack to abort service discovery. If this becomes an issue, it - * may be better to make a local copy of the discoveredService and - * wait for service discovery to terminate before operating on the - * service. - * @param[in] matchingServiceUUID - * UUID-based filter for specifying a service in which the application is - * interested. By default it is set as the wildcard UUID_UNKNOWN, - * in which case it matches all services. + * The procedure will invoke the application callback for matching services. + * The process ends after all the services present on the distant GATT + * server have been discovered. + * Termination callbacks registered with onServiceDiscoveryTermination() are + * invoked to notify the application of the termination of the procedure. * - * @return - * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. + * Application code can track the status of the procedure by invoking the + * function isServiceDiscoveryActive() which will return true if the + * procedure is ongoing. + * + * At any point application code can terminate prematurely the discovery + * procedure by calling terminateServiceDiscovery(). + * + * @param[in] connectionHandle Handle of the connection with the peer GATT + * server. + * @param[in] callback Service discovered event handler invoked when a + * matching service has been discovered. This parameter may be NULL. + * @param[in] matchingServiceUUID UUID of the service the caller is + * interrested in. If a service discovered match this filter then @p sc is + * invoked with it. The special value BLE_UUID_UNKNOWN act is a wildcard + * which can be used to discover all services present on the peer GATT + * server. + * + * @return BLE_ERROR_NONE if the discovery procedure has been successfully + * started and an appropriate error otherwise. */ - virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, - ServiceDiscovery::ServiceCallback_t callback, - const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) { - return launchServiceDiscovery(connectionHandle, callback, NULL, matchingServiceUUID); /* We take advantage of the property - * that providing NULL for the characteristic callback will result in - * characteristic discovery being skipped for each matching - * service. This allows for an inexpensive method to discover only - * services. Porters are free to override this. */ + virtual ble_error_t discoverServices( + Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN) + ) { + /* We take advantage of the property + * that providing NULL for the characteristic callback will result in + * characteristic discovery being skipped for each matching + * service. This allows for an inexpensive method to discover only + * services. Porters are free to override this. */ + return launchServiceDiscovery( + connectionHandle, callback, NULL, matchingServiceUUID + ); } /** - * Launch service discovery for services. Once launched, service discovery will remain - * active with service-callbacks being issued back into the application for matching - * services. isServiceDiscoveryActive() can be used to - * determine status, and a termination callback (if set up) will be invoked - * at the end. Service discovery can be terminated prematurely, if needed, - * using terminateServiceDiscovery(). + * Launch the service discovery procedure of a GATT server peer. * - * @param[in] connectionHandle - * Handle for the connection with the peer. - * @param[in] callback - * This is the application callback for a matching service. - * Note: service discovery may still be active - * when this callback is issued; calling asynchronous BLE-stack - * APIs from within this application callback might cause the - * stack to abort service discovery. If this becomes an issue, it - * may be better to make a local copy of the discoveredService and - * wait for service discovery to terminate before operating on the - * service. - * @param[in] startHandle, endHandle - * Handle range within which to limit the search. + * The process ends after all the services present in the attribute range @p + * startHandle to @p endHandle have been discovered. * - * @return - * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. + * Termination callbacks registered with onServiceDiscoveryTermination() are + * invoked to notify the application of the termination of the procedure. + * + * Application code can track the status of the procedure by invoking the + * function isServiceDiscoveryActive() which will return true if the + * procedure is ongoing. + * + * At any point application code can terminate prematurely the discovery + * procedure by calling terminateServiceDiscovery(). + * + * @param[in] connectionHandle Handle of the connection with the peer GATT + * server. + * @param[in] callback Service discovered event handler invoked when a + * matching service has been discovered. This parameter may be NULL. + * @param[in] startHandle First attribute handle of the discovery range. + * @param[in] endHandle end Lasr attribute handle of the discovery range. + * + * @return BLE_ERROR_NONE if the discovery procedure has been successfully + * started and an appropriate error otherwise. */ - virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle, - ServiceDiscovery::ServiceCallback_t callback, - GattAttribute::Handle_t startHandle, - GattAttribute::Handle_t endHandle) { + virtual ble_error_t discoverServices( + Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t callback, + GattAttribute::Handle_t startHandle, + GattAttribute::Handle_t endHandle + ) { /* Avoid compiler warnings about unused variables. */ (void)connectionHandle; (void)callback; (void)startHandle; (void)endHandle; - return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ + /* Requesting action from porters: override this API if this capability + is supported. */ + return BLE_ERROR_NOT_IMPLEMENTED; } /** - * Check if service-discovery is currently active. + * Check if the service discovery procedure is currently active. * - * @return true if service-discovery is active, false otherwise. + * @return true if service discovery procedure is active and false otherwise. */ - virtual bool isServiceDiscoveryActive(void) const { - return false; /* Requesting action from porters: override this API if this capability is supported. */ + virtual bool isServiceDiscoveryActive(void) const + { + /* Requesting action from porters: override this API if this capability + is supported. */ + return false; } /** - * Terminate an ongoing service discovery. This should result in an - * invocation of TerminationCallback if service-discovery is active. + * Terminate all ongoing service discovery procedures. + * + * It result in an invocation of the service discovery termination handler + * registered with onServiceDiscoveryTermination(). */ - virtual void terminateServiceDiscovery(void) { - /* Requesting action from porters: override this API if this capability is supported. */ + virtual void terminateServiceDiscovery(void) + { + /* Requesting action from porters: override this API if this capability + is supported. */ } /** - * Initiate a GATT Client read procedure by attribute-handle. + * Initiate the read procedure of an attribute handle. * - * @param[in] connHandle - * Handle for the connection with the peer. - * @param[in] attributeHandle - * Handle of the attribute to read data from. - * @param[in] offset - * The offset from the start of the attribute value to be read. + * Once the attribute value has been read in its entirety the process issue + * an attribute read event and pass it to all events handlers registered by + * onDataRead. * - * @return - * BLE_ERROR_NONE if read procedure was successfully started. + * @param[in] connHandle Handle of the connection used to send the read + * request. + * @param[in] attributeHandle Handle of the attribute to read data from. + * @param[in] offset The offset from the start of the attribute value to be + * read. + * + * @return BLE_ERROR_NONE if read procedure was successfully started. + * + * @par Implementation notes: + * + * Reading the attribute value in its entirety may involve sending several + * GATT requests to the peer. The following algorithm may be used to + * implement the process: + * + * If the offset is equal to 0 then send a read request otherwise send a + * read blob request at the specified offset. + * + * While the attribute data in the response are MTU - 1 long: + * - Concat the response to the value containing the previous responses. + * - Increment the value of the offset by MTU - 1 . + * - send a read blob request with the updated offset. + * + * Finally concat the last response with the value containing all the + * previous responses and forward that value to the event handlers. */ - virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const { + virtual ble_error_t read( + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + uint16_t offset + ) const { /* Avoid compiler warnings about unused variables. */ (void)connHandle; (void)attributeHandle; (void)offset; - return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ + /* Requesting action from porters: override this API if this capability + is supported. */ + return BLE_ERROR_NOT_IMPLEMENTED; } /** - * Initiate a GATT Client write procedure. + * Initiate a write procedure on an attribute value. * - * @param[in] cmd - * Command can be either a write-request (which generates a - * matching response from the peripheral), or a write-command - * (which doesn't require the connected peer to respond). - * @param[in] connHandle - * Connection handle. - * @param[in] attributeHandle - * Handle for the target attribtue on the remote GATT server. - * @param[in] length - * Length of the new value. - * @param[in] value - * New value being written. + * If @p cmd is equal to GATT_OP_WRITE_REQ then the status of the operation + * is reported to the event handlers registered via onDataWritten(). * - * @return - * BLE_ERROR_NONE if write procedure was successfully started. + * @param[in] cmd Type of the write procedure used. If GATT_OP_WRITE_CMD + * is set then value length shall be not be greater than the size of the mtu + * of connHandle minus three. + * @param[in] connHandle Handle of the connection used to send the write + * request or command. + * @param[in] attributeHandle Handle of the attribute value to write. + * @param[in] length Number of bytes present in @p value. + * @param[in] value Data buffer to write to attributeHandle. + * + * @return BLE_ERROR_NONE if the write procedure was successfully started. + * + * @par Implementation notes: + * + * If the operation is a write command then an implementation shall use the + * GATT write without response procedure and an error shall be returned if + * the data buffer to write is larger than the size of the . + * + * If the operation is a write command and the size of the data buffer to + * write is less than than the size of the MTU - 3 then the ATT write request + * procedure shall be used and the response shall be reported to the handlers + * listening for write response. + * + * Otherwise the data buffer to write shall be divided in chunk with a + * maximum size of MTU - 5. Those chunks shall be sent sequentially to the + * peer in ATT prepare write requests. If an error response is received + * during the process, the procedure shall ends immediately, the prepared + * write discarded and an error shall be reported to the application handlers. + * Once all the chunks have been sent, the transaction shall be completed + * by sending an execute write request to the peer. The peer response shall + * be forwarded to the application handlers. */ - virtual ble_error_t write(GattClient::WriteOp_t cmd, - Gap::Handle_t connHandle, - GattAttribute::Handle_t attributeHandle, - size_t length, - const uint8_t *value) const { + virtual ble_error_t write( + GattClient::WriteOp_t cmd, + Gap::Handle_t connHandle, + GattAttribute::Handle_t attributeHandle, + size_t length, + const uint8_t *value + ) const { /* Avoid compiler warnings about unused variables. */ (void)cmd; (void)connHandle; @@ -297,217 +453,238 @@ public: (void)length; (void)value; - return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if this capability is supported. */ + /* Requesting action from porters: override this API if this capability + is supported. */ + return BLE_ERROR_NOT_IMPLEMENTED; } /* Event callback handlers. */ public: + /** - * Set up a callback for read response events. - * - * @param[in] callback - * Event handler being registered. - * - * @note It is possible to chain together multiple onDataRead callbacks - * (potentially from different modules of an application). + * Register an attribute read event handler. * * @note It is possible to unregister a callback using * onDataRead().detach(callbackToRemove). + * + * @param[in] callback Event handler being registered. */ - void onDataRead(ReadCallback_t callback) { + void onDataRead(ReadCallback_t callback) + { onDataReadCallbackChain.add(callback); } /** - * @brief Provide access to the callchain of read event callbacks. + * Get the callchain of attribute read event handlers. * * @return A reference to the read event callback chain. * - * @note It is possible to register callbacks using onDataRead().add(callback). + * @note It is possible to register new handlers using + * onDataRead().add(callback). * - * @note It is possible to unregister callbacks using onDataRead().detach(callback). + * @note It is possible to unregister an handler by using + * onDataRead().detach(callback). */ - ReadCallbackChain_t& onDataRead() { + ReadCallbackChain_t& onDataRead() + { return onDataReadCallbackChain; } /** - * Set up a callback for write response events. + * Register an attribute write event handler. * - * @param[in] callback - * Event handler being registered. + * @param[in] callback Event handler being registered. * - * @note It is possible to remove registered callbacks using + * @note It is possible to remove registered handlers using * onDataWritten().detach(callbackToRemove). * - * @note Write commands (issued using writeWoResponse) don't generate a response. + * @note Write commands (issued using writeWoResponse) don't generate a + * response. */ - void onDataWritten(WriteCallback_t callback) { + void onDataWritten(WriteCallback_t callback) + { onDataWriteCallbackChain.add(callback); } /** - * @brief Provide access to the callchain of data written callbacks. + * Get the callchain of attribute write event handlers. * * @return A reference to the data written callbacks chain. * - * @note It is possible to register callbacks using onDataWritten().add(callback). + * @note It is possible to register new handlers by using + * onDataWritten().add(callback). * - * @note It is possible to unregister callbacks using onDataWritten().detach(callback). + * @note It is possible to unregister an handler by using + * onDataWritten().detach(callback). */ - WriteCallbackChain_t& onDataWritten() { + WriteCallbackChain_t& onDataWritten() + { return onDataWriteCallbackChain; } /** - * Set up a callback for write response events. + * Register an attribute write event handler. * - * @param[in] callback - * Event handler being registered. + * @param[in] callback Event handler being registered. * - * @note Write commands (issued using writeWoResponse) don't generate a response. + * @note It is possible to remove registered handlers using + * onDataWritten().detach(callbackToRemove). * - * @deprecated Please use GattServer::onDataWritten() instead. + * @note Write commands (issued using writeWoResponse) don't generate a + * response. + * + * @deprecated Use GattServer::onDataWritten(). */ - void onDataWrite(WriteCallback_t callback) { + MBED_DEPRECATED("Use GattServer::onDataWritten()") + void onDataWrite(WriteCallback_t callback) + { onDataWritten(callback); } /** - * Set up a callback for when serviceDiscovery terminates. + * Register a service discovery termination event handler. * - * @param[in] callback - * Event handler being registered. + * @param[in] callback Event handler being registered. */ - virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + virtual void onServiceDiscoveryTermination( + ServiceDiscovery::TerminationCallback_t callback + ) { (void)callback; /* Avoid compiler warnings about ununsed variables. */ - /* Requesting action from porters: override this API if this capability is supported. */ + /* Requesting action from porters: override this API if this capability + is supported. */ } /** - * @brief Launch discovery of descriptors for a given characteristic. + * Initiate the descriptor discovery procedure for a given characteristic. * - * @details This function will discover all descriptors available for a - * specific characteristic. + * When a descriptor is discovered the discovered descriptor is forwarded + * to @p discoveryCallback. After the discovery of all the descriptor, the + * procedure ends and send a descriptor discovery termination event to @p + * termination callback. * - * @param[in] characteristic - * The characteristic targeted by this discovery procedure. - * @param[in] discoveryCallback - * User function called each time a descriptor is found during - * the procedure. - * @param[in] terminationCallback - * User provided function which will be called once the - * discovery procedure is terminating. This will get called - * when all the descriptors have been discovered or if an - * error occur during the discovery procedure. + * Application code may monitor the discovery process by querying its status + * with isCharacteristicDescriptorDiscoveryActive(). It can also ends the + * discovery process by calling terminateCharacteristicDescriptorDiscovery(). * - * @return - * BLE_ERROR_NONE if characteristic descriptor discovery is launched - * successfully; else an appropriate error. + * @param[in] characteristic The characteristic owning the descriptors to + * discover. + * @param[in] discoveryCallback Handle descriptor discovered events for the + * duration of the procedure. + * @param[in] terminationCallback Handle descriptor discovery termination + * event of the procedure. + * + * @return BLE_ERROR_NONE if the characteristic descriptor discovery + * procedureis has been launched successfully otherwise an appropriate error. */ virtual ble_error_t discoverCharacteristicDescriptors( const DiscoveredCharacteristic& characteristic, const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, - const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) { + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback + ) { (void) characteristic; (void) discoveryCallback; (void) terminationCallback; - /* Requesting action from porter(s): override this API if this capability is supported. */ + /* Requesting action from porter(s): override this API if this + capability is supported. */ return BLE_ERROR_NOT_IMPLEMENTED; } /** - * @brief Indicate if the discovery of characteristic descriptors is active - * for a given characteristic or not. + * Query status of the descriptor discovery procedure for a given + * characteristic. * - * @param[in] characteristic - * The characteristic concerned by the descriptors discovery. + * @param[in] characteristic The characteristic concerned by the descriptors + * discovery. * * @return true if a descriptors discovery is active for the characteristic - * in input; otherwise false. + * in input otherwise false. */ - virtual bool isCharacteristicDescriptorDiscoveryActive(const DiscoveredCharacteristic& characteristic) const - { + virtual bool isCharacteristicDescriptorDiscoveryActive( + const DiscoveredCharacteristic& characteristic + ) const { (void) characteristic; - return false; /* Requesting action from porter(s): override this API if this capability is supported. */ + /* Requesting action from porter(s): override this API if this + capability is supported. */ + return false; } /** - * @brief Terminate an ongoing characteristic descriptor discovery. + * @brief Terminate an ongoing characteristic descriptor discovery procedure. * - * @details This should result in an invocation of the TerminationCallback if - * the characteristic descriptor discovery is active. + * If the procedure is active then it shall end and the termination handler + * associated with the procedure shall be called. * - * @param[in] characteristic - * The characteristic on which the running descriptors - * discovery should be stopped. + * @param[in] characteristic The characteristic containing the descriptors + * being discovered. */ - virtual void terminateCharacteristicDescriptorDiscovery(const DiscoveredCharacteristic& characteristic) { - /* Requesting action from porter(s): override this API if this capability is supported. */ + virtual void terminateCharacteristicDescriptorDiscovery( + const DiscoveredCharacteristic& characteristic + ) { + /* Requesting action from porter(s): override this API if this + capability is supported. */ (void) characteristic; } /** - * Set up a callback for when the GATT Client receives an update event - * corresponding to a change in the value of a characteristic on the remote - * GATT Server. + * Register an handler for Handle Value Notification/Indication events. * - * @note It is possible to unregister callbacks using - * onHVX().detach(callbackToRemove). + * @param callback Event handler to register. + * + * @note It is possible to unregister a callback by using + * onHVX().detach(callbackToRemove). */ - void onHVX(HVXCallback_t callback) { + void onHVX(HVXCallback_t callback) + { onHVXCallbackChain.add(callback); } /** - * Setup a callback to be invoked to notify the user application that the - * GattClient instance is about to shutdown (possibly as a result of a call - * to BLE::shutdown()). + * Register a shutdown event handler. * - * @param[in] callback - * Event handler being registered. + * The registered handler will be invoked when the GattClient instance is + * about to be shutdown. * - * @note It is possible to chain together multiple onShutdown callbacks - * (potentially from different modules of an application) to be notified - * before the GattClient is shutdown. + * @param[in] callback Event handler to invoke when a shutdown event is + * available. * - * @note It is also possible to set up a callback into a member function of - * some object. + * @note onShutdown().detach(callback) may be used to unregister a given + * callback. * - * @note It is possible to unregister a callback using onShutdown().detach(callback). + * @see BLE::shutdown() */ - void onShutdown(const GattClientShutdownCallback_t& callback) { + void onShutdown(const GattClientShutdownCallback_t& callback) + { shutdownCallChain.add(callback); } /** - * Same as GattClient::onShutdown(), but allows the possibility to add an object - * reference and member function as handler for shutdown event - * callbacks. + * Register a shutdown event handler. * - * @param[in] objPtr - * Pointer to the object of a class defining the member callback - * function (@p memberPtr). - * @param[in] memberPtr - * The member callback (within the context of an object) to be - * invoked. + * The registered handler will be invoked when the GattClient instance is + * about to be shutdown. + * + * @param[in] objPtr Instance which will be used to invoke @p memberPtr. + * @param[in] memberPtr Event handler to invoke when a shutdown event is + * available. */ template - void onShutdown(T *objPtr, void (T::*memberPtr)(const GattClient *)) { + void onShutdown(T *objPtr, void (T::*memberPtr)(const GattClient *)) + { shutdownCallChain.add(objPtr, memberPtr); } /** - * @brief Provide access to the callchain of shutdown event callbacks. + * Get the callchain of shutdown event handlers. * * @return A reference to the shutdown event callbacks chain. * - * @note It is possible to register callbacks using onShutdown().add(callback). + * @note onShutdown().add(callback) may be used to register new handlers. * - * @note It is possible to unregister callbacks using onShutdown().detach(callback). + * @note onShutdown().detach(callback) may be used to unregister an handler. */ - GattClientShutdownCallbackChain_t& onShutdown() { + GattClientShutdownCallbackChain_t& onShutdown() + { return shutdownCallChain; } @@ -526,9 +703,14 @@ public: public: /** - * Notify all registered onShutdown callbacks that the GattClient is - * about to be shutdown and clear all GattClient state of the - * associated object. + * Reset the state of the GattClient instance. + * + * Prior to any state modification shutdown event handlers shall be notified + * that the GattClient instance is about to be shutdown. Then running + * procedures shall be ended. Finally the state of the instance shall be + * reset. + * + * @par implementation note * * This function is meant to be overridden in the platform-specific * sub-class. Nevertheless, the sub-class is only expected to reset its @@ -538,7 +720,8 @@ public: * * @return BLE_ERROR_NONE on success. */ - virtual ble_error_t reset(void) { + virtual ble_error_t reset(void) + { /* Notify that the instance is about to shutdown */ shutdownCallChain.call(this); shutdownCallChain.clear(); @@ -551,48 +734,52 @@ public: } protected: - GattClient() { + GattClient() + { /* Empty */ } /* Entry points for the underlying stack to report events back to the user. */ public: /** - * Helper function that notifies all registered handlers of an occurrence - * of a data read event. This function is meant to be called from the - * BLE stack specific implementation when a data read event occurs. + * Forward an attribute read event to all registered handlers. * - * @param[in] params - * The data read parameters passed to the registered - * handlers. + * @important This function is meant to be called from the vendor + * implementation when an attribute read event occurs. + * + * @param[in] params Attribute read event to pass to the registered handlers. */ - void processReadResponse(const GattReadCallbackParams *params) { + void processReadResponse(const GattReadCallbackParams *params) + { onDataReadCallbackChain(params); } /** - * Helper function that notifies all registered handlers of an occurrence - * of a data written event. This function is meant to be called from the - * BLE stack specific implementation when a data written event occurs. + * Forward an attribute written event to all registered handlers. * - * @param[in] params - * The data written parameters passed to the registered - * handlers. + * @important This function is meant to be called from the vendor + * implementation when an attribute written event occurs. + * + * @param[in] params Attribute written event to pass to the registered + * handlers. */ - void processWriteResponse(const GattWriteCallbackParams *params) { + void processWriteResponse(const GattWriteCallbackParams *params) + { onDataWriteCallbackChain(params); } /** - * Helper function that notifies all registered handlers of an occurrence - * of an update event. This function is meant to be called from the - * BLE stack specific implementation when an update event occurs. + * Forward an Handle Value Notification or Indication event to all registered + * handlers. * - * @param[in] params - * The update event parameters passed to the registered - * handlers. + * @important This function is meant to be called from the vendor + * implementation when a notification or indication event is available. + * + * @param[in] params Notification or Indication event to pass to the + * registered handlers. */ - void processHVXEvent(const GattHVXCallbackParams *params) { + void processHVXEvent(const GattHVXCallbackParams *params) + { if (onHVXCallbackChain) { onHVXCallbackChain(params); } @@ -600,22 +787,25 @@ public: protected: /** - * Callchain containing all registered callback handlers for data read + * Callchain containing all registered event handlers for data read * events. */ - ReadCallbackChain_t onDataReadCallbackChain; + ReadCallbackChain_t onDataReadCallbackChain; + /** - * Callchain containing all registered callback handlers for data write + * Callchain containing all registered event handlers for data write * events. */ - WriteCallbackChain_t onDataWriteCallbackChain; + WriteCallbackChain_t onDataWriteCallbackChain; + /** - * Callchain containing all registered callback handlers for update + * Callchain containing all registered event handlers for update * events. */ - HVXCallbackChain_t onHVXCallbackChain; + HVXCallbackChain_t onHVXCallbackChain; + /** - * Callchain containing all registered callback handlers for shutdown + * Callchain containing all registered event handlers for shutdown * events. */ GattClientShutdownCallbackChain_t shutdownCallChain; @@ -626,4 +816,10 @@ private: GattClient& operator=(const GattClient &); }; -#endif /* ifndef __GATT_CLIENT_H__ */ +/** + * @} + * @} + * @} + */ + +#endif /* ifndef MBED_GATT_CLIENT_H__ */