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