xref: /btstack/src/ble/gatt_client.h (revision 98e87e7776ef9a7fe55135aea8cddc761fe3a7a5)
1 /*
2  * Copyright (C) 2014 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 Client
40  *
41  */
42 
43 #ifndef btstack_gatt_client_h
44 #define btstack_gatt_client_h
45 
46 #include "hci.h"
47 
48 #if defined __cplusplus
49 extern "C" {
50 #endif
51 
52 typedef enum {
53     P_READY,
54     P_W2_SEND_SERVICE_QUERY,
55     P_W4_SERVICE_QUERY_RESULT,
56     P_W2_SEND_SERVICE_WITH_UUID_QUERY,
57     P_W4_SERVICE_WITH_UUID_RESULT,
58 
59     P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY,
60     P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT,
61     P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY,
62     P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT,
63 
64     P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY,
65     P_W4_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT,
66 
67     P_W2_SEND_INCLUDED_SERVICE_QUERY,
68     P_W4_INCLUDED_SERVICE_QUERY_RESULT,
69     P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY,
70     P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT,
71 
72     P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY,
73     P_W4_READ_CHARACTERISTIC_VALUE_RESULT,
74 
75     P_W2_SEND_READ_BLOB_QUERY,
76     P_W4_READ_BLOB_RESULT,
77 
78     P_W2_SEND_READ_BY_TYPE_REQUEST,
79     P_W4_READ_BY_TYPE_RESPONSE,
80 
81     P_W2_SEND_READ_MULTIPLE_REQUEST,
82     P_W4_READ_MULTIPLE_RESPONSE,
83 
84     P_W2_SEND_READ_MULTIPLE_VARIABLE_REQUEST,
85     P_W4_READ_MULTIPLE_VARIABLE_RESPONSE,
86 
87     P_W2_SEND_WRITE_CHARACTERISTIC_VALUE,
88     P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT,
89 
90     P_W2_PREPARE_WRITE,
91     P_W4_PREPARE_WRITE_RESULT,
92     P_W2_PREPARE_RELIABLE_WRITE,
93     P_W4_PREPARE_RELIABLE_WRITE_RESULT,
94 
95     P_W2_EXECUTE_PREPARED_WRITE,
96     P_W4_EXECUTE_PREPARED_WRITE_RESULT,
97     P_W2_CANCEL_PREPARED_WRITE,
98     P_W4_CANCEL_PREPARED_WRITE_RESULT,
99     P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH,
100     P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT,
101 
102 #ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
103     P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY,
104     P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT,
105 #else
106     P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY,
107     P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT,
108 #endif
109     P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION,
110     P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT,
111 
112     P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY,
113     P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT,
114 
115     P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY,
116     P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT,
117 
118     P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR,
119     P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT,
120 
121     // all long writes use this
122     P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR,
123     P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT,
124     P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR,
125     P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT,
126 
127     // gatt reliable write API use this (manual version of the above)
128     P_W2_PREPARE_WRITE_SINGLE,
129     P_W4_PREPARE_WRITE_SINGLE_RESULT,
130 
131     P_W4_IDENTITY_RESOLVING,
132     P_W4_CMAC_READY,
133     P_W4_CMAC_RESULT,
134     P_W2_SEND_SIGNED_WRITE,
135     P_W4_SEND_SINGED_WRITE_DONE,
136 
137     P_W2_SDP_QUERY,
138     P_W4_SDP_QUERY,
139     P_W4_L2CAP_CONNECTION,
140 } gatt_client_state_t;
141 
142 
143 typedef enum{
144     SEND_MTU_EXCHANGE,
145     SENT_MTU_EXCHANGE,
146     MTU_EXCHANGED,
147     MTU_AUTO_EXCHANGE_DISABLED
148 } gatt_client_mtu_t;
149 
150 #ifdef ENABLE_GATT_OVER_EATT
151 typedef enum {
152     GATT_CLIENT_EATT_IDLE,
153     GATT_CLIENT_EATT_DISCOVER_GATT_SERVICE_W2_SEND,
154     GATT_CLIENT_EATT_DISCOVER_GATT_SERVICE_W4_DONE,
155     GATT_CLIENT_EATT_READ_SERVER_SUPPORTED_FEATURES_W2_SEND,
156     GATT_CLIENT_EATT_READ_SERVER_SUPPORTED_FEATURES_W4_DONE,
157     GATT_CLIENT_EATT_FIND_CLIENT_SUPPORTED_FEATURES_W2_SEND,
158     GATT_CLIENT_EATT_FIND_CLIENT_SUPPORTED_FEATURES_W4_DONE,
159     GATT_CLIENT_EATT_WRITE_ClIENT_SUPPORTED_FEATURES_W2_SEND,
160     GATT_CLIENT_EATT_WRITE_ClIENT_SUPPORTED_FEATURES_W4_DONE,
161     GATT_CLIENT_EATT_L2CAP_SETUP,
162     GATT_CLIENT_EATT_READY,
163 } gatt_client_eatt_state_t;
164 #endif
165 
166 typedef struct gatt_client{
167     btstack_linked_item_t    item;
168     // TODO: rename gatt_client_state -> state
169     gatt_client_state_t gatt_client_state;
170 
171     // user callback
172     btstack_packet_handler_t callback;
173 
174     // can write without response callback
175     btstack_packet_handler_t write_without_response_callback;
176 
177     // can write without response requests
178     btstack_linked_list_t write_without_response_requests;
179 
180     // regular gatt query requests
181     btstack_linked_list_t query_requests;
182 
183     hci_con_handle_t con_handle;
184 
185     att_bearer_type_t bearer_type;
186 
187 #ifdef ENABLE_GATT_OVER_CLASSIC
188     bd_addr_t addr;
189     uint16_t  l2cap_psm;
190     uint16_t  l2cap_cid;
191     btstack_context_callback_registration_t sdp_query_request;
192 #endif
193 
194 #ifdef ENABLE_GATT_OVER_EATT
195     gatt_client_eatt_state_t eatt_state;
196     btstack_linked_list_t eatt_clients;
197     uint8_t * eatt_storage_buffer;
198     uint16_t eatt_storage_size;
199     uint8_t  eatt_num_clients;
200     uint8_t  gatt_server_supported_features;
201     uint16_t gatt_service_start_group_handle;
202     uint16_t gatt_service_end_group_handle;
203     uint16_t gatt_client_supported_features_handle;
204 #endif
205 
206     uint16_t          mtu;
207     gatt_client_mtu_t mtu_state;
208 
209     uint16_t uuid16;
210     uint8_t  uuid128[16];
211 
212     uint16_t start_group_handle;
213     uint16_t end_group_handle;
214 
215     uint16_t query_start_handle;
216     uint16_t query_end_handle;
217 
218     uint8_t  characteristic_properties;
219     uint16_t characteristic_start_handle;
220 
221     uint16_t attribute_handle;
222     uint16_t attribute_offset;
223     uint16_t attribute_length;
224     uint8_t* attribute_value;
225 
226     // read multiple characteristic values
227     uint16_t    read_multiple_handle_count;
228     uint16_t  * read_multiple_handles;
229 
230     uint16_t client_characteristic_configuration_handle;
231     uint8_t  client_characteristic_configuration_value[2];
232 
233     uint8_t  filter_with_uuid;
234     uint8_t  send_confirmation;
235 
236     int      le_device_index;
237     uint8_t  cmac[8];
238 
239     btstack_timer_source_t gc_timeout;
240 
241     uint8_t  security_counter;
242     uint8_t  wait_for_authentication_complete;
243     uint8_t  pending_error_code;
244 
245     bool     reencryption_active;
246     uint8_t  reencryption_result;
247 
248     gap_security_level_t security_level;
249 
250 } gatt_client_t;
251 
252 typedef struct gatt_client_notification {
253     btstack_linked_item_t    item;
254     btstack_packet_handler_t callback;
255     hci_con_handle_t con_handle;
256     uint16_t attribute_handle;
257 } gatt_client_notification_t;
258 
259 /* API_START */
260 
261 typedef struct {
262     uint16_t start_group_handle;
263     uint16_t end_group_handle;
264     uint16_t uuid16;
265     uint8_t  uuid128[16];
266 } gatt_client_service_t;
267 
268 typedef struct {
269     uint16_t start_handle;
270     uint16_t value_handle;
271     uint16_t end_handle;
272     uint16_t properties;
273     uint16_t uuid16;
274     uint8_t  uuid128[16];
275 } gatt_client_characteristic_t;
276 
277 typedef struct {
278     uint16_t handle;
279     uint16_t uuid16;
280     uint8_t  uuid128[16];
281 } gatt_client_characteristic_descriptor_t;
282 
283 /**
284  * @brief Set up GATT client.
285  */
286 void gatt_client_init(void);
287 
288 /**
289  * @brief Set minimum required security level for GATT Client
290  * @note  The Bluetooth specification makes the GATT Server responsible to check for security.
291  *        This allows an attacker to spoof an existing device with a GATT Servers, but skip the authentication part.
292  *        If your application is exchanging sensitive data with a remote device, you would need to manually check
293  *        the security level before sending/receive such data.
294  *        With level > 0, the GATT Client triggers authentication for all GATT Requests and defers any exchange
295  *        until the required security level is established.
296  *        gatt_client_request_can_write_without_response_event does not trigger authentication
297  *        gatt_client_request_to_write_without_response does not trigger authentication
298  *  @pram level, default LEVEL_0 (no encryption required)
299  */
300 void gatt_client_set_required_security_level(gap_security_level_t level);
301 
302 /**
303  * @brief Connect to remote GATT Server over Classic (BR/EDR) Connection
304  *        GATT_EVENT_CONNECTED with status and con_handle for other API functions
305  *        is emitted on connection complete.
306  * @note requires ENABLE_GATT_OVER_CLASSIC.
307  * @param addr
308  * @return status
309  */
310 uint8_t gatt_client_classic_connect(btstack_packet_handler_t callback, bd_addr_t addr);
311 
312 /**
313  * @brief Disconnect o Classic (BR/EDR) connection to a remote GATT Server
314  * @note requires ENABLE_GATT_OVER_CLASSIC
315  * @param con_handle
316  * @return status
317  */
318 uint8_t gatt_client_classic_disconnect(btstack_packet_handler_t callback, hci_con_handle_t con_handle);
319 
320 /**
321  * @brief Setup Enhanced LE Bearer with up to 5 channels on existing LE connection
322  * @param callback for GATT_EVENT_CONNECTED and GATT_EVENT_DISCONNECTED events
323  * @param con_handle
324  * @param num_channels
325  * @param storage_buffer for L2CAP connection
326  * @param storage_size - each channel requires (2 * ATT MTU) + 10 bytes
327  * @return
328  */
329 uint8_t gatt_client_le_enhanced_connect(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint8_t num_channels, uint8_t * storage_buffer, uint16_t storage_size);
330 
331 /**
332  * @brief MTU is available after the first query has completed. If status is equal to ERROR_CODE_SUCCESS, it returns the real value,
333  * otherwise the default value ATT_DEFAULT_MTU (see bluetooth.h).
334  * @param  con_handle
335  * @param  mtu
336  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
337  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
338  *                GATT_CLIENT_IN_WRONG_STATE                                if MTU is not exchanged and MTU auto-exchange is disabled
339  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
340  */
341 uint8_t gatt_client_get_mtu(hci_con_handle_t con_handle, uint16_t * mtu);
342 
343 /**
344  * @brief Sets whether a MTU Exchange Request shall be automatically send before the
345  * first attribute read request is send. Default is enabled.
346  * @param enabled
347  */
348 void gatt_client_mtu_enable_auto_negotiation(uint8_t enabled);
349 
350 /**
351  * @brief Sends a MTU Exchange Request, this allows for the client to exchange MTU
352  * when gatt_client_mtu_enable_auto_negotiation is disabled.
353  * @param  callback
354  * @param  con_handle
355  */
356 void gatt_client_send_mtu_negotiation(btstack_packet_handler_t callback, hci_con_handle_t con_handle);
357 
358 /**
359  * @brief Returns 1 if the GATT client is ready to receive a query. It is used with daemon.
360  * @param  con_handle
361  * @return is_ready_status     0 - if no GATT client for con_handle is found, or is not ready, otherwise 1
362  */
363 int gatt_client_is_ready(hci_con_handle_t con_handle);
364 
365 /**
366  * @brief Discovers all primary services.
367  * For each found service a GATT_EVENT_SERVICE_QUERY_RESULT event will be emitted.
368  * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery.
369  * @param  callback
370  * @param  con_handle
371  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
372  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
373  *                ERROR_CODE_SUCCESS         , if query is successfully registered
374  */
375 uint8_t gatt_client_discover_primary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle);
376 
377 /**
378  * @brief Discovers all secondary services.
379  * For each found service a GATT_EVENT_SERVICE_QUERY_RESULT event will be emitted.
380  * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery.
381  * @param  callback
382  * @param  con_handle
383  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
384  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
385  *                ERROR_CODE_SUCCESS         , if query is successfully registered
386  */
387 uint8_t gatt_client_discover_secondary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle);
388 
389 /**
390  * @brief Discovers a specific primary service given its UUID. This service may exist multiple times.
391  * For each found service a GATT_EVENT_SERVICE_QUERY_RESULT event will be emitted.
392  * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery.
393  * @param callback
394  * @param con_handle
395  * @param uuid16
396  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
397  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
398  *                ERROR_CODE_SUCCESS         , if query is successfully registered
399  */
400 uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16);
401 
402 /**
403  * @brief Discovers a specific primary service given its UUID. This service may exist multiple times.
404  * For each found service a GATT_EVENT_SERVICE_QUERY_RESULT event will be emitted.
405  * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery.
406  * @param  callback
407  * @param  con_handle
408  * @param  uuid128
409  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
410  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
411  *                ERROR_CODE_SUCCESS         , if query is successfully registered
412  */
413 uint8_t gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, const uint8_t * uuid128);
414 
415 /**
416  * @brief Finds included services within the specified service.
417  * For each found included service a GATT_EVENT_INCLUDED_SERVICE_QUERY_RESULT event will be emitted.
418  * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery.
419  * Information about included service type (primary/secondary) can be retrieved either by sending
420  * an ATT find information request for the returned start group handle
421  * (returning the handle and the UUID for primary or secondary service) or by comparing the service
422  * to the list of all primary services.
423  * @param  callback
424  * @param  con_handle
425  * @param  service
426  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
427  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
428  *                ERROR_CODE_SUCCESS         , if query is successfully registered
429  */
430 uint8_t gatt_client_find_included_services_for_service(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service);
431 
432 /**
433  * @brief Discovers all characteristics within the specified service.
434  * For each found characteristic a GATT_EVENT_CHARACTERISTIC_QUERY_RESULT event will be emited.
435  * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery.
436  * @param  callback
437  * @param  con_handle
438  * @param  service
439  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
440  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
441  *                ERROR_CODE_SUCCESS         , if query is successfully registered
442  */
443 uint8_t gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service);
444 
445 /**
446  * @brief The following four functions are used to discover all characteristics within
447  * the specified service or handle range, and return those that match the given UUID.
448  *
449  * For each found characteristic a GATT_EVENT_CHARACTERISTIC_QUERY_RESULT event will emitted.
450  * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery.
451  * @param  callback
452  * @param  con_handle
453  * @param  start_handle
454  * @param  end_handle
455  * @param  uuid16
456  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
457  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
458  *                ERROR_CODE_SUCCESS         , if query is successfully registered
459  */
460 uint8_t gatt_client_discover_characteristics_for_handle_range_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t start_handle, uint16_t end_handle, uint16_t uuid16);
461 
462 /**
463  * @brief The following four functions are used to discover all characteristics within the
464  * specified service or handle range, and return those that match the given UUID.
465  * For each found characteristic a GATT_EVENT_CHARACTERISTIC_QUERY_RESULT event will emitted.
466  * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery.
467  * @param  callback
468  * @param  con_handle
469  * @param  start_handle
470  * @param  end_handle
471  * @param  uuid128
472  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
473  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
474  *                ERROR_CODE_SUCCESS         , if query is successfully registered
475  */
476 uint8_t gatt_client_discover_characteristics_for_handle_range_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t start_handle, uint16_t end_handle, const uint8_t * uuid128);
477 
478 /**
479  * @brief The following four functions are used to discover all characteristics within the
480  * specified service or handle range, and return those that match the given UUID.
481  * For each found characteristic a GATT_EVENT_CHARACTERISTIC_QUERY_RESULT event will emitted.
482  * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery.
483  * @param  callback
484  * @param  con_handle
485  * @param  service
486  * @param  uuid16
487  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
488  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
489  *                ERROR_CODE_SUCCESS         , if query is successfully registered
490  */
491 uint8_t gatt_client_discover_characteristics_for_service_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service, uint16_t uuid16);
492 
493 /**
494  * @brief The following four functions are used to discover all characteristics within the
495  * specified service or handle range, and return those that match the given UUID.
496  * For each found characteristic a GATT_EVENT_CHARACTERISTIC_QUERY_RESULT event will emitted.
497  * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery.
498  * @param  callback
499  * @param  con_handle
500  * @param  service
501  * @param  uuid128
502  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
503  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
504  *                ERROR_CODE_SUCCESS         , if query is successfully registered
505  */
506 uint8_t gatt_client_discover_characteristics_for_service_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service, const uint8_t * uuid128);
507 
508 /**
509  * @brief Discovers attribute handle and UUID of a characteristic descriptor within the specified characteristic.
510  * For each found descriptor a GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT event will be emitted.
511  *
512  * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery.
513  * @param  callback
514  * @param  con_handle
515  * @param  characteristic
516  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
517  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
518  *                ERROR_CODE_SUCCESS         , if query is successfully registered
519  */
520 uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic);
521 
522 /**
523  * @brief Reads the characteristic value using the characteristic's value handle.
524  * If the characteristic value is found a GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT event will be emitted.
525  * The GATT_EVENT_QUERY_COMPLETE event marks the end of read.
526  * @param  callback
527  * @param  con_handle
528  * @param  characteristic
529  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
530  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
531  *                ERROR_CODE_SUCCESS         , if query is successfully registered
532  */
533 uint8_t gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic);
534 
535 /**
536  * @brief Reads the characteristic value using the characteristic's value handle.
537  * If the characteristic value is found a GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT event will be emitted.
538  * The GATT_EVENT_QUERY_COMPLETE event marks the end of read.
539  * @param  callback
540  * @param  con_handle
541  * @param  value_handle
542  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
543  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
544  *                ERROR_CODE_SUCCESS         , if query is successfully registered
545  */
546 uint8_t gatt_client_read_value_of_characteristic_using_value_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle);
547 
548 /**
549  * @brief Reads the characteric value of all characteristics with the uuid.
550  * For each characteristic value found a GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT event will be emitted.
551  * The GATT_EVENT_QUERY_COMPLETE event marks the end of read.
552  * @param  callback
553  * @param  con_handle
554  * @param  start_handle
555  * @param  end_handle
556  * @param  uuid16
557  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
558  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
559  *                ERROR_CODE_SUCCESS         , if query is successfully registered
560  */
561 uint8_t gatt_client_read_value_of_characteristics_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t start_handle, uint16_t end_handle, uint16_t uuid16);
562 
563 /**
564  * @brief Reads the characteric value of all characteristics with the uuid.
565  * For each characteristic value found a GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT event will be emitted.
566  * The GATT_EVENT_QUERY_COMPLETE event marks the end of read.
567  * @param  callback
568  * @param  con_handle
569  * @param  start_handle
570  * @param  end_handle
571  * @param  uuid128
572  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
573  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
574  *                ERROR_CODE_SUCCESS         , if query is successfully registered
575  */
576 uint8_t gatt_client_read_value_of_characteristics_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t start_handle, uint16_t end_handle, const uint8_t * uuid128);
577 
578 /**
579  * @brief Reads the long characteristic value using the characteristic's value handle.
580  * The value will be returned in several blobs.
581  * For each blob, a GATT_EVENT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT event with updated value offset will be emitted.
582  * The GATT_EVENT_QUERY_COMPLETE event marks the end of read.
583  * @param  callback
584  * @param  con_handle
585  * @param  characteristic
586  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
587  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
588  *                ERROR_CODE_SUCCESS         , if query is successfully registered
589  */
590 uint8_t gatt_client_read_long_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic);
591 
592 /**
593  * @brief Reads the long characteristic value using the characteristic's value handle.
594  * The value will be returned in several blobs.
595  * For each blob, a GATT_EVENT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT event with updated value offset will be emitted.
596  * The GATT_EVENT_QUERY_COMPLETE event marks the end of read.
597  * @param  callback
598  * @param  con_handle
599  * @param  value_handle
600  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
601  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
602  *                ERROR_CODE_SUCCESS         , if query is successfully registered
603  */
604 uint8_t gatt_client_read_long_value_of_characteristic_using_value_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle);
605 
606 /**
607  * @brief Reads the long characteristic value using the characteristic's value handle.
608  * The value will be returned in several blobs.
609  * For each blob, a GATT_EVENT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT event with updated value offset will be emitted.
610  * The GATT_EVENT_QUERY_COMPLETE event marks the end of read.
611  * @param  callback
612  * @param  con_handle
613  * @param  value_handle
614  * @param  offset
615  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
616  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
617  *                ERROR_CODE_SUCCESS         , if query is successfully registered
618  */
619 uint8_t gatt_client_read_long_value_of_characteristic_using_value_handle_with_offset(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, uint16_t offset);
620 
621 /*
622  * @brief Read multiple characteristic values.
623  * The all results are emitted via single GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT event,
624  * followed by the GATT_EVENT_QUERY_COMPLETE event, which marks the end of read.
625  * @param  callback
626  * @param  con_handle
627  * @param  num_value_handles
628  * @param  value_handles list of handles
629  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
630  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
631  *                ERROR_CODE_SUCCESS         , if query is successfully registered
632  */
633 uint8_t gatt_client_read_multiple_characteristic_values(btstack_packet_handler_t callback, hci_con_handle_t con_handle, int num_value_handles, uint16_t * value_handles);
634 
635 /*
636  * @brief Read multiple varaible characteristic values. Only supported over LE Enhanced Bearer
637  * The all results are emitted via single GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT event,
638  * followed by the GATT_EVENT_QUERY_COMPLETE event, which marks the end of read.
639  * @param  callback
640  * @param  con_handle
641  * @param  num_value_handles
642  * @param  value_handles list of handles
643  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
644  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
645  *                ERROR_CODE_SUCCESS         , if query is successfully registered
646  */
647 uint8_t gatt_client_read_multiple_variable_characteristic_values(btstack_packet_handler_t callback, hci_con_handle_t con_handle, int num_value_handles, uint16_t * value_handles);
648 
649 /**
650  * @brief Writes the characteristic value using the characteristic's value handle without
651  * an acknowledgment that the write was successfully performed.
652  * @param  con_handle
653  * @param  value_handle
654  * @param  value_length
655  * @param  value is copied on success and does not need to be retained
656  * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found
657  *                GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready
658  *                BTSTACK_ACL_BUFFERS_FULL   , if L2CAP cannot send, there are no free ACL slots
659  *                ERROR_CODE_SUCCESS         , if query is successfully registered
660  */
661 uint8_t gatt_client_write_value_of_characteristic_without_response(hci_con_handle_t con_handle, uint16_t value_handle, uint16_t value_length, uint8_t * value);
662 
663 /**
664  * @brief Writes the authenticated characteristic value using the characteristic's value handle
665  * without an acknowledgment that the write was successfully performed.
666  * @note GATT_EVENT_QUERY_COMPLETE is emitted with ATT_ERROR_SUCCESS for success,
667  * or ATT_ERROR_BONDING_INFORMATION_MISSING if there is no bonding information stored.
668  * @param  callback
669  * @param  con_handle
670  * @param  value_handle
671  * @param  message_len
672  * @param  message is not copied, make sure memory is accessible until write is done
673  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
674  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
675  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
676  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
677  */
678 uint8_t gatt_client_signed_write_without_response(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, uint16_t message_len, uint8_t * message);
679 
680 /**
681  * @brief Writes the characteristic value using the characteristic's value handle.
682  * The GATT_EVENT_QUERY_COMPLETE event marks the end of write.
683  * The write is successfully performed, if the event's att_status field is set to
684  * ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes).
685  * @param  callback
686  * @param  con_handle
687  * @param  value_handle
688  * @param  value_length
689  * @param  value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received
690  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
691  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
692  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
693  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
694  */
695 uint8_t gatt_client_write_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, uint16_t value_length, uint8_t * value);
696 
697 /**
698  * @brief Writes the characteristic value using the characteristic's value handle.
699  * The GATT_EVENT_QUERY_COMPLETE event marks the end of write.
700  * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes).
701  * @param  callback
702  * @param  con_handle
703  * @param  value_handle
704  * @param  value_length
705  * @param  value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received
706  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
707  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
708  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
709  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
710  */
711 uint8_t gatt_client_write_long_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, uint16_t value_length, uint8_t * value);
712 
713 /**
714  * @brief Writes the characteristic value using the characteristic's value handle.
715  * The GATT_EVENT_QUERY_COMPLETE event marks the end of write.
716  * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes).
717  * @param  callback
718  * @param  con_handle
719  * @param  value_handle
720  * @param  offset of value
721  * @param  value_length
722  * @param  value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received
723  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
724  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
725  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
726  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
727  */
728 uint8_t gatt_client_write_long_value_of_characteristic_with_offset(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, uint16_t offset, uint16_t value_length, uint8_t * value);
729 
730 /**
731  * @brief Writes of the long characteristic value using the characteristic's value handle.
732  * It uses server response to validate that the write was correctly received.
733  * The GATT_EVENT_QUERY_COMPLETE EVENT marks the end of write.
734  * The write is successfully performed, if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes).
735  * @param  callback
736  * @param  con_handle
737  * @param  value_handle
738  * @param  value_length
739  * @param  value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received
740  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
741  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
742  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
743  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
744  */
745 uint8_t gatt_client_reliable_write_long_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, uint16_t value_length, uint8_t * value);
746 
747 /**
748  * @brief Reads the characteristic descriptor using its handle.
749  * If the characteristic descriptor is found, a GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT event will be emitted.
750  * The GATT_EVENT_QUERY_COMPLETE event marks the end of read.
751  * @param  callback
752  * @param  con_handle
753  * @param  descriptor
754  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
755  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
756  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
757  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
758  */
759 uint8_t gatt_client_read_characteristic_descriptor(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_descriptor_t * descriptor);
760 
761 /**
762  * @brief Reads the characteristic descriptor using its handle.
763  * If the characteristic descriptor is found, a GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT event will be emitted.
764  * The GATT_EVENT_QUERY_COMPLETE event marks the end of read.
765  * @param  callback
766  * @param  con_handle
767  * @param  descriptor
768  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
769  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
770  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
771  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
772  */
773 uint8_t gatt_client_read_characteristic_descriptor_using_descriptor_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t descriptor_handle);
774 
775 /**
776  * @brief Reads the long characteristic descriptor using its handle. It will be returned in several blobs.
777  * For each blob, a GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT event will be emitted.
778  * The GATT_EVENT_QUERY_COMPLETE event marks the end of read.
779  * @param  callback
780  * @param  con_handle
781  * @param  descriptor
782  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
783  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
784  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
785  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
786  */
787 uint8_t gatt_client_read_long_characteristic_descriptor(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_descriptor_t * descriptor);
788 
789 /**
790  * @brief Reads the long characteristic descriptor using its handle. It will be returned in several blobs.
791  * For each blob, a GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT event will be emitted.
792  * The GATT_EVENT_QUERY_COMPLETE event marks the end of read.
793  * @param  callback
794  * @param  con_handle
795  * @param  descriptor_handle
796  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
797  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
798  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
799  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
800  */
801 uint8_t gatt_client_read_long_characteristic_descriptor_using_descriptor_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t descriptor_handle);
802 
803 /**
804  * @brief Reads the long characteristic descriptor using its handle. It will be returned in several blobs.
805  * For each blob, a GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT event will be emitted.
806  * The GATT_EVENT_QUERY_COMPLETE event marks the end of read.
807  * @param  callback
808  * @param  con_handle
809  * @param  descriptor_handle
810  * @param  offset
811  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
812  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
813  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
814  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
815  */
816 uint8_t gatt_client_read_long_characteristic_descriptor_using_descriptor_handle_with_offset(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t descriptor_handle, uint16_t offset);
817 
818 /**
819  * @brief Writes the characteristic descriptor using its handle.
820  * The GATT_EVENT_QUERY_COMPLETE event marks the end of write.
821  * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes).
822  * @param  callback
823  * @param  con_handle
824  * @param  descriptor
825  * @param  value_length
826  * @param  value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received
827  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
828  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
829  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
830  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
831  */
832 uint8_t gatt_client_write_characteristic_descriptor(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_descriptor_t * descriptor, uint16_t value_length, uint8_t * value);
833 
834 /**
835  * @brief Writes the characteristic descriptor using its handle.
836  * The GATT_EVENT_QUERY_COMPLETE event marks the end of write.
837  * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes).
838  * @param  callback
839  * @param  con_handle
840  * @param  descriptor_handle
841  * @param  value_length
842  * @param  value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received
843  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
844  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
845  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
846  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
847  */
848 uint8_t gatt_client_write_characteristic_descriptor_using_descriptor_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t descriptor_handle, uint16_t value_length, uint8_t * value);
849 
850 /**
851  * @brief Writes the characteristic descriptor using its handle.
852  * The GATT_EVENT_QUERY_COMPLETE event marks the end of write.
853  * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes).
854  * @param  callback
855  * @param  con_handle
856  * @param  descriptor
857  * @param  value_length
858  * @param  value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received
859  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
860  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
861  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
862  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
863  */
864 uint8_t gatt_client_write_long_characteristic_descriptor(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_descriptor_t * descriptor, uint16_t value_length, uint8_t * value);
865 
866 /**
867  * @brief Writes the characteristic descriptor using its handle.
868  * The GATT_EVENT_QUERY_COMPLETE event marks the end of write.
869  * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes).
870  * @param  callback
871  * @param  con_handle
872  * @param  descriptor_handle
873  * @param  value_length
874  * @param  value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received
875  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
876  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
877  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
878  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
879  */
880 uint8_t gatt_client_write_long_characteristic_descriptor_using_descriptor_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t descriptor_handle, uint16_t value_length, uint8_t * value);
881 
882 /**
883  * @brief Writes the characteristic descriptor using its handle.
884  * The GATT_EVENT_QUERY_COMPLETE event marks the end of write.
885  * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes).
886  * @param  callback
887  * @param  con_handle
888  * @param  descriptor_handle
889  * @param  offset of value
890  * @param  value_length
891  * @param  value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received
892  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
893  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
894  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
895  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
896  */
897 uint8_t gatt_client_write_long_characteristic_descriptor_using_descriptor_handle_with_offset(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t descriptor_handle, uint16_t offset, uint16_t value_length, uint8_t * value);
898 
899 /**
900  * @brief Writes the client characteristic configuration of the specified characteristic.
901  * It is used to subscribe for notifications or indications of the characteristic value.
902  * For notifications or indications specify: GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION
903  * resp. GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION as configuration value.
904  * The GATT_EVENT_QUERY_COMPLETE event marks the end of write.
905  * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes).
906  * @param  callback
907  * @param  con_handle
908  * @param  characteristic
909  * @param  configuration                                                    GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION
910  * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER                  if no HCI connection for con_handle is found
911  *                BTSTACK_MEMORY_ALLOC_FAILED                               if no GATT client for con_handle could be allocated
912  *                GATT_CLIENT_IN_WRONG_STATE                                if GATT client is not ready
913  *                GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED     if configuring notification, but characteristic has no notification property set
914  *                GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED       if configuring indication, but characteristic has no indication property set
915  *                ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE         if configuration is invalid
916  *                ERROR_CODE_SUCCESS                                        if query is successfully registered
917  */
918 uint8_t gatt_client_write_client_characteristic_configuration(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic, uint16_t configuration);
919 
920 /**
921  * @brief Register for notifications and indications of a characteristic enabled by
922  * the gatt_client_write_client_characteristic_configuration function.
923  * @param notification struct used to store registration
924  * @param callback
925  * @param con_handle or GATT_CLIENT_ANY_CONNECTION to receive updates from all connected devices
926  * @param characteristic or NULL to receive updates for all characteristics
927  */
928 void gatt_client_listen_for_characteristic_value_updates(gatt_client_notification_t * notification, btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic);
929 
930 /**
931  * @brief Stop listening to characteristic value updates registered with
932  * the gatt_client_listen_for_characteristic_value_updates function.
933  * @param notification struct used in gatt_client_listen_for_characteristic_value_updates
934  */
935 void gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification);
936 
937 /**
938  * @brief Transactional write. It can be called as many times as it is needed to write the characteristics within the same transaction.
939  * Call the gatt_client_execute_write function to commit the transaction.
940  * @param  callback
941  * @param  con_handle
942  * @param  attribute_handle
943  * @param  offset of value
944  * @param  value_length
945  * @param  value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received
946  */
947 uint8_t gatt_client_prepare_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t offset, uint16_t value_length, uint8_t * value);
948 
949 /**
950  * @brief Commit transactional write. GATT_EVENT_QUERY_COMPLETE is received.
951  * @param  callback
952  * @param  con_handle
953  * @return status
954  */
955 uint8_t gatt_client_execute_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle);
956 
957 /**
958  * @brief Abort transactional write. GATT_EVENT_QUERY_COMPLETE is received.
959  * @param  callback
960  * @param  con_handle
961  * @return status
962  */
963 uint8_t gatt_client_cancel_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle);
964 
965 /**
966  * @brief Request callback when regular gatt query can be sent
967  * @note callback might happen during call to this function
968  * @param callback_registration to point to callback function and context information
969  * @param con_handle
970  * @return ERROR_CODE_SUCCESS if ok, ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if handle unknown, and ERROR_CODE_COMMAND_DISALLOWED if callback already registered
971  */
972 uint8_t gatt_client_request_to_send_gatt_query(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle);
973 
974 /**
975  * @brief Request callback when writing characteristic value without response is possible
976  * @note callback might happen during call to this function
977  * @param callback_registration to point to callback function and context information
978  * @param con_handle
979  * @return ERROR_CODE_SUCCESS if ok, ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if handle unknown, and ERROR_CODE_COMMAND_DISALLOWED if callback already registered
980  */
981 uint8_t gatt_client_request_to_write_without_response(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle);
982 
983 
984 // the following functions are marked as deprecated and will be removed eventually
985 /**
986  * @brief Requests GATT_EVENT_CAN_WRITE_WITHOUT_RESPONSE that guarantees
987  * a single successful gatt_client_write_value_of_characteristic_without_response call.
988  * @deprecated please use gatt_client_request_to_write_without_response instead
989  * @param  callback
990  * @param  con_handle
991  * @return status
992  */
993 uint8_t gatt_client_request_can_write_without_response_event(btstack_packet_handler_t callback, hci_con_handle_t con_handle);
994 
995 
996 /* API_END */
997 
998 // used by generated btstack_event.c
999 
1000 void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t * service);
1001 void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic);
1002 void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor);
1003 
1004 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1005 void gatt_client_att_packet_handler_fuzz(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size);
1006 uint8_t gatt_client_get_client(hci_con_handle_t con_handle, gatt_client_t ** gatt_client);
1007 #endif
1008 
1009 #if defined __cplusplus
1010 }
1011 #endif
1012 
1013 #endif
1014