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