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