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