lin
2025-08-14 dae8bad597b6607a449b32bf76c523423f7720ed
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
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
/******************************************************************************
 *
 *  Copyright 1999-2012 Broadcom Corporation
 *
 *  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 GATT_API_H
#define GATT_API_H
 
#include "bt_target.h"
#include "btm_ble_api.h"
#include "gattdefs.h"
 
/*****************************************************************************
 *  Constants
 ****************************************************************************/
/* Success code and error codes */
#define GATT_SUCCESS 0x00
#define GATT_INVALID_HANDLE 0x01
#define GATT_READ_NOT_PERMIT 0x02
#define GATT_WRITE_NOT_PERMIT 0x03
#define GATT_INVALID_PDU 0x04
#define GATT_INSUF_AUTHENTICATION 0x05
#define GATT_REQ_NOT_SUPPORTED 0x06
#define GATT_INVALID_OFFSET 0x07
#define GATT_INSUF_AUTHORIZATION 0x08
#define GATT_PREPARE_Q_FULL 0x09
#define GATT_NOT_FOUND 0x0a
#define GATT_NOT_LONG 0x0b
#define GATT_INSUF_KEY_SIZE 0x0c
#define GATT_INVALID_ATTR_LEN 0x0d
#define GATT_ERR_UNLIKELY 0x0e
#define GATT_INSUF_ENCRYPTION 0x0f
#define GATT_UNSUPPORT_GRP_TYPE 0x10
#define GATT_INSUF_RESOURCE 0x11
 
#define GATT_ILLEGAL_PARAMETER 0x87
#define GATT_NO_RESOURCES 0x80
#define GATT_INTERNAL_ERROR 0x81
#define GATT_WRONG_STATE 0x82
#define GATT_DB_FULL 0x83
#define GATT_BUSY 0x84
#define GATT_ERROR 0x85
#define GATT_CMD_STARTED 0x86
#define GATT_PENDING 0x88
#define GATT_AUTH_FAIL 0x89
#define GATT_MORE 0x8a
#define GATT_INVALID_CFG 0x8b
#define GATT_SERVICE_STARTED 0x8c
#define GATT_ENCRYPED_MITM GATT_SUCCESS
#define GATT_ENCRYPED_NO_MITM 0x8d
#define GATT_NOT_ENCRYPTED 0x8e
#define GATT_CONGESTED 0x8f
 
#define GATT_DUP_REG 0x90      /* 0x90 */
#define GATT_ALREADY_OPEN 0x91 /* 0x91 */
#define GATT_CANCEL 0x92       /* 0x92 */
/* 0xE0 ~ 0xFC reserved for future use */
 
/* Client Characteristic Configuration Descriptor Improperly Configured */
#define GATT_CCC_CFG_ERR 0xFD
/* Procedure Already in progress */
#define GATT_PRC_IN_PROGRESS 0xFE
/* Attribute value out of range */
#define GATT_OUT_OF_RANGE 0xFF
typedef uint8_t tGATT_STATUS;
 
#define GATT_RSP_ERROR 0x01
#define GATT_REQ_MTU 0x02
#define GATT_RSP_MTU 0x03
#define GATT_REQ_FIND_INFO 0x04
#define GATT_RSP_FIND_INFO 0x05
#define GATT_REQ_FIND_TYPE_VALUE 0x06
#define GATT_RSP_FIND_TYPE_VALUE 0x07
#define GATT_REQ_READ_BY_TYPE 0x08
#define GATT_RSP_READ_BY_TYPE 0x09
#define GATT_REQ_READ 0x0A
#define GATT_RSP_READ 0x0B
#define GATT_REQ_READ_BLOB 0x0C
#define GATT_RSP_READ_BLOB 0x0D
#define GATT_REQ_READ_MULTI 0x0E
#define GATT_RSP_READ_MULTI 0x0F
#define GATT_REQ_READ_BY_GRP_TYPE 0x10
#define GATT_RSP_READ_BY_GRP_TYPE 0x11
/*                 0001-0010 (write)*/
#define GATT_REQ_WRITE 0x12
#define GATT_RSP_WRITE 0x13
/* changed in V4.0 01001-0010(write cmd)*/
#define GATT_CMD_WRITE 0x52
#define GATT_REQ_PREPARE_WRITE 0x16
#define GATT_RSP_PREPARE_WRITE 0x17
#define GATT_REQ_EXEC_WRITE 0x18
#define GATT_RSP_EXEC_WRITE 0x19
#define GATT_HANDLE_VALUE_NOTIF 0x1B
#define GATT_HANDLE_VALUE_IND 0x1D
#define GATT_HANDLE_VALUE_CONF 0x1E
/* changed in V4.0 1101-0010 (signed write)  see write cmd above*/
#define GATT_SIGN_CMD_WRITE 0xD2
/* 0x1E = 30 + 1 = 31*/
#define GATT_OP_CODE_MAX (GATT_HANDLE_VALUE_CONF + 1)
 
#define GATT_HANDLE_IS_VALID(x) ((x) != 0)
 
