xref: /btstack/src/ble/gatt_client.c (revision 8f37572a30fadea1f47b3a859830610c5c25cf58)
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     emit_event_new(peripheral->callback, packet, sizeof(packet));
563 }
564 ///
565 static void report_gatt_services(gatt_client_t * peripheral, uint8_t * packet,  uint16_t size){
566     uint8_t attr_length = packet[1];
567     uint8_t uuid_length = attr_length - 4;
568 
569     int i;
570     for (i = 2; i < size; i += attr_length){
571         uint16_t start_group_handle = little_endian_read_16(packet,i);
572         uint16_t end_group_handle   = little_endian_read_16(packet,i+2);
573         uint8_t  uuid128[16];
574         uint16_t uuid16 = 0;
575 
576         if (uuid_length == 2){
577             uuid16 = little_endian_read_16(packet, i+4);
578             uuid_add_bluetooth_prefix((uint8_t*) &uuid128, uuid16);
579         } else {
580             reverse_128(&packet[i+4], uuid128);
581         }
582         emit_gatt_service_query_result_event(peripheral, start_group_handle, end_group_handle, uuid128);
583     }
584     // log_info("report_gatt_services for %02X done", peripheral->con_handle);
585 }
586 
587 // helper
588 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){
589     uint8_t uuid128[16];
590     uint16_t uuid16 = 0;
591     if (uuid_length == 2){
592         uuid16 = little_endian_read_16(uuid, 0);
593         uuid_add_bluetooth_prefix((uint8_t*) uuid128, uuid16);
594     } else {
595         reverse_128(uuid, uuid128);
596     }
597 
598     if (peripheral->filter_with_uuid && memcmp(peripheral->uuid128, uuid128, 16) != 0) return;
599 
600     peripheral->characteristic_properties = properties;
601     peripheral->characteristic_start_handle = start_handle;
602     peripheral->attribute_handle = value_handle;
603 
604     if (peripheral->filter_with_uuid) return;
605 
606     peripheral->uuid16 = uuid16;
607     memcpy(peripheral->uuid128, uuid128, 16);
608 }
609 
610 static void characteristic_end_found(gatt_client_t * peripheral, uint16_t end_handle){
611     // TODO: stop searching if filter and uuid found
612 
613     if (!peripheral->characteristic_start_handle) return;
614 
615     emit_gatt_characteristic_query_result_event(peripheral, peripheral->characteristic_start_handle, peripheral->attribute_handle,
616         end_handle, peripheral->characteristic_properties, peripheral->uuid128);
617 
618     peripheral->characteristic_start_handle = 0;
619 }
620 
621 static void report_gatt_characteristics(gatt_client_t * peripheral, uint8_t * packet,  uint16_t size){
622     uint8_t attr_length = packet[1];
623     uint8_t uuid_length = attr_length - 5;
624     int i;
625     for (i = 2; i < size; i += attr_length){
626         uint16_t start_handle = little_endian_read_16(packet, i);
627         uint8_t  properties = packet[i+2];
628         uint16_t value_handle = little_endian_read_16(packet, i+3);
629         characteristic_end_found(peripheral, start_handle-1);
630         characteristic_start_found(peripheral, start_handle, properties, value_handle, &packet[i+5], uuid_length);
631     }
632 }
633 
634 static void report_gatt_included_service_uuid16(gatt_client_t * peripheral, uint16_t include_handle, uint16_t uuid16){
635     uint8_t normalized_uuid128[16];
636     uuid_add_bluetooth_prefix(normalized_uuid128, uuid16);
637     emit_gatt_included_service_query_result_event(peripheral, include_handle, peripheral->query_start_handle,
638         peripheral->query_end_handle, normalized_uuid128);
639 }
640 
641 static void report_gatt_included_service_uuid128(gatt_client_t * peripheral, uint16_t include_handle, uint8_t *uuid128){
642     emit_gatt_included_service_query_result_event(peripheral, include_handle, peripheral->query_start_handle,
643         peripheral->query_end_handle, uuid128);
644 }
645 
646 // @returns packet pointer
647 // @note assume that value is part of an l2cap buffer - overwrite HCI + L2CAP packet headers
648 static const int characteristic_value_event_header_size = 8;
649 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){
650     // before the value inside the ATT PDU
651     uint8_t * packet = value - characteristic_value_event_header_size;
652     packet[0] = type;
653     packet[1] = characteristic_value_event_header_size - 2 + length;
654     little_endian_store_16(packet, 2, con_handle);
655     little_endian_store_16(packet, 4, attribute_handle);
656     little_endian_store_16(packet, 6, length);
657     return packet;
658 }
659 
660 // @returns packet pointer
661 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
662 static const int long_characteristic_value_event_header_size = 10;
663 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){
664 #if defined(HCI_INCOMING_PRE_BUFFER_SIZE) && (HCI_INCOMING_PRE_BUFFER_SIZE >= 10 - 8) // L2CAP Header (4) - ACL Header (4)
665     // before the value inside the ATT PDU
666     uint8_t * packet = value - long_characteristic_value_event_header_size;
667     packet[0] = type;
668     packet[1] = long_characteristic_value_event_header_size - 2 + length;
669     little_endian_store_16(packet, 2, con_handle);
670     little_endian_store_16(packet, 4, attribute_handle);
671     little_endian_store_16(packet, 6, offset);
672     little_endian_store_16(packet, 8, length);
673     return packet;
674 #else
675     log_error("HCI_INCOMING_PRE_BUFFER_SIZE >= 2 required for long characteristic reads");
676     return NULL;
677 #endif
678 }
679 
680 
681 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
682 static void report_gatt_notification(hci_con_handle_t con_handle, uint16_t value_handle, uint8_t * value, int length){
683     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_NOTIFICATION, con_handle, value_handle, value, length);
684     emit_event_to_registered_listeners(con_handle, value_handle, packet, characteristic_value_event_header_size + length);
685 }
686 
687 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
688 static void report_gatt_indication(hci_con_handle_t con_handle, uint16_t value_handle, uint8_t * value, int length){
689     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_INDICATION, con_handle, value_handle, value, length);
690     emit_event_to_registered_listeners(con_handle, value_handle, packet, characteristic_value_event_header_size + length);
691 }
692 
693 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
694 static void report_gatt_characteristic_value(gatt_client_t * peripheral, uint16_t attribute_handle, uint8_t * value, uint16_t length){
695     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT, peripheral->con_handle, attribute_handle, value, length);
696     emit_event_new(peripheral->callback, packet, characteristic_value_event_header_size + length);
697 }
698 
699 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes
700 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){
701     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);
702     if (!packet) return;
703     emit_event_new(peripheral->callback, packet, blob_length + long_characteristic_value_event_header_size);
704 }
705 
706 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){
707     UNUSED(value_offset);
708     uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT, peripheral->con_handle, descriptor_handle, value, value_length);
709     emit_event_new(peripheral->callback, packet, value_length + 8);
710 }
711 
712 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){
713     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);
714     if (!packet) return;
715     emit_event_new(peripheral->callback, packet, blob_length + long_characteristic_value_event_header_size);
716 }
717 
718 static void report_gatt_all_characteristic_descriptors(gatt_client_t * peripheral, uint8_t * packet, uint16_t size, uint16_t pair_size){
719     int i;
720     for (i = 0; i<size; i+=pair_size){
721         uint16_t descriptor_handle = little_endian_read_16(packet,i);
722         uint8_t uuid128[16];
723         uint16_t uuid16 = 0;
724         if (pair_size == 4){
725             uuid16 = little_endian_read_16(packet,i+2);
726             uuid_add_bluetooth_prefix(uuid128, uuid16);
727         } else {
728             reverse_128(&packet[i+2], uuid128);
729         }
730         emit_gatt_all_characteristic_descriptors_result_event(peripheral, descriptor_handle, uuid128);
731     }
732 
733 }
734 
735 static int is_query_done(gatt_client_t * peripheral, uint16_t last_result_handle){
736     return last_result_handle >= peripheral->end_group_handle;
737 }
738 
739 static void trigger_next_query(gatt_client_t * peripheral, uint16_t last_result_handle, gatt_client_state_t next_query_state){
740     if (is_query_done(peripheral, last_result_handle)){
741         gatt_client_handle_transaction_complete(peripheral);
742         emit_gatt_complete_event(peripheral, 0);
743         return;
744     }
745     // next
746     peripheral->start_group_handle = last_result_handle + 1;
747     peripheral->gatt_client_state = next_query_state;
748 }
749 
750 static inline void trigger_next_included_service_query(gatt_client_t * peripheral, uint16_t last_result_handle){
751     trigger_next_query(peripheral, last_result_handle, P_W2_SEND_INCLUDED_SERVICE_QUERY);
752 }
753 
754 static inline void trigger_next_service_query(gatt_client_t * peripheral, uint16_t last_result_handle){
755     trigger_next_query(peripheral, last_result_handle, P_W2_SEND_SERVICE_QUERY);
756 }
757 
758 static inline void trigger_next_service_by_uuid_query(gatt_client_t * peripheral, uint16_t last_result_handle){
759     trigger_next_query(peripheral, last_result_handle, P_W2_SEND_SERVICE_WITH_UUID_QUERY);
760 }
761 
762 static inline void trigger_next_characteristic_query(gatt_client_t * peripheral, uint16_t last_result_handle){
763     if (is_query_done(peripheral, last_result_handle)){
764         // report last characteristic
765         characteristic_end_found(peripheral, peripheral->end_group_handle);
766     }
767     trigger_next_query(peripheral, last_result_handle, P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY);
768 }
769 
770 static inline void trigger_next_characteristic_descriptor_query(gatt_client_t * peripheral, uint16_t last_result_handle){
771     trigger_next_query(peripheral, last_result_handle, P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY);
772 }
773 
774 static inline void trigger_next_read_by_type_query(gatt_client_t * peripheral, uint16_t last_result_handle){
775     trigger_next_query(peripheral, last_result_handle, P_W2_SEND_READ_BY_TYPE_REQUEST);
776 }
777 
778 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){
779     peripheral->attribute_offset += write_blob_length(peripheral);
780     uint16_t next_blob_length =  write_blob_length(peripheral);
781 
782     if (next_blob_length == 0){
783         peripheral->gatt_client_state = done_state;
784         return;
785     }
786     peripheral->gatt_client_state = next_query_state;
787 }
788 
789 static inline void trigger_next_blob_query(gatt_client_t * peripheral, gatt_client_state_t next_query_state, uint16_t received_blob_length){
790 
791     uint16_t max_blob_length = peripheral_mtu(peripheral) - 1;
792     if (received_blob_length < max_blob_length){
793         gatt_client_handle_transaction_complete(peripheral);
794         emit_gatt_complete_event(peripheral, 0);
795         return;
796     }
797 
798     peripheral->attribute_offset += received_blob_length;
799     peripheral->gatt_client_state = next_query_state;
800 }
801 
802 
803 static int is_value_valid(gatt_client_t *peripheral, uint8_t *packet, uint16_t size){
804     uint16_t attribute_handle = little_endian_read_16(packet, 1);
805     uint16_t value_offset = little_endian_read_16(packet, 3);
806 
807     if (peripheral->attribute_handle != attribute_handle) return 0;
808     if (peripheral->attribute_offset != value_offset) return 0;
809     return memcmp(&peripheral->attribute_value[peripheral->attribute_offset], &packet[5], size-5) == 0;
810 }
811 
812 
813 static void gatt_client_run(void){
814 
815     btstack_linked_item_t *it;
816     for (it = (btstack_linked_item_t *) gatt_client_connections; it ; it = it->next){
817 
818         gatt_client_t * peripheral = (gatt_client_t *) it;
819 
820         if (!att_dispatch_client_can_send_now(peripheral->con_handle)) {
821             att_dispatch_client_request_can_send_now_event(peripheral->con_handle);
822             return;
823         }
824 
825         // log_info("- handle_peripheral_list, mtu state %u, client state %u", peripheral->mtu_state, peripheral->gatt_client_state);
826 
827         switch (peripheral->mtu_state) {
828             case SEND_MTU_EXCHANGE:{
829                 peripheral->mtu_state = SENT_MTU_EXCHANGE;
830                 att_exchange_mtu_request(peripheral->con_handle);
831                 return;
832             }
833             case SENT_MTU_EXCHANGE:
834                 return;
835             default:
836                 break;
837         }
838 
839         if (peripheral->send_confirmation){
840             peripheral->send_confirmation = 0;
841             att_confirmation(peripheral->con_handle);
842             return;
843         }
844 
845         // check MTU for writes
846         switch (peripheral->gatt_client_state){
847             case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE:
848             case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR:
849                 if (peripheral->attribute_length <= peripheral_mtu(peripheral) - 3) break;
850                 log_error("gatt_client_run: value len %u > MTU %u - 3\n", peripheral->attribute_length, peripheral_mtu(peripheral));
851                 gatt_client_handle_transaction_complete(peripheral);
852                 emit_gatt_complete_event(peripheral, ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH);
853                 return;
854             default:
855                 break;
856         }
857 
858         // log_info("gatt_client_state %u", peripheral->gatt_client_state);
859         switch (peripheral->gatt_client_state){
860             case P_W2_SEND_SERVICE_QUERY:
861                 peripheral->gatt_client_state = P_W4_SERVICE_QUERY_RESULT;
862                 send_gatt_services_request(peripheral);
863                 return;
864 
865             case P_W2_SEND_SERVICE_WITH_UUID_QUERY:
866                 peripheral->gatt_client_state = P_W4_SERVICE_WITH_UUID_RESULT;
867                 send_gatt_services_by_uuid_request(peripheral);
868                 return;
869 
870             case P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY:
871                 peripheral->gatt_client_state = P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT;
872                 send_gatt_characteristic_request(peripheral);
873                 return;
874 
875             case P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY:
876                 peripheral->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT;
877                 send_gatt_characteristic_request(peripheral);
878                 return;
879 
880             case P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY:
881                 peripheral->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT;
882                 send_gatt_characteristic_descriptor_request(peripheral);
883                 return;
884 
885             case P_W2_SEND_INCLUDED_SERVICE_QUERY:
886                 peripheral->gatt_client_state = P_W4_INCLUDED_SERVICE_QUERY_RESULT;
887                 send_gatt_included_service_request(peripheral);
888                 return;
889 
890             case P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY:
891                 peripheral->gatt_client_state = P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT;
892                 send_gatt_included_service_uuid_request(peripheral);
893                 return;
894 
895             case P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY:
896                 peripheral->gatt_client_state = P_W4_READ_CHARACTERISTIC_VALUE_RESULT;
897                 send_gatt_read_characteristic_value_request(peripheral);
898                 return;
899 
900             case P_W2_SEND_READ_BLOB_QUERY:
901                 peripheral->gatt_client_state = P_W4_READ_BLOB_RESULT;
902                 send_gatt_read_blob_request(peripheral);
903                 return;
904 
905             case P_W2_SEND_READ_BY_TYPE_REQUEST:
906                 peripheral->gatt_client_state = P_W4_READ_BY_TYPE_RESPONSE;
907                 send_gatt_read_by_type_request(peripheral);
908                 break;
909 
910             case P_W2_SEND_READ_MULTIPLE_REQUEST:
911                 peripheral->gatt_client_state = P_W4_READ_MULTIPLE_RESPONSE;
912                 send_gatt_read_multiple_request(peripheral);
913                 break;
914 
915             case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE:
916                 peripheral->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT;
917                 send_gatt_write_attribute_value_request(peripheral);
918                 return;
919 
920             case P_W2_PREPARE_WRITE:
921                 peripheral->gatt_client_state = P_W4_PREPARE_WRITE_RESULT;
922                 send_gatt_prepare_write_request(peripheral);
923                 return;
924 
925             case P_W2_PREPARE_WRITE_SINGLE:
926                 peripheral->gatt_client_state = P_W4_PREPARE_WRITE_SINGLE_RESULT;
927                 send_gatt_prepare_write_request(peripheral);
928                 return;
929 
930             case P_W2_PREPARE_RELIABLE_WRITE:
931                 peripheral->gatt_client_state = P_W4_PREPARE_RELIABLE_WRITE_RESULT;
932                 send_gatt_prepare_write_request(peripheral);
933                 return;
934 
935             case P_W2_EXECUTE_PREPARED_WRITE:
936                 peripheral->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_RESULT;
937                 send_gatt_execute_write_request(peripheral);
938                 return;
939 
940             case P_W2_CANCEL_PREPARED_WRITE:
941                 peripheral->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_RESULT;
942                 send_gatt_cancel_prepared_write_request(peripheral);
943                 return;
944 
945             case P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH:
946                 peripheral->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT;
947                 send_gatt_cancel_prepared_write_request(peripheral);
948                 return;
949 
950             case P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY:
951                 peripheral->gatt_client_state = P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT;
952                 send_gatt_read_client_characteristic_configuration_request(peripheral);
953                 return;
954 
955             case P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY:
956                 peripheral->gatt_client_state = P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT;
957                 send_gatt_read_characteristic_descriptor_request(peripheral);
958                 return;
959 
960             case P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY:
961                 peripheral->gatt_client_state = P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT;
962                 send_gatt_read_blob_request(peripheral);
963                 return;
964 
965             case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR:
966                 peripheral->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT;
967                 send_gatt_write_attribute_value_request(peripheral);
968                 return;
969 
970             case P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION:
971                 peripheral->gatt_client_state = P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT;
972                 send_gatt_write_client_characteristic_configuration_request(peripheral);
973                 return;
974 
975             case P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR:
976                 peripheral->gatt_client_state = P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT;
977                 send_gatt_prepare_write_request(peripheral);
978                 return;
979 
980             case P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR:
981                 peripheral->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT;
982                 send_gatt_execute_write_request(peripheral);
983                 return;
984 
985 #ifdef ENABLE_LE_SIGNED_WRITE
986             case P_W4_CMAC_READY:
987                 if (sm_cmac_ready()){
988                     sm_key_t csrk;
989                     le_device_db_local_csrk_get(peripheral->le_device_index, csrk);
990                     uint32_t sign_counter = le_device_db_local_counter_get(peripheral->le_device_index);
991                     peripheral->gatt_client_state = P_W4_CMAC_RESULT;
992                     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);
993                 }
994                 return;
995 
996             case P_W2_SEND_SIGNED_WRITE: {
997                 peripheral->gatt_client_state = P_W4_SEND_SINGED_WRITE_DONE;
998                 // bump local signing counter
999                 uint32_t sign_counter = le_device_db_local_counter_get(peripheral->le_device_index);
1000                 le_device_db_local_counter_set(peripheral->le_device_index, sign_counter + 1);
1001 
1002                 send_gatt_signed_write_request(peripheral, sign_counter);
1003                 peripheral->gatt_client_state = P_READY;
1004                 // finally, notifiy client that write is complete
1005                 gatt_client_handle_transaction_complete(peripheral);
1006                 return;
1007             }
1008 #endif
1009 
1010             default:
1011                 break;
1012         }
1013     }
1014 
1015 }
1016 
1017 static void gatt_client_report_error_if_pending(gatt_client_t *peripheral, uint8_t error_code) {
1018     if (is_ready(peripheral)) return;
1019     gatt_client_handle_transaction_complete(peripheral);
1020     emit_gatt_complete_event(peripheral, error_code);
1021 }
1022 
1023 static void gatt_client_hci_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
1024     UNUSED(channel);    // ok: handling own l2cap events
1025     UNUSED(size);       // ok: there is no channel
1026 
1027     if (packet_type != HCI_EVENT_PACKET) return;
1028 
1029     switch (hci_event_packet_get_type(packet)) {
1030         case HCI_EVENT_DISCONNECTION_COMPLETE:
1031         {
1032             log_info("GATT Client: HCI_EVENT_DISCONNECTION_COMPLETE");
1033             hci_con_handle_t con_handle = little_endian_read_16(packet,3);
1034             gatt_client_t * peripheral = get_gatt_client_context_for_handle(con_handle);
1035             if (!peripheral) break;
1036             gatt_client_report_error_if_pending(peripheral, ATT_ERROR_HCI_DISCONNECT_RECEIVED);
1037 
1038             btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) peripheral);
1039             btstack_memory_gatt_client_free(peripheral);
1040             break;
1041         }
1042         default:
1043             break;
1044     }
1045 
1046     gatt_client_run();
1047 }
1048 
1049 static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
1050 
1051     if (packet_type == HCI_EVENT_PACKET && packet[0] == L2CAP_EVENT_CAN_SEND_NOW){
1052         gatt_client_run();
1053     }
1054 
1055     if (packet_type != ATT_DATA_PACKET) return;
1056 
1057     // special cases: notifications don't need a context while indications motivate creating one
1058     gatt_client_t * peripheral;
1059     switch (packet[0]){
1060         case ATT_HANDLE_VALUE_NOTIFICATION:
1061             report_gatt_notification(handle, little_endian_read_16(packet,1), &packet[3], size-3);
1062             return;
1063         case ATT_HANDLE_VALUE_INDICATION:
1064             peripheral = provide_context_for_conn_handle(handle);
1065             break;
1066         default:
1067             peripheral = get_gatt_client_context_for_handle(handle);
1068             break;
1069     }
1070 
1071     if (!peripheral) return;
1072 
1073     switch (packet[0]){
1074         case ATT_EXCHANGE_MTU_RESPONSE:
1075         {
1076             uint16_t remote_rx_mtu = little_endian_read_16(packet, 1);
1077             uint16_t local_rx_mtu = l2cap_max_le_mtu();
1078             peripheral->mtu = remote_rx_mtu < local_rx_mtu ? remote_rx_mtu : local_rx_mtu;
1079             peripheral->mtu_state = MTU_EXCHANGED;
1080             emit_gatt_mtu_exchanged_result_event(peripheral, peripheral->mtu);
1081             break;
1082         }
1083         case ATT_READ_BY_GROUP_TYPE_RESPONSE:
1084             switch(peripheral->gatt_client_state){
1085                 case P_W4_SERVICE_QUERY_RESULT:
1086                     report_gatt_services(peripheral, packet, size);
1087                     trigger_next_service_query(peripheral, get_last_result_handle_from_service_list(packet, size));
1088                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1089                     break;
1090                 default:
1091                     break;
1092             }
1093             break;
1094         case ATT_HANDLE_VALUE_INDICATION:
1095             report_gatt_indication(handle, little_endian_read_16(packet,1), &packet[3], size-3);
1096             peripheral->send_confirmation = 1;
1097             break;
1098 
1099         case ATT_READ_BY_TYPE_RESPONSE:
1100             switch (peripheral->gatt_client_state){
1101                 case P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT:
1102                     report_gatt_characteristics(peripheral, packet, size);
1103                     trigger_next_characteristic_query(peripheral, get_last_result_handle_from_characteristics_list(packet, size));
1104                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR
1105                     break;
1106                 case P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT:
1107                     report_gatt_characteristics(peripheral, packet, size);
1108                     trigger_next_characteristic_query(peripheral, get_last_result_handle_from_characteristics_list(packet, size));
1109                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR
1110                     break;
1111                 case P_W4_INCLUDED_SERVICE_QUERY_RESULT:
1112                 {
1113                     uint16_t uuid16 = 0;
1114                     uint16_t pair_size = packet[1];
1115 
1116                     if (pair_size < 7){
1117                         // UUIDs not available, query first included service
1118                         peripheral->start_group_handle = little_endian_read_16(packet, 2); // ready for next query
1119                         peripheral->query_start_handle = little_endian_read_16(packet, 4);
1120                         peripheral->query_end_handle = little_endian_read_16(packet,6);
1121                         peripheral->gatt_client_state = P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY;
1122                         break;
1123                     }
1124 
1125                     uint16_t offset;
1126                     for (offset = 2; offset < size; offset += pair_size){
1127                         uint16_t include_handle = little_endian_read_16(packet, offset);
1128                         peripheral->query_start_handle = little_endian_read_16(packet,offset+2);
1129                         peripheral->query_end_handle = little_endian_read_16(packet,offset+4);
1130                         uuid16 = little_endian_read_16(packet, offset+6);
1131                         report_gatt_included_service_uuid16(peripheral, include_handle, uuid16);
1132                     }
1133 
1134                     trigger_next_included_service_query(peripheral, get_last_result_handle_from_included_services_list(packet, size));
1135                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1136                     break;
1137                 }
1138                 case P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT:
1139                     peripheral->client_characteristic_configuration_handle = little_endian_read_16(packet, 2);
1140                     peripheral->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
1141                     break;
1142                 case P_W4_READ_BY_TYPE_RESPONSE: {
1143                     uint16_t pair_size = packet[1];
1144                     uint16_t offset;
1145                     uint16_t last_result_handle = 0;
1146                     for (offset = 2; offset < size ; offset += pair_size){
1147                         uint16_t value_handle = little_endian_read_16(packet, offset);
1148                         report_gatt_characteristic_value(peripheral, value_handle, &packet[offset+2], pair_size-2);
1149                         last_result_handle = value_handle;
1150                     }
1151                     trigger_next_read_by_type_query(peripheral, last_result_handle);
1152                     break;
1153                 }
1154                 default:
1155                     break;
1156             }
1157             break;
1158         case ATT_READ_RESPONSE:
1159             switch (peripheral->gatt_client_state){
1160                 case P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT: {
1161                     uint8_t uuid128[16];
1162                     reverse_128(&packet[1], uuid128);
1163                     report_gatt_included_service_uuid128(peripheral, peripheral->start_group_handle, uuid128);
1164                     trigger_next_included_service_query(peripheral, peripheral->start_group_handle);
1165                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1166                     break;
1167                 }
1168                 case P_W4_READ_CHARACTERISTIC_VALUE_RESULT:
1169                     gatt_client_handle_transaction_complete(peripheral);
1170                     report_gatt_characteristic_value(peripheral, peripheral->attribute_handle, &packet[1], size-1);
1171                     emit_gatt_complete_event(peripheral, 0);
1172                     break;
1173 
1174                 case P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT:{
1175                     gatt_client_handle_transaction_complete(peripheral);
1176                     report_gatt_characteristic_descriptor(peripheral, peripheral->attribute_handle, &packet[1], size-1, 0);
1177                     emit_gatt_complete_event(peripheral, 0);
1178                     break;
1179                 }
1180                 default:
1181                     break;
1182             }
1183             break;
1184 
1185         case ATT_FIND_BY_TYPE_VALUE_RESPONSE:
1186         {
1187             uint8_t pair_size = 4;
1188             int i;
1189             uint16_t start_group_handle;
1190             uint16_t   end_group_handle= 0xffff; // asserts GATT_EVENT_QUERY_COMPLETE is emitted if no results
1191             for (i = 1; i<size; i+=pair_size){
1192                 start_group_handle = little_endian_read_16(packet,i);
1193                 end_group_handle = little_endian_read_16(packet,i+2);
1194                 emit_gatt_service_query_result_event(peripheral, start_group_handle, end_group_handle, peripheral->uuid128);
1195             }
1196             trigger_next_service_by_uuid_query(peripheral, end_group_handle);
1197             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1198             break;
1199         }
1200         case ATT_FIND_INFORMATION_REPLY:
1201         {
1202             uint8_t pair_size = 4;
1203             if (packet[1] == 2){
1204                 pair_size = 18;
1205             }
1206             uint16_t last_descriptor_handle = little_endian_read_16(packet, size - pair_size);
1207 
1208             report_gatt_all_characteristic_descriptors(peripheral, &packet[2], size-2, pair_size);
1209             trigger_next_characteristic_descriptor_query(peripheral, last_descriptor_handle);
1210             // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1211             break;
1212         }
1213 
1214         case ATT_WRITE_RESPONSE:
1215             switch (peripheral->gatt_client_state){
1216                 case P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT:
1217                     gatt_client_handle_transaction_complete(peripheral);
1218                     emit_gatt_complete_event(peripheral, 0);
1219                     break;
1220                 case P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT:
1221                     gatt_client_handle_transaction_complete(peripheral);
1222                     emit_gatt_complete_event(peripheral, 0);
1223                     break;
1224                 case P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
1225                     gatt_client_handle_transaction_complete(peripheral);
1226                     emit_gatt_complete_event(peripheral, 0);
1227                     break;
1228                 default:
1229                     break;
1230             }
1231             break;
1232 
1233         case ATT_READ_BLOB_RESPONSE:{
1234             uint16_t received_blob_length = size-1;
1235 
1236             switch(peripheral->gatt_client_state){
1237                 case P_W4_READ_BLOB_RESULT:
1238                     report_gatt_long_characteristic_value_blob(peripheral, peripheral->attribute_handle, &packet[1], received_blob_length, peripheral->attribute_offset);
1239                     trigger_next_blob_query(peripheral, P_W2_SEND_READ_BLOB_QUERY, received_blob_length);
1240                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1241                     break;
1242                 case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT:
1243                     report_gatt_long_characteristic_descriptor(peripheral, peripheral->attribute_handle,
1244                                                           &packet[1], received_blob_length,
1245                                                           peripheral->attribute_offset);
1246                     trigger_next_blob_query(peripheral, P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY, received_blob_length);
1247                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1248                     break;
1249                 default:
1250                     break;
1251             }
1252             break;
1253         }
1254         case ATT_PREPARE_WRITE_RESPONSE:
1255             switch (peripheral->gatt_client_state){
1256                 case P_W4_PREPARE_WRITE_SINGLE_RESULT:
1257                     gatt_client_handle_transaction_complete(peripheral);
1258                     if (is_value_valid(peripheral, packet, size)){
1259                         emit_gatt_complete_event(peripheral, 0);
1260                     } else {
1261                         emit_gatt_complete_event(peripheral, ATT_ERROR_DATA_MISMATCH);
1262                     }
1263                     break;
1264 
1265                 case P_W4_PREPARE_WRITE_RESULT:{
1266                     peripheral->attribute_offset = little_endian_read_16(packet, 3);
1267                     trigger_next_prepare_write_query(peripheral, P_W2_PREPARE_WRITE, P_W2_EXECUTE_PREPARED_WRITE);
1268                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1269                     break;
1270                 }
1271                 case P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:{
1272                     peripheral->attribute_offset = little_endian_read_16(packet, 3);
1273                     trigger_next_prepare_write_query(peripheral, P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR, P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR);
1274                     // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1275                     break;
1276                 }
1277                 case P_W4_PREPARE_RELIABLE_WRITE_RESULT:{
1278                     if (is_value_valid(peripheral, packet, size)){
1279                         peripheral->attribute_offset = little_endian_read_16(packet, 3);
1280                         trigger_next_prepare_write_query(peripheral, P_W2_PREPARE_RELIABLE_WRITE, P_W2_EXECUTE_PREPARED_WRITE);
1281                         // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1282                         break;
1283                     }
1284                     peripheral->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH;
1285                     break;
1286                 }
1287                 default:
1288                     break;
1289             }
1290             break;
1291 
1292         case ATT_EXECUTE_WRITE_RESPONSE:
1293             switch (peripheral->gatt_client_state){
1294                 case P_W4_EXECUTE_PREPARED_WRITE_RESULT:
1295                     gatt_client_handle_transaction_complete(peripheral);
1296                     emit_gatt_complete_event(peripheral, 0);
1297                     break;
1298                 case P_W4_CANCEL_PREPARED_WRITE_RESULT:
1299                     gatt_client_handle_transaction_complete(peripheral);
1300                     emit_gatt_complete_event(peripheral, 0);
1301                     break;
1302                 case P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT:
1303                     gatt_client_handle_transaction_complete(peripheral);
1304                     emit_gatt_complete_event(peripheral, ATT_ERROR_DATA_MISMATCH);
1305                     break;
1306                 case P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
1307                     gatt_client_handle_transaction_complete(peripheral);
1308                     emit_gatt_complete_event(peripheral, 0);
1309                     break;
1310                 default:
1311                     break;
1312 
1313             }
1314             break;
1315 
1316         case ATT_READ_MULTIPLE_RESPONSE:
1317             switch(peripheral->gatt_client_state){
1318                 case P_W4_READ_MULTIPLE_RESPONSE:
1319                     report_gatt_characteristic_value(peripheral, 0, &packet[1], size-1);
1320                     gatt_client_handle_transaction_complete(peripheral);
1321                     emit_gatt_complete_event(peripheral, 0);
1322                     break;
1323                 default:
1324                     break;
1325             }
1326             break;
1327 
1328         case ATT_ERROR_RESPONSE:
1329 
1330             switch (packet[4]){
1331                 case ATT_ERROR_ATTRIBUTE_NOT_FOUND: {
1332                     switch(peripheral->gatt_client_state){
1333                         case P_W4_SERVICE_QUERY_RESULT:
1334                         case P_W4_SERVICE_WITH_UUID_RESULT:
1335                         case P_W4_INCLUDED_SERVICE_QUERY_RESULT:
1336                         case P_W4_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT:
1337                             gatt_client_handle_transaction_complete(peripheral);
1338                             emit_gatt_complete_event(peripheral, 0);
1339                             break;
1340                         case P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT:
1341                         case P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT:
1342                             characteristic_end_found(peripheral, peripheral->end_group_handle);
1343                             gatt_client_handle_transaction_complete(peripheral);
1344                             emit_gatt_complete_event(peripheral, 0);
1345                             break;
1346                         case P_W4_READ_BY_TYPE_RESPONSE:
1347                             gatt_client_handle_transaction_complete(peripheral);
1348                             if (peripheral->start_group_handle == peripheral->query_start_handle){
1349                                 emit_gatt_complete_event(peripheral, ATT_ERROR_ATTRIBUTE_NOT_FOUND);
1350                             } else {
1351                                 emit_gatt_complete_event(peripheral, 0);
1352                             }
1353                             break;
1354                         default:
1355                             gatt_client_report_error_if_pending(peripheral, packet[4]);
1356                             break;
1357                     }
1358                     break;
1359                 }
1360                 default:
1361                     gatt_client_report_error_if_pending(peripheral, packet[4]);
1362                     break;
1363             }
1364             break;
1365 
1366         default:
1367             log_info("ATT Handler, unhandled response type 0x%02x", packet[0]);
1368             break;
1369     }
1370     gatt_client_run();
1371 }
1372 
1373 #ifdef ENABLE_LE_SIGNED_WRITE
1374 static void att_signed_write_handle_cmac_result(uint8_t hash[8]){
1375     btstack_linked_list_iterator_t it;
1376     btstack_linked_list_iterator_init(&it, &gatt_client_connections);
1377     while (btstack_linked_list_iterator_has_next(&it)){
1378         gatt_client_t * peripheral = (gatt_client_t *) btstack_linked_list_iterator_next(&it);
1379         if (peripheral->gatt_client_state == P_W4_CMAC_RESULT){
1380             // store result
1381             memcpy(peripheral->cmac, hash, 8);
1382             // reverse_64(hash, peripheral->cmac);
1383             peripheral->gatt_client_state = P_W2_SEND_SIGNED_WRITE;
1384             gatt_client_run();
1385             return;
1386         }
1387     }
1388 }
1389 
1390 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){
1391     gatt_client_t * peripheral = provide_context_for_conn_handle(con_handle);
1392     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1393     peripheral->le_device_index = sm_le_device_index(con_handle);
1394     if (peripheral->le_device_index < 0) return GATT_CLIENT_IN_WRONG_STATE; // device lookup not done / no stored bonding information
1395 
1396     peripheral->callback = callback;
1397     peripheral->attribute_handle = handle;
1398     peripheral->attribute_length = message_len;
1399     peripheral->attribute_value = message;
1400     peripheral->gatt_client_state = P_W4_CMAC_READY;
1401 
1402     gatt_client_run();
1403     return 0;
1404 }
1405 #endif
1406 
1407 uint8_t gatt_client_discover_primary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
1408     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1409     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1410     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1411 
1412     peripheral->callback = callback;
1413     peripheral->start_group_handle = 0x0001;
1414     peripheral->end_group_handle   = 0xffff;
1415     peripheral->gatt_client_state = P_W2_SEND_SERVICE_QUERY;
1416     peripheral->uuid16 = 0;
1417     gatt_client_run();
1418     return 0;
1419 }
1420 
1421 
1422 uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16){
1423     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1424 
1425     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1426     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1427 
1428     peripheral->callback = callback;
1429     peripheral->start_group_handle = 0x0001;
1430     peripheral->end_group_handle   = 0xffff;
1431     peripheral->gatt_client_state = P_W2_SEND_SERVICE_WITH_UUID_QUERY;
1432     peripheral->uuid16 = uuid16;
1433     uuid_add_bluetooth_prefix((uint8_t*) &(peripheral->uuid128), peripheral->uuid16);
1434     gatt_client_run();
1435     return 0;
1436 }
1437 
1438 uint8_t gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, const uint8_t * uuid128){
1439     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1440 
1441     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1442     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1443 
1444     peripheral->callback = callback;
1445     peripheral->start_group_handle = 0x0001;
1446     peripheral->end_group_handle   = 0xffff;
1447     peripheral->uuid16 = 0;
1448     memcpy(peripheral->uuid128, uuid128, 16);
1449     peripheral->gatt_client_state = P_W2_SEND_SERVICE_WITH_UUID_QUERY;
1450     gatt_client_run();
1451     return 0;
1452 }
1453 
1454 uint8_t gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t *service){
1455     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1456 
1457     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1458     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1459 
1460     peripheral->callback = callback;
1461     peripheral->start_group_handle = service->start_group_handle;
1462     peripheral->end_group_handle   = service->end_group_handle;
1463     peripheral->filter_with_uuid = 0;
1464     peripheral->characteristic_start_handle = 0;
1465     peripheral->gatt_client_state = P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY;
1466     gatt_client_run();
1467     return 0;
1468 }
1469 
1470 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){
1471     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1472 
1473     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1474     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1475 
1476     peripheral->callback = callback;
1477     peripheral->start_group_handle = service->start_group_handle;
1478     peripheral->end_group_handle   = service->end_group_handle;
1479     peripheral->gatt_client_state = P_W2_SEND_INCLUDED_SERVICE_QUERY;
1480 
1481     gatt_client_run();
1482     return 0;
1483 }
1484 
1485 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){
1486     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1487 
1488     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1489     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1490 
1491     peripheral->callback = callback;
1492     peripheral->start_group_handle = start_handle;
1493     peripheral->end_group_handle   = end_handle;
1494     peripheral->filter_with_uuid = 1;
1495     peripheral->uuid16 = uuid16;
1496     uuid_add_bluetooth_prefix((uint8_t*) &(peripheral->uuid128), uuid16);
1497     peripheral->characteristic_start_handle = 0;
1498     peripheral->gatt_client_state = P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY;
1499 
1500     gatt_client_run();
1501     return 0;
1502 }
1503 
1504 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){
1505     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1506 
1507     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1508     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1509 
1510     peripheral->callback = callback;
1511     peripheral->start_group_handle = start_handle;
1512     peripheral->end_group_handle   = end_handle;
1513     peripheral->filter_with_uuid = 1;
1514     peripheral->uuid16 = 0;
1515     memcpy(peripheral->uuid128, uuid128, 16);
1516     peripheral->characteristic_start_handle = 0;
1517     peripheral->gatt_client_state = P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY;
1518 
1519     gatt_client_run();
1520     return 0;
1521 }
1522 
1523 
1524 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){
1525     return gatt_client_discover_characteristics_for_handle_range_by_uuid16(callback, handle, service->start_group_handle, service->end_group_handle, uuid16);
1526 }
1527 
1528 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){
1529     return gatt_client_discover_characteristics_for_handle_range_by_uuid128(callback, handle, service->start_group_handle, service->end_group_handle, uuid128);
1530 }
1531 
1532 uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t *characteristic){
1533     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1534 
1535     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1536     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1537 
1538     if (characteristic->value_handle == characteristic->end_handle){
1539         emit_gatt_complete_event(peripheral, 0);
1540         return 0;
1541     }
1542     peripheral->callback = callback;
1543     peripheral->start_group_handle = characteristic->value_handle + 1;
1544     peripheral->end_group_handle   = characteristic->end_handle;
1545     peripheral->gatt_client_state = P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY;
1546 
1547     gatt_client_run();
1548     return 0;
1549 }
1550 
1551 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){
1552     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1553 
1554     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1555     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1556 
1557     peripheral->callback = callback;
1558     peripheral->attribute_handle = value_handle;
1559     peripheral->attribute_offset = 0;
1560     peripheral->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY;
1561     gatt_client_run();
1562     return 0;
1563 }
1564 
1565 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){
1566     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1567 
1568     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1569     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1570 
1571     peripheral->callback = callback;
1572     peripheral->start_group_handle = start_handle;
1573     peripheral->end_group_handle = end_handle;
1574     peripheral->query_start_handle = start_handle;
1575     peripheral->query_end_handle = end_handle;
1576     peripheral->uuid16 = uuid16;
1577     uuid_add_bluetooth_prefix((uint8_t*) &(peripheral->uuid128), uuid16);
1578     peripheral->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
1579     gatt_client_run();
1580     return 0;
1581 }
1582 
1583 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){
1584     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1585 
1586     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1587     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1588 
1589     peripheral->callback = callback;
1590     peripheral->start_group_handle = start_handle;
1591     peripheral->end_group_handle = end_handle;
1592     peripheral->query_start_handle = start_handle;
1593     peripheral->query_end_handle = end_handle;
1594     peripheral->uuid16 = 0;
1595     memcpy(peripheral->uuid128, uuid128, 16);
1596     peripheral->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
1597     gatt_client_run();
1598     return 0;
1599 }
1600 
1601 
1602 uint8_t gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback, uint16_t handle, gatt_client_characteristic_t *characteristic){
1603     return gatt_client_read_value_of_characteristic_using_value_handle(callback, handle, characteristic->value_handle);
1604 }
1605 
1606 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){
1607     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1608 
1609     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1610     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1611 
1612     peripheral->callback = callback;
1613     peripheral->attribute_handle = characteristic_value_handle;
1614     peripheral->attribute_offset = offset;
1615     peripheral->gatt_client_state = P_W2_SEND_READ_BLOB_QUERY;
1616     gatt_client_run();
1617     return 0;
1618 }
1619 
1620 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){
1621     return gatt_client_read_long_value_of_characteristic_using_value_handle_with_offset(callback, con_handle, characteristic_value_handle, 0);
1622 }
1623 
1624 uint8_t gatt_client_read_long_value_of_characteristic(btstack_packet_handler_t callback, uint16_t handle, gatt_client_characteristic_t *characteristic){
1625     return gatt_client_read_long_value_of_characteristic_using_value_handle(callback, handle, characteristic->value_handle);
1626 }
1627 
1628 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){
1629     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1630 
1631     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1632     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1633 
1634     peripheral->callback = callback;
1635     peripheral->read_multiple_handle_count = num_value_handles;
1636     peripheral->read_multiple_handles = value_handles;
1637     peripheral->gatt_client_state = P_W2_SEND_READ_MULTIPLE_REQUEST;
1638     gatt_client_run();
1639     return 0;
1640 }
1641 
1642 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){
1643     gatt_client_t * peripheral = provide_context_for_conn_handle(con_handle);
1644 
1645     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1646     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1647 
1648     if (value_length > peripheral_mtu(peripheral) - 3) return GATT_CLIENT_VALUE_TOO_LONG;
1649     if (!att_dispatch_client_can_send_now(peripheral->con_handle)) return GATT_CLIENT_BUSY;
1650 
1651     att_write_request(ATT_WRITE_COMMAND, peripheral->con_handle, value_handle, value_length, value);
1652     return 0;
1653 }
1654 
1655 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){
1656     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1657 
1658     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1659     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1660 
1661     peripheral->callback = callback;
1662     peripheral->attribute_handle = value_handle;
1663     peripheral->attribute_length = value_length;
1664     peripheral->attribute_value = data;
1665     peripheral->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_VALUE;
1666     gatt_client_run();
1667     return 0;
1668 }
1669 
1670 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){
1671     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1672 
1673     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1674     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1675 
1676     peripheral->callback = callback;
1677     peripheral->attribute_handle = value_handle;
1678     peripheral->attribute_length = value_length;
1679     peripheral->attribute_offset = offset;
1680     peripheral->attribute_value = data;
1681     peripheral->gatt_client_state = P_W2_PREPARE_WRITE;
1682     gatt_client_run();
1683     return 0;
1684 }
1685 
1686 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){
1687     return gatt_client_write_long_value_of_characteristic_with_offset(callback, con_handle, value_handle, 0, value_length, value);
1688 }
1689 
1690 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){
1691     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1692 
1693     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1694     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1695 
1696     peripheral->callback = callback;
1697     peripheral->attribute_handle = value_handle;
1698     peripheral->attribute_length = value_length;
1699     peripheral->attribute_offset = 0;
1700     peripheral->attribute_value = value;
1701     peripheral->gatt_client_state = P_W2_PREPARE_RELIABLE_WRITE;
1702     gatt_client_run();
1703     return 0;
1704 }
1705 
1706 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){
1707     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1708 
1709     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1710     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1711 
1712     if ( (configuration & GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION) &&
1713         (characteristic->properties & ATT_PROPERTY_NOTIFY) == 0) {
1714         log_info("gatt_client_write_client_characteristic_configuration: GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED");
1715         return GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED;
1716     } else if ( (configuration & GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION) &&
1717                (characteristic->properties & ATT_PROPERTY_INDICATE) == 0){
1718         log_info("gatt_client_write_client_characteristic_configuration: GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED");
1719         return GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED;
1720     }
1721 
1722     peripheral->callback = callback;
1723     peripheral->start_group_handle = characteristic->value_handle;
1724     peripheral->end_group_handle = characteristic->end_handle;
1725     little_endian_store_16(peripheral->client_characteristic_configuration_value, 0, configuration);
1726 
1727     peripheral->gatt_client_state = P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY;
1728     gatt_client_run();
1729     return 0;
1730 }
1731 
1732 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){
1733     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1734 
1735     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1736     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1737 
1738     peripheral->callback = callback;
1739     peripheral->attribute_handle = descriptor_handle;
1740 
1741     peripheral->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY;
1742     gatt_client_run();
1743     return 0;
1744 }
1745 
1746 uint8_t gatt_client_read_characteristic_descriptor(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_descriptor_t * descriptor){
1747     return gatt_client_read_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle);
1748 }
1749 
1750 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){
1751     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1752 
1753     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1754     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1755 
1756     peripheral->callback = callback;
1757     peripheral->attribute_handle = descriptor_handle;
1758     peripheral->attribute_offset = offset;
1759     peripheral->gatt_client_state = P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY;
1760     gatt_client_run();
1761     return 0;
1762 }
1763 
1764 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){
1765     return gatt_client_read_long_characteristic_descriptor_using_descriptor_handle_with_offset(callback, con_handle, descriptor_handle, 0);
1766 }
1767 
1768 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){
1769     return gatt_client_read_long_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle);
1770 }
1771 
1772 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){
1773     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1774 
1775     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1776     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1777 
1778     peripheral->callback = callback;
1779     peripheral->attribute_handle = descriptor_handle;
1780     peripheral->attribute_length = length;
1781     peripheral->attribute_offset = 0;
1782     peripheral->attribute_value = data;
1783     peripheral->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR;
1784     gatt_client_run();
1785     return 0;
1786 }
1787 
1788 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){
1789     return gatt_client_write_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle, length, value);
1790 }
1791 
1792 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){
1793     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1794 
1795     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1796     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1797 
1798     peripheral->callback = callback;
1799     peripheral->attribute_handle = descriptor_handle;
1800     peripheral->attribute_length = length;
1801     peripheral->attribute_offset = offset;
1802     peripheral->attribute_value = data;
1803     peripheral->gatt_client_state = P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR;
1804     gatt_client_run();
1805     return 0;
1806 }
1807 
1808 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){
1809     return gatt_client_write_long_characteristic_descriptor_using_descriptor_handle_with_offset(callback, con_handle, descriptor_handle, 0, length, data );
1810 }
1811 
1812 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){
1813     return gatt_client_write_long_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle, length, value);
1814 }
1815 
1816 /**
1817  * @brief -> gatt complete event
1818  */
1819 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){
1820     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1821 
1822     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1823     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1824 
1825     peripheral->callback = callback;
1826     peripheral->attribute_handle = attribute_handle;
1827     peripheral->attribute_length = length;
1828     peripheral->attribute_offset = offset;
1829     peripheral->attribute_value = data;
1830     peripheral->gatt_client_state = P_W2_PREPARE_WRITE_SINGLE;
1831     gatt_client_run();
1832     return 0;
1833 }
1834 
1835 /**
1836  * @brief -> gatt complete event
1837  */
1838 uint8_t gatt_client_execute_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
1839     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1840 
1841     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1842     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1843 
1844     peripheral->callback = callback;
1845     peripheral->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE;
1846     gatt_client_run();
1847     return 0;
1848 }
1849 
1850 /**
1851  * @brief -> gatt complete event
1852  */
1853 uint8_t gatt_client_cancel_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle){
1854     gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
1855 
1856     if (!peripheral) return BTSTACK_MEMORY_ALLOC_FAILED;
1857     if (!is_ready(peripheral)) return GATT_CLIENT_IN_WRONG_STATE;
1858 
1859     peripheral->callback = callback;
1860     peripheral->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE;
1861     gatt_client_run();
1862     return 0;
1863 }
1864 
1865 void gatt_client_pts_suppress_mtu_exchange(void){
1866     pts_suppress_mtu_exchange = 1;
1867 }
1868 
1869 void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t *service){
1870     service->start_group_handle = little_endian_read_16(packet, offset);
1871     service->end_group_handle = little_endian_read_16(packet, offset + 2);
1872     reverse_128(&packet[offset + 4], service->uuid128);
1873     if (uuid_has_bluetooth_prefix(service->uuid128)){
1874         service->uuid16 = big_endian_read_32(service->uuid128, 0);
1875     }
1876 }
1877 
1878 void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic){
1879     characteristic->start_handle = little_endian_read_16(packet, offset);
1880     characteristic->value_handle = little_endian_read_16(packet, offset + 2);
1881     characteristic->end_handle = little_endian_read_16(packet, offset + 4);
1882     characteristic->properties = little_endian_read_16(packet, offset + 6);
1883     reverse_128(&packet[offset+8], characteristic->uuid128);
1884     if (uuid_has_bluetooth_prefix(characteristic->uuid128)){
1885         characteristic->uuid16 = big_endian_read_32(characteristic->uuid128, 0);
1886     }
1887 }
1888 
1889 void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor){
1890     descriptor->handle = little_endian_read_16(packet, offset);
1891     reverse_128(&packet[offset+2], descriptor->uuid128);
1892     if (uuid_has_bluetooth_prefix(descriptor->uuid128)){
1893         descriptor->uuid16 = big_endian_read_32(descriptor->uuid128, 0);
1894     }
1895 }
1896