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 UNUSED(con_handle); 738 return true; 739 #endif 740 } 741 742 743 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes 744 static void report_gatt_notification(hci_con_handle_t con_handle, uint16_t value_handle, uint8_t * value, int length){ 745 if (!gatt_client_accept_server_message(con_handle)) return; 746 uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_NOTIFICATION, con_handle, value_handle, value, length); 747 emit_event_to_registered_listeners(con_handle, value_handle, packet, characteristic_value_event_header_size + length); 748 } 749 750 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes 751 static void report_gatt_indication(hci_con_handle_t con_handle, uint16_t value_handle, uint8_t * value, int length){ 752 if (!gatt_client_accept_server_message(con_handle)) return; 753 uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_INDICATION, con_handle, value_handle, value, length); 754 emit_event_to_registered_listeners(con_handle, value_handle, packet, characteristic_value_event_header_size + length); 755 } 756 757 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes 758 static void report_gatt_characteristic_value(gatt_client_t * gatt_client, uint16_t attribute_handle, uint8_t * value, uint16_t length){ 759 uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT, gatt_client->con_handle, attribute_handle, value, length); 760 emit_event_new(gatt_client->callback, packet, characteristic_value_event_header_size + length); 761 } 762 763 // @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes 764 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){ 765 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); 766 if (!packet) return; 767 emit_event_new(gatt_client->callback, packet, blob_length + long_characteristic_value_event_header_size); 768 } 769 770 static void report_gatt_characteristic_descriptor(gatt_client_t * gatt_client, uint16_t descriptor_handle, uint8_t *value, uint16_t value_length, uint16_t value_offset){ 771 UNUSED(value_offset); 772 uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT, gatt_client->con_handle, descriptor_handle, value, value_length); 773 emit_event_new(gatt_client->callback, packet, value_length + 8u); 774 } 775 776 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){ 777 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); 778 if (!packet) return; 779 emit_event_new(gatt_client->callback, packet, blob_length + long_characteristic_value_event_header_size); 780 } 781 782 static void report_gatt_all_characteristic_descriptors(gatt_client_t * gatt_client, uint8_t * packet, uint16_t size, uint16_t pair_size){ 783 int i; 784 for (i = 0u; (i + pair_size) <= size; i += pair_size){ 785 uint16_t descriptor_handle = little_endian_read_16(packet,i); 786 uint8_t uuid128[16]; 787 uint16_t uuid16 = 0; 788 if (pair_size == 4u){ 789 uuid16 = little_endian_read_16(packet,i+2); 790 uuid_add_bluetooth_prefix(uuid128, uuid16); 791 } else { 792 reverse_128(&packet[i+2], uuid128); 793 } 794 emit_gatt_all_characteristic_descriptors_result_event(gatt_client, descriptor_handle, uuid128); 795 } 796 797 } 798 799 static int is_query_done(gatt_client_t * gatt_client, uint16_t last_result_handle){ 800 return last_result_handle >= gatt_client->end_group_handle; 801 } 802 803 static void trigger_next_query(gatt_client_t * gatt_client, uint16_t last_result_handle, gatt_client_state_t next_query_state){ 804 if (is_query_done(gatt_client, last_result_handle)){ 805 gatt_client_handle_transaction_complete(gatt_client); 806 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 807 return; 808 } 809 // next 810 gatt_client->start_group_handle = last_result_handle + 1u; 811 gatt_client->gatt_client_state = next_query_state; 812 } 813 814 static void trigger_next_included_service_query(gatt_client_t * gatt_client, uint16_t last_result_handle){ 815 trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_INCLUDED_SERVICE_QUERY); 816 } 817 818 static void trigger_next_service_query(gatt_client_t * gatt_client, uint16_t last_result_handle){ 819 trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_SERVICE_QUERY); 820 } 821 822 static void trigger_next_service_by_uuid_query(gatt_client_t * gatt_client, uint16_t last_result_handle){ 823 trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_SERVICE_WITH_UUID_QUERY); 824 } 825 826 static void trigger_next_characteristic_query(gatt_client_t * gatt_client, uint16_t last_result_handle){ 827 if (is_query_done(gatt_client, last_result_handle)){ 828 // report last characteristic 829 characteristic_end_found(gatt_client, gatt_client->end_group_handle); 830 } 831 trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY); 832 } 833 834 static void trigger_next_characteristic_descriptor_query(gatt_client_t * gatt_client, uint16_t last_result_handle){ 835 trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY); 836 } 837 838 static void trigger_next_read_by_type_query(gatt_client_t * gatt_client, uint16_t last_result_handle){ 839 trigger_next_query(gatt_client, last_result_handle, P_W2_SEND_READ_BY_TYPE_REQUEST); 840 } 841 842 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){ 843 gatt_client->attribute_offset += write_blob_length(gatt_client); 844 uint16_t next_blob_length = write_blob_length(gatt_client); 845 846 if (next_blob_length == 0u){ 847 gatt_client->gatt_client_state = done_state; 848 return; 849 } 850 gatt_client->gatt_client_state = next_query_state; 851 } 852 853 static void trigger_next_blob_query(gatt_client_t * gatt_client, gatt_client_state_t next_query_state, uint16_t received_blob_length){ 854 855 uint16_t max_blob_length = gatt_client->mtu - 1u; 856 if (received_blob_length < max_blob_length){ 857 gatt_client_handle_transaction_complete(gatt_client); 858 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 859 return; 860 } 861 862 gatt_client->attribute_offset += received_blob_length; 863 gatt_client->gatt_client_state = next_query_state; 864 } 865 866 867 static int is_value_valid(gatt_client_t *gatt_client, uint8_t *packet, uint16_t size){ 868 uint16_t attribute_handle = little_endian_read_16(packet, 1); 869 uint16_t value_offset = little_endian_read_16(packet, 3); 870 871 if (gatt_client->attribute_handle != attribute_handle) return 0; 872 if (gatt_client->attribute_offset != value_offset) return 0; 873 return memcmp(&gatt_client->attribute_value[gatt_client->attribute_offset], &packet[5], size - 5u) == 0u; 874 } 875 876 // returns 1 if packet was sent 877 static int gatt_client_run_for_gatt_client(gatt_client_t * gatt_client){ 878 879 // wait until re-encryption as central is complete 880 if (gap_reconnect_security_setup_active(gatt_client->con_handle)) return 0; 881 882 #ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 883 // wait until re-encryption complete 884 if (gatt_client->reencryption_active) return 0; 885 886 // report bonding information missing, if re-encryption failed 887 if ((gatt_client->reencryption_result != ERROR_CODE_SUCCESS) && (gatt_client->gatt_client_state != P_READY)){ 888 gatt_client_handle_transaction_complete(gatt_client); 889 emit_gatt_complete_event(gatt_client, ATT_ERROR_BONDING_INFORMATION_MISSING); 890 return 0; 891 } 892 #endif 893 894 // wait until pairing complete (either reactive authentication or due to required security level) 895 if (gatt_client->wait_for_pairing_complete) return 0; 896 897 // verify security level 898 if (gatt_client_required_security_level > gatt_client->security_level){ 899 log_info("Trigger pairing, current security level %u, required %u\n", gatt_client->security_level, gatt_client_required_security_level); 900 gatt_client->wait_for_pairing_complete = 1; 901 // set att error code for pairing failure based on required level 902 switch (gatt_client_required_security_level){ 903 case LEVEL_4: 904 case LEVEL_3: 905 gatt_client->pending_error_code = ATT_ERROR_INSUFFICIENT_AUTHENTICATION; 906 break; 907 default: 908 gatt_client->pending_error_code = ATT_ERROR_INSUFFICIENT_ENCRYPTION; 909 break; 910 } 911 sm_request_pairing(gatt_client->con_handle); 912 // sm probably just sent a pdu 913 return 1; 914 } 915 916 switch (gatt_client->mtu_state) { 917 case SEND_MTU_EXCHANGE: 918 gatt_client->mtu_state = SENT_MTU_EXCHANGE; 919 att_exchange_mtu_request(gatt_client->con_handle); 920 return 1; 921 case SENT_MTU_EXCHANGE: 922 return 0; 923 default: 924 break; 925 } 926 927 if (gatt_client->send_confirmation){ 928 gatt_client->send_confirmation = 0; 929 att_confirmation(gatt_client->con_handle); 930 return 1; 931 } 932 933 // check MTU for writes 934 switch (gatt_client->gatt_client_state){ 935 case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE: 936 case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR: 937 if (gatt_client->attribute_length <= (gatt_client->mtu - 3u)) break; 938 log_error("gatt_client_run: value len %u > MTU %u - 3\n", gatt_client->attribute_length,gatt_client->mtu); 939 gatt_client_handle_transaction_complete(gatt_client); 940 emit_gatt_complete_event(gatt_client, ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH); 941 return 0; 942 default: 943 break; 944 } 945 946 switch (gatt_client->gatt_client_state){ 947 case P_W2_SEND_SERVICE_QUERY: 948 gatt_client->gatt_client_state = P_W4_SERVICE_QUERY_RESULT; 949 send_gatt_services_request(gatt_client); 950 return 1; 951 952 case P_W2_SEND_SERVICE_WITH_UUID_QUERY: 953 gatt_client->gatt_client_state = P_W4_SERVICE_WITH_UUID_RESULT; 954 send_gatt_services_by_uuid_request(gatt_client); 955 return 1; 956 957 case P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY: 958 gatt_client->gatt_client_state = P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT; 959 send_gatt_characteristic_request(gatt_client); 960 return 1; 961 962 case P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY: 963 gatt_client->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT; 964 send_gatt_characteristic_request(gatt_client); 965 return 1; 966 967 case P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY: 968 gatt_client->gatt_client_state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT; 969 send_gatt_characteristic_descriptor_request(gatt_client); 970 return 1; 971 972 case P_W2_SEND_INCLUDED_SERVICE_QUERY: 973 gatt_client->gatt_client_state = P_W4_INCLUDED_SERVICE_QUERY_RESULT; 974 send_gatt_included_service_request(gatt_client); 975 return 1; 976 977 case P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY: 978 gatt_client->gatt_client_state = P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT; 979 send_gatt_included_service_uuid_request(gatt_client); 980 return 1; 981 982 case P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY: 983 gatt_client->gatt_client_state = P_W4_READ_CHARACTERISTIC_VALUE_RESULT; 984 send_gatt_read_characteristic_value_request(gatt_client); 985 return 1; 986 987 case P_W2_SEND_READ_BLOB_QUERY: 988 gatt_client->gatt_client_state = P_W4_READ_BLOB_RESULT; 989 send_gatt_read_blob_request(gatt_client); 990 return 1; 991 992 case P_W2_SEND_READ_BY_TYPE_REQUEST: 993 gatt_client->gatt_client_state = P_W4_READ_BY_TYPE_RESPONSE; 994 send_gatt_read_by_type_request(gatt_client); 995 return 1; 996 997 case P_W2_SEND_READ_MULTIPLE_REQUEST: 998 gatt_client->gatt_client_state = P_W4_READ_MULTIPLE_RESPONSE; 999 send_gatt_read_multiple_request(gatt_client); 1000 return 1; 1001 1002 case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE: 1003 gatt_client->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT; 1004 send_gatt_write_attribute_value_request(gatt_client); 1005 return 1; 1006 1007 case P_W2_PREPARE_WRITE: 1008 gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_RESULT; 1009 send_gatt_prepare_write_request(gatt_client); 1010 return 1; 1011 1012 case P_W2_PREPARE_WRITE_SINGLE: 1013 gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_SINGLE_RESULT; 1014 send_gatt_prepare_write_request(gatt_client); 1015 return 1; 1016 1017 case P_W2_PREPARE_RELIABLE_WRITE: 1018 gatt_client->gatt_client_state = P_W4_PREPARE_RELIABLE_WRITE_RESULT; 1019 send_gatt_prepare_write_request(gatt_client); 1020 return 1; 1021 1022 case P_W2_EXECUTE_PREPARED_WRITE: 1023 gatt_client->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_RESULT; 1024 send_gatt_execute_write_request(gatt_client); 1025 return 1; 1026 1027 case P_W2_CANCEL_PREPARED_WRITE: 1028 gatt_client->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_RESULT; 1029 send_gatt_cancel_prepared_write_request(gatt_client); 1030 return 1; 1031 1032 case P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH: 1033 gatt_client->gatt_client_state = P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT; 1034 send_gatt_cancel_prepared_write_request(gatt_client); 1035 return 1; 1036 1037 #ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY 1038 case P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY: 1039 // use Find Information 1040 gatt_client->gatt_client_state = P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT; 1041 send_gatt_characteristic_descriptor_request(gatt_client); 1042 #else 1043 case P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY: 1044 // Use Read By Type 1045 gatt_client->gatt_client_state = P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT; 1046 send_gatt_read_client_characteristic_configuration_request(gatt_client); 1047 #endif 1048 return 1; 1049 1050 case P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY: 1051 gatt_client->gatt_client_state = P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT; 1052 send_gatt_read_characteristic_descriptor_request(gatt_client); 1053 return 1; 1054 1055 case P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY: 1056 gatt_client->gatt_client_state = P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT; 1057 send_gatt_read_blob_request(gatt_client); 1058 return 1; 1059 1060 case P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR: 1061 gatt_client->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT; 1062 send_gatt_write_attribute_value_request(gatt_client); 1063 return 1; 1064 1065 case P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION: 1066 gatt_client->gatt_client_state = P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT; 1067 send_gatt_write_client_characteristic_configuration_request(gatt_client); 1068 return 1; 1069 1070 case P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR: 1071 gatt_client->gatt_client_state = P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT; 1072 send_gatt_prepare_write_request(gatt_client); 1073 return 1; 1074 1075 case P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR: 1076 gatt_client->gatt_client_state = P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT; 1077 send_gatt_execute_write_request(gatt_client); 1078 return 1; 1079 1080 #ifdef ENABLE_LE_SIGNED_WRITE 1081 case P_W4_IDENTITY_RESOLVING: 1082 log_info("P_W4_IDENTITY_RESOLVING - state %x", sm_identity_resolving_state(gatt_client->con_handle)); 1083 switch (sm_identity_resolving_state(gatt_client->con_handle)){ 1084 case IRK_LOOKUP_SUCCEEDED: 1085 gatt_client->le_device_index = sm_le_device_index(gatt_client->con_handle); 1086 gatt_client->gatt_client_state = P_W4_CMAC_READY; 1087 break; 1088 case IRK_LOOKUP_FAILED: 1089 gatt_client_handle_transaction_complete(gatt_client); 1090 emit_gatt_complete_event(gatt_client, ATT_ERROR_BONDING_INFORMATION_MISSING); 1091 return 0; 1092 default: 1093 return 0; 1094 } 1095 1096 /* Fall through */ 1097 1098 case P_W4_CMAC_READY: 1099 if (sm_cmac_ready()){ 1100 sm_key_t csrk; 1101 le_device_db_local_csrk_get(gatt_client->le_device_index, csrk); 1102 uint32_t sign_counter = le_device_db_local_counter_get(gatt_client->le_device_index); 1103 gatt_client->gatt_client_state = P_W4_CMAC_RESULT; 1104 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); 1105 } 1106 return 0; 1107 1108 case P_W2_SEND_SIGNED_WRITE: { 1109 gatt_client->gatt_client_state = P_W4_SEND_SINGED_WRITE_DONE; 1110 // bump local signing counter 1111 uint32_t sign_counter = le_device_db_local_counter_get(gatt_client->le_device_index); 1112 le_device_db_local_counter_set(gatt_client->le_device_index, sign_counter + 1); 1113 // send signed write command 1114 send_gatt_signed_write_request(gatt_client, sign_counter); 1115 // finally, notifiy client that write is complete 1116 gatt_client_handle_transaction_complete(gatt_client); 1117 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1118 return 1; 1119 } 1120 #endif 1121 default: 1122 break; 1123 } 1124 1125 // requested can send snow? 1126 if (gatt_client->write_without_response_callback){ 1127 btstack_packet_handler_t packet_handler = gatt_client->write_without_response_callback; 1128 gatt_client->write_without_response_callback = NULL; 1129 uint8_t event[4]; 1130 event[0] = GATT_EVENT_CAN_WRITE_WITHOUT_RESPONSE; 1131 event[1] = sizeof(event) - 2u; 1132 little_endian_store_16(event, 2, gatt_client->con_handle); 1133 packet_handler(HCI_EVENT_PACKET, gatt_client->con_handle, event, sizeof(event)); 1134 return 1; // to trigger requeueing (even if higher layer didn't sent) 1135 } 1136 1137 return 0; 1138 } 1139 1140 static void gatt_client_run(void){ 1141 btstack_linked_item_t *it; 1142 for (it = (btstack_linked_item_t *) gatt_client_connections; it != NULL; it = it->next){ 1143 gatt_client_t * gatt_client = (gatt_client_t *) it; 1144 if (!att_dispatch_client_can_send_now(gatt_client->con_handle)) { 1145 att_dispatch_client_request_can_send_now_event(gatt_client->con_handle); 1146 return; 1147 } 1148 int packet_sent = gatt_client_run_for_gatt_client(gatt_client); 1149 if (packet_sent){ 1150 // request new permission 1151 att_dispatch_client_request_can_send_now_event(gatt_client->con_handle); 1152 // requeue client for fairness and exit 1153 // note: iterator has become invalid 1154 btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client); 1155 btstack_linked_list_add_tail(&gatt_client_connections, (btstack_linked_item_t *) gatt_client); 1156 return; 1157 } 1158 } 1159 } 1160 1161 static void gatt_client_report_error_if_pending(gatt_client_t *gatt_client, uint8_t att_error_code) { 1162 if (is_ready(gatt_client) == 1) return; 1163 gatt_client_handle_transaction_complete(gatt_client); 1164 emit_gatt_complete_event(gatt_client, att_error_code); 1165 } 1166 1167 static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 1168 UNUSED(channel); // ok: handling own l2cap events 1169 UNUSED(size); // ok: there is no channel 1170 1171 if (packet_type != HCI_EVENT_PACKET) return; 1172 1173 hci_con_handle_t con_handle; 1174 gatt_client_t * gatt_client; 1175 switch (hci_event_packet_get_type(packet)) { 1176 case HCI_EVENT_DISCONNECTION_COMPLETE: 1177 log_info("GATT Client: HCI_EVENT_DISCONNECTION_COMPLETE"); 1178 con_handle = little_endian_read_16(packet,3); 1179 gatt_client = gatt_client_get_context_for_handle(con_handle); 1180 if (gatt_client == NULL) break; 1181 1182 gatt_client_report_error_if_pending(gatt_client, ATT_ERROR_HCI_DISCONNECT_RECEIVED); 1183 gatt_client_timeout_stop(gatt_client); 1184 btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client); 1185 btstack_memory_gatt_client_free(gatt_client); 1186 break; 1187 1188 // Pairing complete (with/without bonding=storing of pairing information) 1189 case SM_EVENT_PAIRING_COMPLETE: 1190 con_handle = sm_event_pairing_complete_get_handle(packet); 1191 gatt_client = gatt_client_get_context_for_handle(con_handle); 1192 if (gatt_client == NULL) break; 1193 1194 // update security level 1195 gatt_client->security_level = gatt_client_le_security_level_for_connection(con_handle); 1196 1197 if (gatt_client->wait_for_pairing_complete){ 1198 gatt_client->wait_for_pairing_complete = 0; 1199 if (sm_event_pairing_complete_get_status(packet)){ 1200 log_info("pairing failed, report previous error 0x%x", gatt_client->pending_error_code); 1201 gatt_client_report_error_if_pending(gatt_client, gatt_client->pending_error_code); 1202 } else { 1203 log_info("pairing success, retry operation"); 1204 } 1205 } 1206 break; 1207 1208 #ifdef ENABLE_LE_SIGNED_WRITE 1209 // Identity Resolving completed (no code, gatt_client_run will continue) 1210 case SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED: 1211 case SM_EVENT_IDENTITY_RESOLVING_FAILED: 1212 break; 1213 #endif 1214 #ifdef ENABLE_LE_PROACTIVE_AUTHENTICATION 1215 // re-encryption started 1216 case SM_EVENT_REENCRYPTION_STARTED: 1217 con_handle = sm_event_reencryption_complete_get_handle(packet); 1218 gatt_client = gatt_client_get_context_for_handle(con_handle); 1219 if (gatt_client == NULL) break; 1220 1221 gatt_client->reencryption_active = true; 1222 gatt_client->reencryption_result = ERROR_CODE_SUCCESS; 1223 break; 1224 1225 // re-encryption complete 1226 case SM_EVENT_REENCRYPTION_COMPLETE: 1227 con_handle = sm_event_reencryption_complete_get_handle(packet); 1228 gatt_client = gatt_client_get_context_for_handle(con_handle); 1229 if (gatt_client == NULL) break; 1230 1231 // update security level 1232 gatt_client->security_level = gatt_client_le_security_level_for_connection(con_handle); 1233 1234 gatt_client->reencryption_result = sm_event_reencryption_complete_get_status(packet); 1235 gatt_client->reencryption_active = false; 1236 break; 1237 #endif 1238 default: 1239 break; 1240 } 1241 1242 gatt_client_run(); 1243 } 1244 1245 static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){ 1246 gatt_client_t * gatt_client; 1247 if (size < 1u) return; 1248 1249 if (packet_type == HCI_EVENT_PACKET) { 1250 switch (packet[0]){ 1251 case L2CAP_EVENT_CAN_SEND_NOW: 1252 gatt_client_run(); 1253 break; 1254 // att_server has negotiated the mtu for this connection, cache if context exists 1255 case ATT_EVENT_MTU_EXCHANGE_COMPLETE: 1256 if (size < 6u) break; 1257 gatt_client = gatt_client_get_context_for_handle(handle); 1258 if (gatt_client == NULL) break; 1259 gatt_client->mtu = little_endian_read_16(packet, 4); 1260 break; 1261 default: 1262 break; 1263 } 1264 return; 1265 } 1266 1267 if (packet_type != ATT_DATA_PACKET) return; 1268 1269 // special cases: notifications don't need a context while indications motivate creating one 1270 switch (packet[0]){ 1271 case ATT_HANDLE_VALUE_NOTIFICATION: 1272 if (size < 3u) return; 1273 report_gatt_notification(handle, little_endian_read_16(packet,1u), &packet[3], size-3u); 1274 return; 1275 case ATT_HANDLE_VALUE_INDICATION: 1276 gatt_client = gatt_client_provide_context_for_handle(handle); 1277 break; 1278 default: 1279 gatt_client = gatt_client_get_context_for_handle(handle); 1280 break; 1281 } 1282 1283 if (gatt_client == NULL) return; 1284 1285 uint8_t error_code; 1286 switch (packet[0]){ 1287 case ATT_EXCHANGE_MTU_RESPONSE: 1288 { 1289 if (size < 3u) break; 1290 uint16_t remote_rx_mtu = little_endian_read_16(packet, 1); 1291 uint16_t local_rx_mtu = l2cap_max_le_mtu(); 1292 gatt_client->mtu = (remote_rx_mtu < local_rx_mtu) ? remote_rx_mtu : local_rx_mtu; 1293 gatt_client->mtu_state = MTU_EXCHANGED; 1294 emit_gatt_mtu_exchanged_result_event(gatt_client, gatt_client->mtu); 1295 break; 1296 } 1297 case ATT_READ_BY_GROUP_TYPE_RESPONSE: 1298 switch(gatt_client->gatt_client_state){ 1299 case P_W4_SERVICE_QUERY_RESULT: 1300 report_gatt_services(gatt_client, packet, size); 1301 trigger_next_service_query(gatt_client, get_last_result_handle_from_service_list(packet, size)); 1302 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1303 break; 1304 default: 1305 break; 1306 } 1307 break; 1308 case ATT_HANDLE_VALUE_INDICATION: 1309 if (size < 3u) break; 1310 report_gatt_indication(handle, little_endian_read_16(packet,1u), &packet[3], size-3u); 1311 gatt_client->send_confirmation = 1; 1312 break; 1313 1314 case ATT_READ_BY_TYPE_RESPONSE: 1315 switch (gatt_client->gatt_client_state){ 1316 case P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT: 1317 report_gatt_characteristics(gatt_client, packet, size); 1318 trigger_next_characteristic_query(gatt_client, get_last_result_handle_from_characteristics_list(packet, size)); 1319 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR 1320 break; 1321 case P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT: 1322 report_gatt_characteristics(gatt_client, packet, size); 1323 trigger_next_characteristic_query(gatt_client, get_last_result_handle_from_characteristics_list(packet, size)); 1324 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR 1325 break; 1326 case P_W4_INCLUDED_SERVICE_QUERY_RESULT: 1327 { 1328 if (size < 2u) break; 1329 uint16_t uuid16 = 0; 1330 uint16_t pair_size = packet[1]; 1331 1332 if (pair_size == 6u){ 1333 if (size < 8u) break; 1334 // UUIDs not available, query first included service 1335 gatt_client->start_group_handle = little_endian_read_16(packet, 2); // ready for next query 1336 gatt_client->query_start_handle = little_endian_read_16(packet, 4); 1337 gatt_client->query_end_handle = little_endian_read_16(packet, 6); 1338 gatt_client->gatt_client_state = P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY; 1339 break; 1340 } 1341 1342 if (pair_size != 8u) break; 1343 1344 // UUIDs included, report all of them 1345 uint16_t offset; 1346 for (offset = 2u; (offset + 8u) <= size; offset += pair_size){ 1347 uint16_t include_handle = little_endian_read_16(packet, offset); 1348 gatt_client->query_start_handle = little_endian_read_16(packet, offset + 2u); 1349 gatt_client->query_end_handle = little_endian_read_16(packet, offset + 4u); 1350 uuid16 = little_endian_read_16(packet, offset+6u); 1351 report_gatt_included_service_uuid16(gatt_client, include_handle, uuid16); 1352 } 1353 1354 trigger_next_included_service_query(gatt_client, get_last_result_handle_from_included_services_list(packet, size)); 1355 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1356 break; 1357 } 1358 #ifndef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY 1359 case P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT: 1360 gatt_client->client_characteristic_configuration_handle = little_endian_read_16(packet, 2); 1361 gatt_client->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION; 1362 break; 1363 #endif 1364 case P_W4_READ_BY_TYPE_RESPONSE: { 1365 uint16_t pair_size = packet[1]; 1366 uint16_t offset; 1367 uint16_t last_result_handle = 0; 1368 for (offset = 2; offset < size ; offset += pair_size){ 1369 uint16_t value_handle = little_endian_read_16(packet, offset); 1370 report_gatt_characteristic_value(gatt_client, value_handle, &packet[offset + 2u], pair_size - 2u); 1371 last_result_handle = value_handle; 1372 } 1373 trigger_next_read_by_type_query(gatt_client, last_result_handle); 1374 break; 1375 } 1376 default: 1377 break; 1378 } 1379 break; 1380 case ATT_READ_RESPONSE: 1381 switch (gatt_client->gatt_client_state){ 1382 case P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT: { 1383 uint8_t uuid128[16]; 1384 reverse_128(&packet[1], uuid128); 1385 report_gatt_included_service_uuid128(gatt_client, gatt_client->start_group_handle, uuid128); 1386 trigger_next_included_service_query(gatt_client, gatt_client->start_group_handle); 1387 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1388 break; 1389 } 1390 case P_W4_READ_CHARACTERISTIC_VALUE_RESULT: 1391 gatt_client_handle_transaction_complete(gatt_client); 1392 report_gatt_characteristic_value(gatt_client, gatt_client->attribute_handle, &packet[1], size - 1u); 1393 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1394 break; 1395 1396 case P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT:{ 1397 gatt_client_handle_transaction_complete(gatt_client); 1398 report_gatt_characteristic_descriptor(gatt_client, gatt_client->attribute_handle, &packet[1], size - 1u, 0u); 1399 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1400 break; 1401 } 1402 default: 1403 break; 1404 } 1405 break; 1406 1407 case ATT_FIND_BY_TYPE_VALUE_RESPONSE: 1408 { 1409 uint8_t pair_size = 4; 1410 int i; 1411 uint16_t start_group_handle; 1412 uint16_t end_group_handle= 0xffff; // asserts GATT_EVENT_QUERY_COMPLETE is emitted if no results 1413 for (i = 1u; (i + pair_size) <= size; i += pair_size){ 1414 start_group_handle = little_endian_read_16(packet,i); 1415 end_group_handle = little_endian_read_16(packet,i+2); 1416 emit_gatt_service_query_result_event(gatt_client, start_group_handle, end_group_handle, gatt_client->uuid128); 1417 } 1418 trigger_next_service_by_uuid_query(gatt_client, end_group_handle); 1419 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1420 break; 1421 } 1422 case ATT_FIND_INFORMATION_REPLY: 1423 { 1424 if (size < 2u) break; 1425 1426 uint8_t pair_size = 4; 1427 if (packet[1u] == 2u){ 1428 pair_size = 18; 1429 } 1430 uint16_t offset = 2; 1431 1432 if (size < (pair_size + offset)) break; 1433 uint16_t last_descriptor_handle = little_endian_read_16(packet, size - pair_size); 1434 1435 #ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY 1436 log_info("ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY, state %x", gatt_client->gatt_client_state); 1437 if (gatt_client->gatt_client_state == P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT){ 1438 // iterate over descriptors looking for CCC 1439 if (pair_size == 4){ 1440 while ((offset + 4) <= size){ 1441 uint16_t uuid16 = little_endian_read_16(packet, offset + 2); 1442 if (uuid16 == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION){ 1443 gatt_client->client_characteristic_configuration_handle = little_endian_read_16(packet, offset); 1444 gatt_client->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION; 1445 log_info("CCC found %x", gatt_client->client_characteristic_configuration_handle); 1446 break; 1447 } 1448 offset += pair_size; 1449 } 1450 } 1451 if (is_query_done(gatt_client, last_descriptor_handle)){ 1452 1453 } else { 1454 // next 1455 gatt_client->start_group_handle = last_descriptor_handle + 1; 1456 gatt_client->gatt_client_state = P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY; 1457 } 1458 break; 1459 } 1460 #endif 1461 report_gatt_all_characteristic_descriptors(gatt_client, &packet[2], size - 2u, pair_size); 1462 trigger_next_characteristic_descriptor_query(gatt_client, last_descriptor_handle); 1463 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1464 break; 1465 } 1466 1467 case ATT_WRITE_RESPONSE: 1468 switch (gatt_client->gatt_client_state){ 1469 case P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT: 1470 gatt_client_handle_transaction_complete(gatt_client); 1471 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1472 break; 1473 case P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT: 1474 gatt_client_handle_transaction_complete(gatt_client); 1475 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1476 break; 1477 case P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT: 1478 gatt_client_handle_transaction_complete(gatt_client); 1479 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1480 break; 1481 default: 1482 break; 1483 } 1484 break; 1485 1486 case ATT_READ_BLOB_RESPONSE:{ 1487 uint16_t received_blob_length = size-1u; 1488 switch(gatt_client->gatt_client_state){ 1489 case P_W4_READ_BLOB_RESULT: 1490 report_gatt_long_characteristic_value_blob(gatt_client, gatt_client->attribute_handle, &packet[1], received_blob_length, gatt_client->attribute_offset); 1491 trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_QUERY, received_blob_length); 1492 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1493 break; 1494 case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT: 1495 report_gatt_long_characteristic_descriptor(gatt_client, gatt_client->attribute_handle, 1496 &packet[1], received_blob_length, 1497 gatt_client->attribute_offset); 1498 trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY, received_blob_length); 1499 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1500 break; 1501 default: 1502 break; 1503 } 1504 break; 1505 } 1506 case ATT_PREPARE_WRITE_RESPONSE: 1507 switch (gatt_client->gatt_client_state){ 1508 case P_W4_PREPARE_WRITE_SINGLE_RESULT: 1509 gatt_client_handle_transaction_complete(gatt_client); 1510 if (is_value_valid(gatt_client, packet, size)){ 1511 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1512 } else { 1513 emit_gatt_complete_event(gatt_client, ATT_ERROR_DATA_MISMATCH); 1514 } 1515 break; 1516 1517 case P_W4_PREPARE_WRITE_RESULT:{ 1518 gatt_client->attribute_offset = little_endian_read_16(packet, 3); 1519 trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_WRITE, P_W2_EXECUTE_PREPARED_WRITE); 1520 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1521 break; 1522 } 1523 case P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:{ 1524 gatt_client->attribute_offset = little_endian_read_16(packet, 3); 1525 trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR, P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR); 1526 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1527 break; 1528 } 1529 case P_W4_PREPARE_RELIABLE_WRITE_RESULT:{ 1530 if (is_value_valid(gatt_client, packet, size)){ 1531 gatt_client->attribute_offset = little_endian_read_16(packet, 3); 1532 trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_RELIABLE_WRITE, P_W2_EXECUTE_PREPARED_WRITE); 1533 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1534 break; 1535 } 1536 gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH; 1537 break; 1538 } 1539 default: 1540 break; 1541 } 1542 break; 1543 1544 case ATT_EXECUTE_WRITE_RESPONSE: 1545 switch (gatt_client->gatt_client_state){ 1546 case P_W4_EXECUTE_PREPARED_WRITE_RESULT: 1547 gatt_client_handle_transaction_complete(gatt_client); 1548 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1549 break; 1550 case P_W4_CANCEL_PREPARED_WRITE_RESULT: 1551 gatt_client_handle_transaction_complete(gatt_client); 1552 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1553 break; 1554 case P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT: 1555 gatt_client_handle_transaction_complete(gatt_client); 1556 emit_gatt_complete_event(gatt_client, ATT_ERROR_DATA_MISMATCH); 1557 break; 1558 case P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT: 1559 gatt_client_handle_transaction_complete(gatt_client); 1560 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1561 break; 1562 default: 1563 break; 1564 1565 } 1566 break; 1567 1568 case ATT_READ_MULTIPLE_RESPONSE: 1569 switch(gatt_client->gatt_client_state){ 1570 case P_W4_READ_MULTIPLE_RESPONSE: 1571 report_gatt_characteristic_value(gatt_client, 0u, &packet[1], size - 1u); 1572 gatt_client_handle_transaction_complete(gatt_client); 1573 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1574 break; 1575 default: 1576 break; 1577 } 1578 break; 1579 1580 case ATT_ERROR_RESPONSE: 1581 if (size < 5u) return; 1582 error_code = packet[4]; 1583 switch (error_code){ 1584 case ATT_ERROR_ATTRIBUTE_NOT_FOUND: { 1585 switch(gatt_client->gatt_client_state){ 1586 case P_W4_SERVICE_QUERY_RESULT: 1587 case P_W4_SERVICE_WITH_UUID_RESULT: 1588 case P_W4_INCLUDED_SERVICE_QUERY_RESULT: 1589 case P_W4_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT: 1590 gatt_client_handle_transaction_complete(gatt_client); 1591 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1592 break; 1593 case P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT: 1594 case P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT: 1595 characteristic_end_found(gatt_client, gatt_client->end_group_handle); 1596 gatt_client_handle_transaction_complete(gatt_client); 1597 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1598 break; 1599 case P_W4_READ_BY_TYPE_RESPONSE: 1600 gatt_client_handle_transaction_complete(gatt_client); 1601 if (gatt_client->start_group_handle == gatt_client->query_start_handle){ 1602 emit_gatt_complete_event(gatt_client, ATT_ERROR_ATTRIBUTE_NOT_FOUND); 1603 } else { 1604 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1605 } 1606 break; 1607 default: 1608 gatt_client_report_error_if_pending(gatt_client, error_code); 1609 break; 1610 } 1611 break; 1612 } 1613 1614 #ifdef ENABLE_GATT_CLIENT_PAIRING 1615 1616 case ATT_ERROR_INSUFFICIENT_AUTHENTICATION: 1617 case ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE: 1618 case ATT_ERROR_INSUFFICIENT_ENCRYPTION: { 1619 1620 // security too low 1621 if (gatt_client->security_counter > 0) { 1622 gatt_client_report_error_if_pending(gatt_client, error_code); 1623 break; 1624 } 1625 // start security 1626 gatt_client->security_counter++; 1627 1628 // setup action 1629 int retry = 1; 1630 switch (gatt_client->gatt_client_state){ 1631 case P_W4_READ_CHARACTERISTIC_VALUE_RESULT: 1632 gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY ; 1633 break; 1634 case P_W4_READ_BLOB_RESULT: 1635 gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_QUERY; 1636 break; 1637 case P_W4_READ_BY_TYPE_RESPONSE: 1638 gatt_client->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST; 1639 break; 1640 case P_W4_READ_MULTIPLE_RESPONSE: 1641 gatt_client->gatt_client_state = P_W2_SEND_READ_MULTIPLE_REQUEST; 1642 break; 1643 case P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT: 1644 gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_VALUE; 1645 break; 1646 case P_W4_PREPARE_WRITE_RESULT: 1647 gatt_client->gatt_client_state = P_W2_PREPARE_WRITE; 1648 break; 1649 case P_W4_PREPARE_WRITE_SINGLE_RESULT: 1650 gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_SINGLE; 1651 break; 1652 case P_W4_PREPARE_RELIABLE_WRITE_RESULT: 1653 gatt_client->gatt_client_state = P_W2_PREPARE_RELIABLE_WRITE; 1654 break; 1655 case P_W4_EXECUTE_PREPARED_WRITE_RESULT: 1656 gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE; 1657 break; 1658 case P_W4_CANCEL_PREPARED_WRITE_RESULT: 1659 gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE; 1660 break; 1661 case P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT: 1662 gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH; 1663 break; 1664 case P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT: 1665 gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY; 1666 break; 1667 case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT: 1668 gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY; 1669 break; 1670 case P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT: 1671 gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR; 1672 break; 1673 case P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT: 1674 gatt_client->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION; 1675 break; 1676 case P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT: 1677 gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR; 1678 break; 1679 case P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT: 1680 gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR; 1681 break; 1682 #ifdef ENABLE_LE_SIGNED_WRITE 1683 case P_W4_SEND_SINGED_WRITE_DONE: 1684 gatt_client->gatt_client_state = P_W2_SEND_SIGNED_WRITE; 1685 break; 1686 #endif 1687 default: 1688 log_info("retry not supported for state %x", gatt_client->gatt_client_state); 1689 retry = 0; 1690 break; 1691 } 1692 1693 if (!retry) { 1694 gatt_client_report_error_if_pending(gatt_client, error_code); 1695 break; 1696 } 1697 1698 log_info("security error, start pairing"); 1699 1700 // start pairing for higher security level 1701 gatt_client->wait_for_pairing_complete = 1; 1702 gatt_client->pending_error_code = error_code; 1703 sm_request_pairing(gatt_client->con_handle); 1704 break; 1705 } 1706 #endif 1707 1708 // nothing we can do about that 1709 case ATT_ERROR_INSUFFICIENT_AUTHORIZATION: 1710 default: 1711 gatt_client_report_error_if_pending(gatt_client, error_code); 1712 break; 1713 } 1714 break; 1715 1716 default: 1717 log_info("ATT Handler, unhandled response type 0x%02x", packet[0]); 1718 break; 1719 } 1720 gatt_client_run(); 1721 } 1722 1723 #ifdef ENABLE_LE_SIGNED_WRITE 1724 static void att_signed_write_handle_cmac_result(uint8_t hash[8]){ 1725 btstack_linked_list_iterator_t it; 1726 btstack_linked_list_iterator_init(&it, &gatt_client_connections); 1727 while (btstack_linked_list_iterator_has_next(&it)){ 1728 gatt_client_t * gatt_client = (gatt_client_t *) btstack_linked_list_iterator_next(&it); 1729 if (gatt_client->gatt_client_state == P_W4_CMAC_RESULT){ 1730 // store result 1731 (void)memcpy(gatt_client->cmac, hash, 8); 1732 // reverse_64(hash, gatt_client->cmac); 1733 gatt_client->gatt_client_state = P_W2_SEND_SIGNED_WRITE; 1734 gatt_client_run(); 1735 return; 1736 } 1737 } 1738 } 1739 1740 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){ 1741 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle(con_handle); 1742 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1743 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1744 1745 gatt_client->callback = callback; 1746 gatt_client->attribute_handle = handle; 1747 gatt_client->attribute_length = message_len; 1748 gatt_client->attribute_value = message; 1749 gatt_client->gatt_client_state = P_W4_IDENTITY_RESOLVING; 1750 gatt_client_run(); 1751 return ERROR_CODE_SUCCESS; 1752 } 1753 #endif 1754 1755 uint8_t gatt_client_discover_primary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle){ 1756 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1757 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1758 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1759 1760 gatt_client->callback = callback; 1761 gatt_client->start_group_handle = 0x0001; 1762 gatt_client->end_group_handle = 0xffff; 1763 gatt_client->gatt_client_state = P_W2_SEND_SERVICE_QUERY; 1764 gatt_client->uuid16 = 0; 1765 gatt_client_run(); 1766 return ERROR_CODE_SUCCESS; 1767 } 1768 1769 1770 uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16){ 1771 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1772 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1773 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1774 1775 gatt_client->callback = callback; 1776 gatt_client->start_group_handle = 0x0001; 1777 gatt_client->end_group_handle = 0xffff; 1778 gatt_client->gatt_client_state = P_W2_SEND_SERVICE_WITH_UUID_QUERY; 1779 gatt_client->uuid16 = uuid16; 1780 uuid_add_bluetooth_prefix((uint8_t*) &(gatt_client->uuid128), gatt_client->uuid16); 1781 gatt_client_run(); 1782 return ERROR_CODE_SUCCESS; 1783 } 1784 1785 uint8_t gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, const uint8_t * uuid128){ 1786 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1787 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1788 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1789 1790 gatt_client->callback = callback; 1791 gatt_client->start_group_handle = 0x0001; 1792 gatt_client->end_group_handle = 0xffff; 1793 gatt_client->uuid16 = 0; 1794 (void)memcpy(gatt_client->uuid128, uuid128, 16); 1795 gatt_client->gatt_client_state = P_W2_SEND_SERVICE_WITH_UUID_QUERY; 1796 gatt_client_run(); 1797 return ERROR_CODE_SUCCESS; 1798 } 1799 1800 uint8_t gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t *service){ 1801 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1802 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1803 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1804 1805 gatt_client->callback = callback; 1806 gatt_client->start_group_handle = service->start_group_handle; 1807 gatt_client->end_group_handle = service->end_group_handle; 1808 gatt_client->filter_with_uuid = 0; 1809 gatt_client->characteristic_start_handle = 0; 1810 gatt_client->gatt_client_state = P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY; 1811 gatt_client_run(); 1812 return ERROR_CODE_SUCCESS; 1813 } 1814 1815 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){ 1816 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1817 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1818 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1819 gatt_client->callback = callback; 1820 gatt_client->start_group_handle = service->start_group_handle; 1821 gatt_client->end_group_handle = service->end_group_handle; 1822 gatt_client->gatt_client_state = P_W2_SEND_INCLUDED_SERVICE_QUERY; 1823 1824 gatt_client_run(); 1825 return ERROR_CODE_SUCCESS; 1826 } 1827 1828 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){ 1829 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1830 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1831 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1832 1833 gatt_client->callback = callback; 1834 gatt_client->start_group_handle = start_handle; 1835 gatt_client->end_group_handle = end_handle; 1836 gatt_client->filter_with_uuid = 1; 1837 gatt_client->uuid16 = uuid16; 1838 uuid_add_bluetooth_prefix((uint8_t*) &(gatt_client->uuid128), uuid16); 1839 gatt_client->characteristic_start_handle = 0; 1840 gatt_client->gatt_client_state = P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY; 1841 gatt_client_run(); 1842 return ERROR_CODE_SUCCESS; 1843 } 1844 1845 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){ 1846 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1847 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1848 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1849 1850 gatt_client->callback = callback; 1851 gatt_client->start_group_handle = start_handle; 1852 gatt_client->end_group_handle = end_handle; 1853 gatt_client->filter_with_uuid = 1; 1854 gatt_client->uuid16 = 0; 1855 (void)memcpy(gatt_client->uuid128, uuid128, 16); 1856 gatt_client->characteristic_start_handle = 0; 1857 gatt_client->gatt_client_state = P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY; 1858 gatt_client_run(); 1859 return ERROR_CODE_SUCCESS; 1860 } 1861 1862 1863 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){ 1864 return gatt_client_discover_characteristics_for_handle_range_by_uuid16(callback, handle, service->start_group_handle, service->end_group_handle, uuid16); 1865 } 1866 1867 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){ 1868 return gatt_client_discover_characteristics_for_handle_range_by_uuid128(callback, handle, service->start_group_handle, service->end_group_handle, uuid128); 1869 } 1870 1871 uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t *characteristic){ 1872 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1873 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1874 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1875 1876 if (characteristic->value_handle == characteristic->end_handle){ 1877 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); 1878 return ERROR_CODE_SUCCESS; 1879 } 1880 gatt_client->callback = callback; 1881 gatt_client->start_group_handle = characteristic->value_handle + 1u; 1882 gatt_client->end_group_handle = characteristic->end_handle; 1883 gatt_client->gatt_client_state = P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY; 1884 gatt_client_run(); 1885 return ERROR_CODE_SUCCESS; 1886 } 1887 1888 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){ 1889 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1890 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1891 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1892 1893 gatt_client->callback = callback; 1894 gatt_client->attribute_handle = value_handle; 1895 gatt_client->attribute_offset = 0; 1896 gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY; 1897 gatt_client_run(); 1898 return ERROR_CODE_SUCCESS; 1899 } 1900 1901 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){ 1902 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1903 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1904 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1905 1906 gatt_client->callback = callback; 1907 gatt_client->start_group_handle = start_handle; 1908 gatt_client->end_group_handle = end_handle; 1909 gatt_client->query_start_handle = start_handle; 1910 gatt_client->query_end_handle = end_handle; 1911 gatt_client->uuid16 = uuid16; 1912 uuid_add_bluetooth_prefix((uint8_t*) &(gatt_client->uuid128), uuid16); 1913 gatt_client->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST; 1914 gatt_client_run(); 1915 return ERROR_CODE_SUCCESS; 1916 } 1917 1918 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){ 1919 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1920 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1921 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1922 1923 gatt_client->callback = callback; 1924 gatt_client->start_group_handle = start_handle; 1925 gatt_client->end_group_handle = end_handle; 1926 gatt_client->query_start_handle = start_handle; 1927 gatt_client->query_end_handle = end_handle; 1928 gatt_client->uuid16 = 0; 1929 (void)memcpy(gatt_client->uuid128, uuid128, 16); 1930 gatt_client->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST; 1931 gatt_client_run(); 1932 return ERROR_CODE_SUCCESS; 1933 } 1934 1935 1936 uint8_t gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback, uint16_t handle, gatt_client_characteristic_t *characteristic){ 1937 return gatt_client_read_value_of_characteristic_using_value_handle(callback, handle, characteristic->value_handle); 1938 } 1939 1940 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){ 1941 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1942 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1943 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1944 1945 gatt_client->callback = callback; 1946 gatt_client->attribute_handle = characteristic_value_handle; 1947 gatt_client->attribute_offset = offset; 1948 gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_QUERY; 1949 gatt_client_run(); 1950 return ERROR_CODE_SUCCESS; 1951 } 1952 1953 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){ 1954 return gatt_client_read_long_value_of_characteristic_using_value_handle_with_offset(callback, con_handle, characteristic_value_handle, 0); 1955 } 1956 1957 uint8_t gatt_client_read_long_value_of_characteristic(btstack_packet_handler_t callback, uint16_t handle, gatt_client_characteristic_t *characteristic){ 1958 return gatt_client_read_long_value_of_characteristic_using_value_handle(callback, handle, characteristic->value_handle); 1959 } 1960 1961 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){ 1962 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1963 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1964 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1965 1966 gatt_client->callback = callback; 1967 gatt_client->read_multiple_handle_count = num_value_handles; 1968 gatt_client->read_multiple_handles = value_handles; 1969 gatt_client->gatt_client_state = P_W2_SEND_READ_MULTIPLE_REQUEST; 1970 gatt_client_run(); 1971 return ERROR_CODE_SUCCESS; 1972 } 1973 1974 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){ 1975 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle(con_handle); 1976 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1977 1978 if (value_length > (gatt_client->mtu - 3u)) return GATT_CLIENT_VALUE_TOO_LONG; 1979 if (!att_dispatch_client_can_send_now(gatt_client->con_handle)) return GATT_CLIENT_BUSY; 1980 1981 return att_write_request(ATT_WRITE_COMMAND, gatt_client->con_handle, value_handle, value_length, value); 1982 } 1983 1984 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){ 1985 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 1986 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 1987 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 1988 1989 gatt_client->callback = callback; 1990 gatt_client->attribute_handle = value_handle; 1991 gatt_client->attribute_length = value_length; 1992 gatt_client->attribute_value = data; 1993 gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_VALUE; 1994 gatt_client_run(); 1995 return ERROR_CODE_SUCCESS; 1996 } 1997 1998 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){ 1999 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 2000 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 2001 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 2002 2003 gatt_client->callback = callback; 2004 gatt_client->attribute_handle = value_handle; 2005 gatt_client->attribute_length = value_length; 2006 gatt_client->attribute_offset = offset; 2007 gatt_client->attribute_value = data; 2008 gatt_client->gatt_client_state = P_W2_PREPARE_WRITE; 2009 gatt_client_run(); 2010 return ERROR_CODE_SUCCESS; 2011 } 2012 2013 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){ 2014 return gatt_client_write_long_value_of_characteristic_with_offset(callback, con_handle, value_handle, 0, value_length, value); 2015 } 2016 2017 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){ 2018 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 2019 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 2020 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 2021 2022 gatt_client->callback = callback; 2023 gatt_client->attribute_handle = value_handle; 2024 gatt_client->attribute_length = value_length; 2025 gatt_client->attribute_offset = 0; 2026 gatt_client->attribute_value = value; 2027 gatt_client->gatt_client_state = P_W2_PREPARE_RELIABLE_WRITE; 2028 gatt_client_run(); 2029 return ERROR_CODE_SUCCESS; 2030 } 2031 2032 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){ 2033 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 2034 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 2035 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 2036 2037 if ( (configuration & GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION) && 2038 ((characteristic->properties & ATT_PROPERTY_NOTIFY) == 0u)) { 2039 log_info("gatt_client_write_client_characteristic_configuration: GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED"); 2040 return GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED; 2041 } else if ( (configuration & GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION) && 2042 ((characteristic->properties & ATT_PROPERTY_INDICATE) == 0u)){ 2043 log_info("gatt_client_write_client_characteristic_configuration: GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED"); 2044 return GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED; 2045 } 2046 2047 gatt_client->callback = callback; 2048 gatt_client->start_group_handle = characteristic->value_handle; 2049 gatt_client->end_group_handle = characteristic->end_handle; 2050 little_endian_store_16(gatt_client->client_characteristic_configuration_value, 0, configuration); 2051 2052 #ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY 2053 gatt_client->gatt_client_state = P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY; 2054 #else 2055 gatt_client->gatt_client_state = P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY; 2056 #endif 2057 gatt_client_run(); 2058 return ERROR_CODE_SUCCESS; 2059 } 2060 2061 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){ 2062 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 2063 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 2064 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 2065 2066 gatt_client->callback = callback; 2067 gatt_client->attribute_handle = descriptor_handle; 2068 2069 gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY; 2070 gatt_client_run(); 2071 return ERROR_CODE_SUCCESS; 2072 } 2073 2074 uint8_t gatt_client_read_characteristic_descriptor(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_descriptor_t * descriptor){ 2075 return gatt_client_read_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle); 2076 } 2077 2078 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){ 2079 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 2080 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 2081 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 2082 2083 gatt_client->callback = callback; 2084 gatt_client->attribute_handle = descriptor_handle; 2085 gatt_client->attribute_offset = offset; 2086 gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY; 2087 gatt_client_run(); 2088 return ERROR_CODE_SUCCESS; 2089 } 2090 2091 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){ 2092 return gatt_client_read_long_characteristic_descriptor_using_descriptor_handle_with_offset(callback, con_handle, descriptor_handle, 0); 2093 } 2094 2095 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){ 2096 return gatt_client_read_long_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle); 2097 } 2098 2099 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){ 2100 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 2101 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 2102 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 2103 2104 gatt_client->callback = callback; 2105 gatt_client->attribute_handle = descriptor_handle; 2106 gatt_client->attribute_length = length; 2107 gatt_client->attribute_offset = 0; 2108 gatt_client->attribute_value = data; 2109 gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR; 2110 gatt_client_run(); 2111 return ERROR_CODE_SUCCESS; 2112 } 2113 2114 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){ 2115 return gatt_client_write_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle, length, value); 2116 } 2117 2118 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){ 2119 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 2120 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 2121 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 2122 2123 gatt_client->callback = callback; 2124 gatt_client->attribute_handle = descriptor_handle; 2125 gatt_client->attribute_length = length; 2126 gatt_client->attribute_offset = offset; 2127 gatt_client->attribute_value = data; 2128 gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR; 2129 gatt_client_run(); 2130 return ERROR_CODE_SUCCESS; 2131 } 2132 2133 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){ 2134 return gatt_client_write_long_characteristic_descriptor_using_descriptor_handle_with_offset(callback, con_handle, descriptor_handle, 0, length, data ); 2135 } 2136 2137 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){ 2138 return gatt_client_write_long_characteristic_descriptor_using_descriptor_handle(callback, con_handle, descriptor->handle, length, value); 2139 } 2140 2141 /** 2142 * @brief -> gatt complete event 2143 */ 2144 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){ 2145 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 2146 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 2147 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 2148 2149 gatt_client->callback = callback; 2150 gatt_client->attribute_handle = attribute_handle; 2151 gatt_client->attribute_length = length; 2152 gatt_client->attribute_offset = offset; 2153 gatt_client->attribute_value = data; 2154 gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_SINGLE; 2155 gatt_client_run(); 2156 return ERROR_CODE_SUCCESS; 2157 } 2158 2159 /** 2160 * @brief -> gatt complete event 2161 */ 2162 uint8_t gatt_client_execute_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle){ 2163 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 2164 2165 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 2166 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 2167 2168 gatt_client->callback = callback; 2169 gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE; 2170 gatt_client_run(); 2171 return ERROR_CODE_SUCCESS; 2172 } 2173 2174 /** 2175 * @brief -> gatt complete event 2176 */ 2177 uint8_t gatt_client_cancel_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle){ 2178 gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); 2179 if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 2180 if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; 2181 2182 gatt_client->callback = callback; 2183 gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE; 2184 gatt_client_run(); 2185 return ERROR_CODE_SUCCESS; 2186 } 2187 2188 void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t *service){ 2189 service->start_group_handle = little_endian_read_16(packet, offset); 2190 service->end_group_handle = little_endian_read_16(packet, offset + 2); 2191 reverse_128(&packet[offset + 4], service->uuid128); 2192 if (uuid_has_bluetooth_prefix(service->uuid128)){ 2193 service->uuid16 = big_endian_read_32(service->uuid128, 0); 2194 } else { 2195 service->uuid16 = 0; 2196 } 2197 } 2198 2199 void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic){ 2200 characteristic->start_handle = little_endian_read_16(packet, offset); 2201 characteristic->value_handle = little_endian_read_16(packet, offset + 2); 2202 characteristic->end_handle = little_endian_read_16(packet, offset + 4); 2203 characteristic->properties = little_endian_read_16(packet, offset + 6); 2204 reverse_128(&packet[offset+8], characteristic->uuid128); 2205 if (uuid_has_bluetooth_prefix(characteristic->uuid128)){ 2206 characteristic->uuid16 = big_endian_read_32(characteristic->uuid128, 0); 2207 } else { 2208 characteristic->uuid16 = 0; 2209 } 2210 } 2211 2212 void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor){ 2213 descriptor->handle = little_endian_read_16(packet, offset); 2214 reverse_128(&packet[offset+2], descriptor->uuid128); 2215 if (uuid_has_bluetooth_prefix(descriptor->uuid128)){ 2216 descriptor->uuid16 = big_endian_read_32(descriptor->uuid128, 0); 2217 } else { 2218 descriptor->uuid16 = 0; 2219 } 2220 } 2221 2222 void gatt_client_send_mtu_negotiation(btstack_packet_handler_t callback, hci_con_handle_t con_handle){ 2223 gatt_client_t * context = gatt_client_provide_context_for_handle(con_handle); 2224 if (context == NULL) return; 2225 if (context->mtu_state == MTU_AUTO_EXCHANGE_DISABLED){ 2226 context->callback = callback; 2227 context->mtu_state = SEND_MTU_EXCHANGE; 2228 gatt_client_run(); 2229 } 2230 } 2231 2232 uint8_t gatt_client_request_can_write_without_response_event(btstack_packet_handler_t callback, hci_con_handle_t con_handle){ 2233 gatt_client_t * context = gatt_client_provide_context_for_handle(con_handle); 2234 if (context == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 2235 if (context->write_without_response_callback != NULL) return GATT_CLIENT_IN_WRONG_STATE; 2236 context->write_without_response_callback = callback; 2237 att_dispatch_client_request_can_send_now_event(context->con_handle); 2238 return ERROR_CODE_SUCCESS; 2239 } 2240 2241 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 2242 void gatt_client_att_packet_handler_fuzz(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){ 2243 gatt_client_att_packet_handler(packet_type, handle, packet, size); 2244 } 2245 #endif 2246