#define GATT_CONN_UNKNOWN 0
/* general L2cap failure  */
#define GATT_CONN_L2C_FAILURE 1
/* 0x08 connection timeout  */
#define GATT_CONN_TIMEOUT HCI_ERR_CONNECTION_TOUT
/* 0x13 connection terminate by peer user  */
#define GATT_CONN_TERMINATE_PEER_USER HCI_ERR_PEER_USER
/* 0x16 connectionterminated by local host  */
#define GATT_CONN_TERMINATE_LOCAL_HOST HCI_ERR_CONN_CAUSE_LOCAL_HOST
/* 0x03E connection fail to establish  */
#define GATT_CONN_FAIL_ESTABLISH HCI_ERR_CONN_FAILED_ESTABLISHMENT
/* 0x22 connection fail for LMP response tout */
#define GATT_CONN_LMP_TIMEOUT HCI_ERR_LMP_RESPONSE_TIMEOUT
/* 0x0100 L2CAP connection cancelled  */
#define GATT_CONN_CANCEL L2CAP_CONN_CANCEL
typedef uint16_t tGATT_DISCONN_REASON;
 
/* MAX GATT MTU size
*/
#ifndef GATT_MAX_MTU_SIZE
#define GATT_MAX_MTU_SIZE 517
#endif
 
/* max legth of an attribute value
*/
#ifndef GATT_MAX_ATTR_LEN
#define GATT_MAX_ATTR_LEN 600
#endif
 
/* default GATT MTU size over LE link
*/
#define GATT_DEF_BLE_MTU_SIZE 23
 
/* invalid connection ID
*/
#define GATT_INVALID_CONN_ID 0xFFFF
 
#ifndef GATT_CL_MAX_LCB
#define GATT_CL_MAX_LCB 22
#endif
 
/* GATT notification caching timer, default to be three seconds
*/
#ifndef GATTC_NOTIF_TIMEOUT
#define GATTC_NOTIF_TIMEOUT 3
#endif
 
/*****************************************************************************
 * GATT Structure Definition
 ****************************************************************************/
 
/* Attribute permissions
*/
#define GATT_PERM_READ (1 << 0)              /* bit 0 */
#define GATT_PERM_READ_ENCRYPTED (1 << 1)    /* bit 1 */
#define GATT_PERM_READ_ENC_MITM (1 << 2)     /* bit 2 */
#define GATT_PERM_WRITE (1 << 4)             /* bit 4 */
#define GATT_PERM_WRITE_ENCRYPTED (1 << 5)   /* bit 5 */
#define GATT_PERM_WRITE_ENC_MITM (1 << 6)    /* bit 6 */
#define GATT_PERM_WRITE_SIGNED (1 << 7)      /* bit 7 */
#define GATT_PERM_WRITE_SIGNED_MITM (1 << 8) /* bit 8 */
typedef uint16_t tGATT_PERM;
 
/* the MS nibble of tGATT_PERM; key size 7=0; size 16=9 */
#define GATT_ENCRYPT_KEY_SIZE_MASK (0xF000)
 
