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