xref: /btstack/src/ble/gatt_client.c (revision b12646c53b4bd66330eb1f93a0c4ff42a632b846)
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 <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 
45 #include "btstack_config.h"
46 
47 #include "att_dispatch.h"
48 #include "ad_parser.h"
49 #include "ble/att_db.h"
50 #include "ble/core.h"
51 #include "ble/gatt_client.h"
52 #include "ble/le_device_db.h"
53 #include "ble/sm.h"
54 #include "btstack_debug.h"
55 #include "btstack_event.h"
56 #include "btstack_memory.h"
57 #include "btstack_run_loop.h"
58 #include "btstack_util.h"
59 #include "classic/sdp_util.h"
60 #include "hci.h"
61 #include "hci_cmd.h"
62 #include "hci_dump.h"
63 #include "l2cap.h"
64 
65 static btstack_linked_list_t gatt_client_connections;
66 static btstack_linked_list_t gatt_client_value_listeners;
67 static btstack_packet_callback_registration_t hci_event_callback_registration;
68 static uint8_t  pts_suppress_mtu_exchange;
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_hci_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 *peripheral, uint8_t 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 static uint16_t peripheral_mtu(gatt_client_t *peripheral){
79     if (peripheral->mtu > l2cap_max_le_mtu()){
80         log_error("Peripheral mtu is not initialized");
81         return l2cap_max_le_mtu();
82     }
83     return peripheral->mtu;
84 }
85 
86 void gatt_client_init(void){
87     gatt_client_connections = NULL;
88     pts_suppress_mtu_exchange = 0;
89 
90     // regsister for HCI Events
91     hci_event_callback_registration.callback = &gatt_client_hci_event_packet_handler;
92     hci_add_event_handler(&hci_event_callback_registration);
93 
94     // and ATT Client PDUs
95     att_dispatch_register_client(gatt_client_att_packet_handler);
96 }
97 
98 static gatt_client_t * gatt_client_for_timer(btstack_timer_source_t * ts){
99     btstack_linked_list_iterator_t it;
100     btstack_linked_list_iterator_init(&it, &gatt_client_connections);
101     while (btstack_linked_list_iterator_has_next(&it)){
102         gatt_client_t * peripheral = (gatt_client_t *) btstack_linked_list_iterator_next(&it);
103         if ( &peripheral->gc_timeout == ts) {
104             return peripheral;
105         }
106     }
107     return NULL;
108 }
109 
110 static void gatt_client_timeout_handler(btstack_timer_source_t * timer){
111     gatt_client_t * peripheral = gatt_client_for_timer(timer);
112     if (!peripheral) return;
113     log_info("GATT client timeout handle, handle 0x%02x", peripheral->con_handle);
114     gatt_client_report_error_if_pending(peripheral, ATT_ERROR_TIMEOUT);
115 }
116 
117 static void gatt_client_timeout_start(gatt_client_t * peripheral){
118     log_info("GATT client timeout start, handle 0x%02x", peripheral->con_handle);
119     btstack_run_loop_remove_timer(&peripheral->gc_timeout);
120     btstack_run_loop_set_timer_handler(&peripheral->gc_timeout, gatt_client_timeout_handler);
121     btstack_run_loop_set_timer(&peripheral->gc_timeout, 30000); // 30 seconds sm timeout
122     btstack_run_loop_add_timer(&peripheral->gc_timeout);
123 }
124 
125 static void gatt_client_timeout_stop(gatt_client_t * peripheral){
126     log_info("GATT client timeout stop, handle 0x%02x", peripheral->con_handle);
127     btstack_run_loop_remove_timer(&peripheral->gc_timeout);
128 }
129 
130 static gatt_client_t * get_gatt_client_context_for_handle(uint16_t handle){
131     btstack_linked_item_t *it;
132     for (it = (btstack_linked_item_t *) gatt_client_connections; it ; it = it->next){
133         gatt_client_t * peripheral = (gatt_client_t *) it;
134         if (peripheral->con_handle == handle){
135             return peripheral;
136         }
137     }
138     return NULL;
139 }
140 
141 
142 // @returns context
143 // returns existing one, or tries to setup new one
144 static gatt_client_t * provide_context_for_conn_handle(hci_con_handle_t con_handle){
145     gatt_client_t * context = get_gatt_client_context_for_handle(con_handle);
146     if (context) return  context;
147 
148     context = btstack_memory_gatt_client_get();
149     if (!context) return NULL;
150     // init state
151     memset(context, 0, sizeof(gatt_client_t));
152     context->con_handle = con_handle;
153     context->mtu = ATT_DEFAULT_MTU;
154     context->mtu_state = SEND_MTU_EXCHANGE;
155     context->gatt_client_state = P_READY;
156     btstack_linked_list_add(&gatt_client_connections, (btstack_linked_item_t*)context);
157 
158     // skip mtu exchange for testing sm with pts
159     if (pts_suppress_mtu_exchange){
160          context->mtu_state = MTU_EXCHANGED;
161     }
162     return context;
163 }
164 
165 static gatt_client_t * provide_context_for_conn_handle_and_start_timer(hci_con_handle_t con_handle){
166     gatt_client_t * context = provide_context_for_conn_handle(con_handle);
167     if (!context) return NULL;
168     gatt_client_timeout_start(context);
169     return context;
170 }
171 
172 static int is_ready(gatt_client_t * context){
173     return context->gatt_client_state == P_READY;
174 }
175 
176 int gatt_client_is_ready(hci_con_handle_t con_handle){
177     gatt_client_t * context = provide_context_for_conn_handle(con_handle);
178     if (!context) return 0;
179     return is_ready(context);
180 }
181 
182 uint8_t gatt_client_get_mtu(hci_con_handle_t con_handle, uint16_t * mtu){
183     gatt_client_t * context = provide_context_for_conn_handle(con_handle);
184     if (context && context->mtu_state == MTU_EXCHANGED){
185         *mtu = context->mtu;
186         return 0;
187     }
188     *mtu = ATT_DEFAULT_MTU;
189     return GATT_CLIENT_IN_WRONG_STATE;
190 }
191 
192 // precondition: can_send_packet_now == TRUE
193 static void att_confirmation(uint16_t peripheral_handle){
194     l2cap_reserve_packet_buffer();
195     uint8_t * request = l2cap_get_outgoing_buffer();
196     request[0] = ATT_HANDLE_VALUE_CONFIRMATION;
197     l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 1);
198 }
199 
200 // precondition: can_send_packet_now == TRUE
201 static void att_find_information_request(uint16_t request_type, uint16_t peripheral_handle, uint16_t start_handle, uint16_t end_handle){
202     l2cap_reserve_packet_buffer();
203     uint8_t * request = l2cap_get_outgoing_buffer();
204     request[0] = request_type;
205     little_endian_store_16(request, 1, start_handle);
206     little_endian_store_16(request, 3, end_handle);
207 
208     l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 5);
209 }
210 
211 // precondition: can_send_packet_now == TRUE
212 static void att_find_by_type_value_request(uint16_t request_type, uint16_t attribute_group_type, uint16_t peripheral_handle, uint16_t start_handle, uint16_t end_handle, uint8_t * value, uint16_t value_size){
213     l2cap_reserve_packet_buffer();
214     uint8_t * request = l2cap_get_outgoing_buffer();
215 
216     request[0] = request_type;
217     little_endian_store_16(request, 1, start_handle);
218     little_endian_store_16(request, 3, end_handle);
219     little_endian_store_16(request, 5, attribute_group_type);
220     memcpy(&request[7], value, value_size);
221 
222     l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 7+value_size);
223 }
224 
225 // precondition: can_send_packet_now == TRUE
226 static void att_read_by_type_or_group_request_for_uuid16(uint16_t request_type, uint16_t uuid16, uint16_t peripheral_handle, uint16_t start_handle, uint16_t end_handle){
227     l2cap_reserve_packet_buffer();
228     uint8_t * request = l2cap_get_outgoing_buffer();
229     request[0] = request_type;
230     little_endian_store_16(request, 1, start_handle);
231     little_endian_store_16(request, 3, end_handle);
232     little_endian_store_16(request, 5, uuid16);
233 
234     l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 7);
235 }
236 
237 // precondition: can_send_packet_now == TRUE
238 static void att_read_by_type_or_group_request_for_uuid128(uint16_t request_type, uint8_t * uuid128, uint16_t peripheral_handle, uint16_t start_handle, uint16_t end_handle){
239     l2cap_reserve_packet_buffer();
240     uint8_t * request = l2cap_get_outgoing_buffer();
241     request[0] = request_type;
242     little_endian_store_16(request, 1, start_handle);
243     little_endian_store_16(request, 3, end_handle);
244     reverse_128(uuid128, &request[5]);
245 
246     l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 21);
247 }
248 
249 // precondition: can_send_packet_now == TRUE
250 static void att_read_request(uint16_t request_type, uint16_t peripheral_handle, uint16_t attribute_handle){
251     l2cap_reserve_packet_buffer();
252     uint8_t * request = l2cap_get_outgoing_buffer();
253     request[0] = request_type;
254     little_endian_store_16(request, 1, attribute_handle);
255 
256     l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 3);
257 }
258 
259 // precondition: can_send_packet_now == TRUE
260 static void att_read_blob_request(uint16_t request_type, uint16_t peripheral_handle, uint16_t attribute_handle, uint16_t value_offset){
261     l2cap_reserve_packet_buffer();
262     uint8_t * request = l2cap_get_outgoing_buffer();
263     request[0] = request_type;
264     little_endian_store_16(request, 1, attribute_handle);
265     little_endian_store_16(request, 3, value_offset);
266 
267     l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 5);
268 }
269 
270 static void att_read_multiple_request(uint16_t peripheral_handle, uint16_t num_value_handles, uint16_t * value_handles){
271     l2cap_reserve_packet_buffer();
272     uint8_t * request = l2cap_get_outgoing_buffer();
273     request[0] = ATT_READ_MULTIPLE_REQUEST;
274     int i;
275     int offset = 1;
276     for (i=0;i<num_value_handles;i++){
277         little_endian_store_16(request, offset, value_handles[i]);
278         offset += 2;
279     }
280     l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, offset);
281 }
282 
283 #ifdef ENABLE_LE_SIGNED_WRITE
284 // precondition: can_send_packet_now == TRUE
285 static void att_signed_write_request(uint16_t request_type, uint16_t peripheral_handle, uint16_t attribute_handle, uint16_t value_length, uint8_t * value, uint32_t sign_counter, uint8_t sgn[8]){
286     l2cap_reserve_packet_buffer();
287     uint8_t * request = l2cap_get_outgoing_buffer();
288     request[0] = request_type;
289     little_endian_store_16(request, 1, attribute_handle);
290     memcpy(&request[3], value, value_length);
291     little_endian_store_32(request, 3 + value_length, sign_counter);
292     reverse_64(sgn, &request[3 + value_length + 4]);
293     l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 3 + value_length + 12);
294 }
295 #endif
296 
297 // precondition: can_send_packet_now == TRUE
298 static void att_write_request(uint16_t request_type, uint16_t peripheral_handle, uint16_t attribute_handle, uint16_t value_length, uint8_t * value){
299     l2cap_reserve_packet_buffer();
300     uint8_t * request = l2cap_get_outgoing_buffer();
301     request[0] = request_type;
302     little_endian_store_16(request, 1, attribute_handle);
303     memcpy(&request[3], value, value_length);
304 
305     l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 3 + value_length);
306 }
307 
308 // precondition: can_send_packet_now == TRUE
309 static void att_execute_write_request(uint16_t request_type, uint16_t peripheral_handle, uint8_t execute_write){
310     l2cap_reserve_packet_buffer();
311     uint8_t * request = l2cap_get_outgoing_buffer();
312     request[0] = request_type;
313     request[1] = execute_write;
314     l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 2);
315 }
316 
317 // precondition: can_send_packet_now == TRUE
318 static void att_prepare_write_request(uint16_t request_type, uint16_t peripheral_handle,  uint16_t attribute_handle, uint16_t value_offset, uint16_t blob_length, uint8_t * value){
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     little_endian_store_16(request, 3, value_offset);
324     memcpy(&request[5], &value[value_offset], blob_length);
325 
326     l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 5+blob_length);
327 }
328 
329 static void att_exchange_mtu_request(uint16_t peripheral_handle){
330     uint16_t mtu = l2cap_max_le_mtu();
331     l2cap_reserve_packet_buffer();
332     uint8_t * request = l2cap_get_outgoing_buffer();
333     request[0] = ATT_EXCHANGE_MTU_REQUEST;
334     little_endian_store_16(request, 1, mtu);
335     l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 3);
336 }
337 
338 static uint16_t write_blob_length(gatt_client_t * peripheral){
339     uint16_t max_blob_length = peripheral_mtu(peripheral) - 5;
340     if (peripheral->attribute_offset >= peripheral->attribute_length) {
341         return 0;
342     }
343     uint16_t rest_length = peripheral->attribute_length - peripheral->attribute_offset;
344     if (max_blob_length > rest_length){
345         return rest_length;
346     }
347     return max_blob_length;
348 }
349 
350 static void send_gatt_services_request(gatt_client_t *peripheral){
351     att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_GROUP_TYPE_REQUEST, GATT_PRIMARY_SERVICE_UUID, peripheral->con_handle, peripheral->start_group_handle, peripheral->end_group_handle);
352 }
353 
354 static void send_gatt_by_uuid_request(gatt_client_t *peripheral, uint16_t attribute_group_type){
355     if (peripheral->uuid16){
356         uint8_t uuid16[2];
357         little_endian_store_16(uuid16, 0, peripheral->uuid16);
358         att_find_by_type_value_request(ATT_FIND_BY_TYPE_VALUE_REQUEST, attribute_group_type, peripheral->con_handle, peripheral->start_group_handle, peripheral->end_group_handle, uuid16, 2);
359         return;
360     }
361     uint8_t uuid128[16];
362     reverse_128(peripheral->uuid128, uuid128);
363     att_find_by_type_value_request(ATT_FIND_BY_TYPE_VALUE_REQUEST, attribute_group_type, peripheral->con_handle, peripheral->start_group_handle, peripheral->end_group_handle, uuid128, 16);
364 }
365 
366 static void send_gatt_services_by_uuid_request(gatt_client_t *peripheral){
367     send_gatt_by_uuid_request(peripheral, GATT_PRIMARY_SERVICE_UUID);
368 }
369 
370 static void send_gatt_included_service_uuid_request(gatt_client_t *peripheral){
371     att_read_request(ATT_READ_REQUEST, peripheral->con_handle, peripheral->query_start_handle);
372 }
373 
374 static void send_gatt_included_service_request(gatt_client_t *peripheral){
375     att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_TYPE_REQUEST, GATT_INCLUDE_SERVICE_UUID, peripheral->con_handle, peripheral->start_group_handle, peripheral->end_group_handle);
376 }
377 
378 static void send_gatt_characteristic_request(gatt_client_t *peripheral){
379     att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_TYPE_REQUEST, GATT_CHARACTERISTICS_UUID, peripheral->con_handle, peripheral->start_group_handle, peripheral->end_group_handle);
380 }
381 
382 static void send_gatt_characteristic_descriptor_request(gatt_client_t *peripheral){
383     att_find_information_request(ATT_FIND_INFORMATION_REQUEST, peripheral->con_handle, peripheral->start_group_handle, peripheral->end_group_handle);
384 }
385 
386 static void send_gatt_read_characteristic_value_request(gatt_client_t *peripheral){
387     att_read_request(ATT_READ_REQUEST, peripheral->con_handle, peripheral->attribute_handle);
388 }
389 
390 static void send_gatt_read_by_type_request(gatt_client_t * peripheral){
391     if (peripheral->uuid16){
392         att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_TYPE_REQUEST, peripheral->uuid16, peripheral->con_handle, peripheral->start_group_handle, peripheral->end_group_handle);
393     } else {
394         att_read_by_type_or_group_request_for_uuid128(ATT_READ_BY_TYPE_REQUEST, peripheral->uuid128, peripheral->con_handle, peripheral->start_group_handle, peripheral->end_group_handle);
395     }
396 }
397 
398 static void send_gatt_read_blob_request(gatt_client_t *peripheral){
399     att_read_blob_request(ATT_READ_BLOB_REQUEST, peripheral->con_handle, peripheral->attribute_handle, peripheral->attribute_offset);
400 }
401 
402 static void send_gatt_read_multiple_request(gatt_client_t * peripheral){
403     att_read_multiple_request(peripheral->con_handle, peripheral->read_multiple_handle_count, peripheral->read_multiple_handles);
404 }
405 
406 static void send_gatt_write_attribute_value_request(gatt_client_t * peripheral){
407     att_write_request(ATT_WRITE_REQUEST, peripheral->con_handle, peripheral->attribute_handle, peripheral->attribute_length, peripheral->attribute_value);
408 }
409 
410 static void send_gatt_write_client_characteristic_configuration_request(gatt_client_t * peripheral){
411     att_write_request(ATT_WRITE_REQUEST, peripheral->con_handle, peripheral->client_characteristic_configuration_handle, 2, peripheral->client_characteristic_configuration_value);
412 }
413 
414 static void send_gatt_prepare_write_request(gatt_client_t * peripheral){
415     att_prepare_write_request(ATT_PREPARE_WRITE_REQUEST, peripheral->con_handle, peripheral->attribute_handle, peripheral->attribute_offset, write_blob_length(peripheral), peripheral->attribute_value);
416 }
417 
418 static void send_gatt_execute_write_request(gatt_client_t * peripheral){
419     att_execute_write_request(ATT_EXECUTE_WRITE_REQUEST, peripheral->con_handle, 1);
420 }
421 
422 static void send_gatt_cancel_prepared_write_request(gatt_client_t * peripheral){
423     att_execute_write_request(ATT_EXECUTE_WRITE_REQUEST, peripheral->con_handle, 0);
424 }
425 
426 static void send_gatt_read_client_characteristic_configuration_request(gatt_client_t * peripheral){
427     att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_TYPE_REQUEST, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION, peripheral->con_handle, peripheral->start_group_handle, peripheral->end_group_handle);
428 }
429 
430 static void send_gatt_read_characteristic_descriptor_request(gatt_client_t * peripheral){
431     att_read_request(ATT_READ_REQUEST, peripheral->con_handle, peripheral->attribute_handle);
432 }
433 
434 #ifdef ENABLE_LE_SIGNED_WRITE
435 static void send_gatt_signed_write_request(gatt_client_t * peripheral, uint32_t sign_counter){
436     att_signed_write_request(ATT_SIGNED_WRITE_COMMAND, peripheral->con_handle, peripheral->attribute_handle, peripheral->attribute_length, peripheral->attribute_value, sign_counter, peripheral->cmac);
437 }
438 #endif
439 
440 static uint16_t get_last_result_handle_from_service_list(uint8_t * packet, uint16_t size){
441     uint8_t attr_length = packet[1];
442     return little_endian_read_16(packet, size - attr_length + 2);
443 }
444 
445 static uint16_t get_last_result_handle_from_characteristics_list(uint8_t * packet, uint16_t size){
446     uint8_t attr_length = packet[1];
447     return little_endian_read_16(packet, size - attr_length + 3);
448 }
449 
450 static uint16_t get_last_result_handle_from_included_services_list(uint8_t * packet, uint16_t size){
451     uint8_t attr_length = packet[1];
452     return little_endian_read_16(packet, size - attr_length);
453 }
454 
455 static void gatt_client_handle_transaction_complete(gatt_client_t * peripheral){
456     peripheral->gatt_client_state = P_READY;
457     gatt_client_timeout_stop(peripheral);
458 }
459 
460 static void emit_event_new(btstack_packet_handler_t callback, uint8_t * packet, uint16_t size){
461     if (!callback) return;
462     hci_dump_packet(HCI_EVENT_PACKET, 0, packet, size);
463     (*callback)(HCI_EVENT_PACKET, 0, packet, size);
464 }
465 
466 void gatt_client_listen_for_characteristic_value_updates(gatt_client_notification_t * notification, btstack_packet_handler_t packet_handler, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){
467     notification->callback = packet_handler;
468     notification->con_handle = con_handle;
469     notification->attribute_handle = characteristic->value_handle;
470     btstack_linked_list_add(&gatt_client_value_listeners, (btstack_linked_item_t*) notification);
471 }
472 
473 void gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification){
474     btstack_linked_list_remove(&gatt_client_value_listeners, (btstack_linked_item_t*) notification);
475 }
476 
477 static void emit_event_to_registered_listeners(hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t * packet, uint16_t size){
478     btstack_linked_list_iterator_t it;
479     btstack_linked_list_iterator_init(&it, &gatt_client_value_listeners);
480     while (btstack_linked_list_iterator_has_next(&it)){
481         gatt_client_notification_t * notification = (gatt_client_notification_t*) btstack_linked_list_iterator_next(&it);
482         if (notification->con_handle != con_handle) continue;
483         if (notification->attribute_handle != attribute_handle) continue;
484         (*notification->callback)(HCI_EVENT_PACKET, 0, packet, size);
485     }
486 }
487 
488 static void emit_gatt_complete_event(gatt_client_t * peripheral, uint8_t status){
489     // @format H1
490     uint8_t packet[5];
491     packet[0] = GATT_EVENT_QUERY_COMPLETE;
492     packet[1] = 3;
493     little_endian_store_16(packet, 2, peripheral->con_handle);
494     packet[4] = status;
495     emit_event_new(peripheral->callback, packet, sizeof(packet));
496 }
497 
498 static void emit_gatt_service_query_result_event(gatt_client_t * peripheral, uint16_t start_group_handle, uint16_t end_group_handle, uint8_t * uuid128){
499     // @format HX
500     uint8_t packet[24];
501     packet[0] = GATT_EVENT_SERVICE_QUERY_RESULT;
502     packet[1] = sizeof(packet) - 2;
503     little_endian_store_16(packet, 2, peripheral->con_handle);
504     ///
505     little_endian_store_16(packet, 4, start_group_handle);
506     little_endian_store_16(packet, 6, end_group_handle);
507     reverse_128(uuid128, &packet[8]);
508     emit_event_new(peripheral->callback, packet, sizeof(packet));
509 }
510 
511 static void emit_gatt_included_service_query_result_event(gatt_client_t * peripheral, uint16_t include_handle, uint16_t start_group_handle, uint16_t end_group_handle, uint8_t * uuid128){
512     // @format HX
513     uint8_t packet[26];
514     packet[0] = GATT_EVENT_INCLUDED_SERVICE_QUERY_RESULT;
515     packet[1] = sizeof(packet) - 2;
516     little_endian_store_16(packet, 2, peripheral->con_handle);
517     ///
518     little_endian_store_16(packet, 4, include_handle);
519     //
520     little_endian_store_16(packet, 6, start_group_handle);
521     little_endian_store_16(packet, 8, end_group_handle);
522     reverse_128(uuid128, &packet[10]);
523     emit_event_new(peripheral->callback, packet, sizeof(packet));
524 }
525 
526 static void emit_gatt_characteristic_query_result_event(gatt_client_t * peripheral, uint16_t start_handle, uint16_t value_handle, uint16_t end_handle,
527         uint16_t properties, uint8_t * uuid128){
528     // @format HY
529     uint8_t packet[28];
530     packet[0] = GATT_EVENT_CHARACTERISTIC_QUERY_RESULT;
531     packet[1] = sizeof(packet) - 2;
532     little_endian_store_16(packet, 2, peripheral->con_handle);
533     ///
534     little_endian_store_16(packet, 4,  start_handle);
535     little_endian_store_16(packet, 6,  value_handle);
536     little_endian_store_16(packet, 8,  end_handle);
537     little_endian_store_16(packet, 10, properties);
538     reverse_128(uuid128, &packet[12]);
539     emit_event_new(peripheral->callback, packet, sizeof(packet));
540 }
541 
542 static void emit_gatt_all_characteristic_descriptors_result_event(
543     gatt_client_t * peripheral, uint16_t descriptor_handle, uint8_t * uuid128){
544     // @format HZ
545     uint8_t packet[22];
546     packet[0] = GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT;
547     packet[1] = sizeof(packet) - 2;
548     little_endian_store_16(packet, 2, peripheral->con_handle);
549     ///
550     little_endian_store_16(packet, 4,  descriptor_handle);
551     reverse_128(uuid128, &packet[6]);
552     emit_event_new(peripheral->callback, packet, sizeof(packet));
553 }
554 
555 static void emit_gatt_mtu_exchanged_result_event(gatt_client_t * peripheral, uint16_t new_mtu){
556     // @format H2
557     uint8_t packet[6];
558     packet[0] = GATT_EVENT_MTU;
559     packet[1] = sizeof(packet) - 2;
560     little_endian_store_16(packet, 2, peripheral->con_handle);
561     little_endian_store_16(packet, 4, new_mtu);
562     att_dispatch_client_mtu_exchanged(peripheral->con_handle, new_mtu);
563     emit_event_new(peripheral->callback, packet, sizeof(packet));
564 }
565 ///
566 static void report_gatt_services(gatt_client_t * peripheral, uint8_t * packet,  uint16_t size){
567     uint8_t attr_length = packet[1];
568     uint8_t uuid_length = attr_length - 4;
569 
570     int i;
571     for (i = 2; i < size; i += attr_length){
572         uint16_t start_group_handle = little_endian_read_16(packet,i);
573         uint16_t end_group_handle   = little_endian_read_16(packet,i+2);
574         uint8_t  uuid128[16];
575         uint16_t uuid16 = 0;
576 
577         if (uuid_length == 2){
578             uuid16 = little_endian_read_16(packet, i+4);
579             uuid_add_bluetooth_prefix((uint8_t*) &uuid128, uuid16);
580         } else {
581             reverse_128(&packet[i+4], uuid128);
582         }
583         emit_gatt_service_query_result_event(peripheral, start_group_handle, end_group_handle, uuid128);
584     }
585     // log_info("report_gatt_services for %02X done", peripheral->con_handle);
586 }
587 
588 // helper
589 static void characteristic_start_found(gatt_client_t * peripheral, uint16_t start_handle, uint8_t properties, uint16_t value_handle, uint8_t * uuid, uint16_t uuid_length){
590     uint8_t uuid128[16];
591     uint16_t uuid16 = 0;
592     if (uuid_length == 2){
593         uuid16 = little_endian_read_16(uuid, 0);
594         uuid_add_bluetooth_prefix((uint8_t*) uuid128, uuid16);
595     } else {
596         reverse_128(uuid, uuid128);
597     }
598 
599     if (peripheral->filter_with_uuid && memcmp(peripheral->uuid128, uuid128, 16) != 0) return;
600 
601     peripheral->characteristic_properties = properties;
602     peripheral->characteristic_start_handle = start_handle;
603     peripheral->attribute_handle = value_handle;
604 
605     if (peripheral->filter_with_uuid) return;
606 
607     peripheral->uuid16 = uuid16;
608     memcpy(peripheral->uuid128, uuid128, 16);
609 }
610 
611 static void characteristic_end_found(gatt_client_t * peripheral, uint16_t end_handle){
612     // TODO: stop searching if filter and uuid found
613 
614     if (!peripheral->characteristic_start_handle) return;
615 
616     emit_gatt_characteristic_query_result_event(peripheral, peripheral->characteristic_start_handle, peripheral->attribute_handle,
617         end_handle, peripheral->characteristic_properties, peripheral->uuid128);
618 
619     peripheral->characteristic_start_handle = 0;
620 }
621 
622 static void report_gatt_characteristics(gatt_client_t * peripheral, uint8_t * packet,  uint16_t size){
623     uint8_t attr_length = packet[1];
624     uint8_t uuid_length = attr_length - 5;
625     int i;
626     for (i = 2; i < size; i += attr_length){
627         uint16_t start_handle = little_endian_read_16(packet, i);
628         uint8_t  properties = packet[i+2];
629         uint16_t value_handle = little_endian_read_16(packet, i+3);
630         characteristic_end_found(peripheral, start_handle-1);
631         characteristic_start_found(peripheral, start_handle, properties, value_handle, &packet[i+5], uuid_length);
632     }
633 }
634 
635 static void report_gatt_included_service_uuid16(gatt_client_t * peripheral, uint16_t include_handle, uint16_t uuid16){
636     uint8_t normalized_uuid128[16];
637     uuid_add_bluetooth_prefix(normalized_uuid128, uuid16);
638     emit_gatt_included_service_query_result_event(peripheral, include_handle, peripheral->query_start_handle,
639         peripheral->query_end_handle, normalized_uuid128);
640 }
641 
642 static void report_gatt_included_service_uuid128(gatt_client_t * peripheral, uint16_t include_handle, uint8_t *uuid128){
643     emit_gatt_included_service_query_result_event(peripheral, include_handle, peripheral->query_start_handle,
644         peripheral->query_end_handle, uuid128);
645 }
646 
647 // @returns packet pointer
648 // @note assume that value is part of an l2cap buffer - overwrite HCI + L2CAP packet headers
649 static const int characteristic_value_event_header_size = 8;
650 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){
651     // before the value inside the ATT PDU
652     uint8_t * packet = value - characteristic_value_event_header_size;
653     packet[0] = type;
654     packet[1] = characteristic_value_event_header_size - 2 + length;
655     little_endian_store_16(packet, 2, con_handle);
656     little_endian_store_16(packet, 4, attribute_handle);
657     little_endian_store_16(packet, 6, length);
658     return packet;
659 }
660 
661 // @returns packet pointer
662 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
663 static const int long_characteristic_value_event_header_size = 10;
664 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){
665 #if defined(HCI_INCOMING_PRE_BUFFER_SIZE) && (HCI_INCOMING_PRE_BUFFER_SIZE >= 10 - 8) // L2CAP Header (4) - ACL Header (4)
666     // before the value inside the ATT PDU
667     uint8_t * packet = value - long_characteristic_value_event_header_size;
668     packet[0] = type;
669     packet[1] = long_characteristic_value_event_header_size - 2 + length;
670     little_endian_store_16(packet, 2, con_handle);
671     little_endian_store_16(packet, 4, attribute_handle);
672     little_endian_store_16(packet, 6, offset);
673     little_endian_store_16(packet, 8, length);
674     return packet;
675 #else
676     log_error("HCI_INCOMING_PRE_BUFFER_SIZE >= 2 required for long characteristic reads");
677     return NULL;
678 #endif
679 }
680 
681 
682 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
683 static void report_gatt_notification(hci_con_handle_t con_handle, uint16_t value_handle, uint8_t * value, int length){
684     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_NOTIFICATION, con_handle, value_handle, value, length);
685     emit_event_to_registered_listeners(con_handle, value_handle, packet, characteristic_value_event_header_size + length);
686 }
687 
688 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
689 static void report_gatt_indication(hci_con_handle_t con_handle, uint16_t value_handle, uint8_t * value, int length){
690     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_INDICATION, con_handle, value_handle, value, length);
691     emit_event_to_registered_listeners(con_handle, value_handle, packet, characteristic_value_event_header_size + length);
692 }
693 
694 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
695 static void report_gatt_characteristic_value(gatt_client_t * peripheral, uint16_t attribute_handle, uint8_t * value, uint16_t length){
696     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT, peripheral->con_handle, attribute_handle, value, length);
697     emit_event_new(peripheral->callback, packet, characteristic_value_event_header_size + length);
698 }
699 
700 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
701 static void report_gatt_long_characteristic_value_blob(gatt_client_t * peripheral, uint16_t attribute_handle, uint8_t * blob, uint16_t blob_length, int value_offset){
702     uint8_t * packet = setup_long_characteristic_value_packet(GATT_EVENT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT, peripheral->con_handle, attribute_handle, value_offset, blob, blob_length);
703     if (!packet) return;
704     emit_event_new(peripheral->callback, packet, blob_length + long_characteristic_value_event_header_size);
705 }
706 
707 static void report_gatt_characteristic_descriptor(gatt_client_t * peripheral, uint16_t descriptor_handle, uint8_t *value, uint16_t value_length, uint16_t value_offset){
708     UNUSED(value_offset);
709     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT, peripheral->con_handle, descriptor_handle, value, value_length);
710     emit_event_new(peripheral->callback, packet, value_length + 8);
711 }
712 
713 static void report_gatt_long_characteristic_descriptor(gatt_client_t * peripheral, uint16_t descriptor_handle, uint8_t *blob, uint16_t blob_length, uint16_t value_offset){
714     uint8_t * packet = setup_long_characteristic_value_packet(GATT_EVENT_LONG_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT, peripheral->con_handle, descriptor_handle, value_offset, blob, blob_length);
715     if (!packet) return;
716     emit_event_new(peripheral->callback, packet, blob_length + long_characteristic_value_event_header_size);
717 }
718 
719 static void report_gatt_all_characteristic_descriptors(gatt_client_t * peripheral, uint8_t * packet, uint16_t size, uint16_t pair_size){
720     int i;
721     for (i = 0; i<size; i+=pair_size){
722         uint16_t descriptor_handle = little_endian_read_16(packet,i);
723         uint8_t uuid128[16];
724         uint16_t uuid16 = 0;
725         if (pair_size == 4){
726             uuid16 = little_endian_read_16(packet,i+2);
727             uuid_add_bluetooth_prefix(uuid128, uuid16);
728         } else {
729             reverse_128(&packet[i+2], uuid128);
730         }
731         emit_gatt_all_characteristic_descriptors_result_event(peripheral, descriptor_handle, uuid128);
732     }
733 
734 }
735 
736 static int is_query_done(gatt_client_t * peripheral, uint16_t last_result_handle){
737     return last_result_handle >= peripheral->end_group_handle;
738 }
739 
740 static void trigger_next_query(gatt_client_t * peripheral, uint16_t last_result_handle, gatt_client_state_t next_query_state){
741     if (is_query_done(peripheral, last_result_handle)){
742         gatt_client_handle_transaction_complete(peripheral);
743         emit_gatt_complete_event(peripheral, 0);
744         return;
745     }
746     // next
747     peripheral->start_group_handle = last_result_handle + 1;
748     peripheral->gatt_client_state = next_query_state;
749 }
750 
751 static inline void trigger_next_included_service_query(gatt_client_t * peripheral, uint16_t last_result_handle){
752     trigger_next_query(peripheral, last_result_handle, P_W2_SEND_INCLUDED_SERVICE_QUERY);
753 }
754 
755 static inline void trigger_next_service_query(gatt_client_t * peripheral, uint16_t last_result_handle){
756     trigger_next_query(peripheral, last_result_handle, P_W2_SEND_SERVICE_QUERY);
757 }
758 
759 static inline void trigger_next_service_by_uuid_query(gatt_client_t * peripheral, uint16_t last_result_handle){
760     trigger_next_query(peripheral, last_result_handle, P_W2_SEND_SERVICE_WITH_UUID_QUERY);
761 }
762 
763 static inline void trigger_next_characteristic_query(gatt_client_t * peripheral, uint16_t last_result_handle){
764     if (is_query_done(peripheral, last_result_handle)){
765         // report last characteristic
766         characteristic_end_found(peripheral, peripheral->end_group_handle);
767     }
768     trigger_next_query(peripheral, last_result_handle, P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY);
769 }
770 
771 static inline void trigger_next_characteristic_descriptor_query(gatt_client_t * peripheral, uint16_t last_result_handle){
772     trigger_next_query(peripheral, last_result_handle, P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY);
773 }
774 
775 static inline void trigger_next_read_by_type_query(gatt_client_t * peripheral, uint16_t last_result_handle){
776     trigger_next_query(peripheral, last_result_handle, P_W2_SEND_READ_BY_TYPE_REQUEST);
777 }
778 
779 static inline void trigger_next_prepare_write_query(gatt_client_t * peripheral, gatt_client_state_t next_query_state, gatt_client_state_t done_state){
780     peripheral->attribute_offset += write_blob_length(peripheral);
781     uint16_t next_blob_length =  write_blob_length(peripheral);
782 
783     if (next_blob_length == 0){
784         peripheral->gatt_client_state = done_state;
785         return;
786     }
787     peripheral->gatt_client_state = next_query_state;
788 }
789 
790 static inline void trigger_next_blob_query(gatt_client_t * peripheral, gatt_client_state_t next_query_state, uint16_t received_blob_length){
791 
792     uint16_t max_blob_length = peripheral_mtu(peripheral) - 1;
793     if (received_blob_length < max_blob_length){
794         gatt_client_handle_transaction_complete(peripheral);
795         emit_gatt_complete_event(peripheral, 0);
796         return;
797     }
798 
799     peripheral->attribute_offset += received_blob_length;
800     peripheral->gatt_client_state = next_query_state;
801 }
802 
803 
804 static int is_value_valid(gatt_client_t *peripheral, uint8_t *packet, uint16_t size){
805     uint16_t attribute_handle = little_endian_read_16(packet, 1);
806     uint16_t value_offset = little_endian_read_16(packet, 3);
807 
808     if (peripheral->attribute_handle != attribute_handle) return 0;
809     if (peripheral->attribute_offset != value_offset) return 0;
810     return memcmp(&peripheral->attribute_value[peripheral->attribute_offset], &packet[5], size-5) == 0;
811 }
812 
813 
814 static void gatt_client_run(void){
815 
816     btstack_linked_item_t *it;
817     for (it = (btstack_linked_item_t *) gatt_client_connections; it ; it = it->next){
818 
819         gatt_client_t * peripheral = (gatt_client_t *) it;
820 
821         if (!att_dispatch_client_can_send_now(peripheral->con_handle)) {
822             att_dispatch_client_request_can_send_now_event(peripheral->con_handle);
823             return;
824         }
825 
826         // log_info("- handle_peripheral_list, mtu state %u, client state %u", peripheral->mtu_state, peripheral->gatt_client_state);
827 
828         switch (peripheral->mtu_state) {
829             case SEND_MTU_EXCHANGE:{
830                 peripheral->mtu_state = SENT_MTU_EXCHANGE;
831                 att_exchange_mtu_request(peripheral->con_handle);
832                 return;
833             }
834             case SENT_MTU_EXCHANGE:
835                 return;
836             default:
837                 break;
838         }
839 
840         if (peripheral->send_confirmation){
841             peripheral->send_confirmation = 0;
842             att_confirmation(peripheral->con_handle);
843             return;
844         }
845 
846         // check MTU for writes
847         switch (peripheral->gatt_client_state){
848             case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE:
849             case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR:
850                 if (peripheral->attribute_length <= peripheral_mtu(peripheral) - 3) break;
851                 log_error("gatt_client_run: value len %u > MTU %u - 3\n", peripheral->attribute_length, peripheral_mtu(peripheral));
852                 gatt_client_handle_transaction_complete(peripheral);
853                 emit_gatt_complete_event(peripheral, ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH);
854                 return;
855             default:
856                 break;
857         }
858 
859         // log_info("gatt_client_state %u", peripheral->gatt_client_state);
860         switch (peripheral->gatt_client_state){
861             case P_W2_SEND_SERVICE_QUERY:
862                 peripheral->gatt_client_state = P_W4_SERVICE_QUERY_RESULT;
863                 send_gatt_services_request(peripheral);
864                 return;
865 
866             case P_W2_SEND_SERVICE_WITH_UUID_QUERY:
867                 peripheral->gatt_client_state = P_W4_SERVICE_WITH_UUID_RESULT;
868                 send_gatt_services_by_uuid_request(peripheral);
869                 return;
870 
871             case P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY:
872                 peripheral->gatt_client_state = P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT;
873                 send_gatt_characteristic_request(peripheral);
874                 return;
875 
876             case P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY:
877                 peripheral->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT;
878                 send_gatt_characteristic_request(peripheral);
879                 return;
880 
881             case P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY:
882                 peripheral->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT;
883                 send_gatt_characteristic_descriptor_request(peripheral);
884                 return;
885 
886             case P_W2_SEND_INCLUDED_SERVICE_QUERY:
887                 peripheral->gatt_client_state = P_W4_INCLUDED_SERVICE_QUERY_RESULT;
888                 send_gatt_included_service_request(peripheral);
889                 return;
890 
891             case P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY:
892                 peripheral->gatt_client_state = P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT;
893                 send_gatt_included_service_uuid_request(peripheral);
894                 return;
895 
896             case P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY:
897                 peripheral->gatt_client_state = P_W4_READ_CHARACTERISTIC_VALUE_RESULT;
898                 send_gatt_read_characteristic_value_request(peripheral);
899                 return;
900 
901             case P_W2_SEND_READ_BLOB_QUERY:
902                 peripheral->gatt_client_state = P_W4_READ_BLOB_RESULT;
903                 send_gatt_read_blob_request(peripheral);
904                 return;
905 
906             case P_W2_SEND_READ_BY_TYPE_REQUEST:
907                 peripheral->gatt_client_state = P_W4_READ_BY_TYPE_RESPONSE;
908                 send_gatt_read_by_type_request(peripheral);
909                 break;
910 
911             case P_W2_SEND_READ_MULTIPLE_REQUEST:
912                 peripheral->gatt_client_state = P_W4_READ_MULTIPLE_RESPONSE;
913                 send_gatt_read_multiple_request(peripheral);
914                 break;
915 
916             case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE:
917                 peripheral->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT;
918                 send_gatt_write_attribute_value_request(peripheral);
919                 return;
920 
921             case P_W2_PREPARE_WRITE:
922                 peripheral->gatt_client_state = P_W4_PREPARE_WRITE_RESULT;
923                 send_gatt_prepare_write_request(peripheral);
924                 return;
925 
926             case P_W2_PREPARE_WRITE_SINGLE:
927                 peripheral->gatt_client_state = P_W4_PREPARE_WRITE_SINGLE_RESULT;
928                 send_gatt_prepare_write_request(peripheral);
929                 return;
930 
931             case P_W2_PREPARE_RELIABLE_WRITE:
932                 peripheral->gatt_client_state = P_W4_PREPARE_RELIABLE_WRITE_RESULT;
933                 send_gatt_prepare_write_request(peripheral);
934                 return;
935 
936             case P_W2_EXECUTE_PREPARED_WRITE:
937                 peripheral->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_RESULT;
938                 send_gatt_execute_write_request(peripheral);
939                 return;
940 
941             case P_W2_CANCEL_PREPARED_WRITE:
942                 peripheral->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_RESULT;
943                 send_gatt_cancel_prepared_write_request(peripheral);
944                 return;
945 
946             case P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH:
947                 peripheral->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT;
948                 send_gatt_cancel_prepared_write_request(peripheral);
949                 return;
950 
951             case P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY:
952                 peripheral->gatt_client_state = P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT;
953                 send_gatt_read_client_characteristic_configuration_request(peripheral);
954                 return;
955 
956             case P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY:
957                 peripheral->gatt_client_state = P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT;
958                 send_gatt_read_characteristic_descriptor_request(peripheral);
959                 return;
960 
961             case P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY:
962                 peripheral->gatt_client_state = P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT;
963                 send_gatt_read_blob_request(peripheral);
964                 return;
965 
966             case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR:
967                 peripheral->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT;
968                 send_gatt_write_attribute_value_request(peripheral);
969                 return;
970 
971             case P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION:
972                 peripheral->gatt_client_state = P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT;
973                 send_gatt_write_client_characteristic_configuration_request(peripheral);
974                 return;
975 
976             case P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR:
977                 peripheral->gatt_client_state = P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT;
978                 send_gatt_prepare_write_request(peripheral);
979                 return;
980 
981             case P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR:
982                 peripheral->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT;
983                 send_gatt_execute_write_request(peripheral);
984                 return;
985 
986 #ifdef ENABLE_LE_SIGNED_WRITE
987             case P_W4_CMAC_READY:
988                 if (sm_cmac_ready()){
989                     sm_key_t csrk;
990                     le_device_db_local_csrk_get(peripheral->le_device_index, csrk);
991                     uint32_t sign_counter = le_device_db_local_counter_get(peripheral->le_device_index);
992                     peripheral->gatt_client_state = P_W4_CMAC_RESULT;
993                     sm_cmac_signed_write_start(csrk, ATT_SIGNED_WRITE_COMMAND, peripheral->attribute_handle, peripheral->attribute_length, peripheral->attribute_value, sign_counter, att_signed_write_handle_cmac_result);
994                 }
995                 return;
996 
997             case P_W2_SEND_SIGNED_WRITE: {
998                 peripheral->gatt_client_state = P_W4_SEND_SINGED_WRITE_DONE;
999                 // bump local signing counter
1000                 uint32_t sign_counter = le_device_db_local_counter_get(peripheral->le_device_index);
1001                 le_device_db_local_counter_set(peripheral->le_device_index, sign_counter + 1);
1002 
1003                 send_gatt_signed_write_request(peripheral, sign_counter);
1004                 peripheral->gatt_client_state = P_READY;
1005                 // finally, notifiy client that write is complete
1006                 gatt_client_handle_transaction_complete(peripheral);
1007                 return;
1008             }
1009 #endif
1010 
1011             default:
1012                 break;
1013         }
1014     }
1015 
1016 }
1017 
1018 static void gatt_client_report_error_if_pending(gatt_client_t *peripheral, uint8_t error_code) {
1019     if (is_ready(peripheral)) return;
1020     gatt_client_handle_transaction_complete(peripheral);
1021     emit_gatt_complete_event(peripheral, error_code);
1022 }
1023 
1024 static void gatt_client_hci_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
1025     UNUSED(channel);    // ok: handling own l2cap events
1026     UNUSED(size);       // ok: there is no channel
1027 
1028     if (packet_type != HCI_EVENT_PACKET) return;
1029 
1030     switch (hci_event_packet_get_type(packet)) {
1031         case HCI_EVENT_DISCONNECTION_COMPLETE:
1032         {
1033             log_info("GATT Client: HCI_EVENT_DISCONNECTION_COMPLETE");
1034             hci_con_handle_t con_handle = little_endian_read_16(packet,3);
1035             gatt_client_t * peripheral = get_gatt_client_context_for_handle(con_handle);
1036             if (!peripheral) break;
1037             gatt_client_report_error_if_pending(peripheral, ATT_ERROR_HCI_DISCONNECT_RECEIVED);
1038 
1039             btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) peripheral);
1040             btstack_memory_gatt_client_free(peripheral);
1041             break;
1042         }
1043         default:
1044             break;
1045     }
1046 
1047     gatt_client_run();
1048 }
1049 
1050 static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
1051 
1052     if (packet_type == HCI_EVENT_PACKET && packet[0] == L2CAP_EVENT_CAN_SEND_NOW){
1053         gatt_client_run();
1054     }
1055 
1056     if (packet_type != ATT_DATA_PACKET) return;
1057 
1058     // special cases: notifications don't need a context while indications motivate creating one
1059     gatt_client_t * peripheral;
1060     switch (packet[0]){
1061         case ATT_HANDLE_VALUE_NOTIFICATION:
1062             report_gatt_notification(handle, little_endian_read_16(packet,1), &packet[3], size-3);
1063             return;
1064         case ATT_HANDLE_VALUE_INDICATION:
1065             peripheral = provide_context_for_conn_handle(handle);
1066             break;
1067         default:
1068             peripheral = get_gatt_client_context_for_handle(handle);
1069             break;
1070     }
1071 
1072     if (!peripheral) return;
1073 
1074     switch (packet[0]){
1075         // att_server has negotiated the mtu for this connection
1076         case ATT_EVENT_MTU_EXCHANGE_COMPLETE:
1077         {
1078             peripheral->mtu = little_endian_read_16(packet, 4);
1079             break;
1080         }
1081         case ATT_EXCHANGE_MTU_RESPONSE:
1082         {
1083             uint16_t remote_rx_mtu = little_endian_read_16(packet, 1);
1084             uint16_t local_rx_mtu = l2cap_max_le_mtu();
1085             peripheral->mtu = remote_rx_mtu < local_rx_mtu ? remote_rx_mtu : local_rx_mtu;
1086             peripheral->mtu_state = MTU_EXCHANGED;
1087             emit_gatt_mtu_exchanged_result_event(peripheral, peripheral->mtu);
1088             break;
1089         }
1090         case ATT_READ_BY_GROUP_TYPE_RESPONSE:
1091             switch(peripheral->gatt_client_state){
1092                 case P_W4_SERVICE_QUERY_RESULT:
1093                     report_gatt_services(peripheral, packet, size);
1094                     trigger_next_service_query(peripheral, get_last_result_handle_from_service_list(packet, size));
1095                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1096                     break;
1097                 default:
1098                     break;
1099             }
1100             break;
1101         case ATT_HANDLE_VALUE_INDICATION:
1102             report_gatt_indication(handle, little_endian_read_16(packet,1), &packet[3], size-3);
1103             peripheral->send_confirmation = 1;
1104             break;
1105 
1106         case ATT_READ_BY_TYPE_RESPONSE:
1107             switch (peripheral->gatt_client_state){
1108                 case P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT:
1109                     report_gatt_characteristics(peripheral, packet, size);
1110                     trigger_next_characteristic_query(peripheral, get_last_result_handle_from_characteristics_list(packet, size));
1111                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR
1112                     break;
1113                 case P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT:
1114                     report_gatt_characteristics(peripheral, packet, size);
1115                     trigger_next_characteristic_query(peripheral, get_last_result_handle_from_characteristics_list(packet, size));
1116                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR
1117                     break;
1118                 case P_W4_INCLUDED_SERVICE_QUERY_RESULT:
1119                 {
1120                     uint16_t uuid16 = 0;
1121                     uint16_t pair_size = packet[1];
1122 
1123                     if (pair_size < 7){
1124                         // UUIDs not available, query first included service
1125                         peripheral->start_group_handle = little_endian_read_16(packet, 2); // ready for next query
1126                         peripheral->query_start_handle = little_endian_read_16(packet, 4);
1127                         peripheral->query_end_handle = little_endian_read_16(packet,6);
1128                         peripheral->gatt_client_state = P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY;
1129                         break;
1130                     }
1131 
1132                     uint16_t offset;
1133                     for (offset = 2; offset < size; offset += pair_size){
1134                         uint16_t include_handle = little_endian_read_16(packet, offset);
1135                         peripheral->query_start_handle = little_endian_read_16(packet,offset+2);
1136                         peripheral->query_end_handle = little_endian_read_16(packet,offset+4);
1137                         uuid16 = little_endian_read_16(packet, offset+6);
1138                         report_gatt_included_service_uuid16(peripheral, include_handle, uuid16);
1139                     }
1140 
1141                     trigger_next_included_service_query(peripheral, get_last_result_handle_from_included_services_list(packet, size));
1142                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1143                     break;
1144                 }
1145                 case P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT:
1146                     peripheral->client_characteristic_configuration_handle = little_endian_read_16(packet, 2);
1147                     peripheral->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
1148                     break;
1149                 case P_W4_READ_BY_TYPE_RESPONSE: {
1150                     uint16_t pair_size = packet[1];
1151                     uint16_t offset;
1152                     uint16_t last_result_handle = 0;
1153                     for (offset = 2; offset < size ; offset += pair_size){
1154                         uint16_t value_handle = little_endian_read_16(packet, offset);
1155                         report_gatt_characteristic_value(peripheral, value_handle, &packet[offset+2], pair_size-2);
1156                         last_result_handle = value_handle;
1157                     }
1158                     trigger_next_read_by_type_query(peripheral, last_result_handle);
1159                     break;
1160                 }
1161                 default:
1162                     break;
1163             }
1164             break;
1165         case ATT_READ_RESPONSE:
1166             switch (peripheral->gatt_client_state){
1167                 case P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT: {
1168                     uint8_t uuid128[16];
1169                     reverse_128(&packet[1], uuid128);
1170                     report_gatt_included_service_uuid128(peripheral, peripheral->start_group_handle, uuid128);
1171                     trigger_next_included_service_query(peripheral, peripheral->start_group_handle);
1172                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1173                     break;
1174                 }
1175                 case P_W4_READ_CHARACTERISTIC_VALUE_RESULT:
1176                     gatt_client_handle_transaction_complete(peripheral);
1177                     report_gatt_characteristic_value(peripheral, peripheral->attribute_handle, &packet[1], size-1);
1178                     emit_gatt_complete_event(peripheral, 0);
1179                     break;
1180 
1181                 case P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT:{
1182                     gatt_client_handle_transaction_complete(peripheral);
1183                     report_gatt_characteristic_descriptor(peripheral, peripheral->attribute_handle, &packet[1], size-1, 0);
1184                     emit_gatt_complete_event(peripheral, 0);
1185                     break;
1186                 }
1187                 default:
1188                     break;
1189             }
1190             break;
1191 
1192         case ATT_FIND_BY_TYPE_VALUE_RESPONSE:
1193         {
1194             uint8_t pair_size = 4;
1195             int i;
1196             uint16_t start_group_handle;
1197             uint16_t   end_group_handle= 0xffff; // asserts GATT_EVENT_QUERY_COMPLETE is emitted if no results
1198             for (i = 1; i<size; i+=pair_size){
1199                 start_group_handle = little_endian_read_16(packet,i);
1200                 end_group_handle = little_endian_read_16(packet,i+2);
1201                 emit_gatt_service_query_result_event(peripheral, start_group_handle, end_group_handle, peripheral->uuid128);
1202             }
1203             trigger_next_service_by_uuid_query(peripheral, end_group_handle);
1204             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1205             break;
1206         }
1207         case ATT_FIND_INFORMATION_REPLY:
1208         {
1209             uint8_t pair_size = 4;
1210             if (packet[1] == 2){
1211                 pair_size = 18;
1212             }
1213             uint16_t last_descriptor_handle = little_endian_read_16(packet, size - pair_size);
1214 
1215             report_gatt_all_characteristic_descriptors(peripheral, &packet[2], size-2, pair_size);
1216             trigger_next_characteristic_descriptor_query(peripheral, last_descriptor_handle);
1217             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1218             break;
1219         }
1220 
1221         case ATT_WRITE_RESPONSE:
1222             switch (peripheral->gatt_client_state){
1223                 case P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT:
1224                     gatt_client_handle_transaction_complete(peripheral);
1225                     emit_gatt_complete_event(peripheral, 0);
1226                     break;
1227                 case P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT:
1228                     gatt_client_handle_transaction_complete(peripheral);
1229                     emit_gatt_complete_event(peripheral, 0);
1230                     break;
1231                 case P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
1232                     gatt_client_handle_transaction_complete(peripheral);
1233                     emit_gatt_complete_event(peripheral, 0);
1234                     break;
1235                 default:
1236                     break;
1237             }
1238             break;
1239 
1240         case ATT_READ_BLOB_RESPONSE:{
1241             uint16_t received_blob_length = size-1;
1242 
1243             switch(peripheral->gatt_client_state){
1244                 case P_W4_READ_BLOB_RESULT:
1245                     report_gatt_long_characteristic_value_blob(peripheral, peripheral->attribute_handle, &packet[1], received_blob_length, peripheral->attribute_offset);
1246                     trigger_next_blob_query(peripheral, P_W2_SEND_READ_BLOB_QUERY, received_blob_length);
1247                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1248                     break;
1249                 case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT:
1250                     report_gatt_long_characteristic_descriptor(peripheral, peripheral->attribute_handle,
1251                                                           &packet[1], received_blob_length,
1252                                                           peripheral->attribute_offset);
1253                     trigger_next_blob_query(peripheral, P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY, received_blob_length);
1254                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1255                     break;
1256                 default:
1257                     break;
1258             }
1259             break;
1260         }
1261         case ATT_PREPARE_WRITE_RESPONSE:
1262             switch (peripheral->gatt_client_state){
1263                 case P_W4_PREPARE_WRITE_SINGLE_RESULT:
1264                     gatt_client_handle_transaction_complete(peripheral);
1265                     if (is_value_valid(peripheral, packet, size)){
1266                         emit_gatt_complete_event(peripheral, 0);
1267                     } else {
1268                         emit_gatt_complete_event(peripheral, ATT_ERROR_DATA_MISMATCH);
1269                     }
1270                     break;
1271 
1272                 case P_W4_PREPARE_WRITE_RESULT:{
1273                     peripheral->attribute_offset = little_endian_read_16(packet, 3);
1274                     trigger_next_prepare_write_query(peripheral, P_W2_PREPARE_WRITE, P_W2_EXECUTE_PREPARED_WRITE);
1275                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1276                     break;
1277                 }
1278                 case P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:{
1279                     peripheral->attribute_offset = little_endian_read_16(packet, 3);
1280                     trigger_next_prepare_write_query(peripheral, P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR, P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR);
1281                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1282                     break;
1283                 }
1284                 case P_W4_PREPARE_RELIABLE_WRITE_RESULT:{
1285                     if (is_value_valid(peripheral, packet, size)){
1286                         peripheral->attribute_offset = little_endian_read_16(packet, 3);
1287                         trigger_next_prepare_write_query(peripheral, P_W2_PREPARE_RELIABLE_WRITE, P_W2_EXECUTE_PREPARED_WRITE);
1288                         // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1289                         break;
1290                     }
1291                     peripheral->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH;
1292                     break;
1293                 }
1294                 default:
1295                     break;
1296             }
1297             break;
1298 
1299         case ATT_EXECUTE_WRITE_RESPONSE:
1300             switch (peripheral->gatt_client_state){
1301                 case P_W4_EXECUTE_PREPARED_WRITE_RESULT:
1302                     gatt_client_handle_transaction_complete(peripheral);
1303                     emit_gatt_complete_event(peripheral, 0);
1304                     break;
1305                 case P_W4_CANCEL_PREPARED_WRITE_RESULT:
1306                     gatt_client_handle_transaction_complete(peripheral);
1307                     emit_gatt_complete_event(peripheral, 0);
1308                     break;
1309                 case P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT:
1310                     gatt_client_handle_transaction_complete(peripheral);
1311                     emit_gatt_complete_event(peripheral, ATT_ERROR_DATA_MISMATCH);
1312                     break;
1313                 case P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
1314                     gatt_client_handle_transaction_complete(peripheral);
1315                     emit_gatt_complete_event(peripheral, 0);
1316                     break;
1317                 default:
1318                     break;
1319 
1320             }
1321             break;
1322 
1323         case ATT_READ_MULTIPLE_RESPONSE:
1324             switch(peripheral->gatt_client_state){
1325                 case P_W4_READ_MULTIPLE_RESPONSE:
1326                     report_gatt_characteristic_value(peripheral, 0, &packet[1], size-1);
1327                     gatt_client_handle_transaction_complete(peripheral);
1328                     emit_gatt_complete_event(peripheral, 0);
1329                     break;
1330                 default:
1331                     break;
1332             }
1333             break;
1334 
1335         case ATT_ERROR_RESPONSE:
1336 
1337             switch (packet[4]){
1338                 case ATT_ERROR_ATTRIBUTE_NOT_FOUND: {
1339                     switch(peripheral->gatt_client_state){
1340                         case P_W4_SERVICE_QUERY_RESULT:
1341                         case P_W4_SERVICE_WITH_UUID_RESULT:
1342                         case P_W4_INCLUDED_SERVICE_QUERY_RESULT:
1343                         case P_W4_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT:
1344                             gatt_client_handle_transaction_complete(peripheral);
1345                             emit_gatt_complete_event(peripheral, 0);
1346                             break;
1347                         case P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT:
1348                         case P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT:
1349                             characteristic_end_found(peripheral, peripheral->end_group_handle);
1350                             gatt_client_handle_transaction_complete(peripheral);
1351                             emit_gatt_complete_event(peripheral, 0);
1352                             break;
1353                         case P_W4_READ_BY_TYPE_RESPONSE:
1354                             gatt_client_handle_transaction_complete(peripheral);
1355                             if (peripheral->start_group_handle == peripheral->query_start_handle){
1356                                 emit_gatt_complete_event(peripheral, ATT_ERROR_ATTRIBUTE_NOT_FOUND);
1357                             } else {
1358                                 emit_gatt_complete_event(peripheral, 0);
1359                             }
1360                             break;
1361                         default:
1362                             gatt_client_report_error_if_pending(peripheral, packet[4]);
1363                             break;
1364                     }
1365                     break;
1366                 }
1367                 default:
1368                     gatt_client_report_error_if_pending(peripheral, packet[4]);
1369                     break;
1370             }
1371             break;
1372 
1373         default:
1374             log_info("ATT Handler, unhandled response type 0x%02x", packet[0]);
1375             break;
1376     }
1377     gatt_client_run();
1378 }
1379 
1380 #ifdef ENABLE_LE_SIGNED_WRITE
1381 static void att_signed_write_handle_cmac_result(uint8_t hash[8]){
1382     btstack_linked_list_iterator_t it;
1383     btstack_linked_list_iterator_init(&it, &gatt_client_connections);
1384     while (btstack_linked_list_iterator_has_next(&it)){
1385         gatt_client_t * peripheral = (gatt_client_t *) btstack_linked_list_iterator_next(&it);
1386         if (peripheral->gatt_client_state == P_W4_CMAC_RESULT){
1387             // store result
1388             memcpy(peripheral->cmac, hash, 8);
1389             // reverse_64(hash, peripheral->cmac);
1390             peripheral->gatt_client_state = P_W2_SEND_SIGNED_WRITE;
1391             gatt_client_run();
1392             return;
1393         }
1394     }
1395 }
1396 
1397 uint8_t gatt_client_signed_write_without_response(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t handle, uint16_t message_len, uint8_t * message){
1398     gatt_client_t * peripheral = provide_context_for_conn_handle(con_handle);
1399     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1400     peripheral->le_device_index = sm_le_device_index(con_handle);
1401     if (peripheral->le_device_index < 0) return GATT_CLIENT_IN_WRONG_STATE; // device lookup not done / no stored bonding information
1402 
1403     peripheral->callback = callback;
1404     peripheral->attribute_handle = handle;
1405     peripheral->attribute_length = message_len;
1406     peripheral->attribute_value = message;
1407     peripheral->gatt_client_state = P_W4_CMAC_READY;
1408 
1409     gatt_client_run();
1410     return 0;
1411 }
1412 #endif
1413 
1414 uint8_t gatt_client_discover_primary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
1415     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1416     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1417     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1418 
1419     peripheral->callback = callback;
1420     peripheral->start_group_handle = 0x0001;
1421     peripheral->end_group_handle   = 0xffff;
1422     peripheral->gatt_client_state = P_W2_SEND_SERVICE_QUERY;
1423     peripheral->uuid16 = 0;
1424     gatt_client_run();
1425     return 0;
1426 }
1427 
1428 
1429 uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16){
1430     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1431 
1432     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1433     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1434 
1435     peripheral->callback = callback;
1436     peripheral->start_group_handle = 0x0001;
1437     peripheral->end_group_handle   = 0xffff;
1438     peripheral->gatt_client_state = P_W2_SEND_SERVICE_WITH_UUID_QUERY;
1439     peripheral->uuid16 = uuid16;
1440     uuid_add_bluetooth_prefix((uint8_t*) &(peripheral->uuid128), peripheral->uuid16);
1441     gatt_client_run();
1442     return 0;
1443 }
1444 
1445 uint8_t gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, const uint8_t * uuid128){
1446     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1447 
1448     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1449     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1450 
1451     peripheral->callback = callback;
1452     peripheral->start_group_handle = 0x0001;
1453     peripheral->end_group_handle   = 0xffff;
1454     peripheral->uuid16 = 0;
1455     memcpy(peripheral->uuid128, uuid128, 16);
1456     peripheral->gatt_client_state = P_W2_SEND_SERVICE_WITH_UUID_QUERY;
1457     gatt_client_run();
1458     return 0;
1459 }
1460 
1461 uint8_t gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t *service){
1462     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1463 
1464     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1465     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1466 
1467     peripheral->callback = callback;
1468     peripheral->start_group_handle = service->start_group_handle;
1469     peripheral->end_group_handle   = service->end_group_handle;
1470     peripheral->filter_with_uuid = 0;
1471     peripheral->characteristic_start_handle = 0;
1472     peripheral->gatt_client_state = P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY;
1473     gatt_client_run();
1474     return 0;
1475 }
1476 
1477 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){
1478     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1479 
1480     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1481     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1482 
1483     peripheral->callback = callback;
1484     peripheral->start_group_handle = service->start_group_handle;
1485     peripheral->end_group_handle   = service->end_group_handle;
1486     peripheral->gatt_client_state = P_W2_SEND_INCLUDED_SERVICE_QUERY;
1487 
1488     gatt_client_run();
1489     return 0;
1490 }
1491 
1492 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){
1493     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1494 
1495     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1496     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1497 
1498     peripheral->callback = callback;
1499     peripheral->start_group_handle = start_handle;
1500     peripheral->end_group_handle   = end_handle;
1501     peripheral->filter_with_uuid = 1;
1502     peripheral->uuid16 = uuid16;
1503     uuid_add_bluetooth_prefix((uint8_t*) &(peripheral->uuid128), uuid16);
1504     peripheral->characteristic_start_handle = 0;
1505     peripheral->gatt_client_state = P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY;
1506 
1507     gatt_client_run();
1508     return 0;
1509 }
1510 
1511 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, uint8_t * uuid128){
1512     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1513 
1514     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1515     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1516 
1517     peripheral->callback = callback;
1518     peripheral->start_group_handle = start_handle;
1519     peripheral->end_group_handle   = end_handle;
1520     peripheral->filter_with_uuid = 1;
1521     peripheral->uuid16 = 0;
1522     memcpy(peripheral->uuid128, uuid128, 16);
1523     peripheral->characteristic_start_handle = 0;
1524     peripheral->gatt_client_state = P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY;
1525 
1526     gatt_client_run();
1527     return 0;
1528 }
1529 
1530 
1531 uint8_t gatt_client_discover_characteristics_for_service_by_uuid16(btstack_packet_handler_t callback, uint16_t handle, gatt_client_service_t *service, uint16_t  uuid16){
1532     return gatt_client_discover_characteristics_for_handle_range_by_uuid16(callback, handle, service->start_group_handle, service->end_group_handle, uuid16);
1533 }
1534 
1535 uint8_t gatt_client_discover_characteristics_for_service_by_uuid128(btstack_packet_handler_t callback, uint16_t handle, gatt_client_service_t *service, uint8_t * uuid128){
1536     return gatt_client_discover_characteristics_for_handle_range_by_uuid128(callback, handle, service->start_group_handle, service->end_group_handle, uuid128);
1537 }
1538 
1539 uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t *characteristic){
1540     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1541 
1542     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1543     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1544 
1545     if (characteristic->value_handle == characteristic->end_handle){
1546         emit_gatt_complete_event(peripheral, 0);
1547         return 0;
1548     }
1549     peripheral->callback = callback;
1550     peripheral->start_group_handle = characteristic->value_handle + 1;
1551     peripheral->end_group_handle   = characteristic->end_handle;
1552     peripheral->gatt_client_state = P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY;
1553 
1554     gatt_client_run();
1555     return 0;
1556 }
1557 
1558 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){
1559     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1560 
1561     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1562     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1563 
1564     peripheral->callback = callback;
1565     peripheral->attribute_handle = value_handle;
1566     peripheral->attribute_offset = 0;
1567     peripheral->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY;
1568     gatt_client_run();
1569     return 0;
1570 }
1571 
1572 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){
1573     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1574 
1575     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1576     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1577 
1578     peripheral->callback = callback;
1579     peripheral->start_group_handle = start_handle;
1580     peripheral->end_group_handle = end_handle;
1581     peripheral->query_start_handle = start_handle;
1582     peripheral->query_end_handle = end_handle;
1583     peripheral->uuid16 = uuid16;
1584     uuid_add_bluetooth_prefix((uint8_t*) &(peripheral->uuid128), uuid16);
1585     peripheral->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
1586     gatt_client_run();
1587     return 0;
1588 }
1589 
1590 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, uint8_t * uuid128){
1591     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1592 
1593     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1594     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1595 
1596     peripheral->callback = callback;
1597     peripheral->start_group_handle = start_handle;
1598     peripheral->end_group_handle = end_handle;
1599     peripheral->query_start_handle = start_handle;
1600     peripheral->query_end_handle = end_handle;
1601     peripheral->uuid16 = 0;
1602     memcpy(peripheral->uuid128, uuid128, 16);
1603     peripheral->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
1604     gatt_client_run();
1605     return 0;
1606 }
1607 
1608 
1609 uint8_t gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback, uint16_t handle, gatt_client_characteristic_t *characteristic){
1610     return gatt_client_read_value_of_characteristic_using_value_handle(callback, handle, characteristic->value_handle);
1611 }
1612 
1613 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 characteristic_value_handle, uint16_t offset){
1614     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1615 
1616     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1617     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1618 
1619     peripheral->callback = callback;
1620     peripheral->attribute_handle = characteristic_value_handle;
1621     peripheral->attribute_offset = offset;
1622     peripheral->gatt_client_state = P_W2_SEND_READ_BLOB_QUERY;
1623     gatt_client_run();
1624     return 0;
1625 }
1626 
1627 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 characteristic_value_handle){
1628     return gatt_client_read_long_value_of_characteristic_using_value_handle_with_offset(callback, con_handle, characteristic_value_handle, 0);
1629 }
1630 
1631 uint8_t gatt_client_read_long_value_of_characteristic(btstack_packet_handler_t callback, uint16_t handle, gatt_client_characteristic_t *characteristic){
1632     return gatt_client_read_long_value_of_characteristic_using_value_handle(callback, handle, characteristic->value_handle);
1633 }
1634 
1635 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){
1636     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1637 
1638     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1639     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1640 
1641     peripheral->callback = callback;
1642     peripheral->read_multiple_handle_count = num_value_handles;
1643     peripheral->read_multiple_handles = value_handles;
1644     peripheral->gatt_client_state = P_W2_SEND_READ_MULTIPLE_REQUEST;
1645     gatt_client_run();
1646     return 0;
1647 }
1648 
1649 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){
1650     gatt_client_t * peripheral = provide_context_for_conn_handle(con_handle);
1651 
1652     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1653     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1654 
1655     if (value_length > peripheral_mtu(peripheral) - 3) return GATT_CLIENT_VALUE_TOO_LONG;
1656     if (!att_dispatch_client_can_send_now(peripheral->con_handle)) return GATT_CLIENT_BUSY;
1657 
1658     att_write_request(ATT_WRITE_COMMAND, peripheral->con_handle, value_handle, value_length, value);
1659     return 0;
1660 }
1661 
1662 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 * data){
1663     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1664 
1665     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1666     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1667 
1668     peripheral->callback = callback;
1669     peripheral->attribute_handle = value_handle;
1670     peripheral->attribute_length = value_length;
1671     peripheral->attribute_value = data;
1672     peripheral->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_VALUE;
1673     gatt_client_run();
1674     return 0;
1675 }
1676 
1677 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  * data){
1678     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1679 
1680     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1681     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1682 
1683     peripheral->callback = callback;
1684     peripheral->attribute_handle = value_handle;
1685     peripheral->attribute_length = value_length;
1686     peripheral->attribute_offset = offset;
1687     peripheral->attribute_value = data;
1688     peripheral->gatt_client_state = P_W2_PREPARE_WRITE;
1689     gatt_client_run();
1690     return 0;
1691 }
1692 
1693 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){
1694     return gatt_client_write_long_value_of_characteristic_with_offset(callback, con_handle, value_handle, 0, value_length, value);
1695 }
1696 
1697 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){
1698     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1699 
1700     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1701     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1702 
1703     peripheral->callback = callback;
1704     peripheral->attribute_handle = value_handle;
1705     peripheral->attribute_length = value_length;
1706     peripheral->attribute_offset = 0;
1707     peripheral->attribute_value = value;
1708     peripheral->gatt_client_state = P_W2_PREPARE_RELIABLE_WRITE;
1709     gatt_client_run();
1710     return 0;
1711 }
1712 
1713 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){
1714     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1715 
1716     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1717     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1718 
1719     if ( (configuration & GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION) &&
1720         (characteristic->properties & ATT_PROPERTY_NOTIFY) == 0) {
1721         log_info("gatt_client_write_client_characteristic_configuration: GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED");
1722         return GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED;
1723     } else if ( (configuration & GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION) &&
1724                (characteristic->properties & ATT_PROPERTY_INDICATE) == 0){
1725         log_info("gatt_client_write_client_characteristic_configuration: GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED");
1726         return GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED;
1727     }
1728 
1729     peripheral->callback = callback;
1730     peripheral->start_group_handle = characteristic->value_handle;
1731     peripheral->end_group_handle = characteristic->end_handle;
1732     little_endian_store_16(peripheral->client_characteristic_configuration_value, 0, configuration);
1733 
1734     peripheral->gatt_client_state = P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY;
1735     gatt_client_run();
1736     return 0;
1737 }
1738 
1739 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){
1740     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1741 
1742     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1743     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1744 
1745     peripheral->callback = callback;
1746     peripheral->attribute_handle = descriptor_handle;
1747 
1748     peripheral->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY;
1749     gatt_client_run();
1750     return 0;
1751 }
1752 
1753 uint8_t gatt_client_read_characteristic_descriptor(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_descriptor_t * descriptor){
1754     return gatt_client_read_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle);
1755 }
1756 
1757 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){
1758     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1759 
1760     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1761     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1762 
1763     peripheral->callback = callback;
1764     peripheral->attribute_handle = descriptor_handle;
1765     peripheral->attribute_offset = offset;
1766     peripheral->gatt_client_state = P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY;
1767     gatt_client_run();
1768     return 0;
1769 }
1770 
1771 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){
1772     return gatt_client_read_long_characteristic_descriptor_using_descriptor_handle_with_offset(callback, con_handle, descriptor_handle, 0);
1773 }
1774 
1775 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){
1776     return gatt_client_read_long_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle);
1777 }
1778 
1779 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 length, uint8_t  * data){
1780     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1781 
1782     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1783     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1784 
1785     peripheral->callback = callback;
1786     peripheral->attribute_handle = descriptor_handle;
1787     peripheral->attribute_length = length;
1788     peripheral->attribute_offset = 0;
1789     peripheral->attribute_value = data;
1790     peripheral->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR;
1791     gatt_client_run();
1792     return 0;
1793 }
1794 
1795 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 length, uint8_t * value){
1796     return gatt_client_write_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle, length, value);
1797 }
1798 
1799 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 length, uint8_t  * data){
1800     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1801 
1802     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1803     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1804 
1805     peripheral->callback = callback;
1806     peripheral->attribute_handle = descriptor_handle;
1807     peripheral->attribute_length = length;
1808     peripheral->attribute_offset = offset;
1809     peripheral->attribute_value = data;
1810     peripheral->gatt_client_state = P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR;
1811     gatt_client_run();
1812     return 0;
1813 }
1814 
1815 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 length, uint8_t * data){
1816     return gatt_client_write_long_characteristic_descriptor_using_descriptor_handle_with_offset(callback, con_handle, descriptor_handle, 0, length, data );
1817 }
1818 
1819 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 length, uint8_t * value){
1820     return gatt_client_write_long_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle, length, value);
1821 }
1822 
1823 /**
1824  * @brief -> gatt complete event
1825  */
1826 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 length, uint8_t * data){
1827     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1828 
1829     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1830     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1831 
1832     peripheral->callback = callback;
1833     peripheral->attribute_handle = attribute_handle;
1834     peripheral->attribute_length = length;
1835     peripheral->attribute_offset = offset;
1836     peripheral->attribute_value = data;
1837     peripheral->gatt_client_state = P_W2_PREPARE_WRITE_SINGLE;
1838     gatt_client_run();
1839     return 0;
1840 }
1841 
1842 /**
1843  * @brief -> gatt complete event
1844  */
1845 uint8_t gatt_client_execute_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
1846     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1847 
1848     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1849     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1850 
1851     peripheral->callback = callback;
1852     peripheral->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE;
1853     gatt_client_run();
1854     return 0;
1855 }
1856 
1857 /**
1858  * @brief -> gatt complete event
1859  */
1860 uint8_t gatt_client_cancel_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
1861     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1862 
1863     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1864     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1865 
1866     peripheral->callback = callback;
1867     peripheral->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE;
1868     gatt_client_run();
1869     return 0;
1870 }
1871 
1872 void gatt_client_pts_suppress_mtu_exchange(void){
1873     pts_suppress_mtu_exchange = 1;
1874 }
1875 
1876 void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t *service){
1877     service->start_group_handle = little_endian_read_16(packet, offset);
1878     service->end_group_handle = little_endian_read_16(packet, offset + 2);
1879     reverse_128(&packet[offset + 4], service->uuid128);
1880     if (uuid_has_bluetooth_prefix(service->uuid128)){
1881         service->uuid16 = big_endian_read_32(service->uuid128, 0);
1882     }
1883 }
1884 
1885 void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic){
1886     characteristic->start_handle = little_endian_read_16(packet, offset);
1887     characteristic->value_handle = little_endian_read_16(packet, offset + 2);
1888     characteristic->end_handle = little_endian_read_16(packet, offset + 4);
1889     characteristic->properties = little_endian_read_16(packet, offset + 6);
1890     reverse_128(&packet[offset+8], characteristic->uuid128);
1891     if (uuid_has_bluetooth_prefix(characteristic->uuid128)){
1892         characteristic->uuid16 = big_endian_read_32(characteristic->uuid128, 0);
1893     }
1894 }
1895 
1896 void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor){
1897     descriptor->handle = little_endian_read_16(packet, offset);
1898     reverse_128(&packet[offset+2], descriptor->uuid128);
1899     if (uuid_has_bluetooth_prefix(descriptor->uuid128)){
1900         descriptor->uuid16 = big_endian_read_32(descriptor->uuid128, 0);
1901     }
1902 }
1903