#define GATT_READ_ALLOWED \
  (GATT_PERM_READ | GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
#define GATT_READ_AUTH_REQUIRED (GATT_PERM_READ_ENCRYPTED)
#define GATT_READ_MITM_REQUIRED (GATT_PERM_READ_ENC_MITM)
#define GATT_READ_ENCRYPTED_REQUIRED \
  (GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ_ENC_MITM)
 
#define GATT_WRITE_ALLOWED                                                  \
  (GATT_PERM_WRITE | GATT_PERM_WRITE_ENCRYPTED | GATT_PERM_WRITE_ENC_MITM | \
   GATT_PERM_WRITE_SIGNED | GATT_PERM_WRITE_SIGNED_MITM)
 
#define GATT_WRITE_AUTH_REQUIRED \
  (GATT_PERM_WRITE_ENCRYPTED | GATT_PERM_WRITE_SIGNED)
 
#define GATT_WRITE_MITM_REQUIRED \
  (GATT_PERM_WRITE_ENC_MITM | GATT_PERM_WRITE_SIGNED_MITM)
 
#define GATT_WRITE_ENCRYPTED_PERM \
  (GATT_PERM_WRITE_ENCRYPTED | GATT_PERM_WRITE_ENC_MITM)
 
#define GATT_WRITE_SIGNED_PERM \
  (GATT_PERM_WRITE_SIGNED | GATT_PERM_WRITE_SIGNED_MITM)
 
/* Characteristic properties
*/
#define GATT_CHAR_PROP_BIT_BROADCAST (1 << 0)
#define GATT_CHAR_PROP_BIT_READ (1 << 1)
#define GATT_CHAR_PROP_BIT_WRITE_NR (1 << 2)
#define GATT_CHAR_PROP_BIT_WRITE (1 << 3)
#define GATT_CHAR_PROP_BIT_NOTIFY (1 << 4)
#define GATT_CHAR_PROP_BIT_INDICATE (1 << 5)
#define GATT_CHAR_PROP_BIT_AUTH (1 << 6)
#define GATT_CHAR_PROP_BIT_EXT_PROP (1 << 7)
typedef uint8_t tGATT_CHAR_PROP;
 
/* Format of the value of a characteristic. enumeration type
*/
enum {
  GATT_FORMAT_RES,     /* rfu */
  GATT_FORMAT_BOOL,    /* 0x01 boolean */
  GATT_FORMAT_2BITS,   /* 0x02 2 bit */
  GATT_FORMAT_NIBBLE,  /* 0x03 nibble */
  GATT_FORMAT_UINT8,   /* 0x04 uint8 */
  GATT_FORMAT_UINT12,  /* 0x05 uint12 */
  GATT_FORMAT_UINT16,  /* 0x06 uint16 */
  GATT_FORMAT_UINT24,  /* 0x07 uint24 */
  GATT_FORMAT_UINT32,  /* 0x08 uint32 */
  GATT_FORMAT_UINT48,  /* 0x09 uint48 */
  GATT_FORMAT_UINT64,  /* 0x0a uint64 */
  GATT_FORMAT_UINT128, /* 0x0B uint128 */
  GATT_FORMAT_SINT8,   /* 0x0C signed 8 bit integer */
  GATT_FORMAT_SINT12,  /* 0x0D signed 12 bit integer */
  GATT_FORMAT_SINT16,  /* 0x0E signed 16 bit integer */
  GATT_FORMAT_SINT24,  /* 0x0F signed 24 bit integer */
  GATT_FORMAT_SINT32,  /* 0x10 signed 32 bit integer */
  GATT_FORMAT_SINT48,  /* 0x11 signed 48 bit integer */
  GATT_FORMAT_SINT64,  /* 0x12 signed 64 bit integer */
  GATT_FORMAT_SINT128, /* 0x13 signed 128 bit integer */
  GATT_FORMAT_FLOAT32, /* 0x14 float 32 */
  GATT_FORMAT_FLOAT64, /* 0x15 float 64*/
  GATT_FORMAT_SFLOAT,  /* 0x16 IEEE-11073 16 bit SFLOAT */
  GATT_FORMAT_FLOAT,   /* 0x17 IEEE-11073 32 bit SFLOAT */
  GATT_FORMAT_DUINT16, /* 0x18 IEEE-20601 format */
  GATT_FORMAT_UTF8S,   /* 0x19 UTF-8 string */
  GATT_FORMAT_UTF16S,  /* 0x1a UTF-16 string */
  GATT_FORMAT_STRUCT,  /* 0x1b Opaque structure*/
  GATT_FORMAT_MAX      /* 0x1c or above reserved */
};
typedef uint8_t tGATT_FORMAT;
 
/* Characteristic Presentation Format Descriptor value
*/
typedef struct {
  uint16_t unit;  /* as UUIUD defined by SIG */
  uint16_t descr; /* as UUID as defined by SIG */
  tGATT_FORMAT format;
  int8_t exp;
  uint8_t name_spc; /* The name space of the description */
} tGATT_CHAR_PRES;
 
/* Characteristic Report reference Descriptor format
*/
typedef struct {
  uint8_t rpt_id;   /* report ID */
  uint8_t rpt_type; /* report type */
} tGATT_CHAR_RPT_REF;
 
#define GATT_VALID_RANGE_MAX_SIZE 16
typedef struct {
  uint8_t format;
  uint16_t len;
  uint8_t lower_range[GATT_VALID_RANGE_MAX_SIZE]; /* in little endian format */
  uint8_t upper_range[GATT_VALID_RANGE_MAX_SIZE];
} tGATT_VALID_RANGE;
 
/* Characteristic Aggregate Format attribute value
*/
#define GATT_AGGR_HANDLE_NUM_MAX 10
typedef struct {
  uint8_t num_handle;
  uint16_t handle_list[GATT_AGGR_HANDLE_NUM_MAX];
} tGATT_CHAR_AGGRE;
 
/* Characteristic descriptor: Extended Properties value
*/
/* permits reliable writes of the Characteristic Value */
#define GATT_CHAR_BIT_REL_WRITE 0x0001
/* permits writes to the characteristic descriptor */
#define GATT_CHAR_BIT_WRITE_AUX 0x0002
 
/* characteristic descriptor: client configuration value
*/
#define GATT_CLT_CONFIG_NONE 0x0000
#define GATT_CLT_CONFIG_NOTIFICATION 0x0001
#define GATT_CLT_CONFIG_INDICATION 0x0002
 
/* characteristic descriptor: server configuration value
*/
#define GATT_SVR_CONFIG_NONE 0x0000
#define GATT_SVR_CONFIG_BROADCAST 0x0001
typedef uint16_t tGATT_SVR_CHAR_CONFIG;
 
/* Characteristic descriptor: Extended Properties value
*/
/* permits reliable writes of the Characteristic Value */
#define GATT_CHAR_BIT_REL_WRITE 0x0001
/* permits writes to the characteristic descriptor */
#define GATT_CHAR_BIT_WRITE_AUX 0x0002
 
/* authentication requirement
*/
#define GATT_AUTH_REQ_NONE 0
#define GATT_AUTH_REQ_NO_MITM 1 /* unauthenticated encryption */
#define GATT_AUTH_REQ_MITM 2    /* authenticated encryption */
#define GATT_AUTH_REQ_SIGNED_NO_MITM 3
#define GATT_AUTH_REQ_SIGNED_MITM 4
typedef uint8_t tGATT_AUTH_REQ;
 
/* Attribute Value structure
*/
typedef struct {
  uint16_t conn_id;
  uint16_t handle; /* attribute handle */
  uint16_t offset; /* attribute value offset, if no offfset is needed for the
                      command, ignore it */
  uint16_t len;    /* length of attribute value */
  tGATT_AUTH_REQ auth_req;          /*  authentication request */
  uint8_t value[GATT_MAX_ATTR_LEN]; /* the actual attribute value */
} tGATT_VALUE;
 
/* Union of the event data which is used in the server respond API to carry the
 * server response information
*/
typedef union {
  /* data type            member          event   */
  tGATT_VALUE attr_value; /* READ, HANDLE_VALUE_IND, PREPARE_WRITE */
                          /* READ_BLOB, READ_BY_TYPE */
  uint16_t handle;        /* WRITE, WRITE_BLOB */
 
} tGATTS_RSP;
 
/* Transports for the primary service  */
#define GATT_TRANSPORT_LE BT_TRANSPORT_LE
#define GATT_TRANSPORT_BR_EDR BT_TRANSPORT_BR_EDR
#define GATT_TRANSPORT_LE_BR_EDR (BT_TRANSPORT_LE | BT_TRANSPORT_BR_EDR)
typedef uint8_t tGATT_TRANSPORT;
 
#define GATT_PREP_WRITE_CANCEL 0x00
#define GATT_PREP_WRITE_EXEC 0x01
typedef uint8_t tGATT_EXEC_FLAG;
 
/* read request always based on UUID */
typedef struct {
  uint16_t handle;
  uint16_t offset;
  bool is_long;
  bt_gatt_db_attribute_type_t
      gatt_type; /* are we writing characteristic or descriptor */
} tGATT_READ_REQ;
 
/* write request data */
typedef struct {
  uint16_t handle; /* attribute handle */
  uint16_t offset; /* attribute value offset, if no offfset is needed for the
                      command, ignore it */
  uint16_t len;    /* length of attribute value */
  uint8_t value[GATT_MAX_ATTR_LEN]; /* the actual attribute value */
  bool need_rsp;                    /* need write response */
  bool is_prep;                     /* is prepare write */
  bt_gatt_db_attribute_type_t
      gatt_type; /* are we writing characteristic or descriptor */
} tGATT_WRITE_REQ;
 
/* callback data for server access request from client */
typedef union {
  tGATT_READ_REQ read_req; /* read request, read by Type, read blob */
 
  tGATT_WRITE_REQ write_req;  /* write */
                              /* prepare write */
                              /* write blob */
  uint16_t handle;            /* handle value confirmation */
  uint16_t mtu;               /* MTU exchange request */
  tGATT_EXEC_FLAG exec_write; /* execute write */
} tGATTS_DATA;
 
typedef uint8_t tGATT_SERV_IF; /* GATT Service Interface */
 
enum {
  GATTS_REQ_TYPE_READ_CHARACTERISTIC = 1, /* Char read request */
  GATTS_REQ_TYPE_READ_DESCRIPTOR,         /* Desc read request */
  GATTS_REQ_TYPE_WRITE_CHARACTERISTIC,    /* Char write request */
  GATTS_REQ_TYPE_WRITE_DESCRIPTOR,        /* Desc write request */
  GATTS_REQ_TYPE_WRITE_EXEC,              /* Execute write */
  GATTS_REQ_TYPE_MTU,                     /* MTU exchange information */
  GATTS_REQ_TYPE_CONF                     /* handle value confirmation */
};
typedef uint8_t tGATTS_REQ_TYPE;
 
/* Client Used Data Structure
*/
/* definition of different discovery types */
enum {
  GATT_DISC_SRVC_ALL = 1, /* discover all services */
  GATT_DISC_SRVC_BY_UUID, /* discover service of a special type */
  GATT_DISC_INC_SRVC,     /* discover the included service within a service */
  GATT_DISC_CHAR, /* discover characteristics of a service with/without type
                     requirement */
  GATT_DISC_CHAR_DSCPT, /* discover characteristic descriptors of a character */
  GATT_DISC_MAX         /* maximnun discover type */
};
typedef uint8_t tGATT_DISC_TYPE;
 
/* GATT read type enumeration
*/
enum {
  GATT_READ_BY_TYPE = 1,
  GATT_READ_BY_HANDLE,
  GATT_READ_MULTIPLE,
  GATT_READ_CHAR_VALUE,
  GATT_READ_PARTIAL,
  GATT_READ_MAX
};
typedef uint8_t tGATT_READ_TYPE;
 
/* Read By Type Request (GATT_READ_BY_TYPE) Data
*/
typedef struct {
  tGATT_AUTH_REQ auth_req;
  uint16_t s_handle;
  uint16_t e_handle;
  bluetooth::Uuid uuid;
} tGATT_READ_BY_TYPE;
 
/*   GATT_READ_MULTIPLE request data
*/
#define GATT_MAX_READ_MULTI_HANDLES \
  10 /* Max attributes to read in one request */
typedef struct {
  tGATT_AUTH_REQ auth_req;
  uint16_t num_handles;                          /* number of handles to read */
  uint16_t handles[GATT_MAX_READ_MULTI_HANDLES]; /* handles list to be read */
} tGATT_READ_MULTI;
 
/*   Read By Handle Request (GATT_READ_BY_HANDLE) data */
typedef struct {
  tGATT_AUTH_REQ auth_req;
  uint16_t handle;
} tGATT_READ_BY_HANDLE;
 
/*   READ_BT_HANDLE_Request data */
typedef struct {
  tGATT_AUTH_REQ auth_req;
  uint16_t handle;
  uint16_t offset;
} tGATT_READ_PARTIAL;
 
/* Read Request Data
*/
typedef union {
  tGATT_READ_BY_TYPE service;
  tGATT_READ_BY_TYPE char_type; /* characterisitc type */
  tGATT_READ_MULTI read_multiple;
  tGATT_READ_BY_HANDLE by_handle;
  tGATT_READ_PARTIAL partial;
} tGATT_READ_PARAM;
 
/* GATT write type enumeration */
enum { GATT_WRITE_NO_RSP = 1, GATT_WRITE, GATT_WRITE_PREPARE };
typedef uint8_t tGATT_WRITE_TYPE;
 
/* Client Operation Complete Callback Data
*/
typedef union {
  tGATT_VALUE att_value;
  uint16_t mtu;
  uint16_t handle;
} tGATT_CL_COMPLETE;
 
/* GATT client operation type, used in client callback function
*/
#define GATTC_OPTYPE_NONE 0
#define GATTC_OPTYPE_DISCOVERY 1
#define GATTC_OPTYPE_READ 2
#define GATTC_OPTYPE_WRITE 3
#define GATTC_OPTYPE_EXE_WRITE 4
#define GATTC_OPTYPE_CONFIG 5
#define GATTC_OPTYPE_NOTIFICATION 6
#define GATTC_OPTYPE_INDICATION 7
typedef uint8_t tGATTC_OPTYPE;
 
/* characteristic declaration
*/
typedef struct {
  tGATT_CHAR_PROP char_prop; /* characterisitc properties */
  uint16_t val_handle;       /* characteristic value attribute handle */
  bluetooth::Uuid char_uuid; /* characteristic UUID type */
} tGATT_CHAR_DCLR_VAL;
 
/* primary service group data
*/
typedef struct {
  uint16_t e_handle;     /* ending handle of the group */
  bluetooth::Uuid service_type; /* group type */
} tGATT_GROUP_VALUE;
 
/* included service attribute value
*/
typedef struct {
  bluetooth::Uuid service_type; /* included service UUID */
  uint16_t s_handle;     /* starting handle */
  uint16_t e_handle;     /* ending handle */
} tGATT_INCL_SRVC;
 
typedef union {
  tGATT_INCL_SRVC incl_service;  /* include service value */
  tGATT_GROUP_VALUE group_value; /* Service UUID type.
                                    This field is used with GATT_DISC_SRVC_ALL
                                    or GATT_DISC_SRVC_BY_UUID
                                    type of discovery result callback. */
 
  uint16_t handle; /* When used with GATT_DISC_INC_SRVC type discovery result,
                      it is the included service starting handle.*/
 
  tGATT_CHAR_DCLR_VAL
      dclr_value; /* Characteristic declaration value.
                     This field is used with GATT_DISC_CHAR type discovery.*/
} tGATT_DISC_VALUE;
 
/* discover result record
*/
typedef struct {
  bluetooth::Uuid type;
  uint16_t handle;
  tGATT_DISC_VALUE value;
} tGATT_DISC_RES;
 
#define GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP  \
  1 /* start a idle timer for this duration \
     when no application need to use the link */
 
#define GATT_LINK_NO_IDLE_TIMEOUT 0xFFFF
 
#define GATT_INVALID_ACL_HANDLE 0xFFFF
/* discover result callback function */
typedef void(tGATT_DISC_RES_CB)(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
                                tGATT_DISC_RES* p_data);
 
/* discover complete callback function */
typedef void(tGATT_DISC_CMPL_CB)(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
                                 tGATT_STATUS status);
 
/* Define a callback function for when read/write/disc/config operation is
 * completed. */
typedef void(tGATT_CMPL_CBACK)(uint16_t conn_id, tGATTC_OPTYPE op,
                               tGATT_STATUS status, tGATT_CL_COMPLETE* p_data);
 
/* Define a callback function when an initialized connection is established. */
typedef void(tGATT_CONN_CBACK)(tGATT_IF gatt_if, const RawAddress& bda,
                               uint16_t conn_id, bool connected,
                               tGATT_DISCONN_REASON reason,
                               tBT_TRANSPORT transport);
 
/* attribute request callback for ATT server */
typedef void(tGATT_REQ_CBACK)(uint16_t conn_id, uint32_t trans_id,
                              tGATTS_REQ_TYPE type, tGATTS_DATA* p_data);
 
/* channel congestion/uncongestion callback */
typedef void(tGATT_CONGESTION_CBACK)(uint16_t conn_id, bool congested);
 
/* Define a callback function when encryption is established. */
typedef void(tGATT_ENC_CMPL_CB)(tGATT_IF gatt_if, const RawAddress& bda);
 
/* Define a callback function when phy is updated. */
typedef void(tGATT_PHY_UPDATE_CB)(tGATT_IF gatt_if, uint16_t conn_id,
                                  uint8_t tx_phy, uint8_t rx_phy,
                                  uint8_t status);
 
/* Define a callback function when connection parameters are updated */
typedef void(tGATT_CONN_UPDATE_CB)(tGATT_IF gatt_if, uint16_t conn_id,
                                   uint16_t interval, uint16_t latency,
                                   uint16_t timeout, uint8_t status);
 
/* Define the structure that applications use to register with
 * GATT. This structure includes callback functions. All functions
 * MUST be provided.
*/
typedef struct {
  tGATT_CONN_CBACK* p_conn_cb;
  tGATT_CMPL_CBACK* p_cmpl_cb;
  tGATT_DISC_RES_CB* p_disc_res_cb;
  tGATT_DISC_CMPL_CB* p_disc_cmpl_cb;
  tGATT_REQ_CBACK* p_req_cb;
  tGATT_ENC_CMPL_CB* p_enc_cmpl_cb;
  tGATT_CONGESTION_CBACK* p_congestion_cb;
  tGATT_PHY_UPDATE_CB* p_phy_update_cb;
  tGATT_CONN_UPDATE_CB* p_conn_update_cb;
} tGATT_CBACK;
 
/*****************  Start Handle Management Definitions   *********************/
 
typedef struct {
  bluetooth::Uuid app_uuid128;
  bluetooth::Uuid svc_uuid;
  uint16_t s_handle;
  uint16_t e_handle;
  bool is_primary; /* primary service or secondary */
} tGATTS_HNDL_RANGE;
 
#define GATTS_SRV_CHG_CMD_ADD_CLIENT 1
#define GATTS_SRV_CHG_CMD_UPDATE_CLIENT 2
#define GATTS_SRV_CHG_CMD_REMOVE_CLIENT 3
#define GATTS_SRV_CHG_CMD_READ_NUM_CLENTS 4
#define GATTS_SRV_CHG_CMD_READ_CLENT 5
typedef uint8_t tGATTS_SRV_CHG_CMD;
 
typedef struct {
  RawAddress bda;
  bool srv_changed;
} tGATTS_SRV_CHG;
 
typedef union {
  tGATTS_SRV_CHG srv_chg;
  uint8_t client_read_index; /* only used for sequential reading client srv chg
                                info */
} tGATTS_SRV_CHG_REQ;
 
typedef union {
  tGATTS_SRV_CHG srv_chg;
  uint8_t num_clients;
} tGATTS_SRV_CHG_RSP;
 
/* Attibute server handle ranges NV storage callback functions
*/
typedef void(tGATTS_NV_SAVE_CBACK)(bool is_saved,
                                   tGATTS_HNDL_RANGE* p_hndl_range);
typedef bool(tGATTS_NV_SRV_CHG_CBACK)(tGATTS_SRV_CHG_CMD cmd,
                                      tGATTS_SRV_CHG_REQ* p_req,
                                      tGATTS_SRV_CHG_RSP* p_rsp);
 
typedef struct {
  tGATTS_NV_SAVE_CBACK* p_nv_save_callback;
  tGATTS_NV_SRV_CHG_CBACK* p_srv_chg_callback;
} tGATT_APPL_INFO;
 
/********************  End Handle Management Definitions   ********************/
 
/*******************************************************************************
 *  External Function Declarations
 ******************************************************************************/
 
/******************************************************************************/
/* GATT Profile API Functions */
/******************************************************************************/
/* GATT Profile Server Functions */
/******************************************************************************/
/*******************************************************************************
 *
 * Function         GATTS_AddHandleRange
 *
 * Description      This function add the allocated handles range for the
 *                  specified application UUID, service UUID and service
 *                  instance
 *
 * Parameter        p_hndl_range:   pointer to allocated handles information
 ******************************************************************************/
 
extern void GATTS_AddHandleRange(tGATTS_HNDL_RANGE* p_hndl_range);
 
/*******************************************************************************
 *
 * Function         GATTS_NVRegister
 *
 * Description      Application manager calls this function to register for
 *                  NV save callback function.  There can be one and only one
 *                  NV save callback function.
 *
 * Parameter        p_cb_info : callback informaiton
 *
 * Returns          true if registered OK, else false
 *
 ******************************************************************************/
extern bool GATTS_NVRegister(tGATT_APPL_INFO* p_cb_info);
 
/*******************************************************************************
 *
 * Function         BTA_GATTS_AddService
 *
 * Description      Add a service. When service is ready, a callback
 *                  event BTA_GATTS_ADD_SRVC_EVT is called to report status
 *                  and handles to the profile.
 *
 * Parameters       server_if: server interface.
 *                  service: pointer array describing service.
 *                  count: number of elements in service array.
 *
 * Returns          on success GATT_SERVICE_STARTED is returned, and
 *                  attribute_handle field inside service elements are filled.
 *                  on error error status is returned.
 *
 ******************************************************************************/
extern uint16_t GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service,
                                 int count);
 
