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