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