/*******************************************************************************
 *
 * Function         GATTS_DeleteService
 *
 * Description      This function is called to delete a service.
 *
 * Parameter        gatt_if       : application interface
 *                  p_svc_uuid    : service UUID
 *                  svc_inst      : instance of the service inside the
 *                                  application
 *
 * Returns          true if operation succeed, else false
 *
 ******************************************************************************/
extern bool GATTS_DeleteService(tGATT_IF gatt_if, bluetooth::Uuid* p_svc_uuid,
                                uint16_t svc_inst);
 
/*******************************************************************************
 *
 * Function         GATTS_StopService
 *
 * Description      This function is called to stop a service
 *
 * Parameter         service_handle : this is the start handle of a service
 *
 * Returns          None.
 *
 ******************************************************************************/
extern void GATTS_StopService(uint16_t service_handle);
 
/*******************************************************************************
 *
 * Function         GATTs_HandleValueIndication
 *
 * Description      This function sends a handle value indication to a client.
 *
 * Parameter        conn_id: connection identifier.
 *                  attr_handle: Attribute handle of this handle value
 *                               indication.
 *                  val_len: Length of the indicated attribute value.
 *                  p_val: Pointer to the indicated attribute value data.
 *
 * Returns          GATT_SUCCESS if sucessfully sent or queued; otherwise error
 *                               code.
 *
 ******************************************************************************/
