xref: /btstack/src/ble/gatt_client.c (revision f125a8ef20418254e88108128f7b794243affefe)
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 "ble/att_db.h"
48 #include "ble/gatt_client.h"
49 #include "ble/le_device_db.h"
50 #include "ble/sm.h"
51 #include "btstack_debug.h"
52 #include "btstack_event.h"
53 #include "btstack_memory.h"
54 #include "btstack_run_loop.h"
55 #include "btstack_util.h"
56 #include "hci.h"
57 #include "hci_dump.h"
58 #include "l2cap.h"
59 #include "classic/sdp_client.h"
60 #include "bluetooth_gatt.h"
61 #include "bluetooth_sdp.h"
62 #include "classic/sdp_util.h"
63 
64 static btstack_linked_list_t gatt_client_connections;
65 static btstack_linked_list_t gatt_client_value_listeners;
66 static btstack_packet_callback_registration_t hci_event_callback_registration;
67 static btstack_packet_callback_registration_t sm_event_callback_registration;
68 
69 // GATT Client Configuration
70 static bool                 gatt_client_mtu_exchange_enabled;
71 static gap_security_level_t gatt_client_required_security_level;
72 
73 static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size);
74 static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
75 static void gatt_client_report_error_if_pending(gatt_client_t *gatt_client, uint8_t att_error_code);
76 
77 #ifdef ENABLE_LE_SIGNED_WRITE
78 static void att_signed_write_handle_cmac_result(uint8_t hash[8]);
79 #endif
80 
81 #ifdef ENABLE_GATT_OVER_EATT
82 static bool gatt_client_le_enhanced_handle_can_send_query(gatt_client_t * gatt_client);
83 #endif
84 
85 void gatt_client_init(void){
86     gatt_client_connections = NULL;
87 
88     // default configuration
89     gatt_client_mtu_exchange_enabled    = true;
90     gatt_client_required_security_level = LEVEL_0;
91 
92     // register for HCI Events
93     hci_event_callback_registration.callback = &gatt_client_event_packet_handler;
94     hci_add_event_handler(&hci_event_callback_registration);
95 
96     // register for SM Events
97     sm_event_callback_registration.callback = &gatt_client_event_packet_handler;
98     sm_add_event_handler(&sm_event_callback_registration);
99 
100     // and ATT Client PDUs
101     att_dispatch_register_client(gatt_client_att_packet_handler);
102 }
103 
104 void gatt_client_set_required_security_level(gap_security_level_t level){
105     gatt_client_required_security_level = level;
106 }
107 
108 static gatt_client_t * gatt_client_for_timer(btstack_timer_source_t * ts){
109     btstack_linked_list_iterator_t it;
110     btstack_linked_list_iterator_init(&it, &gatt_client_connections);
111     while (btstack_linked_list_iterator_has_next(&it)){
112         gatt_client_t * gatt_client = (gatt_client_t *) btstack_linked_list_iterator_next(&it);
113         if (&gatt_client->gc_timeout == ts) {
114             return gatt_client;
115         }
116     }
117     return NULL;
118 }
119 
120 static void gatt_client_timeout_handler(btstack_timer_source_t * timer){
121     gatt_client_t * gatt_client = gatt_client_for_timer(timer);
122     if (gatt_client == NULL) return;
123     log_info("GATT client timeout handle, handle 0x%02x", gatt_client->con_handle);
124     gatt_client_report_error_if_pending(gatt_client, ATT_ERROR_TIMEOUT);
125 }
126 
127 static void gatt_client_timeout_start(gatt_client_t * gatt_client){
128     log_info("GATT client timeout start, handle 0x%02x", gatt_client->con_handle);
129     btstack_run_loop_remove_timer(&gatt_client->gc_timeout);
130     btstack_run_loop_set_timer_handler(&gatt_client->gc_timeout, gatt_client_timeout_handler);
131     btstack_run_loop_set_timer(&gatt_client->gc_timeout, 30000); // 30 seconds sm timeout
132     btstack_run_loop_add_timer(&gatt_client->gc_timeout);
133 }
134 
135 static void gatt_client_timeout_stop(gatt_client_t * gatt_client){
136     log_info("GATT client timeout stop, handle 0x%02x", gatt_client->con_handle);
137     btstack_run_loop_remove_timer(&gatt_client->gc_timeout);
138 }
139 
140 static gap_security_level_t gatt_client_le_security_level_for_connection(hci_con_handle_t con_handle){
141     uint8_t encryption_key_size = gap_encryption_key_size(con_handle);
142     if (encryption_key_size == 0) return LEVEL_0;
143 
144     bool authenticated = gap_authenticated(con_handle);
145     if (!authenticated) return LEVEL_2;
146 
147     return encryption_key_size == 16 ? LEVEL_4 : LEVEL_3;
148 }
149 
150 static gatt_client_t * gatt_client_get_context_for_handle(uint16_t handle){
151     btstack_linked_item_t *it;
152     for (it = (btstack_linked_item_t *) gatt_client_connections; it != NULL; it = it->next){
153         gatt_client_t * gatt_client = (gatt_client_t *) it;
154         if (gatt_client->con_handle == handle){
155             return gatt_client;
156         }
157     }
158     return NULL;
159 }
160 
161 
162 // @return gatt_client context
163 // returns existing one, or tries to setup new one
164 static uint8_t gatt_client_provide_context_for_handle(hci_con_handle_t con_handle, gatt_client_t ** out_gatt_client){
165     gatt_client_t * gatt_client = gatt_client_get_context_for_handle(con_handle);
166 
167     if (gatt_client != NULL){
168         *out_gatt_client = gatt_client;
169         return ERROR_CODE_SUCCESS;
170     }
171 
172     // bail if no such hci connection
173     hci_connection_t * hci_connection = hci_connection_for_handle(con_handle);
174     if (hci_connection == NULL){
175         log_error("No connection for handle 0x%04x", con_handle);
176         *out_gatt_client = NULL;
177         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
178     }
179 
180     gatt_client = btstack_memory_gatt_client_get();
181     if (gatt_client == NULL){
182         *out_gatt_client = NULL;
183         return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
184     }
185     // init state
186     gatt_client->bearer_type = ATT_BEARER_UNENHANCED_LE;
187     gatt_client->con_handle = con_handle;
188     gatt_client->mtu = ATT_DEFAULT_MTU;
189     gatt_client->security_level = gatt_client_le_security_level_for_connection(con_handle);
190     if (gatt_client_mtu_exchange_enabled){
191         gatt_client->mtu_state = SEND_MTU_EXCHANGE;
192     } else {
193         gatt_client->mtu_state = MTU_AUTO_EXCHANGE_DISABLED;
194     }
195     gatt_client->gatt_client_state = P_READY;
196 #ifdef ENABLE_GATT_OVER_EATT
197     gatt_client->eatt_state = GATT_CLIENT_EATT_IDLE;
198 #endif
199     btstack_linked_list_add(&gatt_client_connections, (btstack_linked_item_t*)gatt_client);
200 
201     // get unenhanced att bearer state
202     if (hci_connection->att_connection.mtu_exchanged){
203         gatt_client->mtu = hci_connection->att_connection.mtu;
204         gatt_client->mtu_state = MTU_EXCHANGED;
205     }
206     *out_gatt_client = gatt_client;
207     return ERROR_CODE_SUCCESS;
208 }
209 
210 static bool is_ready(gatt_client_t * gatt_client){
211     return gatt_client->gatt_client_state == P_READY;
212 }
213 
214 static uint8_t gatt_client_provide_context_for_request(hci_con_handle_t con_handle, gatt_client_t ** out_gatt_client){
215     gatt_client_t * gatt_client = NULL;
216     uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client);
217     if (status != ERROR_CODE_SUCCESS){
218         return status;
219     }
220 
221 #ifdef ENABLE_GATT_OVER_EATT
222     if (gatt_client->eatt_state == GATT_CLIENT_EATT_READY){
223         btstack_linked_list_iterator_t it;
224         gatt_client_t * eatt_client = NULL;
225         // find free eatt client
226         btstack_linked_list_iterator_init(&it, &gatt_client->eatt_clients);
227         while (btstack_linked_list_iterator_has_next(&it)){
228             gatt_client_t * client = (gatt_client_t *) btstack_linked_list_iterator_next(&it);
229             if (client->gatt_client_state == P_READY){
230                 eatt_client = client;
231                 break;
232             }
233         }
234         if (eatt_client == NULL){
235             return ERROR_CODE_COMMAND_DISALLOWED;
236         }
237         gatt_client = eatt_client;
238     }
239 #endif
240 
241     if (is_ready(gatt_client) == 0){
242         return GATT_CLIENT_IN_WRONG_STATE;
243     }
244 
245     gatt_client_timeout_start(gatt_client);
246 
247     *out_gatt_client = gatt_client;
248 
249     return status;
250 }
251 
252 int gatt_client_is_ready(hci_con_handle_t con_handle){
253     gatt_client_t * gatt_client;
254     uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client);
255     if (status != ERROR_CODE_SUCCESS){
256         return 0;
257     }
258     return is_ready(gatt_client) ? 1 : 0;
259 }
260 
261 void gatt_client_mtu_enable_auto_negotiation(uint8_t enabled){
262     gatt_client_mtu_exchange_enabled = enabled != 0;
263 }
264 
265 uint8_t gatt_client_get_mtu(hci_con_handle_t con_handle, uint16_t * mtu){
266     gatt_client_t * gatt_client;
267     uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client);
268     if (status != ERROR_CODE_SUCCESS){
269         return status;
270     }
271 
272     if ((gatt_client->mtu_state == MTU_EXCHANGED) || (gatt_client->mtu_state == MTU_AUTO_EXCHANGE_DISABLED)){
273         *mtu = gatt_client->mtu;
274         return ERROR_CODE_SUCCESS;
275     }
276     *mtu = ATT_DEFAULT_MTU;
277     return GATT_CLIENT_IN_WRONG_STATE;
278 }
279 
280 #ifdef ENABLE_GATT_OVER_CLASSIC
281     // TODO: re-use single buffer for all eatt channels
282 static uint8_t gatt_client_le_enhanced_request_buffer[512];
283 #endif
284 
285 static uint8_t *gatt_client_reserve_request_buffer(gatt_client_t *gatt_client) {
286     switch (gatt_client->bearer_type){
287 #ifdef ENABLE_GATT_OVER_CLASSIC
288         case ATT_BEARER_UNENHANCED_CLASSIC:
289 #endif
290         case ATT_BEARER_UNENHANCED_LE:
291             l2cap_reserve_packet_buffer();
292             return l2cap_get_outgoing_buffer();
293 #ifdef ENABLE_GATT_OVER_EATT
294         case ATT_BEARER_ENHANCED_LE:
295             return gatt_client->eatt_storage_buffer;
296 #endif
297         default:
298             btstack_unreachable();
299             break;
300     }
301     return NULL;
302 }
303 
304 // precondition: can_send_packet_now == TRUE
305 static uint8_t gatt_client_send(gatt_client_t * gatt_client, uint16_t len){
306     switch (gatt_client->bearer_type){
307         case ATT_BEARER_UNENHANCED_LE:
308             return l2cap_send_prepared_connectionless(gatt_client->con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, len);
309 #ifdef ENABLE_GATT_OVER_CLASSIC
310         case ATT_BEARER_UNENHANCED_CLASSIC:
311             return l2cap_send_prepared(gatt_client->l2cap_cid, len);
312 #endif
313 #ifdef ENABLE_GATT_OVER_EATT
314         case ATT_BEARER_ENHANCED_LE:
315             return l2cap_send(gatt_client->l2cap_cid, gatt_client->eatt_storage_buffer, len);
316 #endif
317         default:
318             btstack_unreachable();
319             return ERROR_CODE_HARDWARE_FAILURE;
320     }
321 }
322 
323 // precondition: can_send_packet_now == TRUE
324 static uint8_t att_confirmation(gatt_client_t * gatt_client) {
325     uint8_t *request = gatt_client_reserve_request_buffer(gatt_client);
326 
327     request[0] = ATT_HANDLE_VALUE_CONFIRMATION;
328 
329     return gatt_client_send(gatt_client, 1);
330 }
331 
332 // precondition: can_send_packet_now == TRUE
333 static uint8_t att_find_information_request(gatt_client_t *gatt_client, uint8_t request_type, uint16_t start_handle,
334                                             uint16_t end_handle) {
335     uint8_t *request = gatt_client_reserve_request_buffer(gatt_client);
336 
337     request[0] = request_type;
338     little_endian_store_16(request, 1, start_handle);
339     little_endian_store_16(request, 3, end_handle);
340 
341     return gatt_client_send(gatt_client, 5);
342 }
343 
344 // precondition: can_send_packet_now == TRUE
345 static uint8_t
346 att_find_by_type_value_request(gatt_client_t *gatt_client, uint8_t request_type, uint16_t attribute_group_type,
347                                uint16_t start_handle, uint16_t end_handle, uint8_t *value, uint16_t value_size) {
348     uint8_t *request = gatt_client_reserve_request_buffer(gatt_client);
349     request[0] = request_type;
350 
351     little_endian_store_16(request, 1, start_handle);
352     little_endian_store_16(request, 3, end_handle);
353     little_endian_store_16(request, 5, attribute_group_type);
354     (void)memcpy(&request[7], value, value_size);
355 
356     return gatt_client_send(gatt_client, 7u + value_size);
357 }
358 
359 // precondition: can_send_packet_now == TRUE
360 static uint8_t
361 att_read_by_type_or_group_request_for_uuid16(gatt_client_t *gatt_client, uint8_t request_type, uint16_t uuid16,
362                                              uint16_t start_handle, uint16_t end_handle) {
363     uint8_t *request = gatt_client_reserve_request_buffer(gatt_client);
364 
365     request[0] = request_type;
366     little_endian_store_16(request, 1, start_handle);
367     little_endian_store_16(request, 3, end_handle);
368     little_endian_store_16(request, 5, uuid16);
369 
370     return gatt_client_send(gatt_client, 7);
371 }
372 
373 // precondition: can_send_packet_now == TRUE
374 static uint8_t
375 att_read_by_type_or_group_request_for_uuid128(gatt_client_t *gatt_client, uint8_t request_type, const uint8_t *uuid128,
376                                               uint16_t start_handle, uint16_t end_handle) {
377     uint8_t *request = gatt_client_reserve_request_buffer(gatt_client);
378 
379     request[0] = request_type;
380     little_endian_store_16(request, 1, start_handle);
381     little_endian_store_16(request, 3, end_handle);
382     reverse_128(uuid128, &request[5]);
383 
384     return gatt_client_send(gatt_client, 21);
385 }
386 
387 // precondition: can_send_packet_now == TRUE
388 static uint8_t att_read_request(gatt_client_t *gatt_client, uint8_t request_type, uint16_t attribute_handle) {
389     uint8_t *request = gatt_client_reserve_request_buffer(gatt_client);
390 
391     request[0] = request_type;
392     little_endian_store_16(request, 1, attribute_handle);
393 
394     return gatt_client_send(gatt_client, 3);
395 }
396 
397 // precondition: can_send_packet_now == TRUE
398 static uint8_t att_read_blob_request(gatt_client_t *gatt_client, uint8_t request_type, uint16_t attribute_handle,
399                                      uint16_t value_offset) {
400     uint8_t *request = gatt_client_reserve_request_buffer(gatt_client);
401 
402     request[0] = request_type;
403     little_endian_store_16(request, 1, attribute_handle);
404     little_endian_store_16(request, 3, value_offset);
405 
406     return gatt_client_send(gatt_client, 5);
407 }
408 
409 static uint8_t
410 att_read_multiple_request_with_opcode(gatt_client_t *gatt_client, uint16_t num_value_handles, uint16_t *value_handles, uint8_t opcode) {
411     uint8_t *request = gatt_client_reserve_request_buffer(gatt_client);
412 
413     request[0] = opcode;
414     uint16_t i;
415     uint16_t offset = 1;
416     for (i=0;i<num_value_handles;i++){
417         little_endian_store_16(request, offset, value_handles[i]);
418         offset += 2;
419     }
420 
421     return gatt_client_send(gatt_client, offset);
422 }
423 
424 static uint8_t
425 att_read_multiple_request(gatt_client_t *gatt_client, uint16_t num_value_handles, uint16_t *value_handles) {
426     return att_read_multiple_request_with_opcode(gatt_client, num_value_handles, value_handles, ATT_READ_MULTIPLE_REQUEST);
427 }
428 
429 #ifdef ENABLE_GATT_OVER_EATT
430 static uint8_t
431 att_read_multiple_variable_request(gatt_client_t *gatt_client, uint16_t num_value_handles, uint16_t *value_handles) {
432     return att_read_multiple_request_with_opcode(gatt_client, num_value_handles, value_handles, ATT_READ_MULTIPLE_VARIABLE_REQ);
433 }
434 #endif
435 
436 #ifdef ENABLE_LE_SIGNED_WRITE
437 // precondition: can_send_packet_now == TRUE
438 static uint8_t att_signed_write_request(gatt_client_t *gatt_client, uint16_t request_type, uint16_t attribute_handle,
439                                         uint16_t value_length, uint8_t *value, uint32_t sign_counter, uint8_t sgn[8]) {
440     uint8_t *request = gatt_client_reserve_request_buffer(gatt_client);
441 
442     request[0] = request_type;
443     little_endian_store_16(request, 1, attribute_handle);
444     (void)memcpy(&request[3], value, value_length);
445     little_endian_store_32(request, 3 + value_length, sign_counter);
446     reverse_64(sgn, &request[3 + value_length + 4]);
447 
448     return gatt_client_send(gatt_client, 3 + value_length + 12);
449 }
450 #endif
451 
452 // precondition: can_send_packet_now == TRUE
453 static uint8_t
454 att_write_request(gatt_client_t *gatt_client, uint8_t request_type, uint16_t attribute_handle, uint16_t value_length,
455                   uint8_t *value) {
456     uint8_t *request = gatt_client_reserve_request_buffer(gatt_client);
457 
458     request[0] = request_type;
459     little_endian_store_16(request, 1, attribute_handle);
460     (void)memcpy(&request[3], value, value_length);
461 
462     return gatt_client_send(gatt_client, 3u + value_length);
463 }
464 
465 // precondition: can_send_packet_now == TRUE
466 static uint8_t att_execute_write_request(gatt_client_t *gatt_client, uint8_t request_type, uint8_t execute_write) {
467     uint8_t *request = gatt_client_reserve_request_buffer(gatt_client);
468 
469     request[0] = request_type;
470     request[1] = execute_write;
471 
472     return gatt_client_send(gatt_client, 2);
473 }
474 
475 // precondition: can_send_packet_now == TRUE
476 static uint8_t att_prepare_write_request(gatt_client_t *gatt_client, uint8_t request_type, uint16_t attribute_handle,
477                                          uint16_t value_offset, uint16_t blob_length, uint8_t *value) {
478     uint8_t *request = gatt_client_reserve_request_buffer(gatt_client);
479 
480     request[0] = request_type;
481     little_endian_store_16(request, 1, attribute_handle);
482     little_endian_store_16(request, 3, value_offset);
483     (void)memcpy(&request[5], &value[value_offset], blob_length);
484 
485     return gatt_client_send(gatt_client,  5u + blob_length);
486 }
487 
488 static uint8_t att_exchange_mtu_request(gatt_client_t *gatt_client) {
489     uint8_t *request = gatt_client_reserve_request_buffer(gatt_client);
490 
491     request[0] = ATT_EXCHANGE_MTU_REQUEST;
492     uint16_t mtu = l2cap_max_le_mtu();
493     little_endian_store_16(request, 1, mtu);
494 
495     return gatt_client_send(gatt_client, 3);
496 }
497 
498 static uint16_t write_blob_length(gatt_client_t * gatt_client){
499     uint16_t max_blob_length = gatt_client->mtu - 5u;
500     if (gatt_client->attribute_offset >= gatt_client->attribute_length) {
501         return 0;
502     }
503     uint16_t rest_length = gatt_client->attribute_length - gatt_client->attribute_offset;
504     if (max_blob_length > rest_length){
505         return rest_length;
506     }
507     return max_blob_length;
508 }
509 
510 static void send_gatt_services_request(gatt_client_t *gatt_client){
511     att_read_by_type_or_group_request_for_uuid16(gatt_client, ATT_READ_BY_GROUP_TYPE_REQUEST,
512                                                  gatt_client->uuid16, gatt_client->start_group_handle,
513                                                  gatt_client->end_group_handle);
514 }
515 
516 static void send_gatt_by_uuid_request(gatt_client_t *gatt_client, uint16_t attribute_group_type){
517     if (gatt_client->uuid16){
518         uint8_t uuid16[2];
519         little_endian_store_16(uuid16, 0, gatt_client->uuid16);
520         att_find_by_type_value_request(gatt_client, ATT_FIND_BY_TYPE_VALUE_REQUEST, attribute_group_type,
521                                        gatt_client->start_group_handle, gatt_client->end_group_handle, uuid16, 2);
522         return;
523     }
524     uint8_t uuid128[16];
525     reverse_128(gatt_client->uuid128, uuid128);
526     att_find_by_type_value_request(gatt_client, ATT_FIND_BY_TYPE_VALUE_REQUEST, attribute_group_type,
527                                    gatt_client->start_group_handle, gatt_client->end_group_handle, uuid128, 16);
528 }
529 
530 static void send_gatt_services_by_uuid_request(gatt_client_t *gatt_client){
531     send_gatt_by_uuid_request(gatt_client, GATT_PRIMARY_SERVICE_UUID);
532 }
533 
534 static void send_gatt_included_service_uuid_request(gatt_client_t *gatt_client){
535     att_read_request(gatt_client, ATT_READ_REQUEST, gatt_client->query_start_handle);
536 }
537 
538 static void send_gatt_included_service_request(gatt_client_t *gatt_client){
539     att_read_by_type_or_group_request_for_uuid16(gatt_client, ATT_READ_BY_TYPE_REQUEST,
540                                                  GATT_INCLUDE_SERVICE_UUID, gatt_client->start_group_handle,
541                                                  gatt_client->end_group_handle);
542 }
543 
544 static void send_gatt_characteristic_request(gatt_client_t *gatt_client){
545     att_read_by_type_or_group_request_for_uuid16(gatt_client, ATT_READ_BY_TYPE_REQUEST,
546                                                  GATT_CHARACTERISTICS_UUID, gatt_client->start_group_handle,
547                                                  gatt_client->end_group_handle);
548 }
549 
550 static void send_gatt_characteristic_descriptor_request(gatt_client_t *gatt_client){
551     att_find_information_request(gatt_client, ATT_FIND_INFORMATION_REQUEST, gatt_client->start_group_handle,
552                                  gatt_client->end_group_handle);
553 }
554 
555 static void send_gatt_read_characteristic_value_request(gatt_client_t *gatt_client){
556     att_read_request(gatt_client, ATT_READ_REQUEST, gatt_client->attribute_handle);
557 }
558 
559 static void send_gatt_read_by_type_request(gatt_client_t * gatt_client){
560     if (gatt_client->uuid16){
561         att_read_by_type_or_group_request_for_uuid16(gatt_client, ATT_READ_BY_TYPE_REQUEST,
562                                                      gatt_client->uuid16, gatt_client->start_group_handle,
563                                                      gatt_client->end_group_handle);
564     } else {
565         att_read_by_type_or_group_request_for_uuid128(gatt_client, ATT_READ_BY_TYPE_REQUEST,
566                                                       gatt_client->uuid128, gatt_client->start_group_handle,
567                                                       gatt_client->end_group_handle);
568     }
569 }
570 
571 static void send_gatt_read_blob_request(gatt_client_t *gatt_client){
572     if (gatt_client->attribute_offset == 0){
573         att_read_request(gatt_client, ATT_READ_REQUEST, gatt_client->attribute_handle);
574     } else {
575         att_read_blob_request(gatt_client, ATT_READ_BLOB_REQUEST, gatt_client->attribute_handle,
576                               gatt_client->attribute_offset);
577     }
578 }
579 
580 static void send_gatt_read_multiple_request(gatt_client_t * gatt_client){
581     att_read_multiple_request(gatt_client, gatt_client->read_multiple_handle_count, gatt_client->read_multiple_handles);
582 }
583 
584 #ifdef ENABLE_GATT_OVER_EATT
585 static void send_gatt_read_multiple_variable_request(gatt_client_t * gatt_client){
586     att_read_multiple_variable_request(gatt_client, gatt_client->read_multiple_handle_count, gatt_client->read_multiple_handles);
587 }
588 #endif
589 
590 static void send_gatt_write_attribute_value_request(gatt_client_t * gatt_client){
591     att_write_request(gatt_client, ATT_WRITE_REQUEST, gatt_client->attribute_handle, gatt_client->attribute_length,
592                       gatt_client->attribute_value);
593 }
594 
595 static void send_gatt_write_client_characteristic_configuration_request(gatt_client_t * gatt_client){
596     att_write_request(gatt_client, ATT_WRITE_REQUEST, gatt_client->client_characteristic_configuration_handle, 2,
597                       gatt_client->client_characteristic_configuration_value);
598 }
599 
600 static void send_gatt_prepare_write_request(gatt_client_t * gatt_client){
601     att_prepare_write_request(gatt_client, ATT_PREPARE_WRITE_REQUEST, gatt_client->attribute_handle,
602                               gatt_client->attribute_offset, write_blob_length(gatt_client),
603                               gatt_client->attribute_value);
604 }
605 
606 static void send_gatt_execute_write_request(gatt_client_t * gatt_client){
607     att_execute_write_request(gatt_client, ATT_EXECUTE_WRITE_REQUEST, 1);
608 }
609 
610 static void send_gatt_cancel_prepared_write_request(gatt_client_t * gatt_client){
611     att_execute_write_request(gatt_client, ATT_EXECUTE_WRITE_REQUEST, 0);
612 }
613 
614 #ifndef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
615 static void send_gatt_read_client_characteristic_configuration_request(gatt_client_t * gatt_client){
616     att_read_by_type_or_group_request_for_uuid16(gatt_client, ATT_READ_BY_TYPE_REQUEST,
617                                                  GATT_CLIENT_CHARACTERISTICS_CONFIGURATION,
618                                                  gatt_client->start_group_handle, gatt_client->end_group_handle);
619 }
620 #endif
621 
622 static void send_gatt_read_characteristic_descriptor_request(gatt_client_t * gatt_client){
623     att_read_request(gatt_client, ATT_READ_REQUEST, gatt_client->attribute_handle);
624 }
625 
626 #ifdef ENABLE_LE_SIGNED_WRITE
627 static void send_gatt_signed_write_request(gatt_client_t * gatt_client, uint32_t sign_counter){
628     att_signed_write_request(gatt_client, ATT_SIGNED_WRITE_COMMAND, gatt_client->attribute_handle,
629                              gatt_client->attribute_length, gatt_client->attribute_value, sign_counter,
630                              gatt_client->cmac);
631 }
632 #endif
633 
634 static uint16_t get_last_result_handle_from_service_list(uint8_t * packet, uint16_t size){
635     if (size < 2) return 0xffff;
636     uint8_t attr_length = packet[1];
637     if ((2 + attr_length) > size) return 0xffff;
638     return little_endian_read_16(packet, size - attr_length + 2u);
639 }
640 
641 static uint16_t get_last_result_handle_from_characteristics_list(uint8_t * packet, uint16_t size){
642     if (size < 2) return 0xffff;
643     uint8_t attr_length = packet[1];
644     if ((2 + attr_length) > size) return 0xffff;
645     return little_endian_read_16(packet, size - attr_length + 3u);
646 }
647 
648 static uint16_t get_last_result_handle_from_included_services_list(uint8_t * packet, uint16_t size){
649     if (size < 2) return 0xffff;
650     uint8_t attr_length = packet[1];
651     if ((2 + attr_length) > size) return 0xffff;
652     return little_endian_read_16(packet, size - attr_length);
653 }
654 
655 static void gatt_client_notify_can_send_query(gatt_client_t * gatt_client){
656     while (gatt_client->gatt_client_state == P_READY){
657 #ifdef ENABLE_GATT_OVER_EATT
658         bool query_sent = gatt_client_le_enhanced_handle_can_send_query(gatt_client);
659         if (query_sent){
660             continue;
661         }
662 #endif
663         btstack_context_callback_registration_t * callback = (btstack_context_callback_registration_t *) btstack_linked_list_pop(&gatt_client->query_requests);
664         if (callback == NULL) {
665             return;
666         }
667         (*callback->callback)(callback->context);
668     }
669 }
670 
671 static void emit_event_new(btstack_packet_handler_t callback, uint8_t * packet, uint16_t size){
672     if (!callback) return;
673     hci_dump_packet(HCI_EVENT_PACKET, 1, packet, size);
674     (*callback)(HCI_EVENT_PACKET, 0, packet, size);
675 }
676 
677 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){
678     notification->callback = callback;
679     notification->con_handle = con_handle;
680     if (characteristic == NULL){
681         notification->attribute_handle = GATT_CLIENT_ANY_VALUE_HANDLE;
682     } else {
683         notification->attribute_handle = characteristic->value_handle;
684     }
685     btstack_linked_list_add(&gatt_client_value_listeners, (btstack_linked_item_t*) notification);
686 }
687 
688 void gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification){
689     btstack_linked_list_remove(&gatt_client_value_listeners, (btstack_linked_item_t*) notification);
690 }
691 
692 static void emit_event_to_registered_listeners(hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t * packet, uint16_t size){
693     btstack_linked_list_iterator_t it;
694     btstack_linked_list_iterator_init(&it, &gatt_client_value_listeners);
695     while (btstack_linked_list_iterator_has_next(&it)){
696         gatt_client_notification_t * notification = (gatt_client_notification_t*) btstack_linked_list_iterator_next(&it);
697         if ((notification->con_handle       != GATT_CLIENT_ANY_CONNECTION)   && (notification->con_handle       != con_handle)) continue;
698         if ((notification->attribute_handle != GATT_CLIENT_ANY_VALUE_HANDLE) && (notification->attribute_handle != attribute_handle)) continue;
699         (*notification->callback)(HCI_EVENT_PACKET, 0, packet, size);
700     }
701 }
702 
703 static void emit_gatt_complete_event(gatt_client_t * gatt_client, uint8_t att_status){
704     // @format H1
705     uint8_t packet[5];
706     packet[0] = GATT_EVENT_QUERY_COMPLETE;
707     packet[1] = 3;
708     little_endian_store_16(packet, 2, gatt_client->con_handle);
709     packet[4] = att_status;
710     emit_event_new(gatt_client->callback, packet, sizeof(packet));
711 }
712 
713 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){
714     // @format HX
715     uint8_t packet[24];
716     packet[0] = GATT_EVENT_SERVICE_QUERY_RESULT;
717     packet[1] = sizeof(packet) - 2u;
718     little_endian_store_16(packet, 2, gatt_client->con_handle);
719     ///
720     little_endian_store_16(packet, 4, start_group_handle);
721     little_endian_store_16(packet, 6, end_group_handle);
722     reverse_128(uuid128, &packet[8]);
723     emit_event_new(gatt_client->callback, packet, sizeof(packet));
724 }
725 
726 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){
727     // @format HX
728     uint8_t packet[26];
729     packet[0] = GATT_EVENT_INCLUDED_SERVICE_QUERY_RESULT;
730     packet[1] = sizeof(packet) - 2u;
731     little_endian_store_16(packet, 2, gatt_client->con_handle);
732     ///
733     little_endian_store_16(packet, 4, include_handle);
734     //
735     little_endian_store_16(packet, 6, start_group_handle);
736     little_endian_store_16(packet, 8, end_group_handle);
737     reverse_128(uuid128, &packet[10]);
738     emit_event_new(gatt_client->callback, packet, sizeof(packet));
739 }
740 
741 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,
742                                                         uint16_t properties, const uint8_t * uuid128){
743     // @format HY
744     uint8_t packet[28];
745     packet[0] = GATT_EVENT_CHARACTERISTIC_QUERY_RESULT;
746     packet[1] = sizeof(packet) - 2u;
747     little_endian_store_16(packet, 2, gatt_client->con_handle);
748     ///
749     little_endian_store_16(packet, 4,  start_handle);
750     little_endian_store_16(packet, 6,  value_handle);
751     little_endian_store_16(packet, 8,  end_handle);
752     little_endian_store_16(packet, 10, properties);
753     reverse_128(uuid128, &packet[12]);
754     emit_event_new(gatt_client->callback, packet, sizeof(packet));
755 }
756 
757 static void emit_gatt_all_characteristic_descriptors_result_event(
758         gatt_client_t * gatt_client, uint16_t descriptor_handle, const uint8_t * uuid128){
759     // @format HZ
760     uint8_t packet[22];
761     packet[0] = GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT;
762     packet[1] = sizeof(packet) - 2u;
763     little_endian_store_16(packet, 2, gatt_client->con_handle);
764     ///
765     little_endian_store_16(packet, 4,  descriptor_handle);
766     reverse_128(uuid128, &packet[6]);
767     emit_event_new(gatt_client->callback, packet, sizeof(packet));
768 }
769 
770 static void emit_gatt_mtu_exchanged_result_event(gatt_client_t * gatt_client, uint16_t new_mtu){
771     // @format H2
772     uint8_t packet[6];
773     packet[0] = GATT_EVENT_MTU;
774     packet[1] = sizeof(packet) - 2u;
775     little_endian_store_16(packet, 2, gatt_client->con_handle);
776     little_endian_store_16(packet, 4, new_mtu);
777     att_dispatch_client_mtu_exchanged(gatt_client->con_handle, new_mtu);
778     emit_event_new(gatt_client->callback, packet, sizeof(packet));
779 }
780 ///
781 static void report_gatt_services(gatt_client_t * gatt_client, uint8_t * packet, uint16_t size){
782     if (size < 2) return;
783     uint8_t attr_length = packet[1];
784     uint8_t uuid_length = attr_length - 4u;
785 
786     int i;
787     for (i = 2; (i+attr_length) <= size; i += attr_length){
788         uint16_t start_group_handle = little_endian_read_16(packet,i);
789         uint16_t end_group_handle   = little_endian_read_16(packet,i+2);
790         uint8_t  uuid128[16];
791         uint16_t uuid16 = 0;
792 
793         if (uuid_length == 2u){
794             uuid16 = little_endian_read_16(packet, i+4);
795             uuid_add_bluetooth_prefix((uint8_t*) &uuid128, uuid16);
796         } else if (uuid_length == 16u) {
797             reverse_128(&packet[i+4], uuid128);
798         } else {
799             return;
800         }
801         emit_gatt_service_query_result_event(gatt_client, start_group_handle, end_group_handle, uuid128);
802     }
803 }
804 
805 static void gatt_client_handle_transaction_complete(gatt_client_t *gatt_client, uint8_t att_status) {
806     gatt_client->gatt_client_state = P_READY;
807     gatt_client_timeout_stop(gatt_client);
808     emit_gatt_complete_event(gatt_client, att_status);
809     gatt_client_notify_can_send_query(gatt_client);
810 }
811 
812 // helper
813 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){
814     uint8_t uuid128[16];
815     uint16_t uuid16 = 0;
816     if (uuid_length == 2u){
817         uuid16 = little_endian_read_16(uuid, 0);
818         uuid_add_bluetooth_prefix((uint8_t*) uuid128, uuid16);
819     } else if (uuid_length == 16u){
820         reverse_128(uuid, uuid128);
821     } else {
822         return;
823     }
824 
825     if (gatt_client->filter_with_uuid && (memcmp(gatt_client->uuid128, uuid128, 16) != 0)) return;
826 
827     gatt_client->characteristic_properties = properties;
828     gatt_client->characteristic_start_handle = start_handle;
829     gatt_client->attribute_handle = value_handle;
830 
831     if (gatt_client->filter_with_uuid) return;
832 
833     gatt_client->uuid16 = uuid16;
834     (void)memcpy(gatt_client->uuid128, uuid128, 16);
835 }
836 
837 static void characteristic_end_found(gatt_client_t * gatt_client, uint16_t end_handle){
838     // TODO: stop searching if filter and uuid found
839 
840     if (!gatt_client->characteristic_start_handle) return;
841 
842     emit_gatt_characteristic_query_result_event(gatt_client, gatt_client->characteristic_start_handle, gatt_client->attribute_handle,
843                                                 end_handle, gatt_client->characteristic_properties, gatt_client->uuid128);
844 
845     gatt_client->characteristic_start_handle = 0;
846 }
847 
848 static void report_gatt_characteristics(gatt_client_t * gatt_client, uint8_t * packet, uint16_t size){
849     if (size < 2u) return;
850     uint8_t attr_length = packet[1];
851     if ((attr_length != 7u) && (attr_length != 21u)) return;
852     uint8_t uuid_length = attr_length - 5u;
853     int i;
854     for (i = 2u; (i + attr_length) <= size; i += attr_length){
855         uint16_t start_handle = little_endian_read_16(packet, i);
856         uint8_t  properties = packet[i+2];
857         uint16_t value_handle = little_endian_read_16(packet, i+3);
858         characteristic_end_found(gatt_client, start_handle - 1u);
859         characteristic_start_found(gatt_client, start_handle, properties, value_handle, &packet[i + 5], uuid_length);
860     }
861 }
862 
863 static void report_gatt_included_service_uuid16(gatt_client_t * gatt_client, uint16_t include_handle, uint16_t uuid16){
864     uint8_t normalized_uuid128[16];
865     uuid_add_bluetooth_prefix(normalized_uuid128, uuid16);
866     emit_gatt_included_service_query_result_event(gatt_client, include_handle, gatt_client->query_start_handle,
867                                                   gatt_client->query_end_handle, normalized_uuid128);
868 }
869 
870 static void report_gatt_included_service_uuid128(gatt_client_t * gatt_client, uint16_t include_handle, const uint8_t * uuid128){
871     emit_gatt_included_service_query_result_event(gatt_client, include_handle, gatt_client->query_start_handle,
872                                                   gatt_client->query_end_handle, uuid128);
873 }
874 
875 // @return packet pointer
876 // @note assume that value is part of an l2cap buffer - overwrite HCI + L2CAP packet headers
877 static const int characteristic_value_event_header_size = 8;
878 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){
879 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
880     // copy value into test packet for testing
881     static uint8_t packet[1000];
882     memcpy(&packet[8], value, length);
883 #else
884     // before the value inside the ATT PDU
885     uint8_t * packet = value - characteristic_value_event_header_size;
886 #endif
887     packet[0] = type;
888     packet[1] = characteristic_value_event_header_size - 2 + length;
889     little_endian_store_16(packet, 2, con_handle);
890     little_endian_store_16(packet, 4, attribute_handle);
891     little_endian_store_16(packet, 6, length);
892     return packet;
893 }
894 
895 // @return packet pointer
896 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
897 static const int long_characteristic_value_event_header_size = 10;
898 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){
899 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
900     // avoid using pre ATT headers.
901     return NULL;
902 #endif
903 #if defined(HCI_INCOMING_PRE_BUFFER_SIZE) && (HCI_INCOMING_PRE_BUFFER_SIZE >= 10 - 8) // L2CAP Header (4) - ACL Header (4)
904     // before the value inside the ATT PDU
905     uint8_t * packet = value - long_characteristic_value_event_header_size;
906     packet[0] = type;
907     packet[1] = long_characteristic_value_event_header_size - 2 + length;
908     little_endian_store_16(packet, 2, con_handle);
909     little_endian_store_16(packet, 4, attribute_handle);
910     little_endian_store_16(packet, 6, offset);
911     little_endian_store_16(packet, 8, length);
912     return packet;
913 #else
914     log_error("HCI_INCOMING_PRE_BUFFER_SIZE >= 2 required for long characteristic reads");
915     return NULL;
916 #endif
917 }
918 
919 // test if notification/indication should be delivered to application (BLESA)
920 static bool gatt_client_accept_server_message(gatt_client_t *gatt_client) {
921 #ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION
922 	// ignore messages until re-encryption is complete
923     if (gap_reconnect_security_setup_active(gatt_client->con_handle)) return false;
924 
925 	// after that ignore if bonded but not encrypted
926 	return !gap_bonded(gatt_client->con_handle) || (gap_encryption_key_size(gatt_client->con_handle) > 0);
927 #else
928     UNUSED(gatt_client);
929 	return true;
930 #endif
931 }
932 
933 
934 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
935 static void report_gatt_notification(gatt_client_t *gatt_client, uint16_t value_handle, uint8_t *value, int length) {
936 	if (!gatt_client_accept_server_message(gatt_client)) return;
937     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_NOTIFICATION, gatt_client->con_handle, value_handle, value, length);
938     emit_event_to_registered_listeners(gatt_client->con_handle, value_handle, packet, characteristic_value_event_header_size + length);
939 }
940 
941 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
942 static void report_gatt_indication(gatt_client_t *gatt_client, uint16_t value_handle, uint8_t *value, int length) {
943 	if (!gatt_client_accept_server_message(gatt_client)) return;
944     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_INDICATION, gatt_client->con_handle, value_handle, value, length);
945     emit_event_to_registered_listeners(gatt_client->con_handle, value_handle, packet, characteristic_value_event_header_size + length);
946 }
947 
948 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
949 static void report_gatt_characteristic_value(gatt_client_t * gatt_client, uint16_t attribute_handle, uint8_t * value, uint16_t length){
950     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT, gatt_client->con_handle, attribute_handle, value, length);
951     emit_event_new(gatt_client->callback, packet, characteristic_value_event_header_size + length);
952 }
953 
954 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
955 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){
956     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);
957     if (!packet) return;
958     emit_event_new(gatt_client->callback, packet, blob_length + long_characteristic_value_event_header_size);
959 }
960 
961 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){
962     UNUSED(value_offset);
963     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT, gatt_client->con_handle, descriptor_handle, value, value_length);
964     emit_event_new(gatt_client->callback, packet, value_length + 8u);
965 }
966 
967 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){
968     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);
969     if (!packet) return;
970     emit_event_new(gatt_client->callback, packet, blob_length + long_characteristic_value_event_header_size);
971 }
972 
973 static void report_gatt_all_characteristic_descriptors(gatt_client_t * gatt_client, uint8_t * packet, uint16_t size, uint16_t pair_size){
974     int i;
975     for (i = 0u; (i + pair_size) <= size; i += pair_size){
976         uint16_t descriptor_handle = little_endian_read_16(packet,i);
977         uint8_t uuid128[16];
978         uint16_t uuid16 = 0;
979         if (pair_size == 4u){
980             uuid16 = little_endian_read_16(packet,i+2);
981             uuid_add_bluetooth_prefix(uuid128, uuid16);
982         } else {
983             reverse_128(&packet[i+2], uuid128);
984         }
985         emit_gatt_all_characteristic_descriptors_result_event(gatt_client, descriptor_handle, uuid128);
986     }
987 
988 }
989 
990 static int is_query_done(gatt_client_t * gatt_client, uint16_t last_result_handle){
991     return last_result_handle >= gatt_client->end_group_handle;
992 }
993 
994 static void trigger_next_query(gatt_client_t * gatt_client, uint16_t last_result_handle, gatt_client_state_t next_query_state){
995     if (is_query_done(gatt_client, last_result_handle)){
996         gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
997         return;
998     }
999     // next
1000     gatt_client->start_group_handle = last_result_handle + 1u;
1001     gatt_client->gatt_client_state = next_query_state;
1002 }
1003 
1004 static void trigger_next_included_service_query(gatt_client_t * gatt_client, uint16_t last_result_handle){
1005     trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_INCLUDED_SERVICE_QUERY);
1006 }
1007 
1008 static void trigger_next_service_query(gatt_client_t * gatt_client, uint16_t last_result_handle){
1009     trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_SERVICE_QUERY);
1010 }
1011 
1012 static void trigger_next_service_by_uuid_query(gatt_client_t * gatt_client, uint16_t last_result_handle){
1013     trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_SERVICE_WITH_UUID_QUERY);
1014 }
1015 
1016 static void trigger_next_characteristic_query(gatt_client_t * gatt_client, uint16_t last_result_handle){
1017     if (is_query_done(gatt_client, last_result_handle)){
1018         // report last characteristic
1019         characteristic_end_found(gatt_client, gatt_client->end_group_handle);
1020     }
1021     trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY);
1022 }
1023 
1024 static void trigger_next_characteristic_descriptor_query(gatt_client_t * gatt_client, uint16_t last_result_handle){
1025     trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY);
1026 }
1027 
1028 static void trigger_next_read_by_type_query(gatt_client_t * gatt_client, uint16_t last_result_handle){
1029     trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_READ_BY_TYPE_REQUEST);
1030 }
1031 
1032 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){
1033     gatt_client->attribute_offset += write_blob_length(gatt_client);
1034     uint16_t next_blob_length =  write_blob_length(gatt_client);
1035 
1036     if (next_blob_length == 0u){
1037         gatt_client->gatt_client_state = done_state;
1038         return;
1039     }
1040     gatt_client->gatt_client_state = next_query_state;
1041 }
1042 
1043 static void trigger_next_blob_query(gatt_client_t * gatt_client, gatt_client_state_t next_query_state, uint16_t received_blob_length){
1044 
1045     uint16_t max_blob_length = gatt_client->mtu - 1u;
1046     if (received_blob_length < max_blob_length){
1047         gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1048         return;
1049     }
1050 
1051     gatt_client->attribute_offset += received_blob_length;
1052     gatt_client->gatt_client_state = next_query_state;
1053 }
1054 
1055 
1056 static int is_value_valid(gatt_client_t *gatt_client, uint8_t *packet, uint16_t size){
1057     uint16_t attribute_handle = little_endian_read_16(packet, 1);
1058     uint16_t value_offset = little_endian_read_16(packet, 3);
1059 
1060     if (gatt_client->attribute_handle != attribute_handle) return 0;
1061     if (gatt_client->attribute_offset != value_offset) return 0;
1062     return memcmp(&gatt_client->attribute_value[gatt_client->attribute_offset], &packet[5], size - 5u) == 0u;
1063 }
1064 
1065 #ifdef ENABLE_LE_SIGNED_WRITE
1066 static void gatt_client_run_for_client_start_signed_write(gatt_client_t *gatt_client) {
1067     sm_key_t csrk;
1068     le_device_db_local_csrk_get(gatt_client->le_device_index, csrk);
1069     uint32_t sign_counter = le_device_db_local_counter_get(gatt_client->le_device_index);
1070     gatt_client->gatt_client_state = P_W4_CMAC_RESULT;
1071     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);
1072 }
1073 #endif
1074 
1075 // returns true if packet was sent
1076 static bool gatt_client_run_for_gatt_client(gatt_client_t * gatt_client){
1077 
1078     // wait until re-encryption is complete
1079     if (gap_reconnect_security_setup_active(gatt_client->con_handle)) return false;
1080 
1081     // wait until re-encryption is complete
1082     if (gatt_client->reencryption_active) return false;
1083 
1084     // wait until pairing complete (either reactive authentication or due to required security level)
1085     if (gatt_client->wait_for_authentication_complete) return false;
1086 
1087     bool client_request_pending = gatt_client->gatt_client_state != P_READY;
1088 
1089     // verify security level for Mandatory Authentication over LE
1090     bool check_security;
1091     switch (gatt_client->bearer_type){
1092         case ATT_BEARER_UNENHANCED_LE:
1093             check_security = true;
1094             break;
1095         default:
1096             check_security = false;
1097             break;
1098     }
1099     if (client_request_pending && (gatt_client_required_security_level > gatt_client->security_level) && check_security){
1100         log_info("Trigger pairing, current security level %u, required %u\n", gatt_client->security_level, gatt_client_required_security_level);
1101         gatt_client->wait_for_authentication_complete = 1;
1102         // set att error code for pairing failure based on required level
1103         switch (gatt_client_required_security_level){
1104             case LEVEL_4:
1105             case LEVEL_3:
1106                 gatt_client->pending_error_code = ATT_ERROR_INSUFFICIENT_AUTHENTICATION;
1107                 break;
1108             default:
1109                 gatt_client->pending_error_code = ATT_ERROR_INSUFFICIENT_ENCRYPTION;
1110                 break;
1111         }
1112         sm_request_pairing(gatt_client->con_handle);
1113         // sm probably just sent a pdu
1114         return true;
1115     }
1116 
1117     switch (gatt_client->mtu_state) {
1118         case SEND_MTU_EXCHANGE:
1119             gatt_client->mtu_state = SENT_MTU_EXCHANGE;
1120             att_exchange_mtu_request(gatt_client);
1121             return true;
1122         case SENT_MTU_EXCHANGE:
1123             return false;
1124         default:
1125             break;
1126     }
1127 
1128     if (gatt_client->send_confirmation){
1129         gatt_client->send_confirmation = 0;
1130         att_confirmation(gatt_client);
1131         return true;
1132     }
1133 
1134     // check MTU for writes
1135     switch (gatt_client->gatt_client_state){
1136         case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE:
1137         case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR:
1138             if (gatt_client->attribute_length <= (gatt_client->mtu - 3u)) break;
1139             log_error("gatt_client_run: value len %u > MTU %u - 3\n", gatt_client->attribute_length,gatt_client->mtu);
1140             gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH);
1141             return false;
1142         default:
1143             break;
1144     }
1145 
1146     bool packet_sent = true;
1147     bool done = true;
1148     switch (gatt_client->gatt_client_state){
1149         case P_W2_SEND_SERVICE_QUERY:
1150             gatt_client->gatt_client_state = P_W4_SERVICE_QUERY_RESULT;
1151             send_gatt_services_request(gatt_client);
1152             break;
1153 
1154         case P_W2_SEND_SERVICE_WITH_UUID_QUERY:
1155             gatt_client->gatt_client_state = P_W4_SERVICE_WITH_UUID_RESULT;
1156             send_gatt_services_by_uuid_request(gatt_client);
1157             break;
1158 
1159         case P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY:
1160             gatt_client->gatt_client_state = P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT;
1161             send_gatt_characteristic_request(gatt_client);
1162             break;
1163 
1164         case P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY:
1165             gatt_client->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT;
1166             send_gatt_characteristic_request(gatt_client);
1167             break;
1168 
1169         case P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY:
1170             gatt_client->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT;
1171             send_gatt_characteristic_descriptor_request(gatt_client);
1172             break;
1173 
1174         case P_W2_SEND_INCLUDED_SERVICE_QUERY:
1175             gatt_client->gatt_client_state = P_W4_INCLUDED_SERVICE_QUERY_RESULT;
1176             send_gatt_included_service_request(gatt_client);
1177             break;
1178 
1179         case P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY:
1180             gatt_client->gatt_client_state = P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT;
1181             send_gatt_included_service_uuid_request(gatt_client);
1182             break;
1183 
1184         case P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY:
1185             gatt_client->gatt_client_state = P_W4_READ_CHARACTERISTIC_VALUE_RESULT;
1186             send_gatt_read_characteristic_value_request(gatt_client);
1187             break;
1188 
1189         case P_W2_SEND_READ_BLOB_QUERY:
1190             gatt_client->gatt_client_state = P_W4_READ_BLOB_RESULT;
1191             send_gatt_read_blob_request(gatt_client);
1192             break;
1193 
1194         case P_W2_SEND_READ_BY_TYPE_REQUEST:
1195             gatt_client->gatt_client_state = P_W4_READ_BY_TYPE_RESPONSE;
1196             send_gatt_read_by_type_request(gatt_client);
1197             break;
1198 
1199         case P_W2_SEND_READ_MULTIPLE_REQUEST:
1200             gatt_client->gatt_client_state = P_W4_READ_MULTIPLE_RESPONSE;
1201             send_gatt_read_multiple_request(gatt_client);
1202             break;
1203 
1204 #ifdef ENABLE_GATT_OVER_EATT
1205         case P_W2_SEND_READ_MULTIPLE_VARIABLE_REQUEST:
1206             gatt_client->gatt_client_state = P_W4_READ_MULTIPLE_VARIABLE_RESPONSE;
1207             send_gatt_read_multiple_variable_request(gatt_client);
1208             break;
1209 #endif
1210 
1211         case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE:
1212             gatt_client->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT;
1213             send_gatt_write_attribute_value_request(gatt_client);
1214             break;
1215 
1216         case P_W2_PREPARE_WRITE:
1217             gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_RESULT;
1218             send_gatt_prepare_write_request(gatt_client);
1219             break;
1220 
1221         case P_W2_PREPARE_WRITE_SINGLE:
1222             gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_SINGLE_RESULT;
1223             send_gatt_prepare_write_request(gatt_client);
1224             break;
1225 
1226         case P_W2_PREPARE_RELIABLE_WRITE:
1227             gatt_client->gatt_client_state = P_W4_PREPARE_RELIABLE_WRITE_RESULT;
1228             send_gatt_prepare_write_request(gatt_client);
1229             break;
1230 
1231         case P_W2_EXECUTE_PREPARED_WRITE:
1232             gatt_client->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_RESULT;
1233             send_gatt_execute_write_request(gatt_client);
1234             break;
1235 
1236         case P_W2_CANCEL_PREPARED_WRITE:
1237             gatt_client->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_RESULT;
1238             send_gatt_cancel_prepared_write_request(gatt_client);
1239             break;
1240 
1241         case P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH:
1242             gatt_client->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT;
1243             send_gatt_cancel_prepared_write_request(gatt_client);
1244             break;
1245 
1246 #ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
1247         case P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY:
1248             // use Find Information
1249             gatt_client->gatt_client_state = P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT;
1250             send_gatt_characteristic_descriptor_request(gatt_client);
1251 #else
1252         case P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY:
1253             // Use Read By Type
1254             gatt_client->gatt_client_state = P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT;
1255             send_gatt_read_client_characteristic_configuration_request(gatt_client);
1256 #endif
1257             break;
1258 
1259         case P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY:
1260             gatt_client->gatt_client_state = P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT;
1261             send_gatt_read_characteristic_descriptor_request(gatt_client);
1262             break;
1263 
1264         case P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY:
1265             gatt_client->gatt_client_state = P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT;
1266             send_gatt_read_blob_request(gatt_client);
1267             break;
1268 
1269         case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR:
1270             gatt_client->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT;
1271             send_gatt_write_attribute_value_request(gatt_client);
1272             break;
1273 
1274         case P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION:
1275             gatt_client->gatt_client_state = P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT;
1276             send_gatt_write_client_characteristic_configuration_request(gatt_client);
1277             break;
1278 
1279         case P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR:
1280             gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT;
1281             send_gatt_prepare_write_request(gatt_client);
1282             break;
1283 
1284         case P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR:
1285             gatt_client->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT;
1286             send_gatt_execute_write_request(gatt_client);
1287             break;
1288 
1289 #ifdef ENABLE_LE_SIGNED_WRITE
1290         case P_W4_IDENTITY_RESOLVING:
1291             log_info("P_W4_IDENTITY_RESOLVING - state %x", sm_identity_resolving_state(gatt_client->con_handle));
1292             switch (sm_identity_resolving_state(gatt_client->con_handle)){
1293                 case IRK_LOOKUP_SUCCEEDED:
1294                     gatt_client->le_device_index = sm_le_device_index(gatt_client->con_handle);
1295                     gatt_client->gatt_client_state = P_W4_CMAC_READY;
1296                     if (sm_cmac_ready()){
1297                         gatt_client_run_for_client_start_signed_write(gatt_client);
1298                     }
1299                     break;
1300                 case IRK_LOOKUP_FAILED:
1301                     gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_BONDING_INFORMATION_MISSING);
1302                     break;
1303                 default:
1304                     break;
1305             }
1306             packet_sent = false;
1307             break;
1308 
1309         case P_W4_CMAC_READY:
1310             if (sm_cmac_ready()){
1311                 gatt_client_run_for_client_start_signed_write(gatt_client);
1312             }
1313             packet_sent = false;
1314             break;
1315 
1316         case P_W2_SEND_SIGNED_WRITE: {
1317             gatt_client->gatt_client_state = P_W4_SEND_SINGED_WRITE_DONE;
1318             // bump local signing counter
1319             uint32_t sign_counter = le_device_db_local_counter_get(gatt_client->le_device_index);
1320             le_device_db_local_counter_set(gatt_client->le_device_index, sign_counter + 1);
1321             // send signed write command
1322             send_gatt_signed_write_request(gatt_client, sign_counter);
1323             // finally, notifiy client that write is complete
1324             gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1325             break;
1326         }
1327 #endif
1328         default:
1329             done = false;
1330             break;
1331     }
1332 
1333     if (done){
1334         return packet_sent;
1335     }
1336 
1337     // write without response callback
1338     btstack_context_callback_registration_t * callback =
1339             (btstack_context_callback_registration_t *) btstack_linked_list_pop(&gatt_client->write_without_response_requests);
1340     if (callback != NULL){
1341         (*callback->callback)(callback->context);
1342         return true;
1343     }
1344 
1345     // requested can send now old
1346     if (gatt_client->write_without_response_callback){
1347         btstack_packet_handler_t packet_handler = gatt_client->write_without_response_callback;
1348         gatt_client->write_without_response_callback = NULL;
1349         uint8_t event[4];
1350         event[0] = GATT_EVENT_CAN_WRITE_WITHOUT_RESPONSE;
1351         event[1] = sizeof(event) - 2u;
1352         little_endian_store_16(event, 2, gatt_client->con_handle);
1353         packet_handler(HCI_EVENT_PACKET, gatt_client->con_handle, event, sizeof(event));
1354         return true; // to trigger requeueing (even if higher layer didn't sent)
1355     }
1356 
1357     return false;
1358 }
1359 
1360 static void gatt_client_run(void){
1361     btstack_linked_item_t *it;
1362 #ifdef ENABLE_GATT_OVER_EATT
1363     btstack_linked_list_iterator_t it_eatt;
1364 #endif
1365     for (it = (btstack_linked_item_t *) gatt_client_connections; it != NULL; it = it->next){
1366         gatt_client_t * gatt_client = (gatt_client_t *) it;
1367         switch (gatt_client->bearer_type){
1368             case ATT_BEARER_UNENHANCED_LE:
1369 #ifdef ENABLE_GATT_OVER_EATT
1370                 btstack_linked_list_iterator_init(&it_eatt, &gatt_client->eatt_clients);
1371                 while (btstack_linked_list_iterator_has_next(&it_eatt)) {
1372                     gatt_client_t * eatt_client = (gatt_client_t *) btstack_linked_list_iterator_next(&it_eatt);
1373                     if (eatt_client->gatt_client_state != P_READY){
1374                         if (l2cap_can_send_packet_now(eatt_client->l2cap_cid)){
1375                             gatt_client_run_for_gatt_client(eatt_client);
1376                         }
1377                     }
1378                 }
1379 #endif
1380                 if (!att_dispatch_client_can_send_now(gatt_client->con_handle)) {
1381                     att_dispatch_client_request_can_send_now_event(gatt_client->con_handle);
1382                     return;
1383                 }
1384                 bool packet_sent = gatt_client_run_for_gatt_client(gatt_client);
1385                 if (packet_sent){
1386                     // request new permission
1387                     att_dispatch_client_request_can_send_now_event(gatt_client->con_handle);
1388                     // requeue client for fairness and exit
1389                     // note: iterator has become invalid
1390                     btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
1391                     btstack_linked_list_add_tail(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
1392                     return;
1393                 }
1394                 break;
1395 #ifdef ENABLE_GATT_OVER_CLASSIC
1396             case ATT_BEARER_UNENHANCED_CLASSIC:
1397                 if (gatt_client->con_handle == HCI_CON_HANDLE_INVALID) {
1398                     continue;
1399                 }
1400 
1401                 // handle GATT over BR/EDR
1402                 if (gatt_client->l2cap_psm != 0){
1403                     if (l2cap_can_send_packet_now(gatt_client->l2cap_cid) == false){
1404                         l2cap_request_can_send_now_event(gatt_client->l2cap_cid);
1405                         return;
1406                     }
1407                     bool packet_sent = gatt_client_run_for_gatt_client(gatt_client);
1408                     if (packet_sent){
1409                         // request new permission
1410                         att_dispatch_client_request_can_send_now_event(gatt_client->con_handle);
1411                         // requeue client for fairness and exit
1412                         // note: iterator has become invalid
1413                         btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
1414                         btstack_linked_list_add_tail(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
1415                         return;
1416                     }
1417                 }
1418                 break;
1419 #endif
1420             default:
1421                 btstack_unreachable();
1422                 break;
1423         }
1424 
1425 
1426     }
1427 }
1428 
1429 static void gatt_client_report_error_if_pending(gatt_client_t *gatt_client, uint8_t att_error_code) {
1430     if (is_ready(gatt_client) == 1) return;
1431     gatt_client_handle_transaction_complete(gatt_client, att_error_code);
1432 }
1433 
1434 static void gatt_client_handle_reencryption_complete(const uint8_t * packet){
1435     hci_con_handle_t con_handle = sm_event_reencryption_complete_get_handle(packet);
1436     gatt_client_t * gatt_client = gatt_client_get_context_for_handle(con_handle);
1437     if (gatt_client == NULL) return;
1438 
1439     // update security level
1440     gatt_client->security_level = gatt_client_le_security_level_for_connection(con_handle);
1441 
1442     gatt_client->reencryption_result = sm_event_reencryption_complete_get_status(packet);
1443     gatt_client->reencryption_active = false;
1444     gatt_client->wait_for_authentication_complete = 0;
1445 
1446     if (gatt_client->gatt_client_state == P_READY) return;
1447 
1448     switch (sm_event_reencryption_complete_get_status(packet)){
1449         case ERROR_CODE_SUCCESS:
1450             log_info("re-encryption success, retry operation");
1451             break;
1452         case ERROR_CODE_AUTHENTICATION_FAILURE:
1453         case ERROR_CODE_PIN_OR_KEY_MISSING:
1454 #if defined(ENABLE_GATT_CLIENT_PAIRING) && !defined(ENABLE_LE_PROACTIVE_AUTHENTICATION)
1455             if (gatt_client_required_security_level == LEVEL_0) {
1456                 // re-encryption failed for reactive authentication with pairing and we have a pending client request
1457                 // => try to resolve it by deleting bonding information if we started pairing before
1458                 // delete bonding information
1459                 int le_device_db_index = sm_le_device_index(gatt_client->con_handle);
1460                 btstack_assert(le_device_db_index >= 0);
1461                 log_info("reactive auth with pairing: delete bonding and start pairing");
1462 #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION
1463                 hci_remove_le_device_db_entry_from_resolving_list((uint16_t) le_device_db_index);
1464 #endif
1465                 le_device_db_remove(le_device_db_index);
1466                 // trigger pairing again
1467                 sm_request_pairing(gatt_client->con_handle);
1468                 break;
1469             }
1470 #endif
1471             // report bonding information missing
1472             gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_BONDING_INFORMATION_MISSING);
1473             break;
1474         default:
1475             // report bonding information missing
1476             gatt_client_handle_transaction_complete(gatt_client, gatt_client->pending_error_code);
1477             break;
1478     }
1479 }
1480 
1481 static void gatt_client_handle_disconnection_complete(const uint8_t * packet){
1482     log_info("GATT Client: HCI_EVENT_DISCONNECTION_COMPLETE");
1483     hci_con_handle_t con_handle = little_endian_read_16(packet,3);
1484     gatt_client_t * gatt_client = gatt_client_get_context_for_handle(con_handle);
1485     if (gatt_client == NULL) return;
1486 
1487     gatt_client_report_error_if_pending(gatt_client, ATT_ERROR_HCI_DISCONNECT_RECEIVED);
1488     gatt_client_timeout_stop(gatt_client);
1489     btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
1490     btstack_memory_gatt_client_free(gatt_client);
1491 }
1492 
1493 static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
1494     UNUSED(channel);    // ok: handling own l2cap events
1495     UNUSED(size);       // ok: there is no channel
1496 
1497     if (packet_type != HCI_EVENT_PACKET) return;
1498 
1499     hci_con_handle_t con_handle;
1500     gatt_client_t * gatt_client;
1501     switch (hci_event_packet_get_type(packet)) {
1502         case HCI_EVENT_DISCONNECTION_COMPLETE:
1503             gatt_client_handle_disconnection_complete(packet);
1504             break;
1505 
1506         // Pairing complete (with/without bonding=storing of pairing information)
1507         case SM_EVENT_PAIRING_COMPLETE:
1508             con_handle = sm_event_pairing_complete_get_handle(packet);
1509             gatt_client = gatt_client_get_context_for_handle(con_handle);
1510             if (gatt_client == NULL) break;
1511 
1512             // update security level
1513             gatt_client->security_level = gatt_client_le_security_level_for_connection(con_handle);
1514 
1515             if (gatt_client->wait_for_authentication_complete){
1516                 gatt_client->wait_for_authentication_complete = 0;
1517                 if (sm_event_pairing_complete_get_status(packet)){
1518                     log_info("pairing failed, report previous error 0x%x", gatt_client->pending_error_code);
1519                     gatt_client_report_error_if_pending(gatt_client, gatt_client->pending_error_code);
1520                 } else {
1521                     log_info("pairing success, retry operation");
1522                 }
1523             }
1524             break;
1525 
1526 #ifdef ENABLE_LE_SIGNED_WRITE
1527         // Identity Resolving completed (no code, gatt_client_run will continue)
1528         case SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED:
1529         case SM_EVENT_IDENTITY_RESOLVING_FAILED:
1530             break;
1531 #endif
1532 
1533         // re-encryption started
1534         case SM_EVENT_REENCRYPTION_STARTED:
1535             con_handle = sm_event_reencryption_complete_get_handle(packet);
1536             gatt_client = gatt_client_get_context_for_handle(con_handle);
1537             if (gatt_client == NULL) break;
1538 
1539             gatt_client->reencryption_active = true;
1540             gatt_client->reencryption_result = ERROR_CODE_SUCCESS;
1541             break;
1542 
1543         // re-encryption complete
1544         case SM_EVENT_REENCRYPTION_COMPLETE:
1545             gatt_client_handle_reencryption_complete(packet);
1546             break;
1547         default:
1548             break;
1549     }
1550 
1551     gatt_client_run();
1552 }
1553 
1554 static void gatt_client_handle_att_read_response(gatt_client_t *gatt_client, uint8_t *packet, uint16_t size) {
1555     switch (gatt_client->gatt_client_state) {
1556         case P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT:
1557             if (size >= 17) {
1558                 uint8_t uuid128[16];
1559                 reverse_128(&packet[1], uuid128);
1560                 report_gatt_included_service_uuid128(gatt_client, gatt_client->start_group_handle, uuid128);
1561             }
1562             trigger_next_included_service_query(gatt_client, gatt_client->start_group_handle);
1563             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1564             break;
1565 
1566         case P_W4_READ_CHARACTERISTIC_VALUE_RESULT:
1567             report_gatt_characteristic_value(gatt_client, gatt_client->attribute_handle, &packet[1], size - 1u);
1568             gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1569             break;
1570 
1571         case P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT:
1572             report_gatt_characteristic_descriptor(gatt_client, gatt_client->attribute_handle, &packet[1],
1573                                                   size - 1u, 0u);
1574             gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1575             break;
1576 
1577             // Use ATT_READ_REQUEST for first blob of Read Long Characteristic
1578         case P_W4_READ_BLOB_RESULT:
1579             report_gatt_long_characteristic_value_blob(gatt_client, gatt_client->attribute_handle, &packet[1],
1580                                                        size - 1u, gatt_client->attribute_offset);
1581             trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_QUERY, size - 1u);
1582             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1583             break;
1584 
1585             // Use ATT_READ_REQUEST for first blob of Read Long Characteristic Descriptor
1586         case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT:
1587             report_gatt_long_characteristic_descriptor(gatt_client, gatt_client->attribute_handle, &packet[1],
1588                                                        size - 1u, gatt_client->attribute_offset);
1589             trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY,
1590                                     size - 1u);
1591             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1592             break;
1593 
1594         default:
1595             break;
1596     }
1597 }
1598 
1599 static void gatt_client_handle_att_read_by_type_response(gatt_client_t *gatt_client, uint8_t *packet, uint16_t size) {
1600     switch (gatt_client->gatt_client_state) {
1601         case P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT:
1602             report_gatt_characteristics(gatt_client, packet, size);
1603             trigger_next_characteristic_query(gatt_client,
1604                                               get_last_result_handle_from_characteristics_list(packet, size));
1605             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR
1606             break;
1607         case P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT:
1608             report_gatt_characteristics(gatt_client, packet, size);
1609             trigger_next_characteristic_query(gatt_client,
1610                                               get_last_result_handle_from_characteristics_list(packet, size));
1611             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR
1612             break;
1613         case P_W4_INCLUDED_SERVICE_QUERY_RESULT: {
1614             if (size < 2u) break;
1615             uint16_t uuid16 = 0;
1616             uint16_t pair_size = packet[1];
1617 
1618             if (pair_size == 6u) {
1619                 if (size < 8u) break;
1620                 // UUIDs not available, query first included service
1621                 gatt_client->start_group_handle = little_endian_read_16(packet, 2); // ready for next query
1622                 gatt_client->query_start_handle = little_endian_read_16(packet, 4);
1623                 gatt_client->query_end_handle = little_endian_read_16(packet, 6);
1624                 gatt_client->gatt_client_state = P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY;
1625                 break;
1626             }
1627 
1628             if (pair_size != 8u) break;
1629 
1630             // UUIDs included, report all of them
1631             uint16_t offset;
1632             for (offset = 2u; (offset + 8u) <= size; offset += pair_size) {
1633                 uint16_t include_handle = little_endian_read_16(packet, offset);
1634                 gatt_client->query_start_handle = little_endian_read_16(packet, offset + 2u);
1635                 gatt_client->query_end_handle = little_endian_read_16(packet, offset + 4u);
1636                 uuid16 = little_endian_read_16(packet, offset + 6u);
1637                 report_gatt_included_service_uuid16(gatt_client, include_handle, uuid16);
1638             }
1639 
1640             trigger_next_included_service_query(gatt_client,
1641                                                 get_last_result_handle_from_included_services_list(packet,
1642                                                                                                    size));
1643             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1644             break;
1645         }
1646 #ifndef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
1647         case P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT:
1648             gatt_client->client_characteristic_configuration_handle = little_endian_read_16(packet, 2);
1649             gatt_client->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
1650             break;
1651 #endif
1652         case P_W4_READ_BY_TYPE_RESPONSE: {
1653             uint16_t pair_size = packet[1];
1654             // set last result handle to last valid handle, only used if pair_size invalid
1655             uint16_t last_result_handle = 0xffff;
1656             if (pair_size > 2) {
1657                 uint16_t offset;
1658                 for (offset = 2; offset < size; offset += pair_size) {
1659                     uint16_t value_handle = little_endian_read_16(packet, offset);
1660                     report_gatt_characteristic_value(gatt_client, value_handle, &packet[offset + 2u],
1661                                                      pair_size - 2u);
1662                     last_result_handle = value_handle;
1663                 }
1664             }
1665             trigger_next_read_by_type_query(gatt_client, last_result_handle);
1666             break;
1667         }
1668         default:
1669             break;
1670     }
1671 }
1672 
1673 static void gatt_client_handle_att_write_response(gatt_client_t *gatt_client) {
1674     switch (gatt_client->gatt_client_state) {
1675         case P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT:
1676             gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1677             break;
1678         case P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT:
1679             gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1680             break;
1681         case P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
1682             gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1683             break;
1684         default:
1685             break;
1686     }
1687 }
1688 
1689 static void gatt_client_handle_att_response(gatt_client_t * gatt_client, uint8_t * packet, uint16_t size) {
1690     uint8_t att_status;
1691     switch (packet[0]) {
1692         case ATT_EXCHANGE_MTU_RESPONSE: {
1693             if (size < 3u) break;
1694             bool update_gatt_server_att_mtu = false;
1695             uint16_t remote_rx_mtu = little_endian_read_16(packet, 1);
1696             uint16_t local_rx_mtu = l2cap_max_le_mtu();
1697             switch (gatt_client->bearer_type){
1698                 case ATT_BEARER_UNENHANCED_LE:
1699                     update_gatt_server_att_mtu = true;
1700                     break;
1701 #ifdef ENABLE_GATT_OVER_CLASSIC
1702                 case ATT_BEARER_UNENHANCED_CLASSIC:
1703                     local_rx_mtu = gatt_client->mtu;
1704                     break;
1705 #endif
1706                 default:
1707                     btstack_unreachable();
1708                     break;
1709             }
1710 
1711             uint16_t mtu = (remote_rx_mtu < local_rx_mtu) ? remote_rx_mtu : local_rx_mtu;
1712 
1713             // set gatt client mtu
1714             gatt_client->mtu = mtu;
1715             gatt_client->mtu_state = MTU_EXCHANGED;
1716 
1717             if (update_gatt_server_att_mtu){
1718                 // set per connection mtu state - for fixed channel
1719                 hci_connection_t *hci_connection = hci_connection_for_handle(gatt_client->con_handle);
1720                 hci_connection->att_connection.mtu = gatt_client->mtu;
1721                 hci_connection->att_connection.mtu_exchanged = true;
1722             }
1723             emit_gatt_mtu_exchanged_result_event(gatt_client, gatt_client->mtu);
1724             break;
1725         }
1726         case ATT_READ_BY_GROUP_TYPE_RESPONSE:
1727             switch (gatt_client->gatt_client_state) {
1728                 case P_W4_SERVICE_QUERY_RESULT:
1729                     report_gatt_services(gatt_client, packet, size);
1730                     trigger_next_service_query(gatt_client, get_last_result_handle_from_service_list(packet, size));
1731                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1732                     break;
1733                 default:
1734                     break;
1735             }
1736             break;
1737         case ATT_HANDLE_VALUE_NOTIFICATION:
1738             if (size < 3u) return;
1739             report_gatt_notification(gatt_client, little_endian_read_16(packet, 1u), &packet[3], size - 3u);
1740             return;
1741         case ATT_HANDLE_VALUE_INDICATION:
1742             if (size < 3u) break;
1743             report_gatt_indication(gatt_client, little_endian_read_16(packet, 1u), &packet[3], size - 3u);
1744             gatt_client->send_confirmation = 1;
1745             break;
1746         case ATT_READ_BY_TYPE_RESPONSE:
1747             gatt_client_handle_att_read_by_type_response(gatt_client, packet, size);
1748             break;
1749         case ATT_READ_RESPONSE:
1750             gatt_client_handle_att_read_response(gatt_client, packet, size);
1751             break;
1752         case ATT_FIND_BY_TYPE_VALUE_RESPONSE: {
1753             uint8_t pair_size = 4;
1754             int i;
1755             uint16_t start_group_handle;
1756             uint16_t end_group_handle = 0xffff; // asserts GATT_EVENT_QUERY_COMPLETE is emitted if no results
1757             for (i = 1u; (i + pair_size) <= size; i += pair_size) {
1758                 start_group_handle = little_endian_read_16(packet, i);
1759                 end_group_handle = little_endian_read_16(packet, i + 2);
1760                 emit_gatt_service_query_result_event(gatt_client, start_group_handle, end_group_handle,
1761                                                      gatt_client->uuid128);
1762             }
1763             trigger_next_service_by_uuid_query(gatt_client, end_group_handle);
1764             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1765             break;
1766         }
1767         case ATT_FIND_INFORMATION_REPLY: {
1768             if (size < 2u) break;
1769 
1770             uint8_t pair_size = 4;
1771             if (packet[1u] == 2u) {
1772                 pair_size = 18;
1773             }
1774             uint16_t offset = 2;
1775 
1776             if (size < (pair_size + offset)) break;
1777             uint16_t last_descriptor_handle = little_endian_read_16(packet, size - pair_size);
1778 
1779 #ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
1780             log_info("ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY, state %x", gatt_client->gatt_client_state);
1781             if (gatt_client->gatt_client_state == P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT){
1782                 // iterate over descriptors looking for CCC
1783                 if (pair_size == 4){
1784                     while ((offset + 4) <= size){
1785                         uint16_t uuid16 = little_endian_read_16(packet, offset + 2);
1786                         if (uuid16 == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION){
1787                             gatt_client->client_characteristic_configuration_handle = little_endian_read_16(packet, offset);
1788                             gatt_client->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
1789                             log_info("CCC found %x", gatt_client->client_characteristic_configuration_handle);
1790                             break;
1791                         }
1792                         offset += pair_size;
1793                     }
1794                 }
1795                 if (is_query_done(gatt_client, last_descriptor_handle)){
1796 
1797                 } else {
1798                     // next
1799                     gatt_client->start_group_handle = last_descriptor_handle + 1;
1800                     gatt_client->gatt_client_state = P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY;
1801                 }
1802                 break;
1803             }
1804 #endif
1805             report_gatt_all_characteristic_descriptors(gatt_client, &packet[2], size - 2u, pair_size);
1806             trigger_next_characteristic_descriptor_query(gatt_client, last_descriptor_handle);
1807             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1808             break;
1809         }
1810 
1811         case ATT_WRITE_RESPONSE:
1812             gatt_client_handle_att_write_response(gatt_client);
1813             break;
1814 
1815         case ATT_READ_BLOB_RESPONSE: {
1816             uint16_t received_blob_length = size - 1u;
1817             switch (gatt_client->gatt_client_state) {
1818                 case P_W4_READ_BLOB_RESULT:
1819                     report_gatt_long_characteristic_value_blob(gatt_client, gatt_client->attribute_handle, &packet[1],
1820                                                                received_blob_length, gatt_client->attribute_offset);
1821                     trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_QUERY, received_blob_length);
1822                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1823                     break;
1824                 case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT:
1825                     report_gatt_long_characteristic_descriptor(gatt_client, gatt_client->attribute_handle,
1826                                                                &packet[1], received_blob_length,
1827                                                                gatt_client->attribute_offset);
1828                     trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY,
1829                                             received_blob_length);
1830                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1831                     break;
1832                 default:
1833                     break;
1834             }
1835             break;
1836         }
1837         case ATT_PREPARE_WRITE_RESPONSE:
1838             switch (gatt_client->gatt_client_state) {
1839                 case P_W4_PREPARE_WRITE_SINGLE_RESULT:
1840                     if (is_value_valid(gatt_client, packet, size)) {
1841                         att_status = ATT_ERROR_SUCCESS;
1842                     } else {
1843                         att_status = ATT_ERROR_DATA_MISMATCH;
1844                     }
1845                     gatt_client_handle_transaction_complete(gatt_client, att_status);
1846                     break;
1847 
1848                 case P_W4_PREPARE_WRITE_RESULT: {
1849                     gatt_client->attribute_offset = little_endian_read_16(packet, 3);
1850                     trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_WRITE, P_W2_EXECUTE_PREPARED_WRITE);
1851                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1852                     break;
1853                 }
1854                 case P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT: {
1855                     gatt_client->attribute_offset = little_endian_read_16(packet, 3);
1856                     trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR,
1857                                                      P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR);
1858                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1859                     break;
1860                 }
1861                 case P_W4_PREPARE_RELIABLE_WRITE_RESULT: {
1862                     if (is_value_valid(gatt_client, packet, size)) {
1863                         gatt_client->attribute_offset = little_endian_read_16(packet, 3);
1864                         trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_RELIABLE_WRITE,
1865                                                          P_W2_EXECUTE_PREPARED_WRITE);
1866                         // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1867                         break;
1868                     }
1869                     gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH;
1870                     break;
1871                 }
1872                 default:
1873                     break;
1874             }
1875             break;
1876 
1877         case ATT_EXECUTE_WRITE_RESPONSE:
1878             switch (gatt_client->gatt_client_state) {
1879                 case P_W4_EXECUTE_PREPARED_WRITE_RESULT:
1880                     gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1881                     break;
1882                 case P_W4_CANCEL_PREPARED_WRITE_RESULT:
1883                     gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1884                     break;
1885                 case P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT:
1886                     gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_DATA_MISMATCH);
1887                     break;
1888                 case P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
1889                     gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1890                     break;
1891                 default:
1892                     break;
1893 
1894             }
1895             break;
1896 
1897         case ATT_READ_MULTIPLE_RESPONSE:
1898             switch (gatt_client->gatt_client_state) {
1899                 case P_W4_READ_MULTIPLE_RESPONSE:
1900                     report_gatt_characteristic_value(gatt_client, 0u, &packet[1], size - 1u);
1901                     gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1902                     break;
1903                 default:
1904                     break;
1905             }
1906             break;
1907 
1908 #ifdef ENABLE_GATT_OVER_EATT
1909         case ATT_READ_MULTIPLE_VARIABLE_RSP:
1910             switch (gatt_client->gatt_client_state) {
1911                 case P_W4_READ_MULTIPLE_RESPONSE:
1912                     report_gatt_characteristic_value(gatt_client, 0u, &packet[1], size - 1u);
1913                     gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1914                     break;
1915                 default:
1916                     break;
1917             }
1918             break;
1919 #endif
1920 
1921         case ATT_ERROR_RESPONSE:
1922             if (size < 5u) return;
1923             att_status = packet[4];
1924             switch (att_status) {
1925                 case ATT_ERROR_ATTRIBUTE_NOT_FOUND: {
1926                     switch (gatt_client->gatt_client_state) {
1927                         case P_W4_SERVICE_QUERY_RESULT:
1928                         case P_W4_SERVICE_WITH_UUID_RESULT:
1929                         case P_W4_INCLUDED_SERVICE_QUERY_RESULT:
1930                         case P_W4_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT:
1931                             gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1932                             break;
1933                         case P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT:
1934                         case P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT:
1935                             characteristic_end_found(gatt_client, gatt_client->end_group_handle);
1936                             gatt_client_handle_transaction_complete(gatt_client, ATT_ERROR_SUCCESS);
1937                             break;
1938                         case P_W4_READ_BY_TYPE_RESPONSE:
1939                             if (gatt_client->start_group_handle == gatt_client->query_start_handle) {
1940                                 att_status = ATT_ERROR_ATTRIBUTE_NOT_FOUND;
1941                             } else {
1942                                 att_status = ATT_ERROR_SUCCESS;
1943                             }
1944                             gatt_client_handle_transaction_complete(gatt_client, att_status);
1945                             break;
1946                         default:
1947                             gatt_client_report_error_if_pending(gatt_client, att_status);
1948                             break;
1949                     }
1950                     break;
1951                 }
1952 
1953 #ifdef ENABLE_GATT_CLIENT_PAIRING
1954 
1955                     case ATT_ERROR_INSUFFICIENT_AUTHENTICATION:
1956                     case ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
1957                     case ATT_ERROR_INSUFFICIENT_ENCRYPTION: {
1958 
1959                         // security too low
1960                         if (gatt_client->security_counter > 0) {
1961                             gatt_client_report_error_if_pending(gatt_client, att_status);
1962                             break;
1963                         }
1964                         // start security
1965                         gatt_client->security_counter++;
1966 
1967                         // setup action
1968                         int retry = 1;
1969                         switch (gatt_client->gatt_client_state){
1970                             case P_W4_READ_CHARACTERISTIC_VALUE_RESULT:
1971                                 gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY ;
1972                                 break;
1973                             case P_W4_READ_BLOB_RESULT:
1974                                 gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_QUERY;
1975                                 break;
1976                             case P_W4_READ_BY_TYPE_RESPONSE:
1977                                 gatt_client->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
1978                                 break;
1979                             case P_W4_READ_MULTIPLE_RESPONSE:
1980                                 gatt_client->gatt_client_state = P_W2_SEND_READ_MULTIPLE_REQUEST;
1981                                 break;
1982                             case P_W4_READ_MULTIPLE_VARIABLE_RESPONSE:
1983                                 gatt_client->gatt_client_state = P_W2_SEND_READ_MULTIPLE_VARIABLE_REQUEST;
1984                                 break;
1985                             case P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT:
1986                                 gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_VALUE;
1987                                 break;
1988                             case P_W4_PREPARE_WRITE_RESULT:
1989                                 gatt_client->gatt_client_state = P_W2_PREPARE_WRITE;
1990                                 break;
1991                             case P_W4_PREPARE_WRITE_SINGLE_RESULT:
1992                                 gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_SINGLE;
1993                                 break;
1994                             case P_W4_PREPARE_RELIABLE_WRITE_RESULT:
1995                                 gatt_client->gatt_client_state = P_W2_PREPARE_RELIABLE_WRITE;
1996                                 break;
1997                             case P_W4_EXECUTE_PREPARED_WRITE_RESULT:
1998                                 gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE;
1999                                 break;
2000                             case P_W4_CANCEL_PREPARED_WRITE_RESULT:
2001                                 gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE;
2002                                 break;
2003                             case P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT:
2004                                 gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH;
2005                                 break;
2006                             case P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT:
2007                                 gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY;
2008                                 break;
2009                             case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT:
2010                                 gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY;
2011                                 break;
2012                             case P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
2013                                 gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR;
2014                                 break;
2015                             case P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT:
2016                                 gatt_client->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
2017                                 break;
2018                             case P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
2019                                 gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR;
2020                                 break;
2021                             case P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
2022                                 gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR;
2023                                 break;
2024 #ifdef ENABLE_LE_SIGNED_WRITE
2025                             case P_W4_SEND_SINGED_WRITE_DONE:
2026                                 gatt_client->gatt_client_state = P_W2_SEND_SIGNED_WRITE;
2027                                 break;
2028 #endif
2029                             default:
2030                                 log_info("retry not supported for state %x", gatt_client->gatt_client_state);
2031                                 retry = 0;
2032                                 break;
2033                         }
2034 
2035                         if (!retry) {
2036                             gatt_client_report_error_if_pending(gatt_client, att_status);
2037                             break;
2038                         }
2039 
2040                         log_info("security error, start pairing");
2041 
2042                         // start pairing for higher security level
2043                         gatt_client->wait_for_authentication_complete = 1;
2044                         gatt_client->pending_error_code = att_status;
2045                         sm_request_pairing(gatt_client->con_handle);
2046                         break;
2047                     }
2048 #endif
2049 
2050                     // nothing we can do about that
2051                 case ATT_ERROR_INSUFFICIENT_AUTHORIZATION:
2052                 default:
2053                     gatt_client_report_error_if_pending(gatt_client, att_status);
2054                     break;
2055             }
2056             break;
2057 
2058         default:
2059             log_info("ATT Handler, unhandled response type 0x%02x", packet[0]);
2060             break;
2061     }
2062 }
2063 
2064 static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size) {
2065     gatt_client_t *gatt_client;
2066     if (size < 1u) return;
2067 
2068     if (packet_type == HCI_EVENT_PACKET) {
2069         switch (packet[0]) {
2070             case L2CAP_EVENT_CAN_SEND_NOW:
2071                 gatt_client_run();
2072                 break;
2073                 // att_server has negotiated the mtu for this connection, cache if context exists
2074             case ATT_EVENT_MTU_EXCHANGE_COMPLETE:
2075                 if (size < 6u) break;
2076                 gatt_client = gatt_client_get_context_for_handle(handle);
2077                 if (gatt_client == NULL) break;
2078                 gatt_client->mtu = little_endian_read_16(packet, 4);
2079                 break;
2080             default:
2081                 break;
2082         }
2083         return;
2084     }
2085 
2086     if (packet_type != ATT_DATA_PACKET) return;
2087 
2088     // special cases: notifications & indications motivate creating context
2089     switch (packet[0]) {
2090         case ATT_HANDLE_VALUE_NOTIFICATION:
2091         case ATT_HANDLE_VALUE_INDICATION:
2092             gatt_client_provide_context_for_handle(handle, &gatt_client);
2093             break;
2094         default:
2095             gatt_client = gatt_client_get_context_for_handle(handle);
2096             break;
2097     }
2098 
2099     if (gatt_client != NULL) {
2100         gatt_client_handle_att_response(gatt_client, packet, size);
2101         gatt_client_run();
2102     }
2103 }
2104 
2105 #ifdef ENABLE_LE_SIGNED_WRITE
2106 static void att_signed_write_handle_cmac_result(uint8_t hash[8]){
2107     btstack_linked_list_iterator_t it;
2108     btstack_linked_list_iterator_init(&it, &gatt_client_connections);
2109     while (btstack_linked_list_iterator_has_next(&it)){
2110         gatt_client_t * gatt_client = (gatt_client_t *) btstack_linked_list_iterator_next(&it);
2111         if (gatt_client->gatt_client_state == P_W4_CMAC_RESULT){
2112             // store result
2113             (void)memcpy(gatt_client->cmac, hash, 8);
2114             // reverse_64(hash, gatt_client->cmac);
2115             gatt_client->gatt_client_state = P_W2_SEND_SIGNED_WRITE;
2116             gatt_client_run();
2117             return;
2118         }
2119     }
2120 }
2121 
2122 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){
2123     gatt_client_t * gatt_client;
2124     uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client);
2125     if (status != ERROR_CODE_SUCCESS){
2126         return status;
2127     }
2128     if (is_ready(gatt_client) == 0){
2129         return GATT_CLIENT_IN_WRONG_STATE;
2130     }
2131 
2132     gatt_client->callback = callback;
2133     gatt_client->attribute_handle = value_handle;
2134     gatt_client->attribute_length = message_len;
2135     gatt_client->attribute_value = message;
2136     gatt_client->gatt_client_state = P_W4_IDENTITY_RESOLVING;
2137     gatt_client_run();
2138     return ERROR_CODE_SUCCESS;
2139 }
2140 #endif
2141 
2142 uint8_t gatt_client_discover_primary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
2143     gatt_client_t * gatt_client;
2144     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2145     if (status != ERROR_CODE_SUCCESS){
2146         return status;
2147     }
2148 
2149     gatt_client->callback = callback;
2150     gatt_client->start_group_handle = 0x0001;
2151     gatt_client->end_group_handle   = 0xffff;
2152     gatt_client->gatt_client_state = P_W2_SEND_SERVICE_QUERY;
2153     gatt_client->uuid16 = GATT_PRIMARY_SERVICE_UUID;
2154     gatt_client_run();
2155     return ERROR_CODE_SUCCESS;
2156 }
2157 
2158 uint8_t gatt_client_discover_secondary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
2159     gatt_client_t * gatt_client;
2160     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2161     if (status != ERROR_CODE_SUCCESS){
2162         return status;
2163     }
2164 
2165     gatt_client->callback = callback;
2166     gatt_client->start_group_handle = 0x0001;
2167     gatt_client->end_group_handle   = 0xffff;
2168     gatt_client->gatt_client_state = P_W2_SEND_SERVICE_QUERY;
2169     gatt_client->uuid16 = GATT_SECONDARY_SERVICE_UUID;
2170     gatt_client_run();
2171     return ERROR_CODE_SUCCESS;
2172 }
2173 
2174 uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16){
2175     gatt_client_t * gatt_client;
2176     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2177     if (status != ERROR_CODE_SUCCESS){
2178         return status;
2179     }
2180 
2181     gatt_client->callback = callback;
2182     gatt_client->start_group_handle = 0x0001;
2183     gatt_client->end_group_handle   = 0xffff;
2184     gatt_client->gatt_client_state = P_W2_SEND_SERVICE_WITH_UUID_QUERY;
2185     gatt_client->uuid16 = uuid16;
2186     uuid_add_bluetooth_prefix((uint8_t*) &(gatt_client->uuid128), gatt_client->uuid16);
2187     gatt_client_run();
2188     return ERROR_CODE_SUCCESS;
2189 }
2190 
2191 uint8_t gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, const uint8_t * uuid128){
2192     gatt_client_t * gatt_client;
2193     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2194     if (status != ERROR_CODE_SUCCESS){
2195         return status;
2196     }
2197 
2198     gatt_client->callback = callback;
2199     gatt_client->start_group_handle = 0x0001;
2200     gatt_client->end_group_handle   = 0xffff;
2201     gatt_client->uuid16 = 0;
2202     (void)memcpy(gatt_client->uuid128, uuid128, 16);
2203     gatt_client->gatt_client_state = P_W2_SEND_SERVICE_WITH_UUID_QUERY;
2204     gatt_client_run();
2205     return ERROR_CODE_SUCCESS;
2206 }
2207 
2208 uint8_t gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service){
2209     gatt_client_t * gatt_client;
2210     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2211     if (status != ERROR_CODE_SUCCESS){
2212         return status;
2213     }
2214 
2215     gatt_client->callback = callback;
2216     gatt_client->start_group_handle = service->start_group_handle;
2217     gatt_client->end_group_handle   = service->end_group_handle;
2218     gatt_client->filter_with_uuid = 0;
2219     gatt_client->characteristic_start_handle = 0;
2220     gatt_client->gatt_client_state = P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY;
2221     gatt_client_run();
2222     return ERROR_CODE_SUCCESS;
2223 }
2224 
2225 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){
2226     gatt_client_t * gatt_client;
2227     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2228     if (status != ERROR_CODE_SUCCESS){
2229         return status;
2230     }
2231 
2232     gatt_client->callback = callback;
2233     gatt_client->start_group_handle = service->start_group_handle;
2234     gatt_client->end_group_handle   = service->end_group_handle;
2235     gatt_client->gatt_client_state = P_W2_SEND_INCLUDED_SERVICE_QUERY;
2236 
2237     gatt_client_run();
2238     return ERROR_CODE_SUCCESS;
2239 }
2240 
2241 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){
2242     gatt_client_t * gatt_client;
2243     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2244     if (status != ERROR_CODE_SUCCESS){
2245         return status;
2246     }
2247 
2248     gatt_client->callback = callback;
2249     gatt_client->start_group_handle = start_handle;
2250     gatt_client->end_group_handle   = end_handle;
2251     gatt_client->filter_with_uuid = 1;
2252     gatt_client->uuid16 = uuid16;
2253     uuid_add_bluetooth_prefix((uint8_t*) &(gatt_client->uuid128), uuid16);
2254     gatt_client->characteristic_start_handle = 0;
2255     gatt_client->gatt_client_state = P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY;
2256     gatt_client_run();
2257     return ERROR_CODE_SUCCESS;
2258 }
2259 
2260 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){
2261     gatt_client_t * gatt_client;
2262     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2263     if (status != ERROR_CODE_SUCCESS){
2264         return status;
2265     }
2266 
2267     gatt_client->callback = callback;
2268     gatt_client->start_group_handle = start_handle;
2269     gatt_client->end_group_handle   = end_handle;
2270     gatt_client->filter_with_uuid = 1;
2271     gatt_client->uuid16 = 0;
2272     (void)memcpy(gatt_client->uuid128, uuid128, 16);
2273     gatt_client->characteristic_start_handle = 0;
2274     gatt_client->gatt_client_state = P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY;
2275     gatt_client_run();
2276     return ERROR_CODE_SUCCESS;
2277 }
2278 
2279 
2280 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){
2281     return gatt_client_discover_characteristics_for_handle_range_by_uuid16(callback, con_handle, service->start_group_handle, service->end_group_handle, uuid16);
2282 }
2283 
2284 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){
2285     return gatt_client_discover_characteristics_for_handle_range_by_uuid128(callback, con_handle, service->start_group_handle, service->end_group_handle, uuid128);
2286 }
2287 
2288 uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){
2289     gatt_client_t * gatt_client;
2290     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2291     if (status != ERROR_CODE_SUCCESS){
2292         return status;
2293     }
2294 
2295     if (characteristic->value_handle == characteristic->end_handle){
2296         return ERROR_CODE_SUCCESS;
2297     }
2298     gatt_client->callback = callback;
2299     gatt_client->start_group_handle = characteristic->value_handle + 1u;
2300     gatt_client->end_group_handle   = characteristic->end_handle;
2301     gatt_client->gatt_client_state = P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY;
2302     gatt_client_run();
2303     return ERROR_CODE_SUCCESS;
2304 }
2305 
2306 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){
2307     gatt_client_t * gatt_client;
2308     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2309     if (status != ERROR_CODE_SUCCESS){
2310         return status;
2311     }
2312 
2313     gatt_client->callback = callback;
2314     gatt_client->attribute_handle = value_handle;
2315     gatt_client->attribute_offset = 0;
2316     gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY;
2317     gatt_client_run();
2318     return ERROR_CODE_SUCCESS;
2319 }
2320 
2321 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){
2322     gatt_client_t * gatt_client;
2323     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2324     if (status != ERROR_CODE_SUCCESS){
2325         return status;
2326     }
2327 
2328     gatt_client->callback = callback;
2329     gatt_client->start_group_handle = start_handle;
2330     gatt_client->end_group_handle = end_handle;
2331     gatt_client->query_start_handle = start_handle;
2332     gatt_client->query_end_handle = end_handle;
2333     gatt_client->uuid16 = uuid16;
2334     uuid_add_bluetooth_prefix((uint8_t*) &(gatt_client->uuid128), uuid16);
2335     gatt_client->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
2336     gatt_client_run();
2337     return ERROR_CODE_SUCCESS;
2338 }
2339 
2340 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){
2341     gatt_client_t * gatt_client;
2342     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2343     if (status != ERROR_CODE_SUCCESS){
2344         return status;
2345     }
2346 
2347     gatt_client->callback = callback;
2348     gatt_client->start_group_handle = start_handle;
2349     gatt_client->end_group_handle = end_handle;
2350     gatt_client->query_start_handle = start_handle;
2351     gatt_client->query_end_handle = end_handle;
2352     gatt_client->uuid16 = 0;
2353     (void)memcpy(gatt_client->uuid128, uuid128, 16);
2354     gatt_client->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
2355     gatt_client_run();
2356     return ERROR_CODE_SUCCESS;
2357 }
2358 
2359 
2360 uint8_t gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){
2361     return gatt_client_read_value_of_characteristic_using_value_handle(callback, con_handle, characteristic->value_handle);
2362 }
2363 
2364 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){
2365     gatt_client_t * gatt_client;
2366     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2367     if (status != ERROR_CODE_SUCCESS){
2368         return status;
2369     }
2370 
2371     gatt_client->callback = callback;
2372     gatt_client->attribute_handle = value_handle;
2373     gatt_client->attribute_offset = offset;
2374     gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_QUERY;
2375     gatt_client_run();
2376     return ERROR_CODE_SUCCESS;
2377 }
2378 
2379 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){
2380     return gatt_client_read_long_value_of_characteristic_using_value_handle_with_offset(callback, con_handle, value_handle, 0);
2381 }
2382 
2383 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){
2384     return gatt_client_read_long_value_of_characteristic_using_value_handle(callback, con_handle, characteristic->value_handle);
2385 }
2386 
2387 static uint8_t gatt_client_read_multiple_characteristic_values_with_state(btstack_packet_handler_t callback, hci_con_handle_t con_handle, int num_value_handles, uint16_t * value_handles, gatt_client_state_t state){
2388     gatt_client_t * gatt_client;
2389     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2390     if (status != ERROR_CODE_SUCCESS){
2391         return status;
2392     }
2393 
2394 #ifdef ENABLE_GATT_OVER_EATT
2395     if (state == P_W2_SEND_READ_MULTIPLE_VARIABLE_REQUEST){
2396         if (gatt_client->bearer_type != ATT_BEARER_ENHANCED_LE){
2397             return ERROR_CODE_COMMAND_DISALLOWED;
2398         }
2399     }
2400 #endif
2401 
2402     gatt_client->callback = callback;
2403     gatt_client->read_multiple_handle_count = num_value_handles;
2404     gatt_client->read_multiple_handles = value_handles;
2405     gatt_client->gatt_client_state = state;
2406     gatt_client_run();
2407     return ERROR_CODE_SUCCESS;
2408 }
2409 
2410 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){
2411     return gatt_client_read_multiple_characteristic_values_with_state(callback, con_handle, num_value_handles, value_handles, P_W2_SEND_READ_MULTIPLE_REQUEST);
2412 }
2413 
2414 #ifdef ENABLE_GATT_OVER_EATT
2415 uint8_t gatt_client_read_multiple_variable_characteristic_values(btstack_packet_handler_t callback, hci_con_handle_t con_handle, int num_value_handles, uint16_t * value_handles){
2416     return gatt_client_read_multiple_characteristic_values_with_state(callback, con_handle, num_value_handles, value_handles, P_W2_SEND_READ_MULTIPLE_VARIABLE_REQUEST);
2417 }
2418 #endif
2419 
2420 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){
2421     gatt_client_t * gatt_client;
2422     uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client);
2423     if (status != ERROR_CODE_SUCCESS){
2424         return status;
2425     }
2426 
2427     if (value_length > (gatt_client->mtu - 3u)) return GATT_CLIENT_VALUE_TOO_LONG;
2428     if (!att_dispatch_client_can_send_now(gatt_client->con_handle)) return GATT_CLIENT_BUSY;
2429 
2430     return att_write_request(gatt_client, ATT_WRITE_COMMAND, value_handle, value_length, value);
2431 }
2432 
2433 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){
2434     gatt_client_t * gatt_client;
2435     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2436     if (status != ERROR_CODE_SUCCESS){
2437         return status;
2438     }
2439 
2440     gatt_client->callback = callback;
2441     gatt_client->attribute_handle = value_handle;
2442     gatt_client->attribute_length = value_length;
2443     gatt_client->attribute_value = value;
2444     gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_VALUE;
2445     gatt_client_run();
2446     return ERROR_CODE_SUCCESS;
2447 }
2448 
2449 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){
2450     gatt_client_t * gatt_client;
2451     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2452     if (status != ERROR_CODE_SUCCESS){
2453         return status;
2454     }
2455 
2456     gatt_client->callback = callback;
2457     gatt_client->attribute_handle = value_handle;
2458     gatt_client->attribute_length = value_length;
2459     gatt_client->attribute_offset = offset;
2460     gatt_client->attribute_value = value;
2461     gatt_client->gatt_client_state = P_W2_PREPARE_WRITE;
2462     gatt_client_run();
2463     return ERROR_CODE_SUCCESS;
2464 }
2465 
2466 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){
2467     return gatt_client_write_long_value_of_characteristic_with_offset(callback, con_handle, value_handle, 0, value_length, value);
2468 }
2469 
2470 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){
2471     gatt_client_t * gatt_client;
2472     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2473     if (status != ERROR_CODE_SUCCESS){
2474         return status;
2475     }
2476 
2477     gatt_client->callback = callback;
2478     gatt_client->attribute_handle = value_handle;
2479     gatt_client->attribute_length = value_length;
2480     gatt_client->attribute_offset = 0;
2481     gatt_client->attribute_value = value;
2482     gatt_client->gatt_client_state = P_W2_PREPARE_RELIABLE_WRITE;
2483     gatt_client_run();
2484     return ERROR_CODE_SUCCESS;
2485 }
2486 
2487 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){
2488     gatt_client_t * gatt_client;
2489     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2490     if (status != ERROR_CODE_SUCCESS){
2491         return status;
2492     }
2493 
2494     if ( (configuration & GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION) &&
2495         ((characteristic->properties & ATT_PROPERTY_NOTIFY) == 0u)) {
2496         log_info("gatt_client_write_client_characteristic_configuration: GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED");
2497         return GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED;
2498     } else if ( (configuration & GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION) &&
2499                ((characteristic->properties & ATT_PROPERTY_INDICATE) == 0u)){
2500         log_info("gatt_client_write_client_characteristic_configuration: GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED");
2501         return GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED;
2502     }
2503 
2504     gatt_client->callback = callback;
2505     gatt_client->start_group_handle = characteristic->value_handle;
2506     gatt_client->end_group_handle = characteristic->end_handle;
2507     little_endian_store_16(gatt_client->client_characteristic_configuration_value, 0, configuration);
2508 
2509 #ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
2510     gatt_client->gatt_client_state = P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY;
2511 #else
2512     gatt_client->gatt_client_state = P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY;
2513 #endif
2514     gatt_client_run();
2515     return ERROR_CODE_SUCCESS;
2516 }
2517 
2518 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){
2519     gatt_client_t * gatt_client;
2520     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2521     if (status != ERROR_CODE_SUCCESS){
2522         return status;
2523     }
2524 
2525     gatt_client->callback = callback;
2526     gatt_client->attribute_handle = descriptor_handle;
2527 
2528     gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY;
2529     gatt_client_run();
2530     return ERROR_CODE_SUCCESS;
2531 }
2532 
2533 uint8_t gatt_client_read_characteristic_descriptor(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_descriptor_t * descriptor){
2534     return gatt_client_read_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle);
2535 }
2536 
2537 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){
2538     gatt_client_t * gatt_client;
2539     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2540     if (status != ERROR_CODE_SUCCESS){
2541         return status;
2542     }
2543 
2544     gatt_client->callback = callback;
2545     gatt_client->attribute_handle = descriptor_handle;
2546     gatt_client->attribute_offset = offset;
2547     gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY;
2548     gatt_client_run();
2549     return ERROR_CODE_SUCCESS;
2550 }
2551 
2552 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){
2553     return gatt_client_read_long_characteristic_descriptor_using_descriptor_handle_with_offset(callback, con_handle, descriptor_handle, 0);
2554 }
2555 
2556 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){
2557     return gatt_client_read_long_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle);
2558 }
2559 
2560 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){
2561     gatt_client_t * gatt_client;
2562     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2563     if (status != ERROR_CODE_SUCCESS){
2564         return status;
2565     }
2566 
2567     gatt_client->callback = callback;
2568     gatt_client->attribute_handle = descriptor_handle;
2569     gatt_client->attribute_length = value_length;
2570     gatt_client->attribute_offset = 0;
2571     gatt_client->attribute_value = value;
2572     gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR;
2573     gatt_client_run();
2574     return ERROR_CODE_SUCCESS;
2575 }
2576 
2577 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){
2578     return gatt_client_write_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle, value_length, value);
2579 }
2580 
2581 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){
2582     gatt_client_t * gatt_client;
2583     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2584     if (status != ERROR_CODE_SUCCESS){
2585         return status;
2586     }
2587 
2588     gatt_client->callback = callback;
2589     gatt_client->attribute_handle = descriptor_handle;
2590     gatt_client->attribute_length = value_length;
2591     gatt_client->attribute_offset = offset;
2592     gatt_client->attribute_value = value;
2593     gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR;
2594     gatt_client_run();
2595     return ERROR_CODE_SUCCESS;
2596 }
2597 
2598 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){
2599     return gatt_client_write_long_characteristic_descriptor_using_descriptor_handle_with_offset(callback, con_handle, descriptor_handle, 0, value_length, value);
2600 }
2601 
2602 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){
2603     return gatt_client_write_long_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle, value_length, value);
2604 }
2605 
2606 /**
2607  * @brief -> gatt complete event
2608  */
2609 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){
2610     gatt_client_t * gatt_client;
2611     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2612     if (status != ERROR_CODE_SUCCESS){
2613         return status;
2614     }
2615 
2616     gatt_client->callback = callback;
2617     gatt_client->attribute_handle = attribute_handle;
2618     gatt_client->attribute_length = value_length;
2619     gatt_client->attribute_offset = offset;
2620     gatt_client->attribute_value = value;
2621     gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_SINGLE;
2622     gatt_client_run();
2623     return ERROR_CODE_SUCCESS;
2624 }
2625 
2626 /**
2627  * @brief -> gatt complete event
2628  */
2629 uint8_t gatt_client_execute_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
2630     gatt_client_t * gatt_client;
2631     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2632     if (status != ERROR_CODE_SUCCESS){
2633         return status;
2634     }
2635 
2636     gatt_client->callback = callback;
2637     gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE;
2638     gatt_client_run();
2639     return ERROR_CODE_SUCCESS;
2640 }
2641 
2642 /**
2643  * @brief -> gatt complete event
2644  */
2645 uint8_t gatt_client_cancel_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
2646     gatt_client_t * gatt_client;
2647     uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2648     if (status != ERROR_CODE_SUCCESS){
2649         return status;
2650     }
2651 
2652     gatt_client->callback = callback;
2653     gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE;
2654     gatt_client_run();
2655     return ERROR_CODE_SUCCESS;
2656 }
2657 
2658 void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t * service){
2659     service->start_group_handle = little_endian_read_16(packet, offset);
2660     service->end_group_handle = little_endian_read_16(packet, offset + 2);
2661     reverse_128(&packet[offset + 4], service->uuid128);
2662     if (uuid_has_bluetooth_prefix(service->uuid128)){
2663         service->uuid16 = big_endian_read_32(service->uuid128, 0);
2664     } else {
2665         service->uuid16 = 0;
2666     }
2667 }
2668 
2669 void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic){
2670     characteristic->start_handle = little_endian_read_16(packet, offset);
2671     characteristic->value_handle = little_endian_read_16(packet, offset + 2);
2672     characteristic->end_handle = little_endian_read_16(packet, offset + 4);
2673     characteristic->properties = little_endian_read_16(packet, offset + 6);
2674     reverse_128(&packet[offset+8], characteristic->uuid128);
2675     if (uuid_has_bluetooth_prefix(characteristic->uuid128)){
2676         characteristic->uuid16 = big_endian_read_32(characteristic->uuid128, 0);
2677     } else {
2678         characteristic->uuid16 = 0;
2679     }
2680 }
2681 
2682 void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor){
2683     descriptor->handle = little_endian_read_16(packet, offset);
2684     reverse_128(&packet[offset+2], descriptor->uuid128);
2685     if (uuid_has_bluetooth_prefix(descriptor->uuid128)){
2686         descriptor->uuid16 = big_endian_read_32(descriptor->uuid128, 0);
2687     } else {
2688         descriptor->uuid16 = 0;
2689     }
2690 }
2691 
2692 void gatt_client_send_mtu_negotiation(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
2693     gatt_client_t * gatt_client;
2694     uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client);
2695     if (status != ERROR_CODE_SUCCESS){
2696         return;
2697     }
2698     if (gatt_client->mtu_state == MTU_AUTO_EXCHANGE_DISABLED){
2699         gatt_client->callback = callback;
2700         gatt_client->mtu_state = SEND_MTU_EXCHANGE;
2701         gatt_client_run();
2702     }
2703 }
2704 
2705 uint8_t gatt_client_request_to_write_without_response(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle){
2706     gatt_client_t * gatt_client;
2707     uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client);
2708     if (status != ERROR_CODE_SUCCESS){
2709         return status;
2710     }
2711     bool added = btstack_linked_list_add_tail(&gatt_client->write_without_response_requests, (btstack_linked_item_t*) callback_registration);
2712     att_dispatch_client_request_can_send_now_event(gatt_client->con_handle);
2713     if (added){
2714         return ERROR_CODE_SUCCESS;
2715     } else {
2716         return ERROR_CODE_COMMAND_DISALLOWED;
2717     }
2718 }
2719 
2720 uint8_t gatt_client_request_to_send_gatt_query(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle){
2721     gatt_client_t * gatt_client;
2722     uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client);
2723     if (status != ERROR_CODE_SUCCESS){
2724         return status;
2725     }
2726     bool added = btstack_linked_list_add_tail(&gatt_client->query_requests, (btstack_linked_item_t*) callback_registration);
2727     gatt_client_notify_can_send_query(gatt_client);
2728     if (added){
2729         return ERROR_CODE_SUCCESS;
2730     } else {
2731         return ERROR_CODE_COMMAND_DISALLOWED;
2732     }
2733 }
2734 
2735 uint8_t gatt_client_request_can_write_without_response_event(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
2736     gatt_client_t * gatt_client;
2737     uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client);
2738     if (status != ERROR_CODE_SUCCESS){
2739         return status;
2740     }
2741     if (gatt_client->write_without_response_callback != NULL){
2742         return GATT_CLIENT_IN_WRONG_STATE;
2743     }
2744     gatt_client->write_without_response_callback = callback;
2745     att_dispatch_client_request_can_send_now_event(gatt_client->con_handle);
2746     return ERROR_CODE_SUCCESS;
2747 }
2748 
2749 
2750 #if defined(ENABLE_GATT_OVER_CLASSIC) || defined(ENABLE_GATT_OVER_EATT)
2751 
2752 #include "hci_event.h"
2753 
2754 static const hci_event_t gatt_client_connected = {
2755         GATT_EVENT_CONNECTED, 0, "1BH"
2756 };
2757 
2758 static const hci_event_t gatt_client_disconnected = {
2759         GATT_EVENT_DISCONNECTED, 0, "H"
2760 };
2761 #endif
2762 
2763 #ifdef ENABLE_GATT_OVER_CLASSIC
2764 
2765 #include "bluetooth_psm.h"
2766 
2767 // single active SDP query
2768 static gatt_client_t * gatt_client_classic_active_sdp_query;
2769 
2770 // macos protocol descriptor list requires 16 bytes
2771 static uint8_t gatt_client_classic_sdp_buffer[32];
2772 
2773 
2774 static gatt_client_t * gatt_client_get_context_for_classic_addr(bd_addr_t addr){
2775     btstack_linked_item_t *it;
2776     for (it = (btstack_linked_item_t *) gatt_client_connections; it != NULL; it = it->next){
2777         gatt_client_t * gatt_client = (gatt_client_t *) it;
2778         if (memcmp(gatt_client->addr, addr, 6) == 0){
2779             return gatt_client;
2780         }
2781     }
2782     return NULL;
2783 }
2784 
2785 static gatt_client_t * gatt_client_get_context_for_l2cap_cid(uint16_t l2cap_cid){
2786     btstack_linked_item_t *it;
2787     for (it = (btstack_linked_item_t *) gatt_client_connections; it != NULL; it = it->next){
2788         gatt_client_t * gatt_client = (gatt_client_t *) it;
2789         if (gatt_client->l2cap_cid == l2cap_cid){
2790             return gatt_client;
2791         }
2792     }
2793     return NULL;
2794 }
2795 
2796 static void gatt_client_classic_handle_connected(gatt_client_t * gatt_client, uint8_t status){
2797     bd_addr_t addr;
2798     // cppcheck-suppress uninitvar ; addr is reported as uninitialized although it's the destination of the memcpy
2799     memcpy(addr, gatt_client->addr, 6);
2800     hci_con_handle_t con_handle = gatt_client->con_handle;
2801     btstack_packet_handler_t callback = gatt_client->callback;
2802     if (status != ERROR_CODE_SUCCESS){
2803         btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
2804         btstack_memory_gatt_client_free(gatt_client);
2805     }
2806     uint8_t buffer[20];
2807     uint16_t len = hci_event_create_from_template_and_arguments(buffer, sizeof(buffer), &gatt_client_connected, status, addr,
2808                                                                 con_handle);
2809     (*callback)(HCI_EVENT_PACKET, 0, buffer, len);
2810 }
2811 
2812 static void gatt_client_classic_handle_disconnected(gatt_client_t * gatt_client){
2813 
2814     gatt_client_report_error_if_pending(gatt_client, ATT_ERROR_HCI_DISCONNECT_RECEIVED);
2815     gatt_client_timeout_stop(gatt_client);
2816 
2817     hci_con_handle_t con_handle = gatt_client->con_handle;
2818     btstack_packet_handler_t callback = gatt_client->callback;
2819     btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
2820     btstack_memory_gatt_client_free(gatt_client);
2821 
2822     uint8_t buffer[20];
2823     uint16_t len = hci_event_create_from_template_and_arguments(buffer, sizeof(buffer), &gatt_client_disconnected, con_handle);
2824     (*callback)(HCI_EVENT_PACKET, 0, buffer, len);
2825 }
2826 
2827 static void gatt_client_l2cap_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
2828     gatt_client_t * gatt_client = NULL;
2829     uint8_t status;
2830     switch (packet_type){
2831         case HCI_EVENT_PACKET:
2832             switch (hci_event_packet_get_type(packet)) {
2833                 case L2CAP_EVENT_CHANNEL_OPENED:
2834                     status = l2cap_event_channel_opened_get_status(packet);
2835                     gatt_client = gatt_client_get_context_for_l2cap_cid(l2cap_event_channel_opened_get_local_cid(packet));
2836                     btstack_assert(gatt_client != NULL);
2837                     // if status != 0, gatt_client will be discarded
2838                     gatt_client->gatt_client_state = P_READY;
2839                     gatt_client->con_handle = l2cap_event_channel_opened_get_handle(packet);
2840                     gatt_client->mtu = l2cap_event_channel_opened_get_remote_mtu(packet);
2841                     gatt_client_classic_handle_connected(gatt_client, status);
2842                     break;
2843                 case L2CAP_EVENT_CHANNEL_CLOSED:
2844                     gatt_client = gatt_client_get_context_for_l2cap_cid(l2cap_event_channel_closed_get_local_cid(packet));
2845                     gatt_client_classic_handle_disconnected(gatt_client);
2846                     break;
2847                 default:
2848                     break;
2849             }
2850             break;
2851         case L2CAP_DATA_PACKET:
2852             gatt_client = gatt_client_get_context_for_l2cap_cid(channel);
2853             btstack_assert(gatt_client != NULL);
2854             gatt_client_handle_att_response(gatt_client, packet, size);
2855             gatt_client_run();
2856             break;
2857         default:
2858             break;
2859     }
2860 }
2861 
2862 static void gatt_client_handle_sdp_client_query_attribute_value(gatt_client_t * connection, uint8_t *packet){
2863     des_iterator_t des_list_it;
2864     des_iterator_t prot_it;
2865 
2866     if (sdp_event_query_attribute_byte_get_attribute_length(packet) <= sizeof(gatt_client_classic_sdp_buffer)) {
2867         gatt_client_classic_sdp_buffer[sdp_event_query_attribute_byte_get_data_offset(packet)] = sdp_event_query_attribute_byte_get_data(packet);
2868         if ((uint16_t)(sdp_event_query_attribute_byte_get_data_offset(packet)+1) == sdp_event_query_attribute_byte_get_attribute_length(packet)) {
2869             switch(sdp_event_query_attribute_byte_get_attribute_id(packet)) {
2870                 case BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST:
2871                     for (des_iterator_init(&des_list_it, gatt_client_classic_sdp_buffer); des_iterator_has_more(&des_list_it); des_iterator_next(&des_list_it)) {
2872                         uint8_t       *des_element;
2873                         uint8_t       *element;
2874                         uint32_t       uuid;
2875 
2876                         if (des_iterator_get_type(&des_list_it) != DE_DES) continue;
2877 
2878                         des_element = des_iterator_get_element(&des_list_it);
2879                         des_iterator_init(&prot_it, des_element);
2880                         element = des_iterator_get_element(&prot_it);
2881 
2882                         if (de_get_element_type(element) != DE_UUID) continue;
2883 
2884                         uuid = de_get_uuid32(element);
2885                         des_iterator_next(&prot_it);
2886                         // we assume that the even if there are both roles supported, remote device uses the same psm and avdtp version for both
2887                         switch (uuid){
2888                             case BLUETOOTH_PROTOCOL_L2CAP:
2889                                 if (!des_iterator_has_more(&prot_it)) continue;
2890                                 de_element_get_uint16(des_iterator_get_element(&prot_it), &connection->l2cap_psm);
2891                                 break;
2892                             default:
2893                                 break;
2894                         }
2895                     }
2896                     break;
2897 
2898                 default:
2899                     break;
2900             }
2901         }
2902     }
2903 }
2904 
2905 static void gatt_client_classic_sdp_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
2906     gatt_client_t * gatt_client = gatt_client_classic_active_sdp_query;
2907     btstack_assert(gatt_client != NULL);
2908     uint8_t status;
2909 
2910     // TODO: handle sdp events, get l2cap psm
2911     switch (hci_event_packet_get_type(packet)){
2912         case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
2913             gatt_client_handle_sdp_client_query_attribute_value(gatt_client, packet);
2914             // TODO:
2915             return;
2916         case SDP_EVENT_QUERY_COMPLETE:
2917             status = sdp_event_query_complete_get_status(packet);
2918             gatt_client_classic_active_sdp_query = NULL;
2919             log_info("l2cap psm: %0x, status %02x", gatt_client->l2cap_psm, status);
2920             if (status != ERROR_CODE_SUCCESS) break;
2921             if (gatt_client->l2cap_psm == 0) {
2922                 status = SDP_SERVICE_NOT_FOUND;
2923                 break;
2924             }
2925             break;
2926         default:
2927             btstack_assert(false);
2928             return;
2929     }
2930 
2931     // done
2932     if (status == ERROR_CODE_SUCCESS){
2933         gatt_client->gatt_client_state = P_W4_L2CAP_CONNECTION;
2934         status = l2cap_create_channel(gatt_client_l2cap_handler, gatt_client->addr, gatt_client->l2cap_psm, 0xffff,
2935                              &gatt_client->l2cap_cid);
2936     }
2937     if (status != ERROR_CODE_SUCCESS) {
2938         gatt_client_classic_handle_connected(gatt_client, status);
2939     }
2940 }
2941 
2942 static void gatt_client_classic_sdp_start(void * context){
2943     gatt_client_classic_active_sdp_query = (gatt_client_t *) context;
2944     gatt_client_classic_active_sdp_query->gatt_client_state = P_W4_SDP_QUERY;
2945     sdp_client_query_uuid16(gatt_client_classic_sdp_handler, gatt_client_classic_active_sdp_query->addr, ORG_BLUETOOTH_SERVICE_GENERIC_ATTRIBUTE);
2946 }
2947 
2948 uint8_t gatt_client_classic_connect(btstack_packet_handler_t callback, bd_addr_t addr){
2949     gatt_client_t * gatt_client = gatt_client_get_context_for_classic_addr(addr);
2950     if (gatt_client != NULL){
2951         return ERROR_CODE_ACL_CONNECTION_ALREADY_EXISTS;
2952     }
2953     gatt_client = btstack_memory_gatt_client_get();
2954     if (gatt_client == NULL){
2955         return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
2956     }
2957     // init state
2958     gatt_client->bearer_type = ATT_BEARER_UNENHANCED_CLASSIC;
2959     gatt_client->con_handle = HCI_CON_HANDLE_INVALID;
2960     memcpy(gatt_client->addr, addr, 6);
2961     gatt_client->mtu = ATT_DEFAULT_MTU;
2962     gatt_client->security_level = LEVEL_0;
2963     gatt_client->mtu_state = MTU_AUTO_EXCHANGE_DISABLED;
2964     gatt_client->gatt_client_state = P_W2_SDP_QUERY;
2965     gatt_client->sdp_query_request.callback = &gatt_client_classic_sdp_start;
2966     gatt_client->sdp_query_request.context = gatt_client;
2967     gatt_client->callback = callback;
2968 #ifdef ENABLE_GATT_OVER_EATT
2969     gatt_client->eatt_state = GATT_CLIENT_EATT_IDLE;
2970 #endif
2971     btstack_linked_list_add(&gatt_client_connections, (btstack_linked_item_t*)gatt_client);
2972     sdp_client_register_query_callback(&gatt_client->sdp_query_request);
2973     return ERROR_CODE_SUCCESS;
2974 }
2975 
2976 uint8_t gatt_client_classic_disconnect(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
2977     gatt_client_t * gatt_client = gatt_client_get_context_for_handle(con_handle);
2978     if (gatt_client == NULL){
2979         return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
2980     }
2981     gatt_client->callback = callback;
2982     return l2cap_disconnect(gatt_client->l2cap_cid);
2983 }
2984 #endif
2985 
2986 #ifdef ENABLE_GATT_OVER_EATT
2987 
2988 #define MAX_NR_EATT_CHANNELS 5
2989 
2990 static void gatt_client_le_enhanced_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
2991 
2992 static void gatt_client_eatt_finalize(gatt_client_t * gatt_client) {
2993     // free eatt clients
2994     btstack_linked_list_iterator_t it;
2995     btstack_linked_list_iterator_init(&it, &gatt_client_connections);
2996     while (btstack_linked_list_iterator_has_next(&it)) {
2997         gatt_client_t *eatt_client = (gatt_client_t *) btstack_linked_list_iterator_next(&it);
2998         btstack_linked_list_iterator_remove(&it);
2999         btstack_memory_gatt_client_free(eatt_client);
3000     }
3001 }
3002 
3003 // all channels connected
3004 static void gatt_client_le_enhanced_handle_connected(gatt_client_t * gatt_client, uint8_t status) {
3005     if (status == ERROR_CODE_SUCCESS){
3006         gatt_client->eatt_state = GATT_CLIENT_EATT_READY;
3007     } else {
3008         gatt_client_eatt_finalize(gatt_client);
3009         gatt_client->eatt_state = GATT_CLIENT_EATT_IDLE;
3010     }
3011 
3012     uint8_t buffer[20];
3013     uint16_t len = hci_event_create_from_template_and_arguments(buffer, sizeof(buffer), &gatt_client_connected, status, gatt_client->addr,
3014                                                                 gatt_client->con_handle);
3015     (*gatt_client->callback)(HCI_EVENT_PACKET, 0, buffer, len);
3016 }
3017 
3018 // single channel disconnected
3019 static void gatt_client_le_enhanced_handle_ecbm_disconnected(gatt_client_t * gatt_client, gatt_client_t * eatt_client) {
3020     if (gatt_client->eatt_state == GATT_CLIENT_EATT_READY) {
3021 
3022         // report error
3023         gatt_client_report_error_if_pending(eatt_client, ATT_ERROR_HCI_DISCONNECT_RECEIVED);
3024 
3025         // free memory
3026         btstack_linked_list_remove(&gatt_client->eatt_clients, (btstack_linked_item_t *) eatt_client);
3027         btstack_memory_gatt_client_free(eatt_client);
3028 
3029         // report disconnected if last channel closed
3030         if (btstack_linked_list_empty(&gatt_client->eatt_clients)){
3031             // emit disconnected when last eatt client is gone
3032             uint8_t buffer[20];
3033             uint16_t len = hci_event_create_from_template_and_arguments(buffer, sizeof(buffer), &gatt_client_disconnected, gatt_client->con_handle);
3034             (*gatt_client->callback)(HCI_EVENT_PACKET, 0, buffer, len);
3035         }
3036     }
3037 }
3038 
3039 static gatt_client_t * gatt_client_le_enhanced_get_context_for_l2cap_cid(uint16_t l2cap_cid, gatt_client_t ** out_eatt_client){
3040     btstack_linked_list_iterator_t it;
3041     btstack_linked_list_iterator_init(&it, &gatt_client_connections);
3042     while (btstack_linked_list_iterator_has_next(&it)) {
3043         gatt_client_t * gatt_client = (gatt_client_t *) btstack_linked_list_iterator_next(&it);
3044         btstack_linked_list_iterator_t it2;
3045         btstack_linked_list_iterator_init(&it2, &gatt_client->eatt_clients);
3046         while (btstack_linked_list_iterator_has_next(&it2)) {
3047             gatt_client_t * eatt_client = (gatt_client_t *) btstack_linked_list_iterator_next(&it2);
3048             if (eatt_client->l2cap_cid == l2cap_cid){
3049                 *out_eatt_client = eatt_client;
3050                 return gatt_client;
3051             }
3052         }
3053     }
3054     return NULL;
3055 }
3056 
3057 static void gatt_client_le_enhanced_setup_l2cap_channel(gatt_client_t * gatt_client){
3058     uint8_t num_channels = gatt_client->eatt_num_clients;
3059 
3060     // setup channels
3061     uint16_t buffer_size_per_client = gatt_client->eatt_storage_size / num_channels;
3062     uint16_t receive_buffer_size  = buffer_size_per_client / 2;
3063     uint16_t transmit_buffer_size = buffer_size_per_client / 2;
3064     uint8_t * receive_buffers[MAX_NR_EATT_CHANNELS];
3065     uint16_t  new_cids[MAX_NR_EATT_CHANNELS];
3066     memset(gatt_client->eatt_storage_buffer, 0, gatt_client->eatt_storage_size);
3067     uint8_t i;
3068     for (i=0;i<gatt_client->eatt_num_clients; i++){
3069         receive_buffers[i] = gatt_client->eatt_storage_buffer;;
3070         gatt_client->eatt_storage_buffer += receive_buffer_size;
3071     }
3072 
3073     log_info("%u EATT clients with receive buffer size %u", gatt_client->eatt_num_clients, buffer_size_per_client);
3074 
3075     uint8_t status = l2cap_ecbm_create_channels(&gatt_client_le_enhanced_packet_handler, gatt_client->con_handle,
3076                                                 gatt_client->security_level,
3077                                                 BLUETOOTH_PSM_EATT, num_channels, L2CAP_LE_AUTOMATIC_CREDITS,
3078                                                 buffer_size_per_client,
3079                                                 receive_buffers, new_cids);
3080 
3081     if (status == ERROR_CODE_SUCCESS){
3082         i = 0;
3083         btstack_linked_list_iterator_t it;
3084         btstack_linked_list_iterator_init(&it, &gatt_client->eatt_clients);
3085         while (btstack_linked_list_iterator_has_next(&it)) {
3086             gatt_client_t *new_eatt_client = (gatt_client_t *) btstack_linked_list_iterator_next(&it);
3087 
3088             // init state with new cid and transmit buffer
3089             new_eatt_client->bearer_type = ATT_BEARER_ENHANCED_LE;
3090             new_eatt_client->con_handle = gatt_client->con_handle;
3091             new_eatt_client->mtu = 64;
3092             new_eatt_client->security_level = LEVEL_0;
3093             new_eatt_client->mtu_state = MTU_AUTO_EXCHANGE_DISABLED;
3094             new_eatt_client->gatt_client_state = P_W4_L2CAP_CONNECTION;
3095             new_eatt_client->l2cap_cid = new_cids[i];
3096             new_eatt_client->eatt_storage_buffer = gatt_client->eatt_storage_buffer;
3097 
3098             gatt_client->eatt_storage_buffer += receive_buffer_size;
3099             i++;
3100         }
3101         gatt_client->eatt_state = GATT_CLIENT_EATT_L2CAP_SETUP;
3102     } else {
3103         gatt_client_le_enhanced_handle_connected(gatt_client, status);
3104     }
3105 }
3106 
3107 static void gatt_client_le_enhanced_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
3108     gatt_client_t *gatt_client;
3109     gatt_client_t *eatt_client;
3110     hci_con_handle_t con_handle;
3111     uint16_t l2cap_cid;
3112     uint8_t status;
3113     gatt_client_characteristic_t characteristic;
3114     gatt_client_service_t service;
3115     switch (packet_type) {
3116         case HCI_EVENT_PACKET:
3117             switch (hci_event_packet_get_type(packet)) {
3118                 case GATT_EVENT_SERVICE_QUERY_RESULT:
3119                     con_handle = gatt_event_service_query_result_get_handle(packet);
3120                     gatt_client = gatt_client_get_context_for_handle(con_handle);
3121                     btstack_assert(gatt_client != NULL);
3122                     btstack_assert(gatt_client->eatt_state == GATT_CLIENT_EATT_DISCOVER_GATT_SERVICE_W4_DONE);
3123                     gatt_event_service_query_result_get_service(packet, &service);
3124                     gatt_client->gatt_service_start_group_handle = service.start_group_handle;
3125                     gatt_client->gatt_service_end_group_handle = service.end_group_handle;
3126                     break;
3127                 case GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT:
3128                     con_handle = gatt_event_characteristic_value_query_result_get_handle(packet);
3129                     gatt_client = gatt_client_get_context_for_handle(con_handle);
3130                     btstack_assert(gatt_client != NULL);
3131                     btstack_assert(gatt_client->eatt_state == GATT_CLIENT_EATT_READ_SERVER_SUPPORTED_FEATURES_W4_DONE);
3132                     if (gatt_event_characteristic_value_query_result_get_value_length(packet) >= 1) {
3133                         gatt_client->gatt_server_supported_features = gatt_event_characteristic_value_query_result_get_value(packet)[0];
3134                     }
3135                     break;
3136                 case GATT_EVENT_CHARACTERISTIC_QUERY_RESULT:
3137                     con_handle = gatt_event_characteristic_query_result_get_handle(packet);
3138                     gatt_client = gatt_client_get_context_for_handle(con_handle);
3139                     btstack_assert(gatt_client != NULL);
3140                     btstack_assert(gatt_client->eatt_state == GATT_CLIENT_EATT_FIND_CLIENT_SUPPORTED_FEATURES_W4_DONE);
3141                     gatt_event_characteristic_query_result_get_characteristic(packet, &characteristic);
3142                     gatt_client->gatt_client_supported_features_handle = characteristic.value_handle;
3143                     break;
3144                 case GATT_EVENT_QUERY_COMPLETE:
3145                     con_handle = gatt_event_query_complete_get_handle(packet);
3146                     gatt_client = gatt_client_get_context_for_handle(con_handle);
3147                     btstack_assert(gatt_client != NULL);
3148                     switch (gatt_client->eatt_state){
3149                         case GATT_CLIENT_EATT_DISCOVER_GATT_SERVICE_W4_DONE:
3150                             if (gatt_client->gatt_service_start_group_handle == 0){
3151                                 gatt_client_le_enhanced_handle_connected(gatt_client, ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
3152                             } else {
3153                                 gatt_client->eatt_state = GATT_CLIENT_EATT_READ_SERVER_SUPPORTED_FEATURES_W2_SEND;
3154                             }
3155                             break;
3156                         case GATT_CLIENT_EATT_READ_SERVER_SUPPORTED_FEATURES_W4_DONE:
3157                             if ((gatt_client->gatt_server_supported_features & 1) == 0) {
3158                                 gatt_client_le_enhanced_handle_connected(gatt_client, ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
3159                             } else {
3160                                 gatt_client->eatt_state = GATT_CLIENT_EATT_FIND_CLIENT_SUPPORTED_FEATURES_W2_SEND;
3161                             }
3162                             break;
3163                         case GATT_CLIENT_EATT_FIND_CLIENT_SUPPORTED_FEATURES_W4_DONE:
3164                             if (gatt_client->gatt_client_supported_features_handle == 0){
3165                                 gatt_client_le_enhanced_handle_connected(gatt_client, ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
3166                             } else {
3167                                 gatt_client->eatt_state = GATT_CLIENT_EATT_WRITE_ClIENT_SUPPORTED_FEATURES_W2_SEND;
3168                             }
3169                             break;
3170                         case GATT_CLIENT_EATT_WRITE_ClIENT_SUPPORTED_FEATURES_W4_DONE:
3171                             gatt_client_le_enhanced_setup_l2cap_channel(gatt_client);
3172                             break;
3173                         default:
3174                             break;
3175                     }
3176                     break;
3177                 case L2CAP_EVENT_ECBM_CHANNEL_OPENED:
3178                     l2cap_cid = l2cap_event_ecbm_channel_opened_get_local_cid(packet);
3179                     gatt_client = gatt_client_le_enhanced_get_context_for_l2cap_cid(l2cap_cid, &eatt_client);
3180 
3181                     btstack_assert(gatt_client != NULL);
3182                     btstack_assert(eatt_client != NULL);
3183                     btstack_assert(eatt_client->gatt_client_state == P_W4_L2CAP_CONNECTION);
3184 
3185                     status = l2cap_event_channel_opened_get_status(packet);
3186                     if (status == ERROR_CODE_SUCCESS){
3187                         eatt_client->gatt_client_state = P_READY;
3188                         eatt_client->mtu = l2cap_event_channel_opened_get_remote_mtu(packet);
3189                     } else {
3190                         gatt_client_le_enhanced_handle_ecbm_disconnected(gatt_client, eatt_client);
3191                     }
3192                     // all channels opened?
3193                     gatt_client->eatt_num_clients--;
3194                     if (gatt_client->eatt_num_clients == 0){
3195                         gatt_client_le_enhanced_handle_connected(gatt_client, ERROR_CODE_SUCCESS);
3196                     }
3197                     break;
3198                 case L2CAP_EVENT_CHANNEL_CLOSED:
3199                     l2cap_cid = l2cap_event_channel_closed_get_local_cid(packet);
3200                     gatt_client = gatt_client_le_enhanced_get_context_for_l2cap_cid(l2cap_cid, &eatt_client);
3201                     btstack_assert(gatt_client != NULL);
3202                     btstack_assert(eatt_client != NULL);
3203                     gatt_client_le_enhanced_handle_ecbm_disconnected(gatt_client, eatt_client);
3204                     break;
3205                 default:
3206                     break;
3207             }
3208             break;
3209         case L2CAP_DATA_PACKET:
3210             gatt_client = gatt_client_le_enhanced_get_context_for_l2cap_cid(channel, &eatt_client);
3211             btstack_assert(gatt_client != NULL);
3212             gatt_client_handle_att_response(gatt_client, packet, size);
3213             gatt_client_run();
3214             break;
3215         default:
3216             break;
3217     }
3218 }
3219 
3220 static bool gatt_client_le_enhanced_handle_can_send_query(gatt_client_t * gatt_client){
3221     uint8_t status = ERROR_CODE_SUCCESS;
3222     uint8_t gatt_client_supported_features = 0x06; // eatt + multiple value notifications
3223     switch (gatt_client->eatt_state){
3224         case GATT_CLIENT_EATT_DISCOVER_GATT_SERVICE_W2_SEND:
3225             gatt_client->gatt_service_start_group_handle = 0;
3226             gatt_client->eatt_state = GATT_CLIENT_EATT_DISCOVER_GATT_SERVICE_W4_DONE;
3227             status = gatt_client_discover_primary_services_by_uuid16(&gatt_client_le_enhanced_packet_handler,
3228                                                                      gatt_client->con_handle,
3229                                                                      ORG_BLUETOOTH_SERVICE_GENERIC_ATTRIBUTE);
3230             break;
3231         case GATT_CLIENT_EATT_READ_SERVER_SUPPORTED_FEATURES_W2_SEND:
3232             gatt_client->gatt_server_supported_features = 0;
3233             gatt_client->eatt_state = GATT_CLIENT_EATT_READ_SERVER_SUPPORTED_FEATURES_W4_DONE;
3234             status = gatt_client_read_value_of_characteristics_by_uuid16(&gatt_client_le_enhanced_packet_handler,
3235                                                                          gatt_client->con_handle,
3236                                                                          gatt_client->gatt_service_start_group_handle,
3237                                                                          gatt_client->gatt_service_end_group_handle,
3238                                                                          ORG_BLUETOOTH_CHARACTERISTIC_SERVER_SUPPORTED_FEATURES);
3239             return true;
3240         case GATT_CLIENT_EATT_FIND_CLIENT_SUPPORTED_FEATURES_W2_SEND:
3241             gatt_client->gatt_client_supported_features_handle = 0;
3242             gatt_client->eatt_state = GATT_CLIENT_EATT_FIND_CLIENT_SUPPORTED_FEATURES_W4_DONE;
3243             status = gatt_client_discover_characteristics_for_handle_range_by_uuid16(&gatt_client_le_enhanced_packet_handler,
3244                                                                                      gatt_client->con_handle,
3245                                                                                      gatt_client->gatt_service_start_group_handle,
3246                                                                                      gatt_client->gatt_service_end_group_handle,
3247                                                                                      ORG_BLUETOOTH_CHARACTERISTIC_CLIENT_SUPPORTED_FEATURES);
3248             return true;
3249         case GATT_CLIENT_EATT_WRITE_ClIENT_SUPPORTED_FEATURES_W2_SEND:
3250             gatt_client->eatt_state = GATT_CLIENT_EATT_WRITE_ClIENT_SUPPORTED_FEATURES_W4_DONE;
3251             status = gatt_client_write_value_of_characteristic(&gatt_client_le_enhanced_packet_handler, gatt_client->con_handle,
3252                                                                gatt_client->gatt_client_supported_features_handle, 1,
3253                                                                &gatt_client_supported_features);
3254             return true;
3255         default:
3256             break;
3257     }
3258     btstack_assert(status == ERROR_CODE_SUCCESS);
3259     UNUSED(status);
3260     return false;
3261 }
3262 
3263 uint8_t gatt_client_le_enhanced_connect(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint8_t num_channels, uint8_t * storage_buffer, uint16_t storage_size) {
3264     gatt_client_t * gatt_client;
3265     uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client);
3266     if (status != ERROR_CODE_SUCCESS){
3267         return status;
3268     }
3269 
3270     if (gatt_client->eatt_state != GATT_CLIENT_EATT_IDLE){
3271         return ERROR_CODE_COMMAND_DISALLOWED;
3272     }
3273 
3274     // need one buffer for sending and one for receiving
3275     uint16_t buffer_size_per_client = storage_size / num_channels;
3276     if (buffer_size_per_client < (64*2)) {
3277         return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
3278     }
3279 
3280     if ((num_channels == 0) || (num_channels > MAX_NR_EATT_CHANNELS)){
3281         return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS;
3282     }
3283 
3284     // create max num_channel eatt clients
3285     uint8_t i;
3286     btstack_linked_list_t eatt_clients = NULL;
3287     for (i=0;i<num_channels;i++) {
3288         gatt_client_t * new_gatt_client = btstack_memory_gatt_client_get();
3289         if (new_gatt_client == NULL) {
3290             break;
3291         }
3292         btstack_linked_list_add(&eatt_clients, (btstack_linked_item_t*)new_gatt_client);
3293     }
3294 
3295     if (i != num_channels){
3296         while (true){
3297             gatt_client = (gatt_client_t *) btstack_linked_list_pop(&eatt_clients);
3298             if (gatt_client == NULL) {
3299                 break;
3300             }
3301             btstack_memory_gatt_client_free(gatt_client);
3302         }
3303         return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED;
3304     }
3305 
3306     gatt_client->callback = callback;
3307     gatt_client->eatt_num_clients   = num_channels;
3308     gatt_client->eatt_storage_buffer = storage_buffer;
3309     gatt_client->eatt_storage_size   = storage_size;
3310     gatt_client->eatt_clients = eatt_clients;
3311     gatt_client->eatt_state = GATT_CLIENT_EATT_DISCOVER_GATT_SERVICE_W2_SEND;
3312     gatt_client_notify_can_send_query(gatt_client);
3313 
3314     return ERROR_CODE_SUCCESS;
3315 }
3316 
3317 #endif
3318 
3319 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
3320 void gatt_client_att_packet_handler_fuzz(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
3321     gatt_client_att_packet_handler(packet_type, handle, packet, size);
3322 }
3323 
3324 uint8_t gatt_client_get_client(hci_con_handle_t con_handle, gatt_client_t ** out_gatt_client){
3325     uint8_t status = gatt_client_provide_context_for_handle(con_handle, out_gatt_client);
3326     return status;
3327 }
3328 #endif
3329