-
Notifications
You must be signed in to change notification settings - Fork 3k
/
GattClient.h
881 lines (806 loc) · 30.3 KB
/
GattClient.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_GATT_CLIENT_H__
#define MBED_GATT_CLIENT_H__
#include "ble/common/StaticInterface.h"
#include "ble/GattAttribute.h"
#include "ble/ServiceDiscovery.h"
#include "ble/CharacteristicDescriptorDiscovery.h"
#include "ble/GattCallbackParamTypes.h"
#include "ble/CallChainOfFunctionPointersWithContext.h"
#include "BleImplementationForward.h"
#if !defined(DOXYGEN_ONLY)
namespace ble {
namespace interface {
#endif
/**
* @addtogroup ble
* @{
* @addtogroup gatt
* @{
* @addtogroup client
* @{
*/
/**
* Define procedures required for interacting with a distant GATT server.
*
* @par Discovery procedures
*
* A GATT server hosts a fixed set of services. These services are a logical
* composition of characteristics that may be discovered, read, written or also
* broadcast their state to a connected client. These characteristics may also
* contain metainformation named characteristic descriptors. 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
* discovers 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 interacting 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 abstracts most read and write operations to offer a single API that
* can be used to read or write characteristics values. Application code does 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 to notify or indicate a property set; then, a client may
* register to a notification or indication from the characteristic. When the
* server updates the characteristic value, the server can forward the
* new value to the registered clients. The notification/indication mechanism
* prevents polling from the client and therefore minimize the transactions
* involved between a client and a server.
*
* Registration is made by writing the Client Characteristic Configuration
* Descriptor, which is present in the characteristic if the notify or
* indicate properties are set. The client discovers that descriptor
* if it intends to register to server initiated events.
*/
#if defined(DOXYGEN_ONLY)
class GattClient {
#else
template <class Impl>
class GattClient : public StaticInterface<Impl, GattClient> {
#endif
using StaticInterface<Impl, ::ble::interface::GattClient>::impl;
public:
/**
* Definition of the general handler of GattClient related events.
*/
struct EventHandler {
/**
* Function invoked when the connections changes the ATT_MTU which controls
* the maximum size of an attribute that can be read in a single L2CAP packet
* which might be fragmented across multiple packets.
*
* @param connectionHandle The handle of the connection that changed the size.
* @param attMtuSize
*/
virtual void onAttMtuChange(
ble::connection_handle_t connectionHandle,
uint16_t attMtuSize
)
{
}
};
/**
* Assign the event handler implementation that will be used by the
* module to signal events back to the application.
*
* @param handler Application implementation of an EventHandler.
*/
void setEventHandler(EventHandler *handler)
{
eventHandler = handler;
}
/**
* Attribute read event handler.
*
* @see GattClient::onDataRead().
*/
typedef FunctionPointerWithContext<const GattReadCallbackParams*>
ReadCallback_t;
/**
* Callchain of attribute read event handlers.
*/
typedef CallChainOfFunctionPointersWithContext<const GattReadCallbackParams*>
ReadCallbackChain_t;
/**
* GATT write operations.
*/
enum WriteOp_t {
/**
* 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 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,
/**
* Signed Write command.
*
* It is used to request the server to write the value of an attribute
* using a signed packet. The server does not acknowledge the status
* of the operation.
*/
GATT_OP_SIGNED_WRITE_CMD = 0x03
};
/**
* Attribute write event handler.
*
* @see GattClient::onDataWrite().
*/
typedef FunctionPointerWithContext<const GattWriteCallbackParams*>
WriteCallback_t;
/**
* Callchain of attribute write event handlers.
*
* @see GattClient::onDataWrite().
*/
typedef CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams*>
WriteCallbackChain_t;
/**
* Handle value notification/indication event handler.
*
* @see to GattClient::onHVX().
*/
typedef FunctionPointerWithContext<const GattHVXCallbackParams*>
HVXCallback_t;
/**
* Callchain of handle value notification/indication event handlers.
*
* @see GattClient::onHVX().
*/
typedef CallChainOfFunctionPointersWithContext<const GattHVXCallbackParams*>
HVXCallbackChain_t;
/**
* Shutdown event handler.
*
* @see GattClient::onShutdown().
*/
typedef FunctionPointerWithContext<const GattClient *>
GattClientShutdownCallback_t;
/**
* Callchain of shutdown event handlers.
*
* @see to GattClient::onShutown().
*/
typedef CallChainOfFunctionPointersWithContext<const GattClient *>
GattClientShutdownCallbackChain_t;
/*
* The following functions are meant to be overridden in the platform
* specific subclass.
*/
public:
~GattClient() { }
/**
* Launch the service and characteristic discovery procedure of a GATT server
* peer.
*
* The procedure invokes 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.
*
* Application code can track the status of the procedure by invoking the
* function isServiceDiscoveryActive(), which returns true if the
* procedure is ongoing.
*
* At any point, application code can prematurely terminate the discovery
* procedure by calling terminateServiceDiscovery().
*
* @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
* interested in. If a service discovered matches this filter, then @p sc is
* invoked with it. The special value BLE_UUID_UNKNOWN acts as 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 interested in. If a characteristic discovered matches this
* filter, then @p cc is invoked with it. The special value BLE_UUID_UNKNOWN
* acts as 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.
*/
ble_error_t launchServiceDiscovery(
ble::connection_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)
);
/**
* Launch the service discovery procedure of a GATT server peer.
*
* The procedure invokes 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.
*
* Application code can track the status of the procedure by invoking the
* function isServiceDiscoveryActive(), which returns true if the
* procedure is ongoing.
*
* At any point, application code can prematurely terminate 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
* interested in. If a service discovered matches 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.
*/
ble_error_t discoverServices(
ble::connection_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 results 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 the service discovery procedure of a GATT server peer.
*
* The process ends after all the services present in the attribute range @p
* startHandle to @p endHandle have been discovered.
*
* 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 returns true if the
* procedure is ongoing.
*
* At any point, application code can prematurely terminate 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.
*/
ble_error_t discoverServices(
ble::connection_handle_t connectionHandle,
ServiceDiscovery::ServiceCallback_t callback,
GattAttribute::Handle_t startHandle,
GattAttribute::Handle_t endHandle
);
/**
* Check if the service discovery procedure is currently active.
*
* @return true if service discovery procedure is active and false otherwise.
*/
bool isServiceDiscoveryActive(void) const;
/**
* Terminate all ongoing service discovery procedures.
*
* It results in an invocation of the service discovery termination handler
* registered with onServiceDiscoveryTermination().
*/
void terminateServiceDiscovery(void);
/**
* Initiate the read procedure of an attribute handle.
*
* Once the attribute value has been read in its entirety, the process issues
* an attribute read event and passes it to all events handlers registered
* by onDataRead.
*
* @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 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.
*/
ble_error_t read(
ble::connection_handle_t connHandle,
GattAttribute::Handle_t attributeHandle,
uint16_t offset
) const;
/**
* Initiate a write procedure on an attribute value.
*
* If @p cmd is equal to GATT_OP_WRITE_REQ, then the status of the operation
* is reported to the event handlers registered through onDataWritten().
*
* @param[in] cmd Type of the write procedure used. If GATT_OP_WRITE_CMD
* is set, then value length is not 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 successfully started.
*
* @par Implementation notes:
*
* If the operation is a write command, then an implementation uses the
* GATT write without response procedure and an error is returned if
* the data buffer to write is larger than the size of the MTU - 3.
*
* 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 is used, and the response is reported to the handlers
* listening for write response.
*
* Otherwise, the data buffer to write is divided in chunks with a
* maximum size of MTU - 5. Those chunks are sent sequentially to the
* peer in ATT prepare write requests. If an error response is received
* during the process, the procedure ends immediately, the prepared
* write is discarded and an error is reported to the application handlers.
* Once all the chunks have been sent, the transaction is completed
* by sending an execute write request to the peer. The peer response is
* forwarded to the application handlers.
*/
ble_error_t write(
GattClient::WriteOp_t cmd,
ble::connection_handle_t connHandle,
GattAttribute::Handle_t attributeHandle,
size_t length,
const uint8_t *value
) const;
/* Event callback handlers. */
public:
/**
* 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)
{
onDataReadCallbackChain.add(callback);
}
/**
* Get the callchain of attribute read event handlers.
*
* @return A reference to the read event callback chain.
*
* @note It is possible to register new handlers using
* onDataRead().add(callback).
*
* @note It is possible to unregister an handler by using
* onDataRead().detach(callback).
*/
ReadCallbackChain_t& onDataRead()
{
return onDataReadCallbackChain;
}
/**
* Register an attribute write event handler.
*
* @param[in] callback Event handler being registered.
*
* @note It is possible to remove registered handlers using
* onDataWritten().detach(callbackToRemove).
*
* @note Write commands (issued using writeWoResponse) don't generate a
* response.
*/
void onDataWritten(WriteCallback_t callback)
{
onDataWriteCallbackChain.add(callback);
}
/**
* Get the callchain of attribute write event handlers.
*
* @return A reference to the data written callbacks chain.
*
* @note It is possible to register new handlers by using
* onDataWritten().add(callback).
*
* @note It is possible to unregister an handler by using
* onDataWritten().detach(callback).
*/
WriteCallbackChain_t& onDataWritten()
{
return onDataWriteCallbackChain;
}
/**
* Register an attribute write event handler.
*
* @param[in] callback Event handler being registered.
*
* @note It is possible to remove registered handlers using
* onDataWritten().detach(callbackToRemove).
*
* @note Write commands (issued using writeWoResponse) don't generate a
* response.
*
* @deprecated Use GattServer::onDataWritten().
*/
MBED_DEPRECATED("Use GattServer::onDataWritten()")
void onDataWrite(WriteCallback_t callback)
{
onDataWritten(callback);
}
/**
* Register a service discovery termination event handler.
*
* @param[in] callback Event handler being registered.
*/
void onServiceDiscoveryTermination(
ServiceDiscovery::TerminationCallback_t callback
);
/**
* Initiate the descriptor discovery procedure for a given characteristic.
*
* When a descriptor is discovered the discovered descriptor is forwarded
* to @p discoveryCallback. After the discovery of all the descriptors, the
* procedure ends and send a descriptor discovery termination event to @p
* termination callback.
*
* Application code may monitor the discovery process by querying its status
* with isCharacteristicDescriptorDiscoveryActive(). It can also end the
* discovery process by calling terminateCharacteristicDescriptorDiscovery().
*
* @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
* procedure has been launched successfully otherwise an appropriate error.
*/
ble_error_t discoverCharacteristicDescriptors(
const DiscoveredCharacteristic& characteristic,
const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback
);
/**
* Query status of the descriptor discovery procedure for a given
* characteristic.
*
* @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.
*/
bool isCharacteristicDescriptorDiscoveryActive(
const DiscoveredCharacteristic& characteristic
) const;
/**
* @brief Terminate an ongoing characteristic descriptor discovery procedure.
*
* If the procedure is active, then it ends, and the termination handler
* associated with the procedure is called.
*
* @param[in] characteristic The characteristic containing the descriptors
* being discovered.
*/
void terminateCharacteristicDescriptorDiscovery(
const DiscoveredCharacteristic& characteristic
);
/**
* Trigger MTU negotiation. This might result in a Gap event onAttMtuChange
* being called if MTU changes.
*
* @note This does not guarantee a change in MTU size. If size remains
* unchanged no event will be generated.
*
* @param connection Connection on which the MTU is to be negotiated.
*
* @return BLE_ERROR_NONE if the procedure has been launched successfully
* otherwise an appropriate error.
*/
ble_error_t negotiateAttMtu(ble::connection_handle_t connection);
/**
* Register an handler for Handle Value Notification/Indication events.
*
* @param callback Event handler to register.
*
* @note It is possible to unregister a callback by using
* onHVX().detach(callbackToRemove).
*/
void onHVX(HVXCallback_t callback)
{
onHVXCallbackChain.add(callback);
}
/**
* Register a shutdown event handler.
*
* The registered handler is invoked when the GattClient instance is
* about to be shut down.
*
* @param[in] callback Event handler to invoke when a shutdown event is
* available.
*
* @note onShutdown().detach(callback) may be used to unregister a given
* callback.
*
* @see BLE::shutdown()
*/
void onShutdown(const GattClientShutdownCallback_t& callback)
{
shutdownCallChain.add(callback);
}
/**
* Register a shutdown event handler.
*
* The registered handler is invoked when the GattClient instance is
* about to be shut down.
*
* @param[in] objPtr Instance that will be used to invoke @p memberPtr.
* @param[in] memberPtr Event handler to invoke when a shutdown event is
* available.
*/
template <typename T>
void onShutdown(T *objPtr, void (T::*memberPtr)(const GattClient *))
{
shutdownCallChain.add(objPtr, memberPtr);
}
/**
* Get the callchain of shutdown event handlers.
*
* @return A reference to the shutdown event callbacks chain.
*
* @note onShutdown().add(callback) may be used to register new handlers.
*
* @note onShutdown().detach(callback) may be used to unregister an handler.
*/
GattClientShutdownCallbackChain_t& onShutdown()
{
return shutdownCallChain;
}
/**
* @brief provide access to the callchain of HVX callbacks.
*
* @return A reference to the HVX callbacks chain.
*
* @note It is possible to register callbacks using onHVX().add(callback).
*
* @note It is possible to unregister callbacks using onHVX().detach(callback).
*/
HVXCallbackChain_t& onHVX() {
return onHVXCallbackChain;
}
public:
/**
* Reset the state of the GattClient instance.
*
* Prior to any state modification, shutdown event handlers are notified
* that the GattClient instance is about to be shut down. Then, running
* procedures end. Finally, the state of the instance is reset.
*
* @par implementation note
*
* This function is meant to be overridden in the platform-specific
* subclass. Nevertheless, the subclass only resets its
* state and not the data held in GattClient members. This is achieved
* by a call to GattClient::reset() from the subclass' reset()
* implementation.
*
* @return BLE_ERROR_NONE on success.
*/
ble_error_t reset(void);
protected:
/* --- Abstract calls to override --- */
/* Derived implementation must call the base class implementation */
ble_error_t reset_(void);
ble_error_t discoverServices_(
ble::connection_handle_t connectionHandle,
ServiceDiscovery::ServiceCallback_t callback,
GattAttribute::Handle_t startHandle,
GattAttribute::Handle_t endHandle
);
ble_error_t launchServiceDiscovery_(
ble::connection_handle_t connectionHandle,
ServiceDiscovery::ServiceCallback_t sc,
ServiceDiscovery::CharacteristicCallback_t cc,
const UUID &matchingServiceUUID,
const UUID &matchingCharacteristicUUIDIn
);
bool isServiceDiscoveryActive_(void) const;
void terminateServiceDiscovery_(void);
ble_error_t negotiateAttMtu_(ble::connection_handle_t connection);
ble_error_t read_(
ble::connection_handle_t connHandle,
GattAttribute::Handle_t attributeHandle,
uint16_t offset
) const;
ble_error_t write_(
GattClient::WriteOp_t cmd,
ble::connection_handle_t connHandle,
GattAttribute::Handle_t attributeHandle,
size_t length,
const uint8_t *value
) const;
void onServiceDiscoveryTermination_(
ServiceDiscovery::TerminationCallback_t callback
);
ble_error_t discoverCharacteristicDescriptors_(
const DiscoveredCharacteristic& characteristic,
const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback
);
bool isCharacteristicDescriptorDiscoveryActive_(
const DiscoveredCharacteristic& characteristic
) const;
void terminateCharacteristicDescriptorDiscovery_(
const DiscoveredCharacteristic& characteristic
);
protected:
GattClient() : eventHandler(NULL)
{
/* Empty */
}
/* Entry points for the underlying stack to report events back to the user. */
public:
/**
* Forward an attribute read event to all registered handlers.
*
* @attention 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)
{
onDataReadCallbackChain(params);
}
/**
* Forward an attribute written event to all registered handlers.
*
* @attention 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)
{
onDataWriteCallbackChain(params);
}
/**
* Forward a handle value notification or indication event to all registered
* handlers.
*
* @attention 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)
{
if (onHVXCallbackChain) {
onHVXCallbackChain(params);
}
}
protected:
/**
* Event handler provided by the application.
*/
EventHandler *eventHandler;
/**
* Callchain containing all registered event handlers for data read
* events.
*/
ReadCallbackChain_t onDataReadCallbackChain;
/**
* Callchain containing all registered event handlers for data write
* events.
*/
WriteCallbackChain_t onDataWriteCallbackChain;
/**
* Callchain containing all registered event handlers for update
* events.
*/
HVXCallbackChain_t onHVXCallbackChain;
/**
* Callchain containing all registered event handlers for shutdown
* events.
*/
GattClientShutdownCallbackChain_t shutdownCallChain;
private:
/* Disallow copy and assignment. */
GattClient(const GattClient &);
GattClient& operator=(const GattClient &);
};
/**
* @}
* @}
* @}
*/
#if !defined(DOXYGEN_ONLY)
} // namespace interface
} // namespace ble
using ble::impl::GattClient;
#endif
#endif /* ifndef MBED_GATT_CLIENT_H__ */