extern tGATT_STATUS GATTS_HandleValueIndication(uint16_t conn_id,
                                                uint16_t attr_handle,
                                                uint16_t val_len,
                                                uint8_t* p_val);
 
/*******************************************************************************
 *
 * Function         GATTS_HandleValueNotification
 *
 * Description      This function sends a handle value notification to a client.
 *
 * Parameter       conn_id: connection identifier.
 *                  attr_handle: Attribute handle of this handle value
 *                               indication.
 *                  val_len: Length of the indicated attribute value.
 *                  p_val: Pointer to the indicated attribute value data.
 *
 * Returns          GATT_SUCCESS if sucessfully sent; otherwise error code.
 *
 ******************************************************************************/
extern tGATT_STATUS GATTS_HandleValueNotification(uint16_t conn_id,
                                                  uint16_t attr_handle,
                                                  uint16_t val_len,
                                                  uint8_t* p_val);
 
/*******************************************************************************
 *
 * Function         GATTS_SendRsp
 *
 * Description      This function sends the server response to client.
 *
 * Parameter        conn_id: connection identifier.
 *                  trans_id: transaction id
 *                  status: response status
 *                  p_msg: pointer to message parameters structure.
 *
 * Returns          GATT_SUCCESS if sucessfully sent; otherwise error code.
 *
 ******************************************************************************/
