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