Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GattClient.h Source File

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 MBED_GATT_CLIENT_H__
00018 #define MBED_GATT_CLIENT_H__
00019 
00020 #include "ble/common/StaticInterface.h"
00021 #include "ble/GattAttribute.h"
00022 #include "ble/ServiceDiscovery.h"
00023 #include "ble/CharacteristicDescriptorDiscovery.h"
00024 #include "ble/GattCallbackParamTypes.h"
00025 #include "ble/CallChainOfFunctionPointersWithContext.h"
00026 #include "BleImplementationForward.h"
00027 
00028 #if !defined(DOXYGEN_ONLY)
00029 namespace ble {
00030 namespace interface {
00031 #endif
00032 
00033 /**
00034  * @addtogroup ble
00035  * @{
00036  * @addtogroup gatt
00037  * @{
00038  * @addtogroup client
00039  * @{
00040  */
00041 
00042 /**
00043  * Define procedures required for interacting with a distant GATT server.
00044  *
00045  * @par Discovery procedures
00046  *
00047  * A GATT server hosts a fixed set of services. These services are a logical
00048  * composition of characteristics that may be discovered, read, written or also
00049  * broadcast their state to a connected client. These characteristics may also
00050  * contain metainformation named characteristic descriptors. A characteristic
00051  * descriptor may be used to indicate the unit used for a characteristic value,
00052  * describe in a textual form the characterisic purpose or allow a client to
00053  * register for notification of updates of the characteristic value.
00054  *
00055  * Prior to any interaction with server characteristic, a GATT client
00056  * discovers the layout of the services and characteristics present on the
00057  * server.
00058  *
00059  * The layout of the descriptors of a characteristic may also be issued to
00060  * as an extra discovery step.
00061  *
00062  * @par Attribute manipulation
00063  *
00064  * As a result of the discovery process, the client can start interacting with
00065  * the characteristic discovered. Depending on the characteristic properties
00066  * (acquired during discovery), a client can read or write the value of a given
00067  * characteristic.
00068  *
00069  * Mbed BLE abstracts most read and write operations to offer a single API that
00070  * can be used to read or write characteristics values. Application code does not
00071  * have to handle the fragmentation/reassembly process necessary if the attribute
00072  * value to transported cannot fit in a single data packet.
00073  *
00074  * @par Server Initiated events
00075  *
00076  * If a characteristic has to notify or indicate a property set; then, a client may
00077  * register to a notification or indication from the characteristic. When the
00078  * server updates the characteristic value, the server can forward the
00079  * new value to the registered clients. The notification/indication mechanism
00080  * prevents polling from the client and therefore minimize the transactions
00081  * involved between a client and a server.
00082  *
00083  * Registration is made by writing the Client Characteristic Configuration
00084  * Descriptor, which is present in the characteristic if the notify or
00085  * indicate properties are set. The client discovers that descriptor
00086  * if it intends to register to server initiated events.
00087  */
00088 #if defined(DOXYGEN_ONLY)
00089 class GattClient {
00090 #else
00091 template <class Impl>
00092 class GattClient : public StaticInterface<Impl, GattClient> {
00093 #endif
00094 
00095     using StaticInterface<Impl, ::ble::interface::GattClient>::impl;
00096 
00097 public:
00098 
00099     /**
00100      * Definition of the general handler of GattClient related events.
00101      */
00102     struct EventHandler {
00103         /**
00104          * Function invoked when the connections changes the ATT_MTU which controls
00105          * the maximum size of an attribute that can be read in a single L2CAP packet
00106          * which might be fragmented across multiple packets.
00107          *
00108          * @param connectionHandle The handle of the connection that changed the size.
00109          * @param attMtuSize
00110          */
00111         virtual void onAttMtuChange(
00112             ble::connection_handle_t connectionHandle,
00113             uint16_t attMtuSize
00114         )
00115         {
00116         }
00117     };
00118 
00119     /**
00120      * Assign the event handler implementation that will be used by the
00121      * module to signal events back to the application.
00122      *
00123      * @param handler Application implementation of an EventHandler.
00124      */
00125     void setEventHandler(EventHandler *handler)
00126     {
00127         eventHandler = handler;
00128     }
00129 
00130     /**
00131      * Attribute read event handler.
00132      *
00133      * @see GattClient::onDataRead().
00134      */
00135     typedef FunctionPointerWithContext<const GattReadCallbackParams*>
00136         ReadCallback_t;
00137 
00138     /**
00139      * Callchain of attribute read event handlers.
00140      */
00141     typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams*>
00142         ReadCallbackChain_t;
00143 
00144     /**
00145      * GATT write operations.
00146      */
00147     enum WriteOp_t {
00148         /**
00149          * Write request.
00150          *
00151          * It is used to request the server to write the value of an attribute
00152          * and acknowledge that this has been achieved in a Write Response.
00153          */
00154         GATT_OP_WRITE_REQ = 0x01,
00155 
00156         /**
00157          * Write command.
00158          *
00159          * It is used to request the server to write the value of an attribute.
00160          * The server does not acknowledge the status of the operation.
00161          */
00162         GATT_OP_WRITE_CMD = 0x02,
00163 
00164         /**
00165          * Signed Write command.
00166          *
00167          * It is used to request the server to write the value of an attribute
00168          * using a signed packet. The server does not acknowledge the status
00169          * of the operation.
00170          */
00171         GATT_OP_SIGNED_WRITE_CMD = 0x03
00172     };
00173 
00174     /**
00175      * Attribute write event handler.
00176      *
00177      * @see GattClient::onDataWrite().
00178      */
00179     typedef FunctionPointerWithContext<const GattWriteCallbackParams*>
00180         WriteCallback_t;
00181 
00182     /**
00183      * Callchain of attribute write event handlers.
00184      *
00185      * @see GattClient::onDataWrite().
00186      */
00187     typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*>
00188         WriteCallbackChain_t;
00189 
00190     /**
00191      * Handle value notification/indication event handler.
00192      *
00193      * @see to GattClient::onHVX().
00194      */
00195     typedef FunctionPointerWithContext<const GattHVXCallbackParams*>
00196         HVXCallback_t;
00197 
00198     /**
00199      * Callchain of handle value notification/indication event handlers.
00200      *
00201      * @see GattClient::onHVX().
00202      */
00203     typedef CallChainOfFunctionPointersWithContext<const GattHVXCallbackParams*>
00204         HVXCallbackChain_t;
00205 
00206     /**
00207      * Shutdown event handler.
00208      *
00209      * @see GattClient::onShutdown().
00210      */
00211     typedef FunctionPointerWithContext<const GattClient *>
00212         GattClientShutdownCallback_t;
00213 
00214 
00215     /**
00216      * Callchain of shutdown event handlers.
00217      *
00218      * @see to GattClient::onShutown().
00219      */
00220     typedef CallChainOfFunctionPointersWithContext<const GattClient *>
00221         GattClientShutdownCallbackChain_t;
00222 
00223     /*
00224      * The following functions are meant to be overridden in the platform
00225      * specific subclass.
00226      */
00227 public:
00228 
00229     ~GattClient() { }
00230 
00231     /**
00232      * Launch the service and characteristic discovery procedure of a GATT server
00233      * peer.
00234      *
00235      * The procedure invokes application callbacks for matching services or
00236      * characteristics. The process ends after all the services and
00237      * characteristics present on the distant GATT server have been discovered.
00238      * Termination callbacks registered with onServiceDiscoveryTermination() are
00239      * invoked to notify the application of the termination of the procedure.
00240      *
00241      * Application code can track the status of the procedure by invoking the
00242      * function isServiceDiscoveryActive(), which returns true if the
00243      * procedure is ongoing.
00244      *
00245      * At any point, application code can prematurely terminate the discovery
00246      * procedure by calling terminateServiceDiscovery().
00247      *
00248      * @param[in] connectionHandle Handle of the connection with the peer GATT
00249      * server.
00250      * @param[in] sc Service discovered event handler invoked when a matching
00251      * service has been discovered. This parameter may be NULL.
00252      * @param[in] cc Characteristic discovered event handler invoked when a
00253      * matching characteristic has been found. This parameter may be NULL.
00254      * @param[in] matchingServiceUUID UUID of the service the caller is
00255      * interested in. If a service discovered matches this filter, then @p sc is
00256      * invoked with it. The special value BLE_UUID_UNKNOWN acts as a wildcard,
00257      * which can be used to discover all services present on the peer GATT
00258      * server.
00259      * @param[in] matchingCharacteristicUUIDIn UUID of the characteristic the
00260      * caller is interested in. If a characteristic discovered matches this
00261      * filter, then @p cc is  invoked with it. The special value BLE_UUID_UNKNOWN
00262      * acts as a wildcard, which can be used to discover all services present on
00263      * the peer GATT server.
00264      *
00265      * @par Discovery procedure implementation detail
00266      *
00267      * It is recommended to implement several strategies based on the
00268      * combination of callbacks and filters passed in input to efficiently
00269      * realize the discovery procedure:
00270      * - If @p sc and @p cc are NULL, then it is not necessay to initiate any
00271      * discovery, and the termination handlers can be invoked immediately.
00272      * - If @p matchingServiceUUID is set, then the GATT discover services by
00273      * service UUID procedure should be used; otherwise, the GATT discover primary
00274      * services procedure should be used.
00275      * - If @p cc is NULL, then the discovery process should end after the discovery
00276      * of the services.
00277      *
00278      * @return BLE_ERROR_NONE if the discovery procedure has been successfully
00279      * started and an appropriate error otherwise.
00280      */
00281     ble_error_t launchServiceDiscovery(
00282         ble::connection_handle_t connectionHandle,
00283         ServiceDiscovery::ServiceCallback_t  sc = NULL,
00284         ServiceDiscovery::CharacteristicCallback_t   cc = NULL,
00285         const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
00286         const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)
00287     );
00288 
00289     /**
00290      * Launch the service discovery procedure of a GATT server peer.
00291      *
00292      * The procedure invokes the application callback for matching services.
00293      * The process ends after all the services present on the distant GATT
00294      * server have been discovered.
00295      * Termination callbacks registered with onServiceDiscoveryTermination() are
00296      * invoked to notify the application of the termination of the procedure.
00297      *
00298      * Application code can track the status of the procedure by invoking the
00299      * function isServiceDiscoveryActive(), which returns true if the
00300      * procedure is ongoing.
00301      *
00302      * At any point, application code can prematurely terminate the discovery
00303      * procedure by calling terminateServiceDiscovery().
00304      *
00305      * @param[in] connectionHandle Handle of the connection with the peer GATT
00306      * server.
00307      * @param[in] callback Service discovered event handler invoked when a
00308      * matching service has been discovered. This parameter may be NULL.
00309      * @param[in] matchingServiceUUID UUID of the service the caller is
00310      * interested in. If a service discovered matches this filter, then @p sc is
00311      * invoked with it. The special value BLE_UUID_UNKNOWN act is a wildcard,
00312      * which can be used to discover all services present on the peer GATT
00313      * server.
00314      *
00315      * @return BLE_ERROR_NONE if the discovery procedure has been successfully
00316      * started and an appropriate error otherwise.
00317      */
00318     ble_error_t discoverServices(
00319         ble::connection_handle_t connectionHandle,
00320         ServiceDiscovery::ServiceCallback_t  callback,
00321         const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)
00322     ) {
00323         /* We take advantage of the property
00324          * that providing NULL for the characteristic callback results in
00325          * characteristic discovery being skipped for each matching
00326          * service. This allows for an inexpensive method to discover only
00327          * services. Porters are free to override this. */
00328         return launchServiceDiscovery(
00329             connectionHandle, callback, NULL, matchingServiceUUID
00330         );
00331     }
00332 
00333     /**
00334      * Launch the service discovery procedure of a GATT server peer.
00335      *
00336      * The process ends after all the services present in the attribute range @p
00337      * startHandle to @p endHandle have been discovered.
00338      *
00339      * Termination callbacks registered with onServiceDiscoveryTermination() are
00340      * invoked to notify the application of the termination of the procedure.
00341      *
00342      * Application code can track the status of the procedure by invoking the
00343      * function isServiceDiscoveryActive(), which returns true if the
00344      * procedure is ongoing.
00345      *
00346      * At any point, application code can prematurely terminate the discovery
00347      * procedure by calling terminateServiceDiscovery().
00348      *
00349      * @param[in] connectionHandle Handle of the connection with the peer GATT
00350      * server.
00351      * @param[in] callback Service discovered event handler invoked when a
00352      * matching service has been discovered. This parameter may be NULL.
00353      * @param[in] startHandle First attribute handle of the discovery range.
00354      * @param[in] endHandle end Lasr attribute handle of the discovery range.
00355      *
00356      * @return BLE_ERROR_NONE if the discovery procedure has been successfully
00357      * started and an appropriate error otherwise.
00358      */
00359     ble_error_t discoverServices(
00360         ble::connection_handle_t connectionHandle,
00361         ServiceDiscovery::ServiceCallback_t  callback,
00362         GattAttribute::Handle_t startHandle,
00363         GattAttribute::Handle_t endHandle
00364     );
00365 
00366     /**
00367      * Check if the service discovery procedure is currently active.
00368      *
00369      * @return true if service discovery procedure is active and false otherwise.
00370      */
00371     bool isServiceDiscoveryActive(void) const;
00372 
00373     /**
00374      * Terminate all ongoing service discovery procedures.
00375      *
00376      * It results in an invocation of the service discovery termination handler
00377      * registered with onServiceDiscoveryTermination().
00378      */
00379     void terminateServiceDiscovery(void);
00380 
00381     /**
00382      * Initiate the read procedure of an attribute handle.
00383      *
00384      * Once the attribute value has been read in its entirety, the process issues
00385      * an attribute read event and passes it to all events handlers registered
00386      * by onDataRead.
00387      *
00388      * @param[in] connHandle Handle of the connection used to send the read
00389      * request.
00390      * @param[in] attributeHandle Handle of the attribute to read data from.
00391      * @param[in] offset The offset from the start of the attribute value to be
00392      * read.
00393      *
00394      * @return BLE_ERROR_NONE if read procedure successfully started.
00395      *
00396      * @par Implementation notes:
00397      *
00398      * Reading the attribute value in its entirety may involve sending several
00399      * GATT requests to the peer. The following algorithm may be used to
00400      * implement the process:
00401      *
00402      * If the offset is equal to 0, then send a read request; otherwise, send a
00403      * read blob request at the specified offset.
00404      *
00405      * While the attribute data in the response are MTU - 1 long:
00406      *   - Concat the response to the value containing the previous responses.
00407      *   - Increment the value of the offset by MTU - 1.
00408      *   - Send a read blob request with the updated offset.
00409      *
00410      * Finally, concat the last response with the value containing all the
00411      * previous responses and forward that value to the event handlers.
00412      */
00413     ble_error_t read(
00414         ble::connection_handle_t connHandle,
00415         GattAttribute::Handle_t attributeHandle,
00416         uint16_t offset
00417     ) const;
00418 
00419     /**
00420      * Initiate a write procedure on an attribute value.
00421      *
00422      * If @p cmd is equal to GATT_OP_WRITE_REQ, then the status of the operation
00423      * is reported to the event handlers registered through onDataWritten().
00424      *
00425      * @param[in] cmd Type of the write procedure used. If GATT_OP_WRITE_CMD
00426      * is set, then value length is not greater than the size of the mtu
00427      * of connHandle minus three.
00428      * @param[in] connHandle Handle of the connection used to send the write
00429      * request or command.
00430      * @param[in] attributeHandle Handle of the attribute value to write.
00431      * @param[in] length Number of bytes present in @p value.
00432      * @param[in] value Data buffer to write to attributeHandle.
00433      *
00434      * @return BLE_ERROR_NONE if the write procedure successfully started.
00435      *
00436      * @par Implementation notes:
00437      *
00438      * If the operation is a write command, then an implementation uses the
00439      * GATT write without response procedure and an error is returned if
00440      * the data buffer to write is larger than the size of the MTU - 3.
00441      *
00442      * If the operation is a write command and the size of the data buffer to
00443      * write is less than than the size of the MTU - 3, then the ATT write request
00444      * procedure is used, and the response is reported to the handlers
00445      * listening for write response.
00446      *
00447      * Otherwise, the data buffer to write is divided in chunks with a
00448      * maximum size of MTU - 5. Those chunks are sent sequentially to the
00449      * peer in ATT prepare write requests. If an error response is received
00450      * during the process, the procedure ends immediately, the prepared
00451      * write is discarded and an error is reported to the application handlers.
00452      * Once all the chunks have been sent, the transaction is completed
00453      * by sending an execute write request to the peer. The peer response is
00454      * forwarded to the application handlers.
00455      */
00456     ble_error_t write(
00457         GattClient::WriteOp_t cmd,
00458         ble::connection_handle_t connHandle,
00459         GattAttribute::Handle_t attributeHandle,
00460         size_t length,
00461         const uint8_t *value
00462     ) const;
00463 
00464     /* Event callback handlers. */
00465 public:
00466 
00467     /**
00468      * Register an attribute read event handler.
00469      *
00470      * @note It is possible to unregister a callback using
00471      * onDataRead().detach(callbackToRemove).
00472      *
00473      * @param[in] callback Event handler being registered.
00474      */
00475     void onDataRead(ReadCallback_t callback)
00476     {
00477         onDataReadCallbackChain.add(callback);
00478     }
00479 
00480     /**
00481      * Get the callchain of attribute read event handlers.
00482      *
00483      * @return A reference to the read event callback chain.
00484      *
00485      * @note It is possible to register new handlers using
00486      * onDataRead().add(callback).
00487      *
00488      * @note It is possible to unregister an handler by using
00489      * onDataRead().detach(callback).
00490      */
00491     ReadCallbackChain_t& onDataRead()
00492     {
00493         return onDataReadCallbackChain;
00494     }
00495 
00496     /**
00497      * Register an attribute write event handler.
00498      *
00499      * @param[in] callback Event handler being registered.
00500      *
00501      * @note It is possible to remove registered handlers using
00502      * onDataWritten().detach(callbackToRemove).
00503      *
00504      * @note Write commands (issued using writeWoResponse) don't generate a
00505      * response.
00506      */
00507     void onDataWritten(WriteCallback_t callback)
00508     {
00509         onDataWriteCallbackChain.add(callback);
00510     }
00511 
00512     /**
00513      * Get the callchain of attribute write event handlers.
00514      *
00515      * @return A reference to the data written callbacks chain.
00516      *
00517      * @note It is possible to register new handlers by using
00518      * onDataWritten().add(callback).
00519      *
00520      * @note It is possible to unregister an handler by using
00521      * onDataWritten().detach(callback).
00522      */
00523     WriteCallbackChain_t& onDataWritten()
00524     {
00525         return onDataWriteCallbackChain;
00526     }
00527 
00528     /**
00529      * Register an attribute write event handler.
00530      *
00531      * @param[in] callback Event handler being registered.
00532      *
00533      * @note It is possible to remove registered handlers using
00534      * onDataWritten().detach(callbackToRemove).
00535      *
00536      * @note Write commands (issued using writeWoResponse) don't generate a
00537      * response.
00538      *
00539      * @deprecated Use GattServer::onDataWritten().
00540      */
00541     MBED_DEPRECATED("Use GattServer::onDataWritten()")
00542     void onDataWrite(WriteCallback_t callback)
00543     {
00544         onDataWritten(callback);
00545     }
00546 
00547     /**
00548      * Register a service discovery termination event handler.
00549      *
00550      * @param[in] callback Event handler being registered.
00551      */
00552     void onServiceDiscoveryTermination(
00553         ServiceDiscovery::TerminationCallback_t  callback
00554     );
00555 
00556     /**
00557      * Initiate the descriptor discovery procedure for a given characteristic.
00558      *
00559      * When a descriptor is discovered the discovered descriptor is forwarded
00560      * to @p discoveryCallback. After the discovery of all the descriptors, the
00561      * procedure ends and send a descriptor discovery termination event to @p
00562      * termination callback.
00563      *
00564      * Application code may monitor the discovery process by querying its status
00565      * with isCharacteristicDescriptorDiscoveryActive(). It can also end the
00566      * discovery process by calling terminateCharacteristicDescriptorDiscovery().
00567      *
00568      * @param[in] characteristic The characteristic owning the descriptors to
00569      * discover.
00570      * @param[in] discoveryCallback Handle descriptor discovered events for the
00571      * duration of the procedure.
00572      * @param[in] terminationCallback Handle descriptor discovery termination
00573      * event of the procedure.
00574      *
00575      * @return BLE_ERROR_NONE if the characteristic descriptor discovery
00576      * procedure has been launched successfully otherwise an appropriate error.
00577      */
00578     ble_error_t discoverCharacteristicDescriptors(
00579         const DiscoveredCharacteristic& characteristic,
00580         const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
00581         const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback
00582     );
00583 
00584     /**
00585      * Query status of the descriptor discovery procedure for a given
00586      * characteristic.
00587      *
00588      * @param[in] characteristic The characteristic concerned by the descriptors
00589      * discovery.
00590      *
00591      * @return true if a descriptors discovery is active for the characteristic
00592      * in input otherwise false.
00593      */
00594     bool isCharacteristicDescriptorDiscoveryActive(
00595         const DiscoveredCharacteristic& characteristic
00596     ) const;
00597 
00598     /**
00599      * @brief Terminate an ongoing characteristic descriptor discovery procedure.
00600      *
00601      * If the procedure is active, then it ends, and the termination handler
00602      * associated with the procedure is called.
00603      *
00604      * @param[in] characteristic The characteristic containing the descriptors
00605      * being discovered.
00606      */
00607     void terminateCharacteristicDescriptorDiscovery(
00608         const DiscoveredCharacteristic& characteristic
00609     );
00610 
00611     /**
00612      * Trigger MTU negotiation. This might result in a Gap event onAttMtuChange
00613      * being called if MTU changes.
00614      *
00615      * @note This does not guarantee a change in MTU size. If size remains
00616      * unchanged no event will be generated.
00617      *
00618      * @param connection Connection on which the MTU is to be negotiated.
00619      *
00620      * @return BLE_ERROR_NONE if the procedure has been launched successfully
00621      * otherwise an appropriate error.
00622      */
00623     ble_error_t negotiateAttMtu(ble::connection_handle_t connection);
00624 
00625     /**
00626      * Register an handler for Handle Value Notification/Indication events.
00627      *
00628      * @param callback Event handler to register.
00629      *
00630      * @note It is possible to unregister a callback by using
00631      * onHVX().detach(callbackToRemove).
00632      */
00633     void onHVX(HVXCallback_t callback)
00634     {
00635         onHVXCallbackChain.add(callback);
00636     }
00637 
00638     /**
00639      * Register a shutdown event handler.
00640      *
00641      * The registered handler is invoked when the GattClient instance is
00642      * about to be shut down.
00643      *
00644      * @param[in] callback Event handler to invoke when a shutdown event is
00645      * available.
00646      *
00647      * @note onShutdown().detach(callback) may be used to unregister a given
00648      * callback.
00649      *
00650      * @see BLE::shutdown()
00651      */
00652     void onShutdown(const GattClientShutdownCallback_t& callback)
00653     {
00654         shutdownCallChain.add(callback);
00655     }
00656 
00657     /**
00658      * Register a shutdown event handler.
00659      *
00660      * The registered handler is invoked when the GattClient instance is
00661      * about to be shut down.
00662      *
00663      * @param[in] objPtr Instance that will be used to invoke @p memberPtr.
00664      * @param[in] memberPtr Event handler to invoke when a shutdown event is
00665      * available.
00666      */
00667     template <typename T>
00668     void onShutdown(T *objPtr, void (T::*memberPtr)(const GattClient *))
00669     {
00670         shutdownCallChain.add(objPtr, memberPtr);
00671     }
00672 
00673     /**
00674      * Get the callchain of shutdown event handlers.
00675      *
00676      * @return A reference to the shutdown event callbacks chain.
00677      *
00678      * @note onShutdown().add(callback) may be used to register new handlers.
00679      *
00680      * @note onShutdown().detach(callback) may be used to unregister an handler.
00681      */
00682     GattClientShutdownCallbackChain_t& onShutdown()
00683     {
00684         return shutdownCallChain;
00685     }
00686 
00687     /**
00688      * @brief provide access to the callchain of HVX callbacks.
00689      *
00690      * @return A reference to the HVX callbacks chain.
00691      *
00692      * @note It is possible to register callbacks using onHVX().add(callback).
00693      *
00694      * @note It is possible to unregister callbacks using onHVX().detach(callback).
00695      */
00696     HVXCallbackChain_t& onHVX() {
00697         return onHVXCallbackChain;
00698     }
00699 
00700 public:
00701     /**
00702      * Reset the state of the GattClient instance.
00703      *
00704      * Prior to any state modification, shutdown event handlers are notified
00705      * that the GattClient instance is about to be shut down. Then, running
00706      * procedures end. Finally, the state of the instance is reset.
00707      *
00708      * @par implementation note
00709      *
00710      * This function is meant to be overridden in the platform-specific
00711      * subclass. Nevertheless, the subclass only resets its
00712      * state and not the data held in GattClient members. This is achieved
00713      * by a call to GattClient::reset() from the subclass' reset()
00714      * implementation.
00715      *
00716      * @return BLE_ERROR_NONE on success.
00717      */
00718     ble_error_t reset(void);
00719 
00720 protected:
00721 
00722     /* --- Abstract calls to override --- */
00723 
00724     /* Derived implementation must call the base class implementation */
00725     ble_error_t reset_(void);
00726 
00727     ble_error_t discoverServices_(
00728         ble::connection_handle_t connectionHandle,
00729         ServiceDiscovery::ServiceCallback_t  callback,
00730         GattAttribute::Handle_t startHandle,
00731         GattAttribute::Handle_t endHandle
00732     );
00733 
00734     ble_error_t launchServiceDiscovery_(
00735         ble::connection_handle_t connectionHandle,
00736         ServiceDiscovery::ServiceCallback_t  sc,
00737         ServiceDiscovery::CharacteristicCallback_t  cc,
00738         const UUID &matchingServiceUUID,
00739         const UUID &matchingCharacteristicUUIDIn
00740     );
00741 
00742     bool isServiceDiscoveryActive_(void) const;
00743 
00744     void terminateServiceDiscovery_(void);
00745 
00746     ble_error_t negotiateAttMtu_(ble::connection_handle_t connection);
00747 
00748     ble_error_t read_(
00749         ble::connection_handle_t connHandle,
00750         GattAttribute::Handle_t attributeHandle,
00751         uint16_t offset
00752     ) const;
00753 
00754     ble_error_t write_(
00755         GattClient::WriteOp_t cmd,
00756         ble::connection_handle_t connHandle,
00757         GattAttribute::Handle_t attributeHandle,
00758         size_t length,
00759         const uint8_t *value
00760     ) const;
00761 
00762     void onServiceDiscoveryTermination_(
00763         ServiceDiscovery::TerminationCallback_t  callback
00764     );
00765 
00766     ble_error_t discoverCharacteristicDescriptors_(
00767         const DiscoveredCharacteristic& characteristic,
00768         const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
00769         const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback
00770     );
00771 
00772     bool isCharacteristicDescriptorDiscoveryActive_(
00773         const DiscoveredCharacteristic& characteristic
00774     ) const;
00775 
00776     void terminateCharacteristicDescriptorDiscovery_(
00777         const DiscoveredCharacteristic& characteristic
00778     );
00779 
00780 protected:
00781     GattClient() : eventHandler(NULL)
00782     {
00783         /* Empty */
00784     }
00785 
00786     /* Entry points for the underlying stack to report events back to the user. */
00787 public:
00788     /**
00789      * Forward an attribute read event to all registered handlers.
00790      *
00791      * @attention This function is meant to be called from the vendor
00792      * implementation when an attribute read event occurs.
00793      *
00794      * @param[in] params Attribute read event to pass to the registered handlers.
00795      */
00796     void processReadResponse(const GattReadCallbackParams *params)
00797     {
00798         onDataReadCallbackChain(params);
00799     }
00800 
00801     /**
00802      * Forward an attribute written event to all registered handlers.
00803      *
00804      * @attention This function is meant to be called from the vendor
00805      * implementation when an attribute written event occurs.
00806      *
00807      * @param[in] params Attribute written event to pass to the registered
00808      * handlers.
00809      */
00810     void processWriteResponse(const GattWriteCallbackParams *params)
00811     {
00812         onDataWriteCallbackChain(params);
00813     }
00814 
00815     /**
00816      * Forward a handle value notification or indication event to all registered
00817      * handlers.
00818      *
00819      * @attention This function is meant to be called from the vendor
00820      * implementation when a notification or indication event is available.
00821      *
00822      * @param[in] params Notification or Indication event to pass to the
00823      * registered handlers.
00824      */
00825     void processHVXEvent(const GattHVXCallbackParams *params)
00826     {
00827         if (onHVXCallbackChain) {
00828             onHVXCallbackChain(params);
00829         }
00830     }
00831 
00832 protected:
00833     /**
00834      * Event handler provided by the application.
00835      */
00836     EventHandler *eventHandler;
00837 
00838     /**
00839      * Callchain containing all registered event handlers for data read
00840      * events.
00841      */
00842     ReadCallbackChain_t onDataReadCallbackChain;
00843 
00844     /**
00845      * Callchain containing all registered event handlers for data write
00846      * events.
00847      */
00848     WriteCallbackChain_t onDataWriteCallbackChain;
00849 
00850     /**
00851      * Callchain containing all registered event handlers for update
00852      * events.
00853      */
00854     HVXCallbackChain_t onHVXCallbackChain;
00855 
00856     /**
00857      * Callchain containing all registered event handlers for shutdown
00858      * events.
00859      */
00860     GattClientShutdownCallbackChain_t shutdownCallChain;
00861 
00862 private:
00863     /* Disallow copy and assignment. */
00864     GattClient(const GattClient &);
00865     GattClient& operator=(const GattClient &);
00866 };
00867 
00868 /**
00869  * @}
00870  * @}
00871  * @}
00872  */
00873 
00874 #if !defined(DOXYGEN_ONLY)
00875 } // namespace interface
00876 } // namespace ble
00877 
00878 using ble::impl::GattClient;
00879 #endif
00880 
00881 #endif /* ifndef MBED_GATT_CLIENT_H__ */