extern tGATT_STATUS GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id,
                                  tGATT_STATUS status, tGATTS_RSP* p_msg);
 
/******************************************************************************/
/* GATT Profile Client Functions */
/******************************************************************************/
 
/*******************************************************************************
 *
 * Function         GATTC_ConfigureMTU
 *
 * Description      This function is called to configure the ATT MTU size for
 *                  a connection on an LE transport.
 *
 * Parameters       conn_id: connection identifier.
 *                  mtu    - attribute MTU size..
 *
 * Returns          GATT_SUCCESS if command started successfully.
 *
 ******************************************************************************/
extern tGATT_STATUS GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu);
 
/*******************************************************************************
 *
 * Function         GATTC_Discover
 *
 * Description      This function is called to do a discovery procedure on ATT
 *                  server.
 *
 * Parameters       conn_id: connection identifier.
 *                  disc_type:discovery type.
 *                  start_handle and end_handle: range of handles for discovery
 *                  uuid: uuid to discovery. set to Uuid::kEmpty for requests
 *                        that don't need it
 *
 * Returns          GATT_SUCCESS if command received/sent successfully.
 *
 ******************************************************************************/
extern tGATT_STATUS GATTC_Discover(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
                                   uint16_t start_handle, uint16_t end_handle,
                                   const bluetooth::Uuid& uuid);
