takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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