xref: /btstack/src/ble/gatt_client.c (revision 7e71cd90741790aea51a44b55df7604bd417df41)
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 #define BTSTACK_FILE__ "gatt_client.c"
39 
40 #include <stdint.h>
41 #include <string.h>
42 #include <stddef.h>
43 
44 #include "btstack_config.h"
45 
46 #include "ble/att_dispatch.h"
47 #include "ad_parser.h"
48 #include "ble/att_db.h"
49 #include "ble/gatt_client.h"
50 #include "ble/le_device_db.h"
51 #include "ble/sm.h"
52 #include "btstack_debug.h"
53 #include "btstack_event.h"
54 #include "btstack_memory.h"
55 #include "btstack_run_loop.h"
56 #include "btstack_util.h"
57 #include "hci.h"
58 #include "hci_dump.h"
59 #include "l2cap.h"
60 
61 static btstack_linked_list_t gatt_client_connections;
62 static btstack_linked_list_t gatt_client_value_listeners;
63 static btstack_packet_callback_registration_t hci_event_callback_registration;
64 static btstack_packet_callback_registration_t sm_event_callback_registration;
65 
66 // GATT Client Configuration
67 static bool                 gatt_client_mtu_exchange_enabled;
68 static gap_security_level_t gatt_client_required_security_level;
69 
70 static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size);
71 static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
72 static void gatt_client_report_error_if_pending(gatt_client_t *gatt_client, uint8_t att_error_code);
73 
74 #ifdef ENABLE_LE_SIGNED_WRITE
75 static void att_signed_write_handle_cmac_result(uint8_t hash[8]);
76 #endif
77 
78 void gatt_client_init(void){
79     gatt_client_connections = NULL;
80 
81     // default configuration
82     gatt_client_mtu_exchange_enabled    = true;
83     gatt_client_required_security_level = LEVEL_0;
84 
85     // register for HCI Events
86     hci_event_callback_registration.callback = &gatt_client_event_packet_handler;
87     hci_add_event_handler(&hci_event_callback_registration);
88 
89     // register for SM Events
90     sm_event_callback_registration.callback = &gatt_client_event_packet_handler;
91     sm_add_event_handler(&sm_event_callback_registration);
92 
93     // and ATT Client PDUs
94     att_dispatch_register_client(gatt_client_att_packet_handler);
95 }
96 
97 void gatt_client_set_required_security_level(gap_security_level_t level){
98     gatt_client_required_security_level = level;
99 }
100 
101 static gatt_client_t * gatt_client_for_timer(btstack_timer_source_t * ts){
102     btstack_linked_list_iterator_t it;
103     btstack_linked_list_iterator_init(&it, &gatt_client_connections);
104     while (btstack_linked_list_iterator_has_next(&it)){
105         gatt_client_t * gatt_client = (gatt_client_t *) btstack_linked_list_iterator_next(&it);
106         if (&gatt_client->gc_timeout == ts) {
107             return gatt_client;
108         }
109     }
110     return NULL;
111 }
112 
113 static void gatt_client_timeout_handler(btstack_timer_source_t * timer){
114     gatt_client_t * gatt_client = gatt_client_for_timer(timer);
115     if (gatt_client == NULL) return;
116     log_info("GATT client timeout handle, handle 0x%02x", gatt_client->con_handle);
117     gatt_client_report_error_if_pending(gatt_client, ATT_ERROR_TIMEOUT);
118 }
119 
120 static void gatt_client_timeout_start(gatt_client_t * gatt_client){
121     log_info("GATT client timeout start, handle 0x%02x", gatt_client->con_handle);
122     btstack_run_loop_remove_timer(&gatt_client->gc_timeout);
123     btstack_run_loop_set_timer_handler(&gatt_client->gc_timeout, gatt_client_timeout_handler);
124     btstack_run_loop_set_timer(&gatt_client->gc_timeout, 30000); // 30 seconds sm timeout
125     btstack_run_loop_add_timer(&gatt_client->gc_timeout);
126 }
127 
128 static void gatt_client_timeout_stop(gatt_client_t * gatt_client){
129     log_info("GATT client timeout stop, handle 0x%02x", gatt_client->con_handle);
130     btstack_run_loop_remove_timer(&gatt_client->gc_timeout);
131 }
132 
133 static gap_security_level_t gatt_client_le_security_level_for_connection(hci_con_handle_t con_handle){
134     uint8_t encryption_key_size = gap_encryption_key_size(con_handle);
135     if (encryption_key_size == 0) return LEVEL_0;
136 
137     bool authenticated = gap_authenticated(con_handle);
138     if (!authenticated) return LEVEL_2;
139 
140     return encryption_key_size == 16 ? LEVEL_4 : LEVEL_3;
141 }
142 
143 static gatt_client_t * gatt_client_get_context_for_handle(uint16_t handle){
144     btstack_linked_item_t *it;
145     for (it = (btstack_linked_item_t *) gatt_client_connections; it != NULL; it = it->next){
146         gatt_client_t * gatt_client = (gatt_client_t *) it;
147         if (gatt_client->con_handle == handle){
148             return gatt_client;
149         }
150     }
151     return NULL;
152 }
153 
154 
155 // @return gatt_client context
156 // returns existing one, or tries to setup new one
157 static gatt_client_t * gatt_client_provide_context_for_handle(hci_con_handle_t con_handle){
158     gatt_client_t * gatt_client = gatt_client_get_context_for_handle(con_handle);
159     if (gatt_client != NULL) return gatt_client;
160 
161     // bail if no such hci connection
162     hci_connection_t * hci_connection = hci_connection_for_handle(con_handle);
163     if (hci_connection == NULL){
164         log_error("No connection for handle 0x%04x", con_handle);
165         return NULL;
166     }
167     gatt_client = btstack_memory_gatt_client_get();
168     if (!gatt_client) return NULL;
169     // init state
170     gatt_client->con_handle = con_handle;
171     gatt_client->mtu = ATT_DEFAULT_MTU;
172     gatt_client->security_level = gatt_client_le_security_level_for_connection(con_handle);
173     if (gatt_client_mtu_exchange_enabled){
174         gatt_client->mtu_state = SEND_MTU_EXCHANGE;
175     } else {
176         gatt_client->mtu_state = MTU_AUTO_EXCHANGE_DISABLED;
177     }
178     gatt_client->gatt_client_state = P_READY;
179     btstack_linked_list_add(&gatt_client_connections, (btstack_linked_item_t*)gatt_client);
180 
181     // get unenhanced att bearer state
182     if (hci_connection->att_connection.mtu_exchanged){
183         gatt_client->mtu = hci_connection->att_connection.mtu;
184         gatt_client->mtu_state = MTU_EXCHANGED;
185     }
186 
187     return gatt_client;
188 }
189 
190 static gatt_client_t * gatt_client_provide_context_for_handle_and_start_timer(hci_con_handle_t con_handle){
191     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle(con_handle);
192     if (gatt_client == NULL) return NULL;
193     gatt_client_timeout_start(gatt_client);
194     return gatt_client;
195 }
196 
197 static bool is_ready(gatt_client_t * gatt_client){
198     return gatt_client->gatt_client_state == P_READY;
199 }
200 
201 int gatt_client_is_ready(hci_con_handle_t con_handle){
202     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle(con_handle);
203     if (gatt_client == NULL) return 0;
204     return is_ready(gatt_client) ? 1 : 0;
205 }
206 
207 void gatt_client_mtu_enable_auto_negotiation(uint8_t enabled){
208     gatt_client_mtu_exchange_enabled = enabled != 0;
209 }
210 
211 uint8_t gatt_client_get_mtu(hci_con_handle_t con_handle, uint16_t * mtu){
212     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle(con_handle);
213     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
214 
215     if ((gatt_client->mtu_state == MTU_EXCHANGED) || (gatt_client->mtu_state == MTU_AUTO_EXCHANGE_DISABLED)){
216         *mtu = gatt_client->mtu;
217         return ERROR_CODE_SUCCESS;
218     }
219     *mtu = ATT_DEFAULT_MTU;
220     return GATT_CLIENT_IN_WRONG_STATE;
221 }
222 
223 // precondition: can_send_packet_now == TRUE
224 static uint8_t att_confirmation(uint16_t con_handle){
225     l2cap_reserve_packet_buffer();
226     uint8_t * request = l2cap_get_outgoing_buffer();
227     request[0] = ATT_HANDLE_VALUE_CONFIRMATION;
228 
229     return l2cap_send_prepared_connectionless(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 1);
230 }
231 
232 // precondition: can_send_packet_now == TRUE
233 static uint8_t att_find_information_request(uint8_t request_type, uint16_t con_handle, uint16_t start_handle, uint16_t end_handle){
234     l2cap_reserve_packet_buffer();
235     uint8_t * request = l2cap_get_outgoing_buffer();
236     request[0] = request_type;
237     little_endian_store_16(request, 1, start_handle);
238     little_endian_store_16(request, 3, end_handle);
239 
240     return l2cap_send_prepared_connectionless(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 5);
241 }
242 
243 // precondition: can_send_packet_now == TRUE
244 static uint8_t att_find_by_type_value_request(uint8_t request_type, uint16_t attribute_group_type, uint16_t con_handle, uint16_t start_handle, uint16_t end_handle, uint8_t * value, uint16_t value_size){
245     l2cap_reserve_packet_buffer();
246     uint8_t * request = l2cap_get_outgoing_buffer();
247 
248     request[0] = request_type;
249     little_endian_store_16(request, 1, start_handle);
250     little_endian_store_16(request, 3, end_handle);
251     little_endian_store_16(request, 5, attribute_group_type);
252     (void)memcpy(&request[7], value, value_size);
253 
254     return l2cap_send_prepared_connectionless(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 7u + value_size);
255 }
256 
257 // precondition: can_send_packet_now == TRUE
258 static uint8_t att_read_by_type_or_group_request_for_uuid16(uint8_t request_type, uint16_t uuid16, uint16_t con_handle, uint16_t start_handle, uint16_t end_handle){
259     l2cap_reserve_packet_buffer();
260     uint8_t * request = l2cap_get_outgoing_buffer();
261     request[0] = request_type;
262     little_endian_store_16(request, 1, start_handle);
263     little_endian_store_16(request, 3, end_handle);
264     little_endian_store_16(request, 5, uuid16);
265 
266     return l2cap_send_prepared_connectionless(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 7);
267 }
268 
269 // precondition: can_send_packet_now == TRUE
270 static uint8_t att_read_by_type_or_group_request_for_uuid128(uint8_t request_type, const uint8_t * uuid128, uint16_t con_handle, uint16_t start_handle, uint16_t end_handle){
271     l2cap_reserve_packet_buffer();
272     uint8_t * request = l2cap_get_outgoing_buffer();
273     request[0] = request_type;
274     little_endian_store_16(request, 1, start_handle);
275     little_endian_store_16(request, 3, end_handle);
276     reverse_128(uuid128, &request[5]);
277 
278     return l2cap_send_prepared_connectionless(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 21);
279 }
280 
281 // precondition: can_send_packet_now == TRUE
282 static uint8_t att_read_request(uint8_t request_type, uint16_t con_handle, uint16_t attribute_handle){
283     l2cap_reserve_packet_buffer();
284     uint8_t * request = l2cap_get_outgoing_buffer();
285     request[0] = request_type;
286     little_endian_store_16(request, 1, attribute_handle);
287 
288     return l2cap_send_prepared_connectionless(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 3);
289 }
290 
291 // precondition: can_send_packet_now == TRUE
292 static uint8_t att_read_blob_request(uint8_t request_type, uint16_t con_handle, uint16_t attribute_handle, uint16_t value_offset){
293     l2cap_reserve_packet_buffer();
294     uint8_t * request = l2cap_get_outgoing_buffer();
295     request[0] = request_type;
296     little_endian_store_16(request, 1, attribute_handle);
297     little_endian_store_16(request, 3, value_offset);
298 
299     return l2cap_send_prepared_connectionless(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 5);
300 }
301 
302 static uint8_t att_read_multiple_request(uint16_t con_handle, uint16_t num_value_handles, uint16_t * value_handles){
303     l2cap_reserve_packet_buffer();
304     uint8_t * request = l2cap_get_outgoing_buffer();
305     request[0] = ATT_READ_MULTIPLE_REQUEST;
306     int i;
307     int offset = 1;
308     for (i=0;i<num_value_handles;i++){
309         little_endian_store_16(request, offset, value_handles[i]);
310         offset += 2;
311     }
312 
313     return l2cap_send_prepared_connectionless(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, offset);
314 }
315 
316 #ifdef ENABLE_LE_SIGNED_WRITE
317 // precondition: can_send_packet_now == TRUE
318 static uint8_t att_signed_write_request(uint16_t request_type, uint16_t con_handle, uint16_t attribute_handle, uint16_t value_length, uint8_t * value, uint32_t sign_counter, uint8_t sgn[8]){
319     l2cap_reserve_packet_buffer();
320     uint8_t * request = l2cap_get_outgoing_buffer();
321     request[0] = request_type;
322     little_endian_store_16(request, 1, attribute_handle);
323     (void)memcpy(&request[3], value, value_length);
324     little_endian_store_32(request, 3 + value_length, sign_counter);
325     reverse_64(sgn, &request[3 + value_length + 4]);
326 
327     return l2cap_send_prepared_connectionless(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 3 + value_length + 12);
328 }
329 #endif
330 
331 // precondition: can_send_packet_now == TRUE
332 static uint8_t att_write_request(uint8_t request_type, uint16_t con_handle, uint16_t attribute_handle, uint16_t value_length, uint8_t * value){
333     l2cap_reserve_packet_buffer();
334     uint8_t * request = l2cap_get_outgoing_buffer();
335     request[0] = request_type;
336     little_endian_store_16(request, 1, attribute_handle);
337     (void)memcpy(&request[3], value, value_length);
338 
339     return l2cap_send_prepared_connectionless(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 3u + value_length);
340 }
341 
342 // precondition: can_send_packet_now == TRUE
343 static uint8_t att_execute_write_request(uint8_t request_type, uint16_t con_handle, uint8_t execute_write){
344     l2cap_reserve_packet_buffer();
345     uint8_t * request = l2cap_get_outgoing_buffer();
346     request[0] = request_type;
347     request[1] = execute_write;
348 
349     return l2cap_send_prepared_connectionless(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 2);
350 }
351 
352 // precondition: can_send_packet_now == TRUE
353 static uint8_t att_prepare_write_request(uint8_t request_type, uint16_t con_handle, uint16_t attribute_handle, uint16_t value_offset, uint16_t blob_length, uint8_t * value){
354     l2cap_reserve_packet_buffer();
355     uint8_t * request = l2cap_get_outgoing_buffer();
356     request[0] = request_type;
357     little_endian_store_16(request, 1, attribute_handle);
358     little_endian_store_16(request, 3, value_offset);
359     (void)memcpy(&request[5], &value[value_offset], blob_length);
360 
361     return l2cap_send_prepared_connectionless(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 5u + blob_length);
362 }
363 
364 static uint8_t att_exchange_mtu_request(uint16_t con_handle){
365     uint16_t mtu = l2cap_max_le_mtu();
366     l2cap_reserve_packet_buffer();
367     uint8_t * request = l2cap_get_outgoing_buffer();
368     request[0] = ATT_EXCHANGE_MTU_REQUEST;
369     little_endian_store_16(request, 1, mtu);
370 
371     return l2cap_send_prepared_connectionless(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 3);
372 }
373 
374 static uint16_t write_blob_length(gatt_client_t * gatt_client){
375     uint16_t max_blob_length = gatt_client->mtu - 5u;
376     if (gatt_client->attribute_offset >= gatt_client->attribute_length) {
377         return 0;
378     }
379     uint16_t rest_length = gatt_client->attribute_length - gatt_client->attribute_offset;
380     if (max_blob_length > rest_length){
381         return rest_length;
382     }
383     return max_blob_length;
384 }
385 
386 static void send_gatt_services_request(gatt_client_t *gatt_client){
387     att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_GROUP_TYPE_REQUEST, gatt_client->uuid16, gatt_client->con_handle, gatt_client->start_group_handle, gatt_client->end_group_handle);
388 }
389 
390 static void send_gatt_by_uuid_request(gatt_client_t *gatt_client, uint16_t attribute_group_type){
391     if (gatt_client->uuid16){
392         uint8_t uuid16[2];
393         little_endian_store_16(uuid16, 0, gatt_client->uuid16);
394         att_find_by_type_value_request(ATT_FIND_BY_TYPE_VALUE_REQUEST, attribute_group_type, gatt_client->con_handle, gatt_client->start_group_handle, gatt_client->end_group_handle, uuid16, 2);
395         return;
396     }
397     uint8_t uuid128[16];
398     reverse_128(gatt_client->uuid128, uuid128);
399     att_find_by_type_value_request(ATT_FIND_BY_TYPE_VALUE_REQUEST, attribute_group_type, gatt_client->con_handle, gatt_client->start_group_handle, gatt_client->end_group_handle, uuid128, 16);
400 }
401 
402 static void send_gatt_services_by_uuid_request(gatt_client_t *gatt_client){
403     send_gatt_by_uuid_request(gatt_client, GATT_PRIMARY_SERVICE_UUID);
404 }
405 
406 static void send_gatt_included_service_uuid_request(gatt_client_t *gatt_client){
407     att_read_request(ATT_READ_REQUEST, gatt_client->con_handle, gatt_client->query_start_handle);
408 }
409 
410 static void send_gatt_included_service_request(gatt_client_t *gatt_client){
411     att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_TYPE_REQUEST, GATT_INCLUDE_SERVICE_UUID, gatt_client->con_handle, gatt_client->start_group_handle, gatt_client->end_group_handle);
412 }
413 
414 static void send_gatt_characteristic_request(gatt_client_t *gatt_client){
415     att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_TYPE_REQUEST, GATT_CHARACTERISTICS_UUID, gatt_client->con_handle, gatt_client->start_group_handle, gatt_client->end_group_handle);
416 }
417 
418 static void send_gatt_characteristic_descriptor_request(gatt_client_t *gatt_client){
419     att_find_information_request(ATT_FIND_INFORMATION_REQUEST, gatt_client->con_handle, gatt_client->start_group_handle, gatt_client->end_group_handle);
420 }
421 
422 static void send_gatt_read_characteristic_value_request(gatt_client_t *gatt_client){
423     att_read_request(ATT_READ_REQUEST, gatt_client->con_handle, gatt_client->attribute_handle);
424 }
425 
426 static void send_gatt_read_by_type_request(gatt_client_t * gatt_client){
427     if (gatt_client->uuid16){
428         att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_TYPE_REQUEST, gatt_client->uuid16, gatt_client->con_handle, gatt_client->start_group_handle, gatt_client->end_group_handle);
429     } else {
430         att_read_by_type_or_group_request_for_uuid128(ATT_READ_BY_TYPE_REQUEST, gatt_client->uuid128, gatt_client->con_handle, gatt_client->start_group_handle, gatt_client->end_group_handle);
431     }
432 }
433 
434 static void send_gatt_read_blob_request(gatt_client_t *gatt_client){
435     if (gatt_client->attribute_offset == 0){
436         att_read_request(ATT_READ_REQUEST, gatt_client->con_handle, gatt_client->attribute_handle);
437     } else {
438         att_read_blob_request(ATT_READ_BLOB_REQUEST, gatt_client->con_handle, gatt_client->attribute_handle, gatt_client->attribute_offset);
439     }
440 }
441 
442 static void send_gatt_read_multiple_request(gatt_client_t * gatt_client){
443     att_read_multiple_request(gatt_client->con_handle, gatt_client->read_multiple_handle_count, gatt_client->read_multiple_handles);
444 }
445 
446 static void send_gatt_write_attribute_value_request(gatt_client_t * gatt_client){
447     att_write_request(ATT_WRITE_REQUEST, gatt_client->con_handle, gatt_client->attribute_handle, gatt_client->attribute_length, gatt_client->attribute_value);
448 }
449 
450 static void send_gatt_write_client_characteristic_configuration_request(gatt_client_t * gatt_client){
451     att_write_request(ATT_WRITE_REQUEST, gatt_client->con_handle, gatt_client->client_characteristic_configuration_handle, 2, gatt_client->client_characteristic_configuration_value);
452 }
453 
454 static void send_gatt_prepare_write_request(gatt_client_t * gatt_client){
455     att_prepare_write_request(ATT_PREPARE_WRITE_REQUEST, gatt_client->con_handle, gatt_client->attribute_handle, gatt_client->attribute_offset, write_blob_length(gatt_client), gatt_client->attribute_value);
456 }
457 
458 static void send_gatt_execute_write_request(gatt_client_t * gatt_client){
459     att_execute_write_request(ATT_EXECUTE_WRITE_REQUEST, gatt_client->con_handle, 1);
460 }
461 
462 static void send_gatt_cancel_prepared_write_request(gatt_client_t * gatt_client){
463     att_execute_write_request(ATT_EXECUTE_WRITE_REQUEST, gatt_client->con_handle, 0);
464 }
465 
466 #ifndef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
467 static void send_gatt_read_client_characteristic_configuration_request(gatt_client_t * gatt_client){
468     att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_TYPE_REQUEST, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION, gatt_client->con_handle, gatt_client->start_group_handle, gatt_client->end_group_handle);
469 }
470 #endif
471 
472 static void send_gatt_read_characteristic_descriptor_request(gatt_client_t * gatt_client){
473     att_read_request(ATT_READ_REQUEST, gatt_client->con_handle, gatt_client->attribute_handle);
474 }
475 
476 #ifdef ENABLE_LE_SIGNED_WRITE
477 static void send_gatt_signed_write_request(gatt_client_t * gatt_client, uint32_t sign_counter){
478     att_signed_write_request(ATT_SIGNED_WRITE_COMMAND, gatt_client->con_handle, gatt_client->attribute_handle, gatt_client->attribute_length, gatt_client->attribute_value, sign_counter, gatt_client->cmac);
479 }
480 #endif
481 
482 static uint16_t get_last_result_handle_from_service_list(uint8_t * packet, uint16_t size){
483     if (size < 2) return 0xffff;
484     uint8_t attr_length = packet[1];
485     if ((2 + attr_length) > size) return 0xffff;
486     return little_endian_read_16(packet, size - attr_length + 2u);
487 }
488 
489 static uint16_t get_last_result_handle_from_characteristics_list(uint8_t * packet, uint16_t size){
490     if (size < 2) return 0xffff;
491     uint8_t attr_length = packet[1];
492     if ((2 + attr_length) > size) return 0xffff;
493     return little_endian_read_16(packet, size - attr_length + 3u);
494 }
495 
496 static uint16_t get_last_result_handle_from_included_services_list(uint8_t * packet, uint16_t size){
497     if (size < 2) return 0xffff;
498     uint8_t attr_length = packet[1];
499     if ((2 + attr_length) > size) return 0xffff;
500     return little_endian_read_16(packet, size - attr_length);
501 }
502 
503 static void gatt_client_handle_transaction_complete(gatt_client_t * gatt_client){
504     gatt_client->gatt_client_state = P_READY;
505     gatt_client_timeout_stop(gatt_client);
506 }
507 
508 static void emit_event_new(btstack_packet_handler_t callback, uint8_t * packet, uint16_t size){
509     if (!callback) return;
510     hci_dump_packet(HCI_EVENT_PACKET, 1, packet, size);
511     (*callback)(HCI_EVENT_PACKET, 0, packet, size);
512 }
513 
514 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){
515     notification->callback = callback;
516     notification->con_handle = con_handle;
517     if (characteristic == NULL){
518         notification->attribute_handle = GATT_CLIENT_ANY_VALUE_HANDLE;
519     } else {
520         notification->attribute_handle = characteristic->value_handle;
521     }
522     btstack_linked_list_add(&gatt_client_value_listeners, (btstack_linked_item_t*) notification);
523 }
524 
525 void gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification){
526     btstack_linked_list_remove(&gatt_client_value_listeners, (btstack_linked_item_t*) notification);
527 }
528 
529 static void emit_event_to_registered_listeners(hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t * packet, uint16_t size){
530     btstack_linked_list_iterator_t it;
531     btstack_linked_list_iterator_init(&it, &gatt_client_value_listeners);
532     while (btstack_linked_list_iterator_has_next(&it)){
533         gatt_client_notification_t * notification = (gatt_client_notification_t*) btstack_linked_list_iterator_next(&it);
534         if ((notification->con_handle       != GATT_CLIENT_ANY_CONNECTION)   && (notification->con_handle       != con_handle)) continue;
535         if ((notification->attribute_handle != GATT_CLIENT_ANY_VALUE_HANDLE) && (notification->attribute_handle != attribute_handle)) continue;
536         (*notification->callback)(HCI_EVENT_PACKET, 0, packet, size);
537     }
538 }
539 
540 static void emit_gatt_complete_event(gatt_client_t * gatt_client, uint8_t att_status){
541     // @format H1
542     uint8_t packet[5];
543     packet[0] = GATT_EVENT_QUERY_COMPLETE;
544     packet[1] = 3;
545     little_endian_store_16(packet, 2, gatt_client->con_handle);
546     packet[4] = att_status;
547     emit_event_new(gatt_client->callback, packet, sizeof(packet));
548 }
549 
550 static void emit_gatt_service_query_result_event(gatt_client_t * gatt_client, uint16_t start_group_handle, uint16_t end_group_handle, const uint8_t * uuid128){
551     // @format HX
552     uint8_t packet[24];
553     packet[0] = GATT_EVENT_SERVICE_QUERY_RESULT;
554     packet[1] = sizeof(packet) - 2u;
555     little_endian_store_16(packet, 2, gatt_client->con_handle);
556     ///
557     little_endian_store_16(packet, 4, start_group_handle);
558     little_endian_store_16(packet, 6, end_group_handle);
559     reverse_128(uuid128, &packet[8]);
560     emit_event_new(gatt_client->callback, packet, sizeof(packet));
561 }
562 
563 static void emit_gatt_included_service_query_result_event(gatt_client_t * gatt_client, uint16_t include_handle, uint16_t start_group_handle, uint16_t end_group_handle, const uint8_t * uuid128){
564     // @format HX
565     uint8_t packet[26];
566     packet[0] = GATT_EVENT_INCLUDED_SERVICE_QUERY_RESULT;
567     packet[1] = sizeof(packet) - 2u;
568     little_endian_store_16(packet, 2, gatt_client->con_handle);
569     ///
570     little_endian_store_16(packet, 4, include_handle);
571     //
572     little_endian_store_16(packet, 6, start_group_handle);
573     little_endian_store_16(packet, 8, end_group_handle);
574     reverse_128(uuid128, &packet[10]);
575     emit_event_new(gatt_client->callback, packet, sizeof(packet));
576 }
577 
578 static void emit_gatt_characteristic_query_result_event(gatt_client_t * gatt_client, uint16_t start_handle, uint16_t value_handle, uint16_t end_handle,
579                                                         uint16_t properties, const uint8_t * uuid128){
580     // @format HY
581     uint8_t packet[28];
582     packet[0] = GATT_EVENT_CHARACTERISTIC_QUERY_RESULT;
583     packet[1] = sizeof(packet) - 2u;
584     little_endian_store_16(packet, 2, gatt_client->con_handle);
585     ///
586     little_endian_store_16(packet, 4,  start_handle);
587     little_endian_store_16(packet, 6,  value_handle);
588     little_endian_store_16(packet, 8,  end_handle);
589     little_endian_store_16(packet, 10, properties);
590     reverse_128(uuid128, &packet[12]);
591     emit_event_new(gatt_client->callback, packet, sizeof(packet));
592 }
593 
594 static void emit_gatt_all_characteristic_descriptors_result_event(
595         gatt_client_t * gatt_client, uint16_t descriptor_handle, const uint8_t * uuid128){
596     // @format HZ
597     uint8_t packet[22];
598     packet[0] = GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT;
599     packet[1] = sizeof(packet) - 2u;
600     little_endian_store_16(packet, 2, gatt_client->con_handle);
601     ///
602     little_endian_store_16(packet, 4,  descriptor_handle);
603     reverse_128(uuid128, &packet[6]);
604     emit_event_new(gatt_client->callback, packet, sizeof(packet));
605 }
606 
607 static void emit_gatt_mtu_exchanged_result_event(gatt_client_t * gatt_client, uint16_t new_mtu){
608     // @format H2
609     uint8_t packet[6];
610     packet[0] = GATT_EVENT_MTU;
611     packet[1] = sizeof(packet) - 2u;
612     little_endian_store_16(packet, 2, gatt_client->con_handle);
613     little_endian_store_16(packet, 4, new_mtu);
614     att_dispatch_client_mtu_exchanged(gatt_client->con_handle, new_mtu);
615     emit_event_new(gatt_client->callback, packet, sizeof(packet));
616 }
617 ///
618 static void report_gatt_services(gatt_client_t * gatt_client, uint8_t * packet, uint16_t size){
619     if (size < 2) return;
620     uint8_t attr_length = packet[1];
621     uint8_t uuid_length = attr_length - 4u;
622 
623     int i;
624     for (i = 2; (i+attr_length) <= size; i += attr_length){
625         uint16_t start_group_handle = little_endian_read_16(packet,i);
626         uint16_t end_group_handle   = little_endian_read_16(packet,i+2);
627         uint8_t  uuid128[16];
628         uint16_t uuid16 = 0;
629 
630         if (uuid_length == 2u){
631             uuid16 = little_endian_read_16(packet, i+4);
632             uuid_add_bluetooth_prefix((uint8_t*) &uuid128, uuid16);
633         } else if (uuid_length == 16u) {
634             reverse_128(&packet[i+4], uuid128);
635         } else {
636             return;
637         }
638         emit_gatt_service_query_result_event(gatt_client, start_group_handle, end_group_handle, uuid128);
639     }
640 }
641 
642 // helper
643 static void characteristic_start_found(gatt_client_t * gatt_client, uint16_t start_handle, uint8_t properties, uint16_t value_handle, uint8_t * uuid, uint16_t uuid_length){
644     uint8_t uuid128[16];
645     uint16_t uuid16 = 0;
646     if (uuid_length == 2u){
647         uuid16 = little_endian_read_16(uuid, 0);
648         uuid_add_bluetooth_prefix((uint8_t*) uuid128, uuid16);
649     } else if (uuid_length == 16u){
650         reverse_128(uuid, uuid128);
651     } else {
652         return;
653     }
654 
655     if (gatt_client->filter_with_uuid && (memcmp(gatt_client->uuid128, uuid128, 16) != 0)) return;
656 
657     gatt_client->characteristic_properties = properties;
658     gatt_client->characteristic_start_handle = start_handle;
659     gatt_client->attribute_handle = value_handle;
660 
661     if (gatt_client->filter_with_uuid) return;
662 
663     gatt_client->uuid16 = uuid16;
664     (void)memcpy(gatt_client->uuid128, uuid128, 16);
665 }
666 
667 static void characteristic_end_found(gatt_client_t * gatt_client, uint16_t end_handle){
668     // TODO: stop searching if filter and uuid found
669 
670     if (!gatt_client->characteristic_start_handle) return;
671 
672     emit_gatt_characteristic_query_result_event(gatt_client, gatt_client->characteristic_start_handle, gatt_client->attribute_handle,
673                                                 end_handle, gatt_client->characteristic_properties, gatt_client->uuid128);
674 
675     gatt_client->characteristic_start_handle = 0;
676 }
677 
678 static void report_gatt_characteristics(gatt_client_t * gatt_client, uint8_t * packet, uint16_t size){
679     if (size < 2u) return;
680     uint8_t attr_length = packet[1];
681     if ((attr_length != 7u) && (attr_length != 21u)) return;
682     uint8_t uuid_length = attr_length - 5u;
683     int i;
684     for (i = 2u; (i + attr_length) <= size; i += attr_length){
685         uint16_t start_handle = little_endian_read_16(packet, i);
686         uint8_t  properties = packet[i+2];
687         uint16_t value_handle = little_endian_read_16(packet, i+3);
688         characteristic_end_found(gatt_client, start_handle - 1u);
689         characteristic_start_found(gatt_client, start_handle, properties, value_handle, &packet[i + 5], uuid_length);
690     }
691 }
692 
693 static void report_gatt_included_service_uuid16(gatt_client_t * gatt_client, uint16_t include_handle, uint16_t uuid16){
694     uint8_t normalized_uuid128[16];
695     uuid_add_bluetooth_prefix(normalized_uuid128, uuid16);
696     emit_gatt_included_service_query_result_event(gatt_client, include_handle, gatt_client->query_start_handle,
697                                                   gatt_client->query_end_handle, normalized_uuid128);
698 }
699 
700 static void report_gatt_included_service_uuid128(gatt_client_t * gatt_client, uint16_t include_handle, const uint8_t * uuid128){
701     emit_gatt_included_service_query_result_event(gatt_client, include_handle, gatt_client->query_start_handle,
702                                                   gatt_client->query_end_handle, uuid128);
703 }
704 
705 // @return packet pointer
706 // @note assume that value is part of an l2cap buffer - overwrite HCI + L2CAP packet headers
707 static const int characteristic_value_event_header_size = 8;
708 static uint8_t * setup_characteristic_value_packet(uint8_t type, hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t * value, uint16_t length){
709 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
710     // copy value into test packet for testing
711     static uint8_t packet[1000];
712     memcpy(&packet[8], value, length);
713 #else
714     // before the value inside the ATT PDU
715     uint8_t * packet = value - characteristic_value_event_header_size;
716 #endif
717     packet[0] = type;
718     packet[1] = characteristic_value_event_header_size - 2 + length;
719     little_endian_store_16(packet, 2, con_handle);
720     little_endian_store_16(packet, 4, attribute_handle);
721     little_endian_store_16(packet, 6, length);
722     return packet;
723 }
724 
725 // @return packet pointer
726 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
727 static const int long_characteristic_value_event_header_size = 10;
728 static uint8_t * setup_long_characteristic_value_packet(uint8_t type, hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t offset, uint8_t * value, uint16_t length){
729 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
730     // avoid using pre ATT headers.
731     return NULL;
732 #endif
733 #if defined(HCI_INCOMING_PRE_BUFFER_SIZE) && (HCI_INCOMING_PRE_BUFFER_SIZE >= 10 - 8) // L2CAP Header (4) - ACL Header (4)
734     // before the value inside the ATT PDU
735     uint8_t * packet = value - long_characteristic_value_event_header_size;
736     packet[0] = type;
737     packet[1] = long_characteristic_value_event_header_size - 2 + length;
738     little_endian_store_16(packet, 2, con_handle);
739     little_endian_store_16(packet, 4, attribute_handle);
740     little_endian_store_16(packet, 6, offset);
741     little_endian_store_16(packet, 8, length);
742     return packet;
743 #else
744     log_error("HCI_INCOMING_PRE_BUFFER_SIZE >= 2 required for long characteristic reads");
745     return NULL;
746 #endif
747 }
748 
749 // test if notification/indication should be delivered to application (BLESA)
750 static bool gatt_client_accept_server_message(hci_con_handle_t con_handle){
751 #ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION
752 	// ignore messages until re-encryption is complete
753     if (gap_reconnect_security_setup_active(con_handle)) return false;
754 
755 	// after that ignore if bonded but not encrypted
756 	return !gap_bonded(con_handle) || (gap_encryption_key_size(con_handle) > 0);
757 #else
758     UNUSED(con_handle);
759 	return true;
760 #endif
761 }
762 
763 
764 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
765 static void report_gatt_notification(hci_con_handle_t con_handle, uint16_t value_handle, uint8_t * value, int length){
766 	if (!gatt_client_accept_server_message(con_handle)) return;
767     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_NOTIFICATION, con_handle, value_handle, value, length);
768     emit_event_to_registered_listeners(con_handle, value_handle, packet, characteristic_value_event_header_size + length);
769 }
770 
771 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
772 static void report_gatt_indication(hci_con_handle_t con_handle, uint16_t value_handle, uint8_t * value, int length){
773 	if (!gatt_client_accept_server_message(con_handle)) return;
774     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_INDICATION, con_handle, value_handle, value, length);
775     emit_event_to_registered_listeners(con_handle, value_handle, packet, characteristic_value_event_header_size + length);
776 }
777 
778 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
779 static void report_gatt_characteristic_value(gatt_client_t * gatt_client, uint16_t attribute_handle, uint8_t * value, uint16_t length){
780     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT, gatt_client->con_handle, attribute_handle, value, length);
781     emit_event_new(gatt_client->callback, packet, characteristic_value_event_header_size + length);
782 }
783 
784 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
785 static void report_gatt_long_characteristic_value_blob(gatt_client_t * gatt_client, uint16_t attribute_handle, uint8_t * blob, uint16_t blob_length, int value_offset){
786     uint8_t * packet = setup_long_characteristic_value_packet(GATT_EVENT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT, gatt_client->con_handle, attribute_handle, value_offset, blob, blob_length);
787     if (!packet) return;
788     emit_event_new(gatt_client->callback, packet, blob_length + long_characteristic_value_event_header_size);
789 }
790 
791 static void report_gatt_characteristic_descriptor(gatt_client_t * gatt_client, uint16_t descriptor_handle, uint8_t *value, uint16_t value_length, uint16_t value_offset){
792     UNUSED(value_offset);
793     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT, gatt_client->con_handle, descriptor_handle, value, value_length);
794     emit_event_new(gatt_client->callback, packet, value_length + 8u);
795 }
796 
797 static void report_gatt_long_characteristic_descriptor(gatt_client_t * gatt_client, uint16_t descriptor_handle, uint8_t *blob, uint16_t blob_length, uint16_t value_offset){
798     uint8_t * packet = setup_long_characteristic_value_packet(GATT_EVENT_LONG_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT, gatt_client->con_handle, descriptor_handle, value_offset, blob, blob_length);
799     if (!packet) return;
800     emit_event_new(gatt_client->callback, packet, blob_length + long_characteristic_value_event_header_size);
801 }
802 
803 static void report_gatt_all_characteristic_descriptors(gatt_client_t * gatt_client, uint8_t * packet, uint16_t size, uint16_t pair_size){
804     int i;
805     for (i = 0u; (i + pair_size) <= size; i += pair_size){
806         uint16_t descriptor_handle = little_endian_read_16(packet,i);
807         uint8_t uuid128[16];
808         uint16_t uuid16 = 0;
809         if (pair_size == 4u){
810             uuid16 = little_endian_read_16(packet,i+2);
811             uuid_add_bluetooth_prefix(uuid128, uuid16);
812         } else {
813             reverse_128(&packet[i+2], uuid128);
814         }
815         emit_gatt_all_characteristic_descriptors_result_event(gatt_client, descriptor_handle, uuid128);
816     }
817 
818 }
819 
820 static int is_query_done(gatt_client_t * gatt_client, uint16_t last_result_handle){
821     return last_result_handle >= gatt_client->end_group_handle;
822 }
823 
824 static void trigger_next_query(gatt_client_t * gatt_client, uint16_t last_result_handle, gatt_client_state_t next_query_state){
825     if (is_query_done(gatt_client, last_result_handle)){
826         gatt_client_handle_transaction_complete(gatt_client);
827         emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
828         return;
829     }
830     // next
831     gatt_client->start_group_handle = last_result_handle + 1u;
832     gatt_client->gatt_client_state = next_query_state;
833 }
834 
835 static void trigger_next_included_service_query(gatt_client_t * gatt_client, uint16_t last_result_handle){
836     trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_INCLUDED_SERVICE_QUERY);
837 }
838 
839 static void trigger_next_service_query(gatt_client_t * gatt_client, uint16_t last_result_handle){
840     trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_SERVICE_QUERY);
841 }
842 
843 static void trigger_next_service_by_uuid_query(gatt_client_t * gatt_client, uint16_t last_result_handle){
844     trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_SERVICE_WITH_UUID_QUERY);
845 }
846 
847 static void trigger_next_characteristic_query(gatt_client_t * gatt_client, uint16_t last_result_handle){
848     if (is_query_done(gatt_client, last_result_handle)){
849         // report last characteristic
850         characteristic_end_found(gatt_client, gatt_client->end_group_handle);
851     }
852     trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY);
853 }
854 
855 static void trigger_next_characteristic_descriptor_query(gatt_client_t * gatt_client, uint16_t last_result_handle){
856     trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY);
857 }
858 
859 static void trigger_next_read_by_type_query(gatt_client_t * gatt_client, uint16_t last_result_handle){
860     trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_READ_BY_TYPE_REQUEST);
861 }
862 
863 static void trigger_next_prepare_write_query(gatt_client_t * gatt_client, gatt_client_state_t next_query_state, gatt_client_state_t done_state){
864     gatt_client->attribute_offset += write_blob_length(gatt_client);
865     uint16_t next_blob_length =  write_blob_length(gatt_client);
866 
867     if (next_blob_length == 0u){
868         gatt_client->gatt_client_state = done_state;
869         return;
870     }
871     gatt_client->gatt_client_state = next_query_state;
872 }
873 
874 static void trigger_next_blob_query(gatt_client_t * gatt_client, gatt_client_state_t next_query_state, uint16_t received_blob_length){
875 
876     uint16_t max_blob_length = gatt_client->mtu - 1u;
877     if (received_blob_length < max_blob_length){
878         gatt_client_handle_transaction_complete(gatt_client);
879         emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
880         return;
881     }
882 
883     gatt_client->attribute_offset += received_blob_length;
884     gatt_client->gatt_client_state = next_query_state;
885 }
886 
887 
888 static int is_value_valid(gatt_client_t *gatt_client, uint8_t *packet, uint16_t size){
889     uint16_t attribute_handle = little_endian_read_16(packet, 1);
890     uint16_t value_offset = little_endian_read_16(packet, 3);
891 
892     if (gatt_client->attribute_handle != attribute_handle) return 0;
893     if (gatt_client->attribute_offset != value_offset) return 0;
894     return memcmp(&gatt_client->attribute_value[gatt_client->attribute_offset], &packet[5], size - 5u) == 0u;
895 }
896 
897 // returns 1 if packet was sent
898 static bool gatt_client_run_for_gatt_client(gatt_client_t * gatt_client){
899 
900     // wait until re-encryption is complete
901     if (gap_reconnect_security_setup_active(gatt_client->con_handle)) return false;
902 
903     // wait until re-encryption is complete
904     if (gatt_client->reencryption_active) return false;
905 
906     // wait until pairing complete (either reactive authentication or due to required security level)
907     if (gatt_client->wait_for_authentication_complete) return false;
908 
909     bool client_request_pending = gatt_client->gatt_client_state != P_READY;
910 
911     // verify security level for Mandatory Authentication
912     if (client_request_pending && (gatt_client_required_security_level > gatt_client->security_level)){
913         log_info("Trigger pairing, current security level %u, required %u\n", gatt_client->security_level, gatt_client_required_security_level);
914         gatt_client->wait_for_authentication_complete = 1;
915         // set att error code for pairing failure based on required level
916         switch (gatt_client_required_security_level){
917             case LEVEL_4:
918             case LEVEL_3:
919                 gatt_client->pending_error_code = ATT_ERROR_INSUFFICIENT_AUTHENTICATION;
920                 break;
921             default:
922                 gatt_client->pending_error_code = ATT_ERROR_INSUFFICIENT_ENCRYPTION;
923                 break;
924         }
925         sm_request_pairing(gatt_client->con_handle);
926         // sm probably just sent a pdu
927         return true;
928     }
929 
930     switch (gatt_client->mtu_state) {
931         case SEND_MTU_EXCHANGE:
932             gatt_client->mtu_state = SENT_MTU_EXCHANGE;
933             att_exchange_mtu_request(gatt_client->con_handle);
934             return true;
935         case SENT_MTU_EXCHANGE:
936             return false;
937         default:
938             break;
939     }
940 
941     if (gatt_client->send_confirmation){
942         gatt_client->send_confirmation = 0;
943         att_confirmation(gatt_client->con_handle);
944         return true;
945     }
946 
947     // check MTU for writes
948     switch (gatt_client->gatt_client_state){
949         case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE:
950         case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR:
951             if (gatt_client->attribute_length <= (gatt_client->mtu - 3u)) break;
952             log_error("gatt_client_run: value len %u > MTU %u - 3\n", gatt_client->attribute_length,gatt_client->mtu);
953             gatt_client_handle_transaction_complete(gatt_client);
954             emit_gatt_complete_event(gatt_client, ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH);
955             return false;
956         default:
957             break;
958     }
959 
960     switch (gatt_client->gatt_client_state){
961         case P_W2_SEND_SERVICE_QUERY:
962             gatt_client->gatt_client_state = P_W4_SERVICE_QUERY_RESULT;
963             send_gatt_services_request(gatt_client);
964             return true;
965 
966         case P_W2_SEND_SERVICE_WITH_UUID_QUERY:
967             gatt_client->gatt_client_state = P_W4_SERVICE_WITH_UUID_RESULT;
968             send_gatt_services_by_uuid_request(gatt_client);
969             return true;
970 
971         case P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY:
972             gatt_client->gatt_client_state = P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT;
973             send_gatt_characteristic_request(gatt_client);
974             return true;
975 
976         case P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY:
977             gatt_client->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT;
978             send_gatt_characteristic_request(gatt_client);
979             return true;
980 
981         case P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY:
982             gatt_client->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT;
983             send_gatt_characteristic_descriptor_request(gatt_client);
984             return true;
985 
986         case P_W2_SEND_INCLUDED_SERVICE_QUERY:
987             gatt_client->gatt_client_state = P_W4_INCLUDED_SERVICE_QUERY_RESULT;
988             send_gatt_included_service_request(gatt_client);
989             return true;
990 
991         case P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY:
992             gatt_client->gatt_client_state = P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT;
993             send_gatt_included_service_uuid_request(gatt_client);
994             return true;
995 
996         case P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY:
997             gatt_client->gatt_client_state = P_W4_READ_CHARACTERISTIC_VALUE_RESULT;
998             send_gatt_read_characteristic_value_request(gatt_client);
999             return true;
1000 
1001         case P_W2_SEND_READ_BLOB_QUERY:
1002             gatt_client->gatt_client_state = P_W4_READ_BLOB_RESULT;
1003             send_gatt_read_blob_request(gatt_client);
1004             return true;
1005 
1006         case P_W2_SEND_READ_BY_TYPE_REQUEST:
1007             gatt_client->gatt_client_state = P_W4_READ_BY_TYPE_RESPONSE;
1008             send_gatt_read_by_type_request(gatt_client);
1009             return true;
1010 
1011         case P_W2_SEND_READ_MULTIPLE_REQUEST:
1012             gatt_client->gatt_client_state = P_W4_READ_MULTIPLE_RESPONSE;
1013             send_gatt_read_multiple_request(gatt_client);
1014             return true;
1015 
1016         case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE:
1017             gatt_client->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT;
1018             send_gatt_write_attribute_value_request(gatt_client);
1019             return true;
1020 
1021         case P_W2_PREPARE_WRITE:
1022             gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_RESULT;
1023             send_gatt_prepare_write_request(gatt_client);
1024             return true;
1025 
1026         case P_W2_PREPARE_WRITE_SINGLE:
1027             gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_SINGLE_RESULT;
1028             send_gatt_prepare_write_request(gatt_client);
1029             return true;
1030 
1031         case P_W2_PREPARE_RELIABLE_WRITE:
1032             gatt_client->gatt_client_state = P_W4_PREPARE_RELIABLE_WRITE_RESULT;
1033             send_gatt_prepare_write_request(gatt_client);
1034             return true;
1035 
1036         case P_W2_EXECUTE_PREPARED_WRITE:
1037             gatt_client->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_RESULT;
1038             send_gatt_execute_write_request(gatt_client);
1039             return true;
1040 
1041         case P_W2_CANCEL_PREPARED_WRITE:
1042             gatt_client->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_RESULT;
1043             send_gatt_cancel_prepared_write_request(gatt_client);
1044             return true;
1045 
1046         case P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH:
1047             gatt_client->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT;
1048             send_gatt_cancel_prepared_write_request(gatt_client);
1049             return true;
1050 
1051 #ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
1052         case P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY:
1053             // use Find Information
1054             gatt_client->gatt_client_state = P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT;
1055             send_gatt_characteristic_descriptor_request(gatt_client);
1056 #else
1057         case P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY:
1058             // Use Read By Type
1059             gatt_client->gatt_client_state = P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT;
1060             send_gatt_read_client_characteristic_configuration_request(gatt_client);
1061 #endif
1062             return true;
1063 
1064         case P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY:
1065             gatt_client->gatt_client_state = P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT;
1066             send_gatt_read_characteristic_descriptor_request(gatt_client);
1067             return true;
1068 
1069         case P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY:
1070             gatt_client->gatt_client_state = P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT;
1071             send_gatt_read_blob_request(gatt_client);
1072             return true;
1073 
1074         case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR:
1075             gatt_client->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT;
1076             send_gatt_write_attribute_value_request(gatt_client);
1077             return true;
1078 
1079         case P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION:
1080             gatt_client->gatt_client_state = P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT;
1081             send_gatt_write_client_characteristic_configuration_request(gatt_client);
1082             return true;
1083 
1084         case P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR:
1085             gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT;
1086             send_gatt_prepare_write_request(gatt_client);
1087             return true;
1088 
1089         case P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR:
1090             gatt_client->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT;
1091             send_gatt_execute_write_request(gatt_client);
1092             return true;
1093 
1094 #ifdef ENABLE_LE_SIGNED_WRITE
1095         case P_W4_IDENTITY_RESOLVING:
1096             log_info("P_W4_IDENTITY_RESOLVING - state %x", sm_identity_resolving_state(gatt_client->con_handle));
1097             switch (sm_identity_resolving_state(gatt_client->con_handle)){
1098                 case IRK_LOOKUP_SUCCEEDED:
1099                     gatt_client->le_device_index = sm_le_device_index(gatt_client->con_handle);
1100                     gatt_client->gatt_client_state = P_W4_CMAC_READY;
1101                     break;
1102                 case IRK_LOOKUP_FAILED:
1103                     gatt_client_handle_transaction_complete(gatt_client);
1104                     emit_gatt_complete_event(gatt_client, ATT_ERROR_BONDING_INFORMATION_MISSING);
1105                     return false;
1106                 default:
1107                     return false;
1108             }
1109 
1110             /* Fall through */
1111 
1112         case P_W4_CMAC_READY:
1113             if (sm_cmac_ready()){
1114                 sm_key_t csrk;
1115                 le_device_db_local_csrk_get(gatt_client->le_device_index, csrk);
1116                 uint32_t sign_counter = le_device_db_local_counter_get(gatt_client->le_device_index);
1117                 gatt_client->gatt_client_state = P_W4_CMAC_RESULT;
1118                 sm_cmac_signed_write_start(csrk, ATT_SIGNED_WRITE_COMMAND, gatt_client->attribute_handle, gatt_client->attribute_length, gatt_client->attribute_value, sign_counter, att_signed_write_handle_cmac_result);
1119             }
1120             return false;
1121 
1122         case P_W2_SEND_SIGNED_WRITE: {
1123             gatt_client->gatt_client_state = P_W4_SEND_SINGED_WRITE_DONE;
1124             // bump local signing counter
1125             uint32_t sign_counter = le_device_db_local_counter_get(gatt_client->le_device_index);
1126             le_device_db_local_counter_set(gatt_client->le_device_index, sign_counter + 1);
1127             // send signed write command
1128             send_gatt_signed_write_request(gatt_client, sign_counter);
1129             // finally, notifiy client that write is complete
1130             gatt_client_handle_transaction_complete(gatt_client);
1131             emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1132             return true;
1133         }
1134 #endif
1135         default:
1136             break;
1137     }
1138 
1139     // requested can send snow?
1140     if (gatt_client->write_without_response_callback){
1141         btstack_packet_handler_t packet_handler = gatt_client->write_without_response_callback;
1142         gatt_client->write_without_response_callback = NULL;
1143         uint8_t event[4];
1144         event[0] = GATT_EVENT_CAN_WRITE_WITHOUT_RESPONSE;
1145         event[1] = sizeof(event) - 2u;
1146         little_endian_store_16(event, 2, gatt_client->con_handle);
1147         packet_handler(HCI_EVENT_PACKET, gatt_client->con_handle, event, sizeof(event));
1148         return true; // to trigger requeueing (even if higher layer didn't sent)
1149     }
1150 
1151     return false;
1152 }
1153 
1154 static void gatt_client_run(void){
1155     btstack_linked_item_t *it;
1156     for (it = (btstack_linked_item_t *) gatt_client_connections; it != NULL; it = it->next){
1157         gatt_client_t * gatt_client = (gatt_client_t *) it;
1158         if (!att_dispatch_client_can_send_now(gatt_client->con_handle)) {
1159             att_dispatch_client_request_can_send_now_event(gatt_client->con_handle);
1160             return;
1161         }
1162         bool packet_sent = gatt_client_run_for_gatt_client(gatt_client);
1163         if (packet_sent){
1164             // request new permission
1165             att_dispatch_client_request_can_send_now_event(gatt_client->con_handle);
1166             // requeue client for fairness and exit
1167             // note: iterator has become invalid
1168             btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
1169             btstack_linked_list_add_tail(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
1170             return;
1171         }
1172     }
1173 }
1174 
1175 static void gatt_client_report_error_if_pending(gatt_client_t *gatt_client, uint8_t att_error_code) {
1176     if (is_ready(gatt_client) == 1) return;
1177     gatt_client_handle_transaction_complete(gatt_client);
1178     emit_gatt_complete_event(gatt_client, att_error_code);
1179 }
1180 
1181 static void gatt_client_handle_reencryption_complete(const uint8_t * packet){
1182     hci_con_handle_t con_handle = sm_event_reencryption_complete_get_handle(packet);
1183     gatt_client_t * gatt_client = gatt_client_get_context_for_handle(con_handle);
1184     if (gatt_client == NULL) return;
1185 
1186     // update security level
1187     gatt_client->security_level = gatt_client_le_security_level_for_connection(con_handle);
1188 
1189     gatt_client->reencryption_result = sm_event_reencryption_complete_get_status(packet);
1190     gatt_client->reencryption_active = false;
1191     gatt_client->wait_for_authentication_complete = 0;
1192 
1193     if (gatt_client->gatt_client_state == P_READY) return;
1194 
1195     switch (sm_event_reencryption_complete_get_status(packet)){
1196         case ERROR_CODE_SUCCESS:
1197             log_info("re-encryption success, retry operation");
1198             break;
1199         case ERROR_CODE_AUTHENTICATION_FAILURE:
1200         case ERROR_CODE_PIN_OR_KEY_MISSING:
1201 #if defined(ENABLE_GATT_CLIENT_PAIRING) && !defined(ENABLE_LE_PROACTIVE_AUTHENTICATION)
1202             if (gatt_client_required_security_level == LEVEL_0) {
1203                 // re-encryption failed for reactive authentication with pairing and we have a pending client request
1204                 // => try to resolve it by deleting bonding information if we started pairing before
1205                 // delete bonding information
1206                 int le_device_db_index = sm_le_device_index(gatt_client->con_handle);
1207                 btstack_assert(le_device_db_index >= 0);
1208                 log_info("reactive auth with pairing: delete bonding and start pairing");
1209 #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION
1210                 hci_remove_le_device_db_entry_from_resolving_list((uint16_t) le_device_db_index);
1211 #endif
1212                 le_device_db_remove(le_device_db_index);
1213                 // trigger pairing again
1214                 sm_request_pairing(gatt_client->con_handle);
1215                 break;
1216             }
1217 #endif
1218             // report bonding information missing
1219             gatt_client_handle_transaction_complete(gatt_client);
1220             emit_gatt_complete_event(gatt_client, ATT_ERROR_BONDING_INFORMATION_MISSING);
1221             break;
1222         default:
1223             // report bonding information missing
1224             gatt_client_handle_transaction_complete(gatt_client);
1225             emit_gatt_complete_event(gatt_client, gatt_client->pending_error_code);
1226             break;
1227     }
1228 }
1229 
1230 static void gatt_client_handle_disconnection_complete(const uint8_t * packet){
1231     log_info("GATT Client: HCI_EVENT_DISCONNECTION_COMPLETE");
1232     hci_con_handle_t con_handle = little_endian_read_16(packet,3);
1233     gatt_client_t * gatt_client = gatt_client_get_context_for_handle(con_handle);
1234     if (gatt_client == NULL) return;
1235 
1236     gatt_client_report_error_if_pending(gatt_client, ATT_ERROR_HCI_DISCONNECT_RECEIVED);
1237     gatt_client_timeout_stop(gatt_client);
1238     btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
1239     btstack_memory_gatt_client_free(gatt_client);
1240 }
1241 
1242 static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
1243     UNUSED(channel);    // ok: handling own l2cap events
1244     UNUSED(size);       // ok: there is no channel
1245 
1246     if (packet_type != HCI_EVENT_PACKET) return;
1247 
1248     hci_con_handle_t con_handle;
1249     gatt_client_t * gatt_client;
1250     switch (hci_event_packet_get_type(packet)) {
1251         case HCI_EVENT_DISCONNECTION_COMPLETE:
1252             gatt_client_handle_disconnection_complete(packet);
1253             break;
1254 
1255         // Pairing complete (with/without bonding=storing of pairing information)
1256         case SM_EVENT_PAIRING_COMPLETE:
1257             con_handle = sm_event_pairing_complete_get_handle(packet);
1258             gatt_client = gatt_client_get_context_for_handle(con_handle);
1259             if (gatt_client == NULL) break;
1260 
1261             // update security level
1262             gatt_client->security_level = gatt_client_le_security_level_for_connection(con_handle);
1263 
1264             if (gatt_client->wait_for_authentication_complete){
1265                 gatt_client->wait_for_authentication_complete = 0;
1266                 if (sm_event_pairing_complete_get_status(packet)){
1267                     log_info("pairing failed, report previous error 0x%x", gatt_client->pending_error_code);
1268                     gatt_client_report_error_if_pending(gatt_client, gatt_client->pending_error_code);
1269                 } else {
1270                     log_info("pairing success, retry operation");
1271                 }
1272             }
1273             break;
1274 
1275 #ifdef ENABLE_LE_SIGNED_WRITE
1276         // Identity Resolving completed (no code, gatt_client_run will continue)
1277         case SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED:
1278         case SM_EVENT_IDENTITY_RESOLVING_FAILED:
1279             break;
1280 #endif
1281 
1282         // re-encryption started
1283         case SM_EVENT_REENCRYPTION_STARTED:
1284             con_handle = sm_event_reencryption_complete_get_handle(packet);
1285             gatt_client = gatt_client_get_context_for_handle(con_handle);
1286             if (gatt_client == NULL) break;
1287 
1288             gatt_client->reencryption_active = true;
1289             gatt_client->reencryption_result = ERROR_CODE_SUCCESS;
1290             break;
1291 
1292         // re-encryption complete
1293         case SM_EVENT_REENCRYPTION_COMPLETE:
1294             gatt_client_handle_reencryption_complete(packet);
1295             break;
1296         default:
1297             break;
1298     }
1299 
1300     gatt_client_run();
1301 }
1302 
1303 static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
1304     gatt_client_t * gatt_client;
1305     if (size < 1u) return;
1306 
1307     if (packet_type == HCI_EVENT_PACKET) {
1308         switch (packet[0]){
1309             case L2CAP_EVENT_CAN_SEND_NOW:
1310                 gatt_client_run();
1311                 break;
1312             // att_server has negotiated the mtu for this connection, cache if context exists
1313             case ATT_EVENT_MTU_EXCHANGE_COMPLETE:
1314                 if (size < 6u) break;
1315                 gatt_client = gatt_client_get_context_for_handle(handle);
1316                 if (gatt_client == NULL) break;
1317                 gatt_client->mtu = little_endian_read_16(packet, 4);
1318                 break;
1319             default:
1320                 break;
1321         }
1322         return;
1323     }
1324 
1325     if (packet_type != ATT_DATA_PACKET) return;
1326 
1327     // special cases: notifications don't need a context while indications motivate creating one
1328     switch (packet[0]){
1329         case ATT_HANDLE_VALUE_NOTIFICATION:
1330             if (size < 3u) return;
1331             report_gatt_notification(handle, little_endian_read_16(packet,1u), &packet[3], size-3u);
1332             return;
1333         case ATT_HANDLE_VALUE_INDICATION:
1334             gatt_client = gatt_client_provide_context_for_handle(handle);
1335             break;
1336         default:
1337             gatt_client = gatt_client_get_context_for_handle(handle);
1338             break;
1339     }
1340 
1341     if (gatt_client == NULL) return;
1342 
1343     uint8_t error_code;
1344     switch (packet[0]){
1345         case ATT_EXCHANGE_MTU_RESPONSE:
1346         {
1347             if (size < 3u) break;
1348             uint16_t remote_rx_mtu = little_endian_read_16(packet, 1);
1349             uint16_t local_rx_mtu = l2cap_max_le_mtu();
1350             uint16_t mtu = (remote_rx_mtu < local_rx_mtu) ? remote_rx_mtu : local_rx_mtu;
1351 
1352             // set gatt client mtu
1353             gatt_client->mtu = mtu;
1354             gatt_client->mtu_state = MTU_EXCHANGED;
1355 
1356             // set per connection mtu state
1357             hci_connection_t * hci_connection = hci_connection_for_handle(handle);
1358             hci_connection->att_connection.mtu = gatt_client->mtu;
1359             hci_connection->att_connection.mtu_exchanged = true;
1360 
1361             emit_gatt_mtu_exchanged_result_event(gatt_client, gatt_client->mtu);
1362             break;
1363         }
1364         case ATT_READ_BY_GROUP_TYPE_RESPONSE:
1365             switch(gatt_client->gatt_client_state){
1366                 case P_W4_SERVICE_QUERY_RESULT:
1367                     report_gatt_services(gatt_client, packet, size);
1368                     trigger_next_service_query(gatt_client, get_last_result_handle_from_service_list(packet, size));
1369                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1370                     break;
1371                 default:
1372                     break;
1373             }
1374             break;
1375         case ATT_HANDLE_VALUE_INDICATION:
1376             if (size < 3u) break;
1377             report_gatt_indication(handle, little_endian_read_16(packet,1u), &packet[3], size-3u);
1378             gatt_client->send_confirmation = 1;
1379             break;
1380 
1381         case ATT_READ_BY_TYPE_RESPONSE:
1382             switch (gatt_client->gatt_client_state){
1383                 case P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT:
1384                     report_gatt_characteristics(gatt_client, packet, size);
1385                     trigger_next_characteristic_query(gatt_client, get_last_result_handle_from_characteristics_list(packet, size));
1386                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR
1387                     break;
1388                 case P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT:
1389                     report_gatt_characteristics(gatt_client, packet, size);
1390                     trigger_next_characteristic_query(gatt_client, get_last_result_handle_from_characteristics_list(packet, size));
1391                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR
1392                     break;
1393                 case P_W4_INCLUDED_SERVICE_QUERY_RESULT:
1394                 {
1395                     if (size < 2u) break;
1396                     uint16_t uuid16 = 0;
1397                     uint16_t pair_size = packet[1];
1398 
1399                     if (pair_size == 6u){
1400                         if (size < 8u) break;
1401                         // UUIDs not available, query first included service
1402                         gatt_client->start_group_handle = little_endian_read_16(packet, 2); // ready for next query
1403                         gatt_client->query_start_handle = little_endian_read_16(packet, 4);
1404                         gatt_client->query_end_handle = little_endian_read_16(packet, 6);
1405                         gatt_client->gatt_client_state = P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY;
1406                         break;
1407                     }
1408 
1409                     if (pair_size != 8u) break;
1410 
1411                     // UUIDs included, report all of them
1412                     uint16_t offset;
1413                     for (offset = 2u; (offset + 8u) <= size; offset += pair_size){
1414                         uint16_t include_handle = little_endian_read_16(packet, offset);
1415                         gatt_client->query_start_handle = little_endian_read_16(packet, offset + 2u);
1416                         gatt_client->query_end_handle = little_endian_read_16(packet, offset + 4u);
1417                         uuid16 = little_endian_read_16(packet, offset+6u);
1418                         report_gatt_included_service_uuid16(gatt_client, include_handle, uuid16);
1419                     }
1420 
1421                     trigger_next_included_service_query(gatt_client, get_last_result_handle_from_included_services_list(packet, size));
1422                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1423                     break;
1424                 }
1425 #ifndef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
1426                 case P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT:
1427                     gatt_client->client_characteristic_configuration_handle = little_endian_read_16(packet, 2);
1428                     gatt_client->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
1429                     break;
1430 #endif
1431                 case P_W4_READ_BY_TYPE_RESPONSE: {
1432                     uint16_t pair_size = packet[1];
1433                     // set last result handle to last valid handle, only used if pair_size invalid
1434                     uint16_t last_result_handle = 0xffff;
1435                     if (pair_size > 2){
1436                         uint16_t offset;
1437                         for (offset = 2; offset < size ; offset += pair_size){
1438                             uint16_t value_handle = little_endian_read_16(packet, offset);
1439                             report_gatt_characteristic_value(gatt_client, value_handle, &packet[offset + 2u], pair_size - 2u);
1440                             last_result_handle = value_handle;
1441                         }
1442                     }
1443                     trigger_next_read_by_type_query(gatt_client, last_result_handle);
1444                     break;
1445                 }
1446                 default:
1447                     break;
1448             }
1449             break;
1450         case ATT_READ_RESPONSE:
1451             switch (gatt_client->gatt_client_state){
1452                 case P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT:
1453                     if (size >= 17){
1454                         uint8_t uuid128[16];
1455                         reverse_128(&packet[1], uuid128);
1456                         report_gatt_included_service_uuid128(gatt_client, gatt_client->start_group_handle, uuid128);
1457                     }
1458                     trigger_next_included_service_query(gatt_client, gatt_client->start_group_handle);
1459                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1460                     break;
1461 
1462                 case P_W4_READ_CHARACTERISTIC_VALUE_RESULT:
1463                     gatt_client_handle_transaction_complete(gatt_client);
1464                     report_gatt_characteristic_value(gatt_client, gatt_client->attribute_handle, &packet[1], size - 1u);
1465                     emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1466                     break;
1467 
1468                 case P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT:
1469                     gatt_client_handle_transaction_complete(gatt_client);
1470                     report_gatt_characteristic_descriptor(gatt_client, gatt_client->attribute_handle, &packet[1], size - 1u, 0u);
1471                     emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1472                     break;
1473 
1474                 // Use ATT_READ_REQUEST for first blob of Read Long Characteristic
1475                 case P_W4_READ_BLOB_RESULT:
1476                     report_gatt_long_characteristic_value_blob(gatt_client, gatt_client->attribute_handle, &packet[1], size - 1u, gatt_client->attribute_offset);
1477                     trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_QUERY, size - 1u);
1478                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1479                     break;
1480 
1481                 // Use ATT_READ_REQUEST for first blob of Read Long Characteristic Descriptor
1482                 case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT:
1483                     report_gatt_long_characteristic_descriptor(gatt_client, gatt_client->attribute_handle, &packet[1], size-1u, gatt_client->attribute_offset);
1484                     trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY, size-1u);
1485                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1486                     break;
1487 
1488                 default:
1489                     break;
1490             }
1491             break;
1492 
1493         case ATT_FIND_BY_TYPE_VALUE_RESPONSE:
1494         {
1495             uint8_t pair_size = 4;
1496             int i;
1497             uint16_t start_group_handle;
1498             uint16_t   end_group_handle= 0xffff; // asserts GATT_EVENT_QUERY_COMPLETE is emitted if no results
1499             for (i = 1u; (i + pair_size) <= size; i += pair_size){
1500                 start_group_handle = little_endian_read_16(packet,i);
1501                 end_group_handle = little_endian_read_16(packet,i+2);
1502                 emit_gatt_service_query_result_event(gatt_client, start_group_handle, end_group_handle, gatt_client->uuid128);
1503             }
1504             trigger_next_service_by_uuid_query(gatt_client, end_group_handle);
1505             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1506             break;
1507         }
1508         case ATT_FIND_INFORMATION_REPLY:
1509         {
1510             if (size < 2u) break;
1511 
1512             uint8_t pair_size = 4;
1513             if (packet[1u] == 2u){
1514                 pair_size = 18;
1515             }
1516             uint16_t offset = 2;
1517 
1518             if (size < (pair_size + offset)) break;
1519             uint16_t last_descriptor_handle = little_endian_read_16(packet, size - pair_size);
1520 
1521 #ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
1522             log_info("ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY, state %x", gatt_client->gatt_client_state);
1523             if (gatt_client->gatt_client_state == P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT){
1524                 // iterate over descriptors looking for CCC
1525                 if (pair_size == 4){
1526                     while ((offset + 4) <= size){
1527                         uint16_t uuid16 = little_endian_read_16(packet, offset + 2);
1528                         if (uuid16 == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION){
1529                             gatt_client->client_characteristic_configuration_handle = little_endian_read_16(packet, offset);
1530                             gatt_client->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
1531                             log_info("CCC found %x", gatt_client->client_characteristic_configuration_handle);
1532                             break;
1533                         }
1534                         offset += pair_size;
1535                     }
1536                 }
1537                 if (is_query_done(gatt_client, last_descriptor_handle)){
1538 
1539                 } else {
1540                     // next
1541                     gatt_client->start_group_handle = last_descriptor_handle + 1;
1542                     gatt_client->gatt_client_state = P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY;
1543                 }
1544                 break;
1545             }
1546 #endif
1547             report_gatt_all_characteristic_descriptors(gatt_client, &packet[2], size - 2u, pair_size);
1548             trigger_next_characteristic_descriptor_query(gatt_client, last_descriptor_handle);
1549             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1550             break;
1551         }
1552 
1553         case ATT_WRITE_RESPONSE:
1554             switch (gatt_client->gatt_client_state){
1555                 case P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT:
1556                     gatt_client_handle_transaction_complete(gatt_client);
1557                     emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1558                     break;
1559                 case P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT:
1560                     gatt_client_handle_transaction_complete(gatt_client);
1561                     emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1562                     break;
1563                 case P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
1564                     gatt_client_handle_transaction_complete(gatt_client);
1565                     emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1566                     break;
1567                 default:
1568                     break;
1569             }
1570             break;
1571 
1572         case ATT_READ_BLOB_RESPONSE:{
1573             uint16_t received_blob_length = size-1u;
1574             switch(gatt_client->gatt_client_state){
1575                 case P_W4_READ_BLOB_RESULT:
1576                     report_gatt_long_characteristic_value_blob(gatt_client, gatt_client->attribute_handle, &packet[1], received_blob_length, gatt_client->attribute_offset);
1577                     trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_QUERY, received_blob_length);
1578                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1579                     break;
1580                 case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT:
1581                     report_gatt_long_characteristic_descriptor(gatt_client, gatt_client->attribute_handle,
1582                                                                &packet[1], received_blob_length,
1583                                                                gatt_client->attribute_offset);
1584                     trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY, received_blob_length);
1585                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1586                     break;
1587                 default:
1588                     break;
1589             }
1590             break;
1591         }
1592         case ATT_PREPARE_WRITE_RESPONSE:
1593             switch (gatt_client->gatt_client_state){
1594                 case P_W4_PREPARE_WRITE_SINGLE_RESULT:
1595                     gatt_client_handle_transaction_complete(gatt_client);
1596                     if (is_value_valid(gatt_client, packet, size)){
1597                         emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1598                     } else {
1599                         emit_gatt_complete_event(gatt_client, ATT_ERROR_DATA_MISMATCH);
1600                     }
1601                     break;
1602 
1603                 case P_W4_PREPARE_WRITE_RESULT:{
1604                     gatt_client->attribute_offset = little_endian_read_16(packet, 3);
1605                     trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_WRITE, P_W2_EXECUTE_PREPARED_WRITE);
1606                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1607                     break;
1608                 }
1609                 case P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:{
1610                     gatt_client->attribute_offset = little_endian_read_16(packet, 3);
1611                     trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR, P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR);
1612                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1613                     break;
1614                 }
1615                 case P_W4_PREPARE_RELIABLE_WRITE_RESULT:{
1616                     if (is_value_valid(gatt_client, packet, size)){
1617                         gatt_client->attribute_offset = little_endian_read_16(packet, 3);
1618                         trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_RELIABLE_WRITE, P_W2_EXECUTE_PREPARED_WRITE);
1619                         // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1620                         break;
1621                     }
1622                     gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH;
1623                     break;
1624                 }
1625                 default:
1626                     break;
1627             }
1628             break;
1629 
1630         case ATT_EXECUTE_WRITE_RESPONSE:
1631             switch (gatt_client->gatt_client_state){
1632                 case P_W4_EXECUTE_PREPARED_WRITE_RESULT:
1633                     gatt_client_handle_transaction_complete(gatt_client);
1634                     emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1635                     break;
1636                 case P_W4_CANCEL_PREPARED_WRITE_RESULT:
1637                     gatt_client_handle_transaction_complete(gatt_client);
1638                     emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1639                     break;
1640                 case P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT:
1641                     gatt_client_handle_transaction_complete(gatt_client);
1642                     emit_gatt_complete_event(gatt_client, ATT_ERROR_DATA_MISMATCH);
1643                     break;
1644                 case P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
1645                     gatt_client_handle_transaction_complete(gatt_client);
1646                     emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1647                     break;
1648                 default:
1649                     break;
1650 
1651             }
1652             break;
1653 
1654         case ATT_READ_MULTIPLE_RESPONSE:
1655             switch(gatt_client->gatt_client_state){
1656                 case P_W4_READ_MULTIPLE_RESPONSE:
1657                     report_gatt_characteristic_value(gatt_client, 0u, &packet[1], size - 1u);
1658                     gatt_client_handle_transaction_complete(gatt_client);
1659                     emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1660                     break;
1661                 default:
1662                     break;
1663             }
1664             break;
1665 
1666         case ATT_ERROR_RESPONSE:
1667             if (size < 5u) return;
1668             error_code = packet[4];
1669             switch (error_code){
1670                 case ATT_ERROR_ATTRIBUTE_NOT_FOUND: {
1671                     switch(gatt_client->gatt_client_state){
1672                         case P_W4_SERVICE_QUERY_RESULT:
1673                         case P_W4_SERVICE_WITH_UUID_RESULT:
1674                         case P_W4_INCLUDED_SERVICE_QUERY_RESULT:
1675                         case P_W4_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT:
1676                             gatt_client_handle_transaction_complete(gatt_client);
1677                             emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1678                             break;
1679                         case P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT:
1680                         case P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT:
1681                             characteristic_end_found(gatt_client, gatt_client->end_group_handle);
1682                             gatt_client_handle_transaction_complete(gatt_client);
1683                             emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1684                             break;
1685                         case P_W4_READ_BY_TYPE_RESPONSE:
1686                             gatt_client_handle_transaction_complete(gatt_client);
1687                             if (gatt_client->start_group_handle == gatt_client->query_start_handle){
1688                                 emit_gatt_complete_event(gatt_client, ATT_ERROR_ATTRIBUTE_NOT_FOUND);
1689                             } else {
1690                                 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1691                             }
1692                             break;
1693                         default:
1694                             gatt_client_report_error_if_pending(gatt_client, error_code);
1695                             break;
1696                     }
1697                     break;
1698                 }
1699 
1700 #ifdef ENABLE_GATT_CLIENT_PAIRING
1701 
1702                 case ATT_ERROR_INSUFFICIENT_AUTHENTICATION:
1703                 case ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
1704                 case ATT_ERROR_INSUFFICIENT_ENCRYPTION: {
1705 
1706                     // security too low
1707                     if (gatt_client->security_counter > 0) {
1708                         gatt_client_report_error_if_pending(gatt_client, error_code);
1709                         break;
1710                     }
1711                     // start security
1712                     gatt_client->security_counter++;
1713 
1714                     // setup action
1715                     int retry = 1;
1716                     switch (gatt_client->gatt_client_state){
1717                         case P_W4_READ_CHARACTERISTIC_VALUE_RESULT:
1718                             gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY ;
1719                             break;
1720                         case P_W4_READ_BLOB_RESULT:
1721                             gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_QUERY;
1722                             break;
1723                         case P_W4_READ_BY_TYPE_RESPONSE:
1724                             gatt_client->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
1725                             break;
1726                         case P_W4_READ_MULTIPLE_RESPONSE:
1727                             gatt_client->gatt_client_state = P_W2_SEND_READ_MULTIPLE_REQUEST;
1728                             break;
1729                         case P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT:
1730                             gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_VALUE;
1731                             break;
1732                         case P_W4_PREPARE_WRITE_RESULT:
1733                             gatt_client->gatt_client_state = P_W2_PREPARE_WRITE;
1734                             break;
1735                         case P_W4_PREPARE_WRITE_SINGLE_RESULT:
1736                             gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_SINGLE;
1737                             break;
1738                         case P_W4_PREPARE_RELIABLE_WRITE_RESULT:
1739                             gatt_client->gatt_client_state = P_W2_PREPARE_RELIABLE_WRITE;
1740                             break;
1741                         case P_W4_EXECUTE_PREPARED_WRITE_RESULT:
1742                             gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE;
1743                             break;
1744                         case P_W4_CANCEL_PREPARED_WRITE_RESULT:
1745                             gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE;
1746                             break;
1747                         case P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT:
1748                             gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH;
1749                             break;
1750                         case P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT:
1751                             gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY;
1752                             break;
1753                         case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT:
1754                             gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY;
1755                             break;
1756                         case P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
1757                             gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR;
1758                             break;
1759                         case P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT:
1760                             gatt_client->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
1761                             break;
1762                         case P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
1763                             gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR;
1764                             break;
1765                         case P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
1766                             gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR;
1767                             break;
1768 #ifdef ENABLE_LE_SIGNED_WRITE
1769                         case P_W4_SEND_SINGED_WRITE_DONE:
1770                             gatt_client->gatt_client_state = P_W2_SEND_SIGNED_WRITE;
1771                             break;
1772 #endif
1773                         default:
1774                             log_info("retry not supported for state %x", gatt_client->gatt_client_state);
1775                             retry = 0;
1776                             break;
1777                     }
1778 
1779                     if (!retry) {
1780                         gatt_client_report_error_if_pending(gatt_client, error_code);
1781                         break;
1782                     }
1783 
1784                     log_info("security error, start pairing");
1785 
1786                     // start pairing for higher security level
1787                     gatt_client->wait_for_authentication_complete = 1;
1788                     gatt_client->pending_error_code = error_code;
1789                     sm_request_pairing(gatt_client->con_handle);
1790                     break;
1791                 }
1792 #endif
1793 
1794                 // nothing we can do about that
1795                 case ATT_ERROR_INSUFFICIENT_AUTHORIZATION:
1796                 default:
1797                     gatt_client_report_error_if_pending(gatt_client, error_code);
1798                     break;
1799             }
1800             break;
1801 
1802         default:
1803             log_info("ATT Handler, unhandled response type 0x%02x", packet[0]);
1804             break;
1805     }
1806     gatt_client_run();
1807 }
1808 
1809 #ifdef ENABLE_LE_SIGNED_WRITE
1810 static void att_signed_write_handle_cmac_result(uint8_t hash[8]){
1811     btstack_linked_list_iterator_t it;
1812     btstack_linked_list_iterator_init(&it, &gatt_client_connections);
1813     while (btstack_linked_list_iterator_has_next(&it)){
1814         gatt_client_t * gatt_client = (gatt_client_t *) btstack_linked_list_iterator_next(&it);
1815         if (gatt_client->gatt_client_state == P_W4_CMAC_RESULT){
1816             // store result
1817             (void)memcpy(gatt_client->cmac, hash, 8);
1818             // reverse_64(hash, gatt_client->cmac);
1819             gatt_client->gatt_client_state = P_W2_SEND_SIGNED_WRITE;
1820             gatt_client_run();
1821             return;
1822         }
1823     }
1824 }
1825 
1826 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){
1827     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle(con_handle);
1828     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
1829     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
1830 
1831     gatt_client->callback = callback;
1832     gatt_client->attribute_handle = value_handle;
1833     gatt_client->attribute_length = message_len;
1834     gatt_client->attribute_value = message;
1835     gatt_client->gatt_client_state = P_W4_IDENTITY_RESOLVING;
1836     gatt_client_run();
1837     return ERROR_CODE_SUCCESS;
1838 }
1839 #endif
1840 
1841 uint8_t gatt_client_discover_primary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
1842     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
1843     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
1844     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
1845 
1846     gatt_client->callback = callback;
1847     gatt_client->start_group_handle = 0x0001;
1848     gatt_client->end_group_handle   = 0xffff;
1849     gatt_client->gatt_client_state = P_W2_SEND_SERVICE_QUERY;
1850     gatt_client->uuid16 = GATT_PRIMARY_SERVICE_UUID;
1851     gatt_client_run();
1852     return ERROR_CODE_SUCCESS;
1853 }
1854 
1855 uint8_t gatt_client_discover_secondary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
1856     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
1857     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
1858     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
1859 
1860     gatt_client->callback = callback;
1861     gatt_client->start_group_handle = 0x0001;
1862     gatt_client->end_group_handle   = 0xffff;
1863     gatt_client->gatt_client_state = P_W2_SEND_SERVICE_QUERY;
1864     gatt_client->uuid16 = GATT_SECONDARY_SERVICE_UUID;
1865     gatt_client_run();
1866     return ERROR_CODE_SUCCESS;
1867 }
1868 
1869 uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16){
1870     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
1871     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
1872     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
1873 
1874     gatt_client->callback = callback;
1875     gatt_client->start_group_handle = 0x0001;
1876     gatt_client->end_group_handle   = 0xffff;
1877     gatt_client->gatt_client_state = P_W2_SEND_SERVICE_WITH_UUID_QUERY;
1878     gatt_client->uuid16 = uuid16;
1879     uuid_add_bluetooth_prefix((uint8_t*) &(gatt_client->uuid128), gatt_client->uuid16);
1880     gatt_client_run();
1881     return ERROR_CODE_SUCCESS;
1882 }
1883 
1884 uint8_t gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, const uint8_t * uuid128){
1885     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
1886     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
1887     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
1888 
1889     gatt_client->callback = callback;
1890     gatt_client->start_group_handle = 0x0001;
1891     gatt_client->end_group_handle   = 0xffff;
1892     gatt_client->uuid16 = 0;
1893     (void)memcpy(gatt_client->uuid128, uuid128, 16);
1894     gatt_client->gatt_client_state = P_W2_SEND_SERVICE_WITH_UUID_QUERY;
1895     gatt_client_run();
1896     return ERROR_CODE_SUCCESS;
1897 }
1898 
1899 uint8_t gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service){
1900     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
1901     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
1902     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
1903 
1904     gatt_client->callback = callback;
1905     gatt_client->start_group_handle = service->start_group_handle;
1906     gatt_client->end_group_handle   = service->end_group_handle;
1907     gatt_client->filter_with_uuid = 0;
1908     gatt_client->characteristic_start_handle = 0;
1909     gatt_client->gatt_client_state = P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY;
1910     gatt_client_run();
1911     return ERROR_CODE_SUCCESS;
1912 }
1913 
1914 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){
1915     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
1916     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
1917     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
1918     gatt_client->callback = callback;
1919     gatt_client->start_group_handle = service->start_group_handle;
1920     gatt_client->end_group_handle   = service->end_group_handle;
1921     gatt_client->gatt_client_state = P_W2_SEND_INCLUDED_SERVICE_QUERY;
1922 
1923     gatt_client_run();
1924     return ERROR_CODE_SUCCESS;
1925 }
1926 
1927 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){
1928     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
1929     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
1930     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
1931 
1932     gatt_client->callback = callback;
1933     gatt_client->start_group_handle = start_handle;
1934     gatt_client->end_group_handle   = end_handle;
1935     gatt_client->filter_with_uuid = 1;
1936     gatt_client->uuid16 = uuid16;
1937     uuid_add_bluetooth_prefix((uint8_t*) &(gatt_client->uuid128), uuid16);
1938     gatt_client->characteristic_start_handle = 0;
1939     gatt_client->gatt_client_state = P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY;
1940     gatt_client_run();
1941     return ERROR_CODE_SUCCESS;
1942 }
1943 
1944 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){
1945     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
1946     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
1947     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
1948 
1949     gatt_client->callback = callback;
1950     gatt_client->start_group_handle = start_handle;
1951     gatt_client->end_group_handle   = end_handle;
1952     gatt_client->filter_with_uuid = 1;
1953     gatt_client->uuid16 = 0;
1954     (void)memcpy(gatt_client->uuid128, uuid128, 16);
1955     gatt_client->characteristic_start_handle = 0;
1956     gatt_client->gatt_client_state = P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY;
1957     gatt_client_run();
1958     return ERROR_CODE_SUCCESS;
1959 }
1960 
1961 
1962 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){
1963     return gatt_client_discover_characteristics_for_handle_range_by_uuid16(callback, con_handle, service->start_group_handle, service->end_group_handle, uuid16);
1964 }
1965 
1966 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){
1967     return gatt_client_discover_characteristics_for_handle_range_by_uuid128(callback, con_handle, service->start_group_handle, service->end_group_handle, uuid128);
1968 }
1969 
1970 uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){
1971     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
1972     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
1973     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
1974 
1975     if (characteristic->value_handle == characteristic->end_handle){
1976         emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1977         return ERROR_CODE_SUCCESS;
1978     }
1979     gatt_client->callback = callback;
1980     gatt_client->start_group_handle = characteristic->value_handle + 1u;
1981     gatt_client->end_group_handle   = characteristic->end_handle;
1982     gatt_client->gatt_client_state = P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY;
1983     gatt_client_run();
1984     return ERROR_CODE_SUCCESS;
1985 }
1986 
1987 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){
1988     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
1989     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
1990     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
1991 
1992     gatt_client->callback = callback;
1993     gatt_client->attribute_handle = value_handle;
1994     gatt_client->attribute_offset = 0;
1995     gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY;
1996     gatt_client_run();
1997     return ERROR_CODE_SUCCESS;
1998 }
1999 
2000 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){
2001     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2002     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2003     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2004 
2005     gatt_client->callback = callback;
2006     gatt_client->start_group_handle = start_handle;
2007     gatt_client->end_group_handle = end_handle;
2008     gatt_client->query_start_handle = start_handle;
2009     gatt_client->query_end_handle = end_handle;
2010     gatt_client->uuid16 = uuid16;
2011     uuid_add_bluetooth_prefix((uint8_t*) &(gatt_client->uuid128), uuid16);
2012     gatt_client->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
2013     gatt_client_run();
2014     return ERROR_CODE_SUCCESS;
2015 }
2016 
2017 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){
2018     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2019     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2020     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2021 
2022     gatt_client->callback = callback;
2023     gatt_client->start_group_handle = start_handle;
2024     gatt_client->end_group_handle = end_handle;
2025     gatt_client->query_start_handle = start_handle;
2026     gatt_client->query_end_handle = end_handle;
2027     gatt_client->uuid16 = 0;
2028     (void)memcpy(gatt_client->uuid128, uuid128, 16);
2029     gatt_client->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
2030     gatt_client_run();
2031     return ERROR_CODE_SUCCESS;
2032 }
2033 
2034 
2035 uint8_t gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){
2036     return gatt_client_read_value_of_characteristic_using_value_handle(callback, con_handle, characteristic->value_handle);
2037 }
2038 
2039 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){
2040     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2041     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2042     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2043 
2044     gatt_client->callback = callback;
2045     gatt_client->attribute_handle = value_handle;
2046     gatt_client->attribute_offset = offset;
2047     gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_QUERY;
2048     gatt_client_run();
2049     return ERROR_CODE_SUCCESS;
2050 }
2051 
2052 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){
2053     return gatt_client_read_long_value_of_characteristic_using_value_handle_with_offset(callback, con_handle, value_handle, 0);
2054 }
2055 
2056 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){
2057     return gatt_client_read_long_value_of_characteristic_using_value_handle(callback, con_handle, characteristic->value_handle);
2058 }
2059 
2060 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){
2061     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2062     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2063     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2064 
2065     gatt_client->callback = callback;
2066     gatt_client->read_multiple_handle_count = num_value_handles;
2067     gatt_client->read_multiple_handles = value_handles;
2068     gatt_client->gatt_client_state = P_W2_SEND_READ_MULTIPLE_REQUEST;
2069     gatt_client_run();
2070     return ERROR_CODE_SUCCESS;
2071 }
2072 
2073 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){
2074     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle(con_handle);
2075     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2076 
2077     if (value_length > (gatt_client->mtu - 3u)) return GATT_CLIENT_VALUE_TOO_LONG;
2078     if (!att_dispatch_client_can_send_now(gatt_client->con_handle)) return GATT_CLIENT_BUSY;
2079 
2080     return att_write_request(ATT_WRITE_COMMAND, gatt_client->con_handle, value_handle, value_length, value);
2081 }
2082 
2083 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){
2084     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2085     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2086     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2087 
2088     gatt_client->callback = callback;
2089     gatt_client->attribute_handle = value_handle;
2090     gatt_client->attribute_length = value_length;
2091     gatt_client->attribute_value = value;
2092     gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_VALUE;
2093     gatt_client_run();
2094     return ERROR_CODE_SUCCESS;
2095 }
2096 
2097 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){
2098     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2099     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2100     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2101 
2102     gatt_client->callback = callback;
2103     gatt_client->attribute_handle = value_handle;
2104     gatt_client->attribute_length = value_length;
2105     gatt_client->attribute_offset = offset;
2106     gatt_client->attribute_value = value;
2107     gatt_client->gatt_client_state = P_W2_PREPARE_WRITE;
2108     gatt_client_run();
2109     return ERROR_CODE_SUCCESS;
2110 }
2111 
2112 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){
2113     return gatt_client_write_long_value_of_characteristic_with_offset(callback, con_handle, value_handle, 0, value_length, value);
2114 }
2115 
2116 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){
2117     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2118     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2119     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2120 
2121     gatt_client->callback = callback;
2122     gatt_client->attribute_handle = value_handle;
2123     gatt_client->attribute_length = value_length;
2124     gatt_client->attribute_offset = 0;
2125     gatt_client->attribute_value = value;
2126     gatt_client->gatt_client_state = P_W2_PREPARE_RELIABLE_WRITE;
2127     gatt_client_run();
2128     return ERROR_CODE_SUCCESS;
2129 }
2130 
2131 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){
2132     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2133     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2134     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2135 
2136     if ( (configuration & GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION) &&
2137         ((characteristic->properties & ATT_PROPERTY_NOTIFY) == 0u)) {
2138         log_info("gatt_client_write_client_characteristic_configuration: GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED");
2139         return GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED;
2140     } else if ( (configuration & GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION) &&
2141                ((characteristic->properties & ATT_PROPERTY_INDICATE) == 0u)){
2142         log_info("gatt_client_write_client_characteristic_configuration: GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED");
2143         return GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED;
2144     }
2145 
2146     gatt_client->callback = callback;
2147     gatt_client->start_group_handle = characteristic->value_handle;
2148     gatt_client->end_group_handle = characteristic->end_handle;
2149     little_endian_store_16(gatt_client->client_characteristic_configuration_value, 0, configuration);
2150 
2151 #ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
2152     gatt_client->gatt_client_state = P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY;
2153 #else
2154     gatt_client->gatt_client_state = P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY;
2155 #endif
2156     gatt_client_run();
2157     return ERROR_CODE_SUCCESS;
2158 }
2159 
2160 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){
2161     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2162     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2163     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2164 
2165     gatt_client->callback = callback;
2166     gatt_client->attribute_handle = descriptor_handle;
2167 
2168     gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY;
2169     gatt_client_run();
2170     return ERROR_CODE_SUCCESS;
2171 }
2172 
2173 uint8_t gatt_client_read_characteristic_descriptor(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_descriptor_t * descriptor){
2174     return gatt_client_read_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle);
2175 }
2176 
2177 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){
2178     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2179     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2180     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2181 
2182     gatt_client->callback = callback;
2183     gatt_client->attribute_handle = descriptor_handle;
2184     gatt_client->attribute_offset = offset;
2185     gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY;
2186     gatt_client_run();
2187     return ERROR_CODE_SUCCESS;
2188 }
2189 
2190 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){
2191     return gatt_client_read_long_characteristic_descriptor_using_descriptor_handle_with_offset(callback, con_handle, descriptor_handle, 0);
2192 }
2193 
2194 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){
2195     return gatt_client_read_long_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle);
2196 }
2197 
2198 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){
2199     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2200     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2201     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2202 
2203     gatt_client->callback = callback;
2204     gatt_client->attribute_handle = descriptor_handle;
2205     gatt_client->attribute_length = value_length;
2206     gatt_client->attribute_offset = 0;
2207     gatt_client->attribute_value = value;
2208     gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR;
2209     gatt_client_run();
2210     return ERROR_CODE_SUCCESS;
2211 }
2212 
2213 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){
2214     return gatt_client_write_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle, value_length, value);
2215 }
2216 
2217 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){
2218     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2219     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2220     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2221 
2222     gatt_client->callback = callback;
2223     gatt_client->attribute_handle = descriptor_handle;
2224     gatt_client->attribute_length = value_length;
2225     gatt_client->attribute_offset = offset;
2226     gatt_client->attribute_value = value;
2227     gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR;
2228     gatt_client_run();
2229     return ERROR_CODE_SUCCESS;
2230 }
2231 
2232 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){
2233     return gatt_client_write_long_characteristic_descriptor_using_descriptor_handle_with_offset(callback, con_handle, descriptor_handle, 0, value_length, value);
2234 }
2235 
2236 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){
2237     return gatt_client_write_long_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle, value_length, value);
2238 }
2239 
2240 /**
2241  * @brief -> gatt complete event
2242  */
2243 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){
2244     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2245     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2246     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2247 
2248     gatt_client->callback = callback;
2249     gatt_client->attribute_handle = attribute_handle;
2250     gatt_client->attribute_length = value_length;
2251     gatt_client->attribute_offset = offset;
2252     gatt_client->attribute_value = value;
2253     gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_SINGLE;
2254     gatt_client_run();
2255     return ERROR_CODE_SUCCESS;
2256 }
2257 
2258 /**
2259  * @brief -> gatt complete event
2260  */
2261 uint8_t gatt_client_execute_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
2262     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2263 
2264     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2265     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2266 
2267     gatt_client->callback = callback;
2268     gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE;
2269     gatt_client_run();
2270     return ERROR_CODE_SUCCESS;
2271 }
2272 
2273 /**
2274  * @brief -> gatt complete event
2275  */
2276 uint8_t gatt_client_cancel_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
2277     gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle);
2278     if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2279     if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE;
2280 
2281     gatt_client->callback = callback;
2282     gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE;
2283     gatt_client_run();
2284     return ERROR_CODE_SUCCESS;
2285 }
2286 
2287 void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t * service){
2288     service->start_group_handle = little_endian_read_16(packet, offset);
2289     service->end_group_handle = little_endian_read_16(packet, offset + 2);
2290     reverse_128(&packet[offset + 4], service->uuid128);
2291     if (uuid_has_bluetooth_prefix(service->uuid128)){
2292         service->uuid16 = big_endian_read_32(service->uuid128, 0);
2293     } else {
2294         service->uuid16 = 0;
2295     }
2296 }
2297 
2298 void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic){
2299     characteristic->start_handle = little_endian_read_16(packet, offset);
2300     characteristic->value_handle = little_endian_read_16(packet, offset + 2);
2301     characteristic->end_handle = little_endian_read_16(packet, offset + 4);
2302     characteristic->properties = little_endian_read_16(packet, offset + 6);
2303     reverse_128(&packet[offset+8], characteristic->uuid128);
2304     if (uuid_has_bluetooth_prefix(characteristic->uuid128)){
2305         characteristic->uuid16 = big_endian_read_32(characteristic->uuid128, 0);
2306     } else {
2307         characteristic->uuid16 = 0;
2308     }
2309 }
2310 
2311 void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor){
2312     descriptor->handle = little_endian_read_16(packet, offset);
2313     reverse_128(&packet[offset+2], descriptor->uuid128);
2314     if (uuid_has_bluetooth_prefix(descriptor->uuid128)){
2315         descriptor->uuid16 = big_endian_read_32(descriptor->uuid128, 0);
2316     } else {
2317         descriptor->uuid16 = 0;
2318     }
2319 }
2320 
2321 void gatt_client_send_mtu_negotiation(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
2322     gatt_client_t * context = gatt_client_provide_context_for_handle(con_handle);
2323     if (context == NULL) return;
2324     if (context->mtu_state == MTU_AUTO_EXCHANGE_DISABLED){
2325         context->callback = callback;
2326         context->mtu_state = SEND_MTU_EXCHANGE;
2327         gatt_client_run();
2328     }
2329 }
2330 
2331 uint8_t gatt_client_request_can_write_without_response_event(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
2332     gatt_client_t * context = gatt_client_provide_context_for_handle(con_handle);
2333     if (context == NULL) return BTSTACK_MEMORY_ALLOC_FAILED;
2334     if (context->write_without_response_callback != NULL) return GATT_CLIENT_IN_WRONG_STATE;
2335     context->write_without_response_callback = callback;
2336     att_dispatch_client_request_can_send_now_event(context->con_handle);
2337     return ERROR_CODE_SUCCESS;
2338 }
2339 
2340 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
2341 void gatt_client_att_packet_handler_fuzz(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
2342     gatt_client_att_packet_handler(packet_type, handle, packet, size);
2343 }
2344 
2345 gatt_client_t * gatt_client_get_client(hci_con_handle_t con_handle){
2346     return gatt_client_provide_context_for_handle(con_handle);
2347 }
2348 #endif
2349