1 /* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 /** 39 * @title GATT Client 40 * 41 */ 42 43 #ifndef btstack_gatt_client_h 44 #define btstack_gatt_client_h 45 46 #include "hci.h" 47 48 // spec defines 100 ms, PTS might indicate an error if we sent after 100 ms 49 #define GATT_CLIENT_COLLISION_BACKOFF_MS 150 50 #if defined __cplusplus 51 extern "C" { 52 #endif 53 54 typedef enum { 55 P_READY, 56 P_W2_EMIT_QUERY_COMPLETE_EVENT, 57 P_W2_SEND_SERVICE_QUERY, 58 P_W4_SERVICE_QUERY_RESULT, 59 P_W2_SEND_SERVICE_WITH_UUID_QUERY, 60 P_W4_SERVICE_WITH_UUID_RESULT, 61 62 P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY, 63 P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT, 64 P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY, 65 P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT, 66 67 P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY, 68 P_W4_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT, 69 70 P_W2_SEND_INCLUDED_SERVICE_QUERY, 71 P_W4_INCLUDED_SERVICE_QUERY_RESULT, 72 P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY, 73 P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT, 74 75 P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY, 76 P_W4_READ_CHARACTERISTIC_VALUE_RESULT, 77 78 P_W2_SEND_READ_BLOB_QUERY, 79 P_W4_READ_BLOB_RESULT, 80 81 P_W2_SEND_READ_BY_TYPE_REQUEST, 82 P_W4_READ_BY_TYPE_RESPONSE, 83 84 P_W2_SEND_READ_MULTIPLE_REQUEST, 85 P_W4_READ_MULTIPLE_RESPONSE, 86 87 P_W2_SEND_READ_MULTIPLE_VARIABLE_REQUEST, 88 P_W4_READ_MULTIPLE_VARIABLE_RESPONSE, 89 90 P_W2_SEND_WRITE_CHARACTERISTIC_VALUE, 91 P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT, 92 93 P_W2_PREPARE_WRITE, 94 P_W4_PREPARE_WRITE_RESULT, 95 P_W2_PREPARE_RELIABLE_WRITE, 96 P_W4_PREPARE_RELIABLE_WRITE_RESULT, 97 98 P_W2_EXECUTE_PREPARED_WRITE, 99 P_W4_EXECUTE_PREPARED_WRITE_RESULT, 100 P_W2_CANCEL_PREPARED_WRITE, 101 P_W4_CANCEL_PREPARED_WRITE_RESULT, 102 P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH, 103 P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT, 104 105 #ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY 106 P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY, 107 P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT, 108 #else 109 P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY, 110 P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT, 111 #endif 112 P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION, 113 P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT, 114 115 P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY, 116 P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT, 117 118 P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY, 119 P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT, 120 121 P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR, 122 P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT, 123 124 // all long writes use this 125 P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR, 126 P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT, 127 P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR, 128 P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT, 129 130 // gatt reliable write API use this (manual version of the above) 131 P_W2_PREPARE_WRITE_SINGLE, 132 P_W4_PREPARE_WRITE_SINGLE_RESULT, 133 134 P_W4_IDENTITY_RESOLVING, 135 P_W4_CMAC_READY, 136 P_W4_CMAC_RESULT, 137 P_W2_SEND_SIGNED_WRITE, 138 P_W4_SEND_SIGNED_WRITE_DONE, 139 140 P_W2_SDP_QUERY, 141 P_W4_SDP_QUERY, 142 P_W2_L2CAP_CONNECT, 143 P_W4_L2CAP_CONNECTION, 144 P_W2_EMIT_CONNECTED, 145 P_L2CAP_CLOSED, 146 } gatt_client_state_t; 147 148 149 typedef enum{ 150 SEND_MTU_EXCHANGE, 151 SENT_MTU_EXCHANGE, 152 MTU_EXCHANGED, 153 MTU_AUTO_EXCHANGE_DISABLED 154 } gatt_client_mtu_t; 155 156 typedef enum { 157 GATT_CLIENT_SERVICE_DISCOVER_W2_SEND, 158 GATT_CLIENT_SERVICE_DISCOVER_W4_DONE, 159 GATT_CLIENT_SERVICE_DISCOVER_CHARACTERISTICS_W2_SEND, 160 GATT_CLIENT_SERVICE_DISCOVER_CHARACTERISTICS_W4_DONE, 161 GATT_CLIENT_SERVICE_SERVICE_CHANGED_WRITE_CCCD_W2_SEND, 162 GATT_CLIENT_SERVICE_SERVICE_CHANGED_WRITE_CCCD_W4_DONE, 163 GATT_CLIENT_SERVICE_DATABASE_HASH_READ_W2_SEND, 164 GATT_CLIENT_SERVICE_DATABASE_HASH_READ_W4_DONE, 165 GATT_CLIENT_SERVICE_DATABASE_HASH_WRITE_CCCD_W2_SEND, 166 GATT_CLIENT_SERVICE_DATABASE_HASH_WRITE_CCCD_W4_DONE, 167 GATT_CLIENT_SERVICE_DONE, 168 } gatt_client_service_state_t; 169 170 #ifdef ENABLE_GATT_OVER_EATT 171 typedef enum { 172 GATT_CLIENT_EATT_IDLE, 173 GATT_CLIENT_EATT_DISCOVER_GATT_SERVICE_W2_SEND, 174 GATT_CLIENT_EATT_DISCOVER_GATT_SERVICE_W4_DONE, 175 GATT_CLIENT_EATT_READ_SERVER_SUPPORTED_FEATURES_W2_SEND, 176 GATT_CLIENT_EATT_READ_SERVER_SUPPORTED_FEATURES_W4_DONE, 177 GATT_CLIENT_EATT_FIND_CLIENT_SUPPORTED_FEATURES_W2_SEND, 178 GATT_CLIENT_EATT_FIND_CLIENT_SUPPORTED_FEATURES_W4_DONE, 179 GATT_CLIENT_EATT_WRITE_ClIENT_SUPPORTED_FEATURES_W2_SEND, 180 GATT_CLIENT_EATT_WRITE_ClIENT_SUPPORTED_FEATURES_W4_DONE, 181 GATT_CLIENT_EATT_L2CAP_SETUP, 182 GATT_CLIENT_EATT_READY, 183 } gatt_client_eatt_state_t; 184 #endif 185 186 typedef struct gatt_client{ 187 btstack_linked_item_t item; 188 189 gatt_client_state_t state; 190 191 // user callback 192 btstack_packet_handler_t callback; 193 194 // can write without response callback 195 btstack_packet_handler_t write_without_response_callback; 196 197 // can write without response requests 198 btstack_linked_list_t write_without_response_requests; 199 200 // regular gatt query requests 201 btstack_linked_list_t query_requests; 202 203 hci_con_handle_t con_handle; 204 205 att_bearer_type_t bearer_type; 206 207 #if defined(ENABLE_GATT_OVER_CLASSIC) || defined(ENABLE_GATT_OVER_EATT) 208 uint16_t l2cap_cid; 209 bd_addr_t addr; 210 bd_addr_type_t addr_type; 211 #endif 212 213 #ifdef ENABLE_GATT_OVER_CLASSIC 214 uint16_t l2cap_psm; 215 btstack_context_callback_registration_t callback_request; 216 #endif 217 218 #ifdef ENABLE_GATT_OVER_EATT 219 gatt_client_eatt_state_t eatt_state; 220 btstack_linked_list_t eatt_clients; 221 uint8_t * eatt_storage_buffer; 222 uint16_t eatt_storage_size; 223 uint8_t eatt_num_clients; 224 uint8_t gatt_server_supported_features; 225 uint16_t gatt_client_supported_features_handle; 226 #endif 227 228 uint16_t mtu; 229 gatt_client_mtu_t mtu_state; 230 231 uint16_t uuid16; 232 uint8_t uuid128[16]; 233 234 uint16_t start_group_handle; 235 uint16_t end_group_handle; 236 237 uint16_t query_start_handle; 238 uint16_t query_end_handle; 239 240 uint8_t characteristic_properties; 241 uint16_t characteristic_start_handle; 242 243 uint16_t attribute_handle; 244 uint16_t attribute_offset; 245 uint16_t attribute_length; 246 uint8_t* attribute_value; 247 248 // read multiple characteristic values 249 uint16_t read_multiple_handle_count; 250 uint16_t * read_multiple_handles; 251 252 uint16_t client_characteristic_configuration_handle; 253 uint8_t client_characteristic_configuration_value[2]; 254 255 bool filter_with_uuid; 256 bool send_confirmation; 257 258 int le_device_index; 259 uint8_t cmac[8]; 260 261 btstack_timer_source_t gc_timeout; 262 263 uint8_t security_counter; 264 bool wait_for_authentication_complete; 265 uint8_t pending_error_code; 266 267 bool reencryption_active; 268 uint8_t reencryption_result; 269 270 gap_security_level_t security_level; 271 272 // Context 273 uint16_t service_id; 274 uint16_t connection_id; 275 276 // GATT Service Changes 277 gatt_client_service_state_t gatt_service_state; 278 uint16_t gatt_service_start_group_handle; 279 uint16_t gatt_service_end_group_handle; 280 // - Service Changed 281 uint16_t gatt_service_changed_value_handle; 282 uint16_t gatt_service_changed_cccd_handle; 283 uint16_t gatt_service_changed_end_handle; 284 // - Database Hash 285 uint16_t gatt_service_database_hash_value_handle; 286 uint16_t gatt_service_database_hash_cccd_handle; 287 uint16_t gatt_service_database_hash_end_handle; 288 289 } gatt_client_t; 290 291 typedef struct gatt_client_notification { 292 btstack_linked_item_t item; 293 btstack_packet_handler_t callback; 294 hci_con_handle_t con_handle; 295 uint16_t attribute_handle; 296 } gatt_client_notification_t; 297 298 /* API_START */ 299 300 typedef struct { 301 uint16_t start_group_handle; 302 uint16_t end_group_handle; 303 uint16_t uuid16; 304 uint8_t uuid128[16]; 305 } gatt_client_service_t; 306 307 typedef struct { 308 uint16_t start_handle; 309 uint16_t value_handle; 310 uint16_t end_handle; 311 uint16_t properties; 312 uint16_t uuid16; 313 uint8_t uuid128[16]; 314 } gatt_client_characteristic_t; 315 316 typedef struct { 317 uint16_t handle; 318 uint16_t uuid16; 319 uint8_t uuid128[16]; 320 } gatt_client_characteristic_descriptor_t; 321 322 /** 323 * @brief Set up GATT client. 324 */ 325 void gatt_client_init(void); 326 327 /** 328 * @brief Set minimum required security level for GATT Client 329 * @note The Bluetooth specification makes the GATT Server responsible to check for security. 330 * This allows an attacker to spoof an existing device with a GATT Servers, but skip the authentication part. 331 * If your application is exchanging sensitive data with a remote device, you would need to manually check 332 * the security level before sending/receive such data. 333 * With level > 0, the GATT Client triggers authentication for all GATT Requests and defers any exchange 334 * until the required security level is established. 335 * gatt_client_request_can_write_without_response_event does not trigger authentication 336 * gatt_client_request_to_write_without_response does not trigger authentication 337 * @pram level, default LEVEL_0 (no encryption required) 338 */ 339 void gatt_client_set_required_security_level(gap_security_level_t level); 340 341 /** 342 * @brief Connect to remote GATT Server over Classic (BR/EDR) Connection 343 * GATT_EVENT_CONNECTED with status and con_handle for other API functions 344 * is emitted on connection complete. 345 * @note requires ENABLE_GATT_OVER_CLASSIC. 346 * @param addr 347 * @return status 348 */ 349 uint8_t gatt_client_classic_connect(btstack_packet_handler_t callback, bd_addr_t addr); 350 351 /** 352 * @brief Disconnect o Classic (BR/EDR) connection to a remote GATT Server 353 * @note requires ENABLE_GATT_OVER_CLASSIC 354 * @param con_handle 355 * @return status 356 */ 357 uint8_t gatt_client_classic_disconnect(btstack_packet_handler_t callback, hci_con_handle_t con_handle); 358 359 /** 360 * @brief Setup Enhanced LE Bearer with up to 5 channels on existing LE connection 361 * @param callback for GATT_EVENT_CONNECTED and GATT_EVENT_DISCONNECTED events 362 * @param con_handle 363 * @param num_channels 364 * @param storage_buffer for L2CAP connection 365 * @param storage_size - each channel requires (2 * ATT MTU) + 10 bytes 366 * @return 367 */ 368 uint8_t gatt_client_le_enhanced_connect(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint8_t num_channels, uint8_t * storage_buffer, uint16_t storage_size); 369 370 /** 371 * @brief MTU is available after the first query has completed. If status is equal to ERROR_CODE_SUCCESS, it returns the real value, 372 * otherwise the default value ATT_DEFAULT_MTU (see bluetooth.h). 373 * @param con_handle 374 * @param mtu 375 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 376 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 377 * GATT_CLIENT_IN_WRONG_STATE if MTU is not exchanged and MTU auto-exchange is disabled 378 * ERROR_CODE_SUCCESS if query is successfully registered 379 */ 380 uint8_t gatt_client_get_mtu(hci_con_handle_t con_handle, uint16_t * mtu); 381 382 /** 383 * @brief Sets whether a MTU Exchange Request shall be automatically send before the 384 * first attribute read request is send. Default is enabled. 385 * @param enabled 386 */ 387 void gatt_client_mtu_enable_auto_negotiation(uint8_t enabled); 388 389 /** 390 * @brief Sends a MTU Exchange Request, this allows for the client to exchange MTU 391 * when gatt_client_mtu_enable_auto_negotiation is disabled. 392 * @param callback 393 * @param con_handle 394 */ 395 void gatt_client_send_mtu_negotiation(btstack_packet_handler_t callback, hci_con_handle_t con_handle); 396 397 /** 398 * @brief Returns 1 if the GATT client is ready to receive a query. It is used with daemon. 399 * @param con_handle 400 * @return is_ready_status 0 - if no GATT client for con_handle is found, or is not ready, otherwise 1 401 */ 402 int gatt_client_is_ready(hci_con_handle_t con_handle); 403 404 /** 405 * @brief Discovers all primary services. 406 * For each found service a GATT_EVENT_SERVICE_QUERY_RESULT event will be emitted. 407 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 408 * @param callback 409 * @param con_handle 410 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 411 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 412 * ERROR_CODE_SUCCESS , if query is successfully registered 413 */ 414 uint8_t gatt_client_discover_primary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle); 415 416 /** 417 * @brief Discovers all secondary services. 418 * For each found service a GATT_EVENT_SERVICE_QUERY_RESULT event will be emitted. 419 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 420 * @param callback 421 * @param con_handle 422 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 423 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 424 * ERROR_CODE_SUCCESS , if query is successfully registered 425 */ 426 uint8_t gatt_client_discover_secondary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle); 427 428 /** 429 * @brief Discovers a specific primary service given its UUID. This service may exist multiple times. 430 * For each found service a GATT_EVENT_SERVICE_QUERY_RESULT event will be emitted. 431 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 432 * @param callback 433 * @param con_handle 434 * @param uuid16 435 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 436 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 437 * ERROR_CODE_SUCCESS , if query is successfully registered 438 */ 439 uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16); 440 441 /** 442 * @brief Discovers a specific primary service given its UUID. This service may exist multiple times. 443 * For each found service a GATT_EVENT_SERVICE_QUERY_RESULT event will be emitted. 444 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 445 * @param callback 446 * @param con_handle 447 * @param uuid16 448 * @param service_id - context provided to callback in events 449 * @param connection_id - contest provided to callback in events 450 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 451 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 452 * ERROR_CODE_SUCCESS , if query is successfully registered 453 */ 454 uint8_t gatt_client_discover_primary_services_by_uuid16_with_context(btstack_packet_handler_t callback, hci_con_handle_t con_handle, 455 uint16_t uuid16, uint16_t service_id, uint16_t connection_id); 456 457 /** 458 * @brief Discovers a specific primary service given its UUID. This service may exist multiple times. 459 * For each found service a GATT_EVENT_SERVICE_QUERY_RESULT event will be emitted. 460 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 461 * @param callback 462 * @param con_handle 463 * @param uuid128 464 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 465 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 466 * ERROR_CODE_SUCCESS , if query is successfully registered 467 */ 468 uint8_t gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, const uint8_t * uuid128); 469 470 /** 471 * @brief Finds included services within the specified service. 472 * For each found included service a GATT_EVENT_INCLUDED_SERVICE_QUERY_RESULT event will be emitted. 473 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 474 * Information about included service type (primary/secondary) can be retrieved either by sending 475 * an ATT find information request for the returned start group handle 476 * (returning the handle and the UUID for primary or secondary service) or by comparing the service 477 * to the list of all primary services. 478 * @param callback 479 * @param con_handle 480 * @param service 481 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 482 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 483 * ERROR_CODE_SUCCESS , if query is successfully registered 484 */ 485 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); 486 487 /** 488 * @brief Finds included services within the specified service. 489 * For each found included service a GATT_EVENT_INCLUDED_SERVICE_QUERY_RESULT event will be emitted. 490 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 491 * Information about included service type (primary/secondary) can be retrieved either by sending 492 * an ATT find information request for the returned start group handle 493 * (returning the handle and the UUID for primary or secondary service) or by comparing the service 494 * to the list of all primary services. 495 * @param callback 496 * @param con_handle 497 * @param service_id - context provided to callback in events 498 * @param connection_id - contest provided to callback in events 499 * @param service_id 500 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 501 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 502 * ERROR_CODE_SUCCESS , if query is successfully registered 503 */ 504 uint8_t gatt_client_find_included_services_for_service_with_context(btstack_packet_handler_t callback, hci_con_handle_t con_handle, 505 gatt_client_service_t * service, uint16_t service_id, uint16_t connection_id); 506 507 /** 508 * @brief Discovers all characteristics within the specified service. 509 * For each found characteristic a GATT_EVENT_CHARACTERISTIC_QUERY_RESULT event will be emited. 510 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 511 * @param callback 512 * @param con_handle 513 * @param service 514 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 515 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 516 * ERROR_CODE_SUCCESS , if query is successfully registered 517 */ 518 uint8_t gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service); 519 520 /** 521 * @brief Discovers all characteristics within the specified service. 522 * For each found characteristic a GATT_EVENT_CHARACTERISTIC_QUERY_RESULT event will be emited. 523 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 524 * @param callback 525 * @param con_handle 526 * @param service 527 * @param service_id - context provided to callback in events 528 * @param connection_id - contest provided to callback in events 529 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 530 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 531 * ERROR_CODE_SUCCESS , if query is successfully registered 532 */ 533 uint8_t gatt_client_discover_characteristics_for_service_with_context(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service, 534 uint16_t service_id, uint16_t connection_id); 535 536 /** 537 * @brief The following four functions are used to discover all characteristics within 538 * the specified service or handle range, and return those that match the given UUID. 539 * 540 * For each found characteristic a GATT_EVENT_CHARACTERISTIC_QUERY_RESULT event will emitted. 541 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 542 * @param callback 543 * @param con_handle 544 * @param start_handle 545 * @param end_handle 546 * @param uuid16 547 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 548 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 549 * ERROR_CODE_SUCCESS , if query is successfully registered 550 */ 551 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); 552 553 /** 554 * @brief The following four functions are used to discover all characteristics within the 555 * specified service or handle range, and return those that match the given UUID. 556 * For each found characteristic a GATT_EVENT_CHARACTERISTIC_QUERY_RESULT event will emitted. 557 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 558 * @param callback 559 * @param con_handle 560 * @param start_handle 561 * @param end_handle 562 * @param uuid128 563 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 564 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 565 * ERROR_CODE_SUCCESS , if query is successfully registered 566 */ 567 uint8_t gatt_client_discover_characteristics_for_handle_range_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t start_handle, uint16_t end_handle, const uint8_t * uuid128); 568 569 /** 570 * @brief The following four functions are used to discover all characteristics within the 571 * specified service or handle range, and return those that match the given UUID. 572 * For each found characteristic a GATT_EVENT_CHARACTERISTIC_QUERY_RESULT event will emitted. 573 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 574 * @param callback 575 * @param con_handle 576 * @param service 577 * @param uuid16 578 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 579 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 580 * ERROR_CODE_SUCCESS , if query is successfully registered 581 */ 582 uint8_t gatt_client_discover_characteristics_for_service_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service, uint16_t uuid16); 583 584 /** 585 * @brief The following four functions are used to discover all characteristics within the 586 * specified service or handle range, and return those that match the given UUID. 587 * For each found characteristic a GATT_EVENT_CHARACTERISTIC_QUERY_RESULT event will emitted. 588 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 589 * @param callback 590 * @param con_handle 591 * @param service 592 * @param uuid128 593 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 594 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 595 * ERROR_CODE_SUCCESS , if query is successfully registered 596 */ 597 uint8_t gatt_client_discover_characteristics_for_service_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service, const uint8_t * uuid128); 598 599 /** 600 * @brief Discovers attribute handle and UUID of a characteristic descriptor within the specified characteristic. 601 * For each found descriptor a GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT event will be emitted. 602 * 603 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 604 * @param callback 605 * @param con_handle 606 * @param characteristic 607 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 608 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 609 * ERROR_CODE_SUCCESS , if query is successfully registered 610 */ 611 uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic); 612 613 614 /** 615 * @brief Discovers attribute handle and UUID of a characteristic descriptor within the specified characteristic. 616 * For each found descriptor a GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT event will be emitted. 617 * 618 * The GATT_EVENT_QUERY_COMPLETE event marks the end of discovery. 619 * @param callback 620 * @param con_handle 621 * @param characteristic 622 * @param service_id - context provided to callback in events 623 * @param connection_id - contest provided to callback in events 624 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 625 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 626 * ERROR_CODE_SUCCESS , if query is successfully registered 627 */ 628 uint8_t gatt_client_discover_characteristic_descriptors_with_context(btstack_packet_handler_t callback, hci_con_handle_t con_handle, 629 gatt_client_characteristic_t * characteristic, uint16_t service_id, uint16_t connection_it); 630 631 /** 632 * @brief Reads the characteristic value using the characteristic's value handle. 633 * If the characteristic value is found a GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT event will be emitted. 634 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 635 * @param callback 636 * @param con_handle 637 * @param characteristic 638 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 639 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 640 * ERROR_CODE_SUCCESS , if query is successfully registered 641 */ 642 uint8_t gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic); 643 644 /** 645 * @brief Reads the characteristic value using the characteristic's value handle. 646 * If the characteristic value is found a GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT event will be emitted. 647 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 648 * @param callback 649 * @param con_handle 650 * @param value_handle 651 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 652 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 653 * ERROR_CODE_SUCCESS , if query is successfully registered 654 */ 655 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); 656 657 /** 658 * @brief Reads the characteristic value using the characteristic's value handle. 659 * If the characteristic value is found a GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT event will be emitted. 660 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 661 * @param callback 662 * @param con_handle 663 * @param value_handle 664 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 665 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 666 * ERROR_CODE_SUCCESS , if query is successfully registered 667 */ 668 uint8_t gatt_client_read_value_of_characteristic_using_value_handle_with_context(btstack_packet_handler_t callback, 669 hci_con_handle_t con_handle, 670 uint16_t value_handle, 671 uint16_t service_id, 672 uint16_t connection_id); 673 674 /** 675 * @brief Reads the characteric value of all characteristics with the uuid. 676 * For each characteristic value found a GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT event will be emitted. 677 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 678 * @param callback 679 * @param con_handle 680 * @param start_handle 681 * @param end_handle 682 * @param uuid16 683 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 684 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 685 * ERROR_CODE_SUCCESS , if query is successfully registered 686 */ 687 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); 688 689 /** 690 * @brief Reads the characteric value of all characteristics with the uuid. 691 * For each characteristic value found a GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT event will be emitted. 692 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 693 * @param callback 694 * @param con_handle 695 * @param start_handle 696 * @param end_handle 697 * @param uuid128 698 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 699 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 700 * ERROR_CODE_SUCCESS , if query is successfully registered 701 */ 702 uint8_t gatt_client_read_value_of_characteristics_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t start_handle, uint16_t end_handle, const uint8_t * uuid128); 703 704 /** 705 * @brief Reads the long characteristic value using the characteristic's value handle. 706 * The value will be returned in several blobs. 707 * For each blob, a GATT_EVENT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT event with updated value offset will be emitted. 708 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 709 * @param callback 710 * @param con_handle 711 * @param characteristic 712 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 713 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 714 * ERROR_CODE_SUCCESS , if query is successfully registered 715 */ 716 uint8_t gatt_client_read_long_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic); 717 718 /** 719 * @brief Reads the long characteristic value using the characteristic's value handle. 720 * The value will be returned in several blobs. 721 * For each blob, a GATT_EVENT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT event with updated value offset will be emitted. 722 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 723 * @param callback 724 * @param con_handle 725 * @param value_handle 726 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 727 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 728 * ERROR_CODE_SUCCESS , if query is successfully registered 729 */ 730 uint8_t gatt_client_read_long_value_of_characteristic_using_value_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle); 731 732 /** 733 * @brief Reads the long characteristic value using the characteristic's value handle. 734 * The value will be returned in several blobs. 735 * For each blob, a GATT_EVENT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT event with updated value offset will be emitted. 736 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 737 * @param callback 738 * @param con_handle 739 * @param value_handle 740 * @param service_id - context provided to callback in events 741 * @param connection_id - contest provided to callback in events 742 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 743 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 744 * ERROR_CODE_SUCCESS , if query is successfully registered 745 */ 746 uint8_t gatt_client_read_long_value_of_characteristic_using_value_handle_with_context(btstack_packet_handler_t callback, 747 hci_con_handle_t con_handle, uint16_t value_handle, 748 uint16_t service_id, uint16_t connection_id); 749 750 /** 751 * @brief Reads the long characteristic value using the characteristic's value handle. 752 * The value will be returned in several blobs. 753 * For each blob, a GATT_EVENT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT event with updated value offset will be emitted. 754 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 755 * @param callback 756 * @param con_handle 757 * @param value_handle 758 * @param offset 759 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 760 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 761 * ERROR_CODE_SUCCESS , if query is successfully registered 762 */ 763 uint8_t gatt_client_read_long_value_of_characteristic_using_value_handle_with_offset(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, uint16_t offset); 764 765 /* 766 * @brief Read multiple characteristic values. 767 * The all results are emitted via single GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT event, 768 * followed by the GATT_EVENT_QUERY_COMPLETE event, which marks the end of read. 769 * @param callback 770 * @param con_handle 771 * @param num_value_handles 772 * @param value_handles list of handles 773 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 774 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 775 * ERROR_CODE_SUCCESS , if query is successfully registered 776 */ 777 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); 778 779 /* 780 * @brief Read multiple varaible characteristic values. Only supported over LE Enhanced Bearer 781 * The all results are emitted via single GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT event, 782 * followed by the GATT_EVENT_QUERY_COMPLETE event, which marks the end of read. 783 * @param callback 784 * @param con_handle 785 * @param num_value_handles 786 * @param value_handles list of handles 787 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 788 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 789 * ERROR_CODE_SUCCESS , if query is successfully registered 790 */ 791 uint8_t gatt_client_read_multiple_variable_characteristic_values(btstack_packet_handler_t callback, hci_con_handle_t con_handle, int num_value_handles, uint16_t * value_handles); 792 793 /** 794 * @brief Writes the characteristic value using the characteristic's value handle without 795 * an acknowledgment that the write was successfully performed. 796 * @param con_handle 797 * @param value_handle 798 * @param value_length 799 * @param value is copied on success and does not need to be retained 800 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 801 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 802 * BTSTACK_ACL_BUFFERS_FULL , if L2CAP cannot send, there are no free ACL slots 803 * ERROR_CODE_SUCCESS , if query is successfully registered 804 */ 805 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); 806 807 /** 808 * @brief Writes the authenticated characteristic value using the characteristic's value handle 809 * without an acknowledgment that the write was successfully performed. 810 * @note GATT_EVENT_QUERY_COMPLETE is emitted with ATT_ERROR_SUCCESS for success, 811 * or ATT_ERROR_BONDING_INFORMATION_MISSING if there is no bonding information stored. 812 * @param callback 813 * @param con_handle 814 * @param value_handle 815 * @param message_len 816 * @param message is not copied, make sure memory is accessible until write is done 817 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 818 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 819 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 820 * ERROR_CODE_SUCCESS if query is successfully registered 821 */ 822 uint8_t gatt_client_signed_write_without_response(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, 823 uint16_t message_len, uint8_t * message); 824 825 /** 826 * @brief Writes the characteristic value using the characteristic's value handle. 827 * The GATT_EVENT_QUERY_COMPLETE event marks the end of write. 828 * The write is successfully performed, if the event's att_status field is set to 829 * ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes). 830 * @param callback 831 * @param con_handle 832 * @param value_handle 833 * @param value_length 834 * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 835 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 836 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 837 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 838 * ERROR_CODE_SUCCESS if query is successfully registered 839 */ 840 uint8_t gatt_client_write_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, uint16_t value_length, uint8_t * value); 841 842 /** 843 * @brief Writes the characteristic value using the characteristic's value handle. 844 * The GATT_EVENT_QUERY_COMPLETE event marks the end of write. 845 * The write is successfully performed, if the event's att_status field is set to 846 * ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes). 847 * @param callback 848 * @param con_handle 849 * @param value_handle 850 * @param value_length 851 * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 852 * @param service_id - context provided to callback in events 853 * @param connection_id - contest provided to callback in events 854 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 855 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 856 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 857 * ERROR_CODE_SUCCESS if query is successfully registered 858 */ 859 uint8_t gatt_client_write_value_of_characteristic_with_context(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, 860 uint16_t value_length, uint8_t * value, uint16_t service_id, uint16_t connection_id); 861 862 /** 863 * @brief Writes the characteristic value using the characteristic's value handle. 864 * The GATT_EVENT_QUERY_COMPLETE event marks the end of write. 865 * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes). 866 * @param callback 867 * @param con_handle 868 * @param value_handle 869 * @param value_length 870 * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 871 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 872 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 873 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 874 * ERROR_CODE_SUCCESS if query is successfully registered 875 */ 876 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); 877 878 /** 879 * @brief Writes the characteristic value using the characteristic's value handle. 880 * The GATT_EVENT_QUERY_COMPLETE event marks the end of write. 881 * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes). 882 * @param callback 883 * @param con_handle 884 * @param value_handle 885 * @param value_length 886 * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 887 * @param service_id - context provided to callback in events 888 * @param connection_id - contest provided to callback in events 889 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 890 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 891 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 892 * ERROR_CODE_SUCCESS if query is successfully registered 893 */ 894 uint8_t gatt_client_write_long_value_of_characteristic_with_context(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, 895 uint16_t value_length, uint8_t * value, uint16_t service_id, uint16_t connection_id); 896 897 /** 898 * @brief Writes the characteristic value using the characteristic's value handle. 899 * The GATT_EVENT_QUERY_COMPLETE event marks the end of write. 900 * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes). 901 * @param callback 902 * @param con_handle 903 * @param value_handle 904 * @param offset of value 905 * @param value_length 906 * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 907 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 908 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 909 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 910 * ERROR_CODE_SUCCESS if query is successfully registered 911 */ 912 uint8_t gatt_client_write_long_value_of_characteristic_with_offset(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, uint16_t offset, uint16_t value_length, uint8_t * value); 913 914 /** 915 * @brief Writes of the long characteristic value using the characteristic's value handle. 916 * It uses server response to validate that the write was correctly received. 917 * The GATT_EVENT_QUERY_COMPLETE EVENT marks the end of write. 918 * The write is successfully performed, if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes). 919 * @param callback 920 * @param con_handle 921 * @param value_handle 922 * @param value_length 923 * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 924 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 925 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 926 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 927 * ERROR_CODE_SUCCESS if query is successfully registered 928 */ 929 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); 930 931 /** 932 * @brief Reads the characteristic descriptor using its handle. 933 * If the characteristic descriptor is found, a GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT event will be emitted. 934 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 935 * @param callback 936 * @param con_handle 937 * @param descriptor 938 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 939 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 940 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 941 * ERROR_CODE_SUCCESS if query is successfully registered 942 */ 943 uint8_t gatt_client_read_characteristic_descriptor(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_descriptor_t * descriptor); 944 945 /** 946 * @brief Reads the characteristic descriptor using its handle. 947 * If the characteristic descriptor is found, a GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT event will be emitted. 948 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 949 * @param callback 950 * @param con_handle 951 * @param descriptor 952 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 953 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 954 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 955 * ERROR_CODE_SUCCESS if query is successfully registered 956 */ 957 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); 958 959 /** 960 * @brief Reads the long characteristic descriptor using its handle. It will be returned in several blobs. 961 * For each blob, a GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT event will be emitted. 962 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 963 * @param callback 964 * @param con_handle 965 * @param descriptor 966 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 967 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 968 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 969 * ERROR_CODE_SUCCESS if query is successfully registered 970 */ 971 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); 972 973 /** 974 * @brief Reads the long characteristic descriptor using its handle. It will be returned in several blobs. 975 * For each blob, a GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT event will be emitted. 976 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 977 * @param callback 978 * @param con_handle 979 * @param descriptor_handle 980 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 981 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 982 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 983 * ERROR_CODE_SUCCESS if query is successfully registered 984 */ 985 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); 986 987 /** 988 * @brief Reads the long characteristic descriptor using its handle. It will be returned in several blobs. 989 * For each blob, a GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT event will be emitted. 990 * The GATT_EVENT_QUERY_COMPLETE event marks the end of read. 991 * @param callback 992 * @param con_handle 993 * @param descriptor_handle 994 * @param offset 995 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 996 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 997 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 998 * ERROR_CODE_SUCCESS if query is successfully registered 999 */ 1000 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); 1001 1002 /** 1003 * @brief Writes the characteristic descriptor using its handle. 1004 * The GATT_EVENT_QUERY_COMPLETE event marks the end of write. 1005 * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes). 1006 * @param callback 1007 * @param con_handle 1008 * @param descriptor 1009 * @param value_length 1010 * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 1011 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 1012 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 1013 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 1014 * ERROR_CODE_SUCCESS if query is successfully registered 1015 */ 1016 uint8_t gatt_client_write_characteristic_descriptor(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_descriptor_t * descriptor, uint16_t value_length, uint8_t * value); 1017 1018 /** 1019 * @brief Writes the characteristic descriptor using its handle. 1020 * The GATT_EVENT_QUERY_COMPLETE event marks the end of write. 1021 * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes). 1022 * @param callback 1023 * @param con_handle 1024 * @param descriptor_handle 1025 * @param value_length 1026 * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 1027 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 1028 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 1029 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 1030 * ERROR_CODE_SUCCESS if query is successfully registered 1031 */ 1032 uint8_t gatt_client_write_characteristic_descriptor_using_descriptor_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t descriptor_handle, uint16_t value_length, uint8_t * value); 1033 1034 /** 1035 * @brief Writes the characteristic descriptor using its handle. 1036 * The GATT_EVENT_QUERY_COMPLETE event marks the end of write. 1037 * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes). 1038 * @param callback 1039 * @param con_handle 1040 * @param descriptor 1041 * @param value_length 1042 * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 1043 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 1044 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 1045 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 1046 * ERROR_CODE_SUCCESS if query is successfully registered 1047 */ 1048 uint8_t gatt_client_write_long_characteristic_descriptor(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_descriptor_t * descriptor, uint16_t value_length, uint8_t * value); 1049 1050 /** 1051 * @brief Writes the characteristic descriptor using its handle. 1052 * The GATT_EVENT_QUERY_COMPLETE event marks the end of write. 1053 * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes). 1054 * @param callback 1055 * @param con_handle 1056 * @param descriptor_handle 1057 * @param value_length 1058 * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 1059 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 1060 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 1061 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 1062 * ERROR_CODE_SUCCESS if query is successfully registered 1063 */ 1064 uint8_t gatt_client_write_long_characteristic_descriptor_using_descriptor_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t descriptor_handle, uint16_t value_length, uint8_t * value); 1065 1066 /** 1067 * @brief Writes the characteristic descriptor using its handle. 1068 * The GATT_EVENT_QUERY_COMPLETE event marks the end of write. 1069 * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes). 1070 * @param callback 1071 * @param con_handle 1072 * @param descriptor_handle 1073 * @param offset of value 1074 * @param value_length 1075 * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 1076 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 1077 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 1078 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 1079 * ERROR_CODE_SUCCESS if query is successfully registered 1080 */ 1081 uint8_t gatt_client_write_long_characteristic_descriptor_using_descriptor_handle_with_offset(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t descriptor_handle, uint16_t offset, uint16_t value_length, uint8_t * value); 1082 1083 /** 1084 * @brief Writes the client characteristic configuration of the specified characteristic. 1085 * It is used to subscribe for notifications or indications of the characteristic value. 1086 * For notifications or indications specify: GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION 1087 * resp. GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION as configuration value. 1088 * The GATT_EVENT_QUERY_COMPLETE event marks the end of write. 1089 * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes). 1090 * @param callback 1091 * @param con_handle 1092 * @param characteristic 1093 * @param configuration GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION 1094 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 1095 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 1096 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 1097 * GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED if configuring notification, but characteristic has no notification property set 1098 * GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED if configuring indication, but characteristic has no indication property set 1099 * ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE if configuration is invalid 1100 * ERROR_CODE_SUCCESS if query is successfully registered 1101 */ 1102 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); 1103 1104 /** 1105 * @brief Writes the client characteristic configuration of the specified characteristic. 1106 * It is used to subscribe for notifications or indications of the characteristic value. 1107 * For notifications or indications specify: GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION 1108 * resp. GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION as configuration value. 1109 * The GATT_EVENT_QUERY_COMPLETE event marks the end of write. 1110 * The write is successfully performed if the event's att_status field is set to ATT_ERROR_SUCCESS (see bluetooth.h for ATT_ERROR codes). 1111 * @param callback 1112 * @param con_handle 1113 * @param characteristic 1114 * @param configuration GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION 1115 * @param service_id - context provided to callback in events 1116 * @param connection_id - contest provided to callback in events 1117 * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found 1118 * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated 1119 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 1120 * GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED if configuring notification, but characteristic has no notification property set 1121 * GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED if configuring indication, but characteristic has no indication property set 1122 * ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE if configuration is invalid 1123 * ERROR_CODE_SUCCESS if query is successfully registered 1124 */ 1125 uint8_t gatt_client_write_client_characteristic_configuration_with_context(btstack_packet_handler_t callback, hci_con_handle_t con_handle, 1126 gatt_client_characteristic_t * characteristic, uint16_t configuration, uint16_t service_id, uint16_t connection_id); 1127 1128 /** 1129 * @brief Register for changes to the Service Changed and Database Hash Characteristics of the remote GATT Service 1130 * * 1131 * When configured, GATT_EVENT_QUERY_COMPLETE event is emitted 1132 * If supported, the Database Hash is read as well 1133 * 1134 * Requires ENABLE_GATT_CLIENT_SERVICE_CHANGED 1135 * 1136 * @param callback 1137 */ 1138 void gatt_client_add_service_changed_handler(btstack_packet_callback_registration_t * callback); 1139 1140 /** 1141 * @brief Remove callback for service changes 1142 * 1143 * Requires ENABLE_GATT_CLIENT_SERVICE_CHANGED 1144 * 1145 * @param callback 1146 */ 1147 void gatt_client_remove_service_changed_handler(btstack_packet_callback_registration_t * callback); 1148 1149 /** 1150 * @brief Register for notifications and indications of a characteristic enabled by 1151 * the gatt_client_write_client_characteristic_configuration function. 1152 * @param notification struct used to store registration 1153 * @param callback 1154 * @param con_handle or GATT_CLIENT_ANY_CONNECTION to receive updates from all connected devices 1155 * @param characteristic or NULL to receive updates for all characteristics 1156 */ 1157 void gatt_client_listen_for_characteristic_value_updates(gatt_client_notification_t * notification, btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic); 1158 1159 /** 1160 * @brief Stop listening to characteristic value updates registered with 1161 * the gatt_client_listen_for_characteristic_value_updates function. 1162 * @param notification struct used in gatt_client_listen_for_characteristic_value_updates 1163 */ 1164 void gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification); 1165 1166 /** 1167 * @brief Transactional write. It can be called as many times as it is needed to write the characteristics within the same transaction. 1168 * Call the gatt_client_execute_write function to commit the transaction. 1169 * @param callback 1170 * @param con_handle 1171 * @param attribute_handle 1172 * @param offset of value 1173 * @param value_length 1174 * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 1175 */ 1176 uint8_t gatt_client_prepare_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t offset, uint16_t value_length, uint8_t * value); 1177 1178 /** 1179 * @brief Commit transactional write. GATT_EVENT_QUERY_COMPLETE is received. 1180 * @param callback 1181 * @param con_handle 1182 * @return status 1183 */ 1184 uint8_t gatt_client_execute_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle); 1185 1186 /** 1187 * @brief Abort transactional write. GATT_EVENT_QUERY_COMPLETE is received. 1188 * @param callback 1189 * @param con_handle 1190 * @return status 1191 */ 1192 uint8_t gatt_client_cancel_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle); 1193 1194 /** 1195 * @brief Request callback when regular gatt query can be sent 1196 * @note callback might happen during call to this function 1197 * @param callback_registration to point to callback function and context information 1198 * @param con_handle 1199 * @return ERROR_CODE_SUCCESS if ok, ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if handle unknown, and ERROR_CODE_COMMAND_DISALLOWED if callback already registered 1200 */ 1201 uint8_t gatt_client_request_to_send_gatt_query(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle); 1202 1203 /** 1204 * @brief Remove queued callback for regular gatt queries, to be used on disconnect for example 1205 * @param callback_registration 1206 * @param con_handle 1207 * @return ERROR_CODE_SUCCESS if ok 1208 */ 1209 uint8_t gatt_client_remove_gatt_query(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle); 1210 1211 /** 1212 * @brief Request callback when writing characteristic value without response is possible 1213 * @note callback might happen during call to this function 1214 * @param callback_registration to point to callback function and context information 1215 * @param con_handle 1216 * @return ERROR_CODE_SUCCESS if ok, ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if handle unknown, and ERROR_CODE_COMMAND_DISALLOWED if callback already registered 1217 */ 1218 uint8_t gatt_client_request_to_write_without_response(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle); 1219 1220 1221 // the following functions are marked as deprecated and will be removed eventually 1222 /** 1223 * @brief Requests GATT_EVENT_CAN_WRITE_WITHOUT_RESPONSE that guarantees 1224 * a single successful gatt_client_write_value_of_characteristic_without_response call. 1225 * @deprecated please use gatt_client_request_to_write_without_response instead 1226 * @param callback 1227 * @param con_handle 1228 * @return status 1229 */ 1230 uint8_t gatt_client_request_can_write_without_response_event(btstack_packet_handler_t callback, hci_con_handle_t con_handle); 1231 1232 1233 /* API_END */ 1234 1235 // used by generated btstack_event.c 1236 1237 void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t * service); 1238 void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic); 1239 void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor); 1240 1241 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 1242 void gatt_client_att_packet_handler_fuzz(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size); 1243 uint8_t gatt_client_get_client(hci_con_handle_t con_handle, gatt_client_t ** gatt_client); 1244 #endif 1245 1246 #if defined __cplusplus 1247 } 1248 #endif 1249 1250 #endif 1251