extern tGATT_STATUS GATTC_Discover(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
                                   uint16_t start_handle, uint16_t end_handle);
 
/*******************************************************************************
 *
 * Function         GATTC_Read
 *
 * Description      This function is called to read the value of an attribute
 *                  from the server.
 *
 * Parameters       conn_id: connection identifier.
 *                  type    - attribute read type.
 *                  p_read  - read operation parameters.
 *
 * Returns          GATT_SUCCESS if command started successfully.
 *
 ******************************************************************************/
extern tGATT_STATUS GATTC_Read(uint16_t conn_id, tGATT_READ_TYPE type,
                               tGATT_READ_PARAM* p_read);
 
/*******************************************************************************
 *
 * Function         GATTC_Write
 *
 * Description      This function is called to read the value of an attribute
 *                  from the server.
 *
 * Parameters       conn_id: connection identifier.
 *                  type    - attribute write type.
 *                  p_write  - write operation parameters.
 *
 * Returns          GATT_SUCCESS if command started successfully.
 *
 ******************************************************************************/
extern tGATT_STATUS GATTC_Write(uint16_t conn_id, tGATT_WRITE_TYPE type,
                                tGATT_VALUE* p_write);
 
/*******************************************************************************
 *
 * Function         GATTC_ExecuteWrite
 *
 * Description      This function is called to send an Execute write request to
 *                  the server.
 *
 * Parameters       conn_id: connection identifier.
 *                  is_execute - to execute or cancel the prepare write
 *                               request(s)
 *
 * Returns          GATT_SUCCESS if command started successfully.
 *
 ******************************************************************************/
extern tGATT_STATUS GATTC_ExecuteWrite(uint16_t conn_id, bool is_execute);
 
/*******************************************************************************
 *
 * Function         GATTC_SendHandleValueConfirm
 *
 * Description      This function is called to send a handle value confirmation
 *                  as response to a handle value notification from server.
 *
 * Parameters       conn_id: connection identifier.
 *                  handle: the handle of the attribute confirmation.
 *
 * Returns          GATT_SUCCESS if command started successfully.
 *
 ******************************************************************************/
extern tGATT_STATUS GATTC_SendHandleValueConfirm(uint16_t conn_id,
                                                 uint16_t handle);
 
/*******************************************************************************
 *
 * Function         GATT_SetIdleTimeout
 *
 * Description      This function (common to both client and server) sets the
 *                  idle timeout for a tansport connection
 *
 * Parameter        bd_addr:   target device bd address.
 *                  idle_tout: timeout value in seconds.
 *                  transport: trasnport option.
 *
 * Returns          void
 *
 ******************************************************************************/
extern void GATT_SetIdleTimeout(const RawAddress& bd_addr, uint16_t idle_tout,
                                tGATT_TRANSPORT transport);
 
/*******************************************************************************
 *
 * Function         GATT_Register
 *
 * Description      This function is called to register an  application
 *                  with GATT
 *
 * Parameter        p_app_uuid128: Application UUID
 *                  p_cb_info: callback functions.
 *
 * Returns          0 for error, otherwise the index of the client registered
 *                  with GATT
 *
 ******************************************************************************/
extern tGATT_IF GATT_Register(const bluetooth::Uuid& p_app_uuid128,
                              tGATT_CBACK* p_cb_info);
 
/*******************************************************************************
 *
 * Function         GATT_Deregister
 *
 * Description      This function deregistered the application from GATT.
 *
 * Parameters       gatt_if: applicaiton interface.
 *
 * Returns          None.
 *
 ******************************************************************************/
extern void GATT_Deregister(tGATT_IF gatt_if);
 
/*******************************************************************************
 *
 * Function         GATT_StartIf
 *
 * Description      This function is called after registration to start
 *                  receiving callbacks for registered interface.  Function may
 *                  call back with connection status and queued notifications
 *
 * Parameter        gatt_if: applicaiton interface.
 *
 * Returns          None
 *
 ******************************************************************************/
extern void GATT_StartIf(tGATT_IF gatt_if);
 
/*******************************************************************************
 *
 * Function         GATT_Connect
 *
 * Description      This function initiate a connecttion to a remote device on
 *                  GATT channel.
 *
 * Parameters       gatt_if: applicaiton interface
 *                  bd_addr: peer device address.
 *                  is_direct: is a direct connection or a background auto
 *                             connection
 *                  transport : Physical transport for GATT connection
 *                              (BR/EDR or LE)
 *                  opportunistic: will not keep device connected if other apps
 *                      disconnect, will not update connected apps counter, when
 *                      disconnected won't cause physical disconnection.
 *
 * Returns          true if connection started; else false
 *
 ******************************************************************************/
extern bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr,
                         bool is_direct, tBT_TRANSPORT transport,
                         bool opportunistic);
extern bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr,
                         bool is_direct, tBT_TRANSPORT transport,
                         bool opportunistic, uint8_t initiating_phys);
 
/*******************************************************************************
 *
 * Function         GATT_CancelConnect
 *
 * Description      Terminate the connection initiation to a remote device on a
 *                  GATT channel.
 *
 * Parameters       gatt_if: client interface. If 0 used as unconditionally
 *                           disconnect, typically used for direct connection
 *                           cancellation.
 *                  bd_addr: peer device address.
 *                  is_direct: is a direct conenection or a background auto
 *                             connection
 *
 * Returns          true if connection started; else false
 *
 ******************************************************************************/
extern bool GATT_CancelConnect(tGATT_IF gatt_if, const RawAddress& bd_addr,
                               bool is_direct);
 
/*******************************************************************************
 *
 * Function         GATT_Disconnect
 *
 * Description      Disconnect the GATT channel for this registered application.
 *
 * Parameters       conn_id: connection identifier.
 *
 * Returns          GATT_SUCCESS if disconnected.
 *
 ******************************************************************************/
extern tGATT_STATUS GATT_Disconnect(uint16_t conn_id);
 
/*******************************************************************************
 *
 * Function         GATT_GetConnectionInfor
 *
 * Description      Use conn_id to find its associated BD address and
 *                  application interface
 *
 * Parameters        conn_id: connection id  (input)
 *                   p_gatt_if: applicaiton interface (output)
 *                   bd_addr: peer device address. (output)
 *                   transport : physical transport of the GATT connection
 *                                (BR/EDR or LE)
 *
 * Returns          true the ligical link information is found for conn_id
 *
 ******************************************************************************/
extern bool GATT_GetConnectionInfor(uint16_t conn_id, tGATT_IF* p_gatt_if,
                                    RawAddress& bd_addr,
                                    tBT_TRANSPORT* p_transport);
 
/*******************************************************************************
 *
 * Function         GATT_GetConnIdIfConnected
 *
 * Description      Find the conn_id if the logical link for a BD address
 *                  and application interface is connected
 *
 * Parameters        gatt_if: applicaiton interface (input)
 *                   bd_addr: peer device address. (input)
 *                   p_conn_id: connection id  (output)
 *                   transport :  physical transport of the GATT connection
 *                               (BR/EDR or LE)
 *
 * Returns          true the ligical link is connected
 *
 ******************************************************************************/
extern bool GATT_GetConnIdIfConnected(tGATT_IF gatt_if,
                                      const RawAddress& bd_addr,
                                      uint16_t* p_conn_id,
                                      tBT_TRANSPORT transport);
 
/*******************************************************************************
 *
 * Function         GATT_ConfigServiceChangeCCC
 *
 * Description      Configure service change indication on remote device
 *
 * Returns          None.
 *
 ******************************************************************************/
extern void GATT_ConfigServiceChangeCCC(const RawAddress& remote_bda,
                                        bool enable, tBT_TRANSPORT transport);
 
// Enables the GATT profile on the device.
// It clears out the control blocks, and registers with L2CAP.
extern void gatt_init(void);
 
// Frees resources used by the GATT profile.
extern void gatt_free(void);
 
// Link encryption complete notification for all encryption process
// initiated outside GATT.
extern void gatt_notify_enc_cmpl(const RawAddress& bd_addr);
 
/** Reset bg device list. If called after controller reset, set |after_reset| to
 * true, as there is no need to wipe controller white list in this case. */
extern void gatt_reset_bgdev_list(bool after_reset);
 
#endif /* GATT_API_H */