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