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