xref: /btstack/src/ble/gatt_service_client.h (revision 7e964e265324d69ae2cdc60eacb365ca3e5bab1f)
1*12879e75SMatthias Ringwald /*
2*12879e75SMatthias Ringwald  * Copyright (C) 2023 BlueKitchen GmbH
3*12879e75SMatthias Ringwald  *
4*12879e75SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5*12879e75SMatthias Ringwald  * modification, are permitted provided that the following conditions
6*12879e75SMatthias Ringwald  * are met:
7*12879e75SMatthias Ringwald  *
8*12879e75SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9*12879e75SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10*12879e75SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*12879e75SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*12879e75SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13*12879e75SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*12879e75SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15*12879e75SMatthias Ringwald  *    from this software without specific prior written permission.
16*12879e75SMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17*12879e75SMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18*12879e75SMatthias Ringwald  *    monetary gain.
19*12879e75SMatthias Ringwald  *
20*12879e75SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21*12879e75SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*12879e75SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*12879e75SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24*12879e75SMatthias Ringwald  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25*12879e75SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26*12879e75SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27*12879e75SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28*12879e75SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29*12879e75SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30*12879e75SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*12879e75SMatthias Ringwald  * SUCH DAMAGE.
32*12879e75SMatthias Ringwald  *
33*12879e75SMatthias Ringwald  * Please inquire about commercial licensing options at
34*12879e75SMatthias Ringwald  * [email protected]
35*12879e75SMatthias Ringwald  *
36*12879e75SMatthias Ringwald  */
37*12879e75SMatthias Ringwald 
38*12879e75SMatthias Ringwald /**
39*12879e75SMatthias Ringwald  * @title GATT Service Client
40*12879e75SMatthias Ringwald  *
41*12879e75SMatthias Ringwald  */
42*12879e75SMatthias Ringwald 
43*12879e75SMatthias Ringwald #ifndef GATT_SERVICE_CLIENT_H
44*12879e75SMatthias Ringwald #define GATT_SERVICE_CLIENT_H
45*12879e75SMatthias Ringwald 
46*12879e75SMatthias Ringwald #include <stdint.h>
47*12879e75SMatthias Ringwald #include "btstack_defines.h"
48*12879e75SMatthias Ringwald #include "bluetooth.h"
49*12879e75SMatthias Ringwald #include "btstack_linked_list.h"
50*12879e75SMatthias Ringwald #include "ble/gatt_client.h"
51*12879e75SMatthias Ringwald 
52*12879e75SMatthias Ringwald #if defined __cplusplus
53*12879e75SMatthias Ringwald extern "C" {
54*12879e75SMatthias Ringwald #endif
55*12879e75SMatthias Ringwald 
56*12879e75SMatthias Ringwald /**
57*12879e75SMatthias Ringwald  * @text A generic GATT Service Client
58*12879e75SMatthias Ringwald  */
59*12879e75SMatthias Ringwald 
60*12879e75SMatthias Ringwald #define GATT_SERVICE_CLIENT_INVALID_INDEX 0xff
61*12879e75SMatthias Ringwald 
62*12879e75SMatthias Ringwald typedef enum {
63*12879e75SMatthias Ringwald     GATT_SERVICE_CLIENT_STATE_W2_QUERY_PRIMARY_SERVICE,
64*12879e75SMatthias Ringwald     GATT_SERVICE_CLIENT_STATE_W4_SERVICE_RESULT,
65*12879e75SMatthias Ringwald     GATT_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTICS,
66*12879e75SMatthias Ringwald     GATT_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_RESULT,
67*12879e75SMatthias Ringwald     GATT_SERVICE_CLIENT_STATE_W2_QUERY_CHARACTERISTIC_DESCRIPTORS,
68*12879e75SMatthias Ringwald     GATT_SERVICE_CLIENT_STATE_W4_CHARACTERISTIC_DESCRIPTORS_RESULT,
69*12879e75SMatthias Ringwald 
70*12879e75SMatthias Ringwald     GATT_SERVICE_CLIENT_STATE_W2_REGISTER_NOTIFICATION,
71*12879e75SMatthias Ringwald     GATT_SERVICE_CLIENT_STATE_W4_NOTIFICATION_REGISTERED,
72*12879e75SMatthias Ringwald     GATT_SERVICE_CLIENT_STATE_CONNECTED
73*12879e75SMatthias Ringwald } gatt_service_client_state_t;
74*12879e75SMatthias Ringwald 
75*12879e75SMatthias Ringwald typedef struct {
76*12879e75SMatthias Ringwald     uint16_t value_handle;
77*12879e75SMatthias Ringwald     uint16_t client_configuration_handle;
78*12879e75SMatthias Ringwald     uint16_t properties;
79*12879e75SMatthias Ringwald     uint16_t end_handle;
80*12879e75SMatthias Ringwald } gatt_service_client_characteristic_t;
81*12879e75SMatthias Ringwald 
82*12879e75SMatthias Ringwald struct gatt_service_client;
83*12879e75SMatthias Ringwald 
84*12879e75SMatthias Ringwald typedef struct {
85*12879e75SMatthias Ringwald     btstack_linked_item_t item;
86*12879e75SMatthias Ringwald 
87*12879e75SMatthias Ringwald     struct gatt_service_client * client;
88*12879e75SMatthias Ringwald 
89*12879e75SMatthias Ringwald     hci_con_handle_t  con_handle;
90*12879e75SMatthias Ringwald     uint16_t          cid;
91*12879e75SMatthias Ringwald     gatt_service_client_state_t  state;
92*12879e75SMatthias Ringwald 
93*12879e75SMatthias Ringwald     // service
94*12879e75SMatthias Ringwald     uint16_t service_uuid16;
95*12879e75SMatthias Ringwald     uint8_t  service_index;
96*12879e75SMatthias Ringwald     uint16_t service_instances_num;
97*12879e75SMatthias Ringwald     uint16_t start_handle;
98*12879e75SMatthias Ringwald     uint16_t end_handle;
99*12879e75SMatthias Ringwald 
100*12879e75SMatthias Ringwald     uint8_t characteristic_index;
101*12879e75SMatthias Ringwald     gatt_service_client_characteristic_t * characteristics;
102*12879e75SMatthias Ringwald 
103*12879e75SMatthias Ringwald     gatt_client_service_notification_t notification_listener;
104*12879e75SMatthias Ringwald } gatt_service_client_connection_t;
105*12879e75SMatthias Ringwald 
106*12879e75SMatthias Ringwald typedef struct gatt_service_client {
107*12879e75SMatthias Ringwald     btstack_linked_item_t item;
108*12879e75SMatthias Ringwald     btstack_linked_list_t connections;
109*12879e75SMatthias Ringwald     uint16_t service_id;
110*12879e75SMatthias Ringwald     uint16_t cid_counter;
111*12879e75SMatthias Ringwald 
112*12879e75SMatthias Ringwald     // characteristics
113*12879e75SMatthias Ringwald     uint8_t  characteristics_desc16_num;     // uuid16s_num
114*12879e75SMatthias Ringwald     const uint16_t * characteristics_desc16; // uuid16s
115*12879e75SMatthias Ringwald 
116*12879e75SMatthias Ringwald     btstack_packet_handler_t packet_handler;
117*12879e75SMatthias Ringwald } gatt_service_client_t;
118*12879e75SMatthias Ringwald 
119*12879e75SMatthias Ringwald /* API_START */
120*12879e75SMatthias Ringwald 
121*12879e75SMatthias Ringwald 
122*12879e75SMatthias Ringwald /**
123*12879e75SMatthias Ringwald  * @brief Initialize GATT Service Client infrastructure
124*12879e75SMatthias Ringwald  */
125*12879e75SMatthias Ringwald void gatt_service_client_init(void);
126*12879e75SMatthias Ringwald 
127*12879e75SMatthias Ringwald /**
128*12879e75SMatthias Ringwald  * @brief Register new GATT Service Client with list of Characteristic UUID16s
129*12879e75SMatthias Ringwald  * @param client
130*12879e75SMatthias Ringwald  * @param characteristic_uuid16s
131*12879e75SMatthias Ringwald  * @param characteristic_uuid16s_num
132*12879e75SMatthias Ringwald  * @param trampoline_packet_handler packet handler that calls gatt_service_client_trampoline_packet_handler with client
133*12879e75SMatthias Ringwald  */
134*12879e75SMatthias Ringwald void gatt_service_client_register_client(gatt_service_client_t *client, btstack_packet_handler_t packet_handler,
135*12879e75SMatthias Ringwald                                          const uint16_t *characteristic_uuid16s, uint16_t characteristic_uuid16s_num);
136*12879e75SMatthias Ringwald 
137*12879e75SMatthias Ringwald /**
138*12879e75SMatthias Ringwald  * @brief Get Characteristic UUID16 for given Characteristic index
139*12879e75SMatthias Ringwald  *
140*12879e75SMatthias Ringwald  * @param client
141*12879e75SMatthias Ringwald  * @param characteristic_index
142*12879e75SMatthias Ringwald  * @return uuid16 or 0 if index out of range
143*12879e75SMatthias Ringwald  */
144*12879e75SMatthias Ringwald uint16_t gatt_service_client_characteristic_uuid16_for_index(const gatt_service_client_t * client, uint8_t characteristic_index);
145*12879e75SMatthias Ringwald 
146*12879e75SMatthias Ringwald /**
147*12879e75SMatthias Ringwald  * @bbreif Unregister GATT Service Client
148*12879e75SMatthias Ringwald  * @param client
149*12879e75SMatthias Ringwald  */
150*12879e75SMatthias Ringwald void gatt_service_client_unregister_client(gatt_service_client_t * client);
151*12879e75SMatthias Ringwald 
152*12879e75SMatthias Ringwald /**
153*12879e75SMatthias Ringwald  * @brief Connect to the n-th instance of Primary GATT Service with UUID16
154*12879e75SMatthias Ringwald  *
155*12879e75SMatthias Ringwald  * @param con_handle
156*12879e75SMatthias Ringwald  * @param client
157*12879e75SMatthias Ringwald  * @param connection
158*12879e75SMatthias Ringwald  * @param service_uuid16
159*12879e75SMatthias Ringwald  * @param service_index
160*12879e75SMatthias Ringwald  * @param characteristics
161*12879e75SMatthias Ringwald  * @param characteristics_num
162*12879e75SMatthias Ringwald  * @return
163*12879e75SMatthias Ringwald  */
164*12879e75SMatthias Ringwald uint8_t
165*12879e75SMatthias Ringwald gatt_service_client_connect_primary_service_with_uuid16(hci_con_handle_t con_handle, gatt_service_client_t *client,
166*12879e75SMatthias Ringwald                                                         gatt_service_client_connection_t *connection,
167*12879e75SMatthias Ringwald                                                         uint16_t service_uuid16, uint8_t service_index,
168*12879e75SMatthias Ringwald                                                         gatt_service_client_characteristic_t *characteristics,
169*12879e75SMatthias Ringwald                                                         uint8_t characteristics_num);
170*12879e75SMatthias Ringwald 
171*12879e75SMatthias Ringwald /**
172*12879e75SMatthias Ringwald  * @brief Connect to the Secondary GATT Service with given handle range
173*12879e75SMatthias Ringwald  *
174*12879e75SMatthias Ringwald  * UUID16 and Service Index are stored for GATT Service Client user only
175*12879e75SMatthias Ringwald  *
176*12879e75SMatthias Ringwald  * @param con_handle
177*12879e75SMatthias Ringwald  * @param client
178*12879e75SMatthias Ringwald  * @param connection
179*12879e75SMatthias Ringwald  * @param service_uuid16
180*12879e75SMatthias Ringwald  * @param service_start_handle
181*12879e75SMatthias Ringwald  * @param service_end_handle
182*12879e75SMatthias Ringwald  * @param service_index
183*12879e75SMatthias Ringwald  * @param characteristics
184*12879e75SMatthias Ringwald  * @param characteristics_num
185*12879e75SMatthias Ringwald  * @return
186*12879e75SMatthias Ringwald  */
187*12879e75SMatthias Ringwald uint8_t
188*12879e75SMatthias Ringwald gatt_service_client_connect_secondary_service_with_uuid16(hci_con_handle_t con_handle, gatt_service_client_t *client,
189*12879e75SMatthias Ringwald                                                           gatt_service_client_connection_t *connection,
190*12879e75SMatthias Ringwald                                                           uint16_t service_uuid16, uint8_t service_index,
191*12879e75SMatthias Ringwald                                                           uint16_t service_start_handle, uint16_t service_end_handle,
192*12879e75SMatthias Ringwald                                                           gatt_service_client_characteristic_t *characteristics,
193*12879e75SMatthias Ringwald                                                           uint8_t characteristics_num);
194*12879e75SMatthias Ringwald 
195*12879e75SMatthias Ringwald /**
196*12879e75SMatthias Ringwald  * @brief Disconnect service client
197*12879e75SMatthias Ringwald  * @param client
198*12879e75SMatthias Ringwald  * @param connection
199*12879e75SMatthias Ringwald  * @return
200*12879e75SMatthias Ringwald  */
201*12879e75SMatthias Ringwald uint8_t gatt_service_client_disconnect(gatt_service_client_connection_t *connection);
202*12879e75SMatthias Ringwald 
203*12879e75SMatthias Ringwald /**
204*12879e75SMatthias Ringwald  * @brief Check if Characteristic is available and can be queried
205*12879e75SMatthias Ringwald  * @param client
206*12879e75SMatthias Ringwald  * @param connection
207*12879e75SMatthias Ringwald  * @param characteristic_index
208*12879e75SMatthias Ringwald  * @return ERROR_CODE_SUCCESS if ready, ERROR_CODE_COMMAND_DISALLOWED or ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE otherwise
209*12879e75SMatthias Ringwald  */
210*12879e75SMatthias Ringwald uint8_t
211*12879e75SMatthias Ringwald gatt_service_client_can_query_characteristic(const gatt_service_client_connection_t *connection,
212*12879e75SMatthias Ringwald                                              uint8_t characteristic_index);
213*12879e75SMatthias Ringwald 
214*12879e75SMatthias Ringwald /**
215*12879e75SMatthias Ringwald  * @brief Get Characteristic Value Handle for given Characteristic index
216*12879e75SMatthias Ringwald  * *
217*12879e75SMatthias Ringwald  * @param connection
218*12879e75SMatthias Ringwald  * @param characteristic_index
219*12879e75SMatthias Ringwald  * @return
220*12879e75SMatthias Ringwald  */
221*12879e75SMatthias Ringwald uint16_t gatt_service_client_characteristic_value_handle_for_index(const gatt_service_client_connection_t *connection,
222*12879e75SMatthias Ringwald                                                                    uint8_t characteristic_index);
223*12879e75SMatthias Ringwald 
224*12879e75SMatthias Ringwald /**
225*12879e75SMatthias Ringwald  * @brief Get Characteristic index Handle for given Characteristic Value Handle
226*12879e75SMatthias Ringwald  * *
227*12879e75SMatthias Ringwald  * @param connection
228*12879e75SMatthias Ringwald  * @param value_handle
229*12879e75SMatthias Ringwald  * @return index of characteristic in initial list or GATT_SERVICE_CLIENT_INVALID_INDEX
230*12879e75SMatthias Ringwald  */
231*12879e75SMatthias Ringwald uint8_t gatt_service_client_characteristic_index_for_value_handle(const gatt_service_client_connection_t *connection,
232*12879e75SMatthias Ringwald                                                                   uint16_t value_handle);
233*12879e75SMatthias Ringwald 
234*12879e75SMatthias Ringwald /**
235*12879e75SMatthias Ringwald  * @brief Get connection id
236*12879e75SMatthias Ringwald  * @param client
237*12879e75SMatthias Ringwald  * @param connection
238*12879e75SMatthias Ringwald  * @returns connection_id
239*12879e75SMatthias Ringwald  */
240*12879e75SMatthias Ringwald uint16_t gatt_service_client_get_connection_id(const gatt_service_client_connection_t * connection);
241*12879e75SMatthias Ringwald 
242*12879e75SMatthias Ringwald /**
243*12879e75SMatthias Ringwald  * @brief Get connection handle
244*12879e75SMatthias Ringwald  * @param client
245*12879e75SMatthias Ringwald  * @param connection
246*12879e75SMatthias Ringwald  * @returns con_handle
247*12879e75SMatthias Ringwald  */
248*12879e75SMatthias Ringwald hci_con_handle_t gatt_service_client_get_con_handle(const gatt_service_client_connection_t * connection);
249*12879e75SMatthias Ringwald 
250*12879e75SMatthias Ringwald /**
251*12879e75SMatthias Ringwald  * @brief Get service index provided in connect call
252*12879e75SMatthias Ringwald  * @param client
253*12879e75SMatthias Ringwald  * @param connection
254*12879e75SMatthias Ringwald  * @returns connection_id
255*12879e75SMatthias Ringwald  */
256*12879e75SMatthias Ringwald uint8_t gatt_service_client_get_service_index(const gatt_service_client_connection_t * connection);
257*12879e75SMatthias Ringwald 
258*12879e75SMatthias Ringwald /**
259*12879e75SMatthias Ringwald  * @brief Get remote MTU
260*12879e75SMatthias Ringwald  * @param client
261*12879e75SMatthias Ringwald  * @param connection
262*12879e75SMatthias Ringwald  * @returns MTU or 0 in case of error
263*12879e75SMatthias Ringwald  */
264*12879e75SMatthias Ringwald uint16_t gatt_service_client_get_mtu(const gatt_service_client_connection_t *connection);
265*12879e75SMatthias Ringwald 
266*12879e75SMatthias Ringwald 
267*12879e75SMatthias Ringwald /**
268*12879e75SMatthias Ringwald  * @brief Dump characteristic value handles
269*12879e75SMatthias Ringwald  * @param client
270*12879e75SMatthias Ringwald  * @param connection
271*12879e75SMatthias Ringwald  * @param characteristic_names
272*12879e75SMatthias Ringwald  */
273*12879e75SMatthias Ringwald void gatt_service_client_dump_characteristic_value_handles(const gatt_service_client_connection_t *connection,
274*12879e75SMatthias Ringwald                                                            const char **characteristic_names);
275*12879e75SMatthias Ringwald 
276*12879e75SMatthias Ringwald /**
277*12879e75SMatthias Ringwald  * @brief De-Init
278*12879e75SMatthias Ringwald  * @param client
279*12879e75SMatthias Ringwald  */
280*12879e75SMatthias Ringwald void gatt_service_client_deinit(void);
281*12879e75SMatthias Ringwald 
282*12879e75SMatthias Ringwald 
283*12879e75SMatthias Ringwald /* API_END */
284*12879e75SMatthias Ringwald 
285*12879e75SMatthias Ringwald #if defined __cplusplus
286*12879e75SMatthias Ringwald }
287*12879e75SMatthias Ringwald #endif
288*12879e75SMatthias Ringwald 
289*12879e75SMatthias Ringwald #endif
290