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