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