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 39 #ifndef btstack_gatt_client_h 40 #define btstack_gatt_client_h 41 42 #include "hci.h" 43 44 #if defined __cplusplus 45 extern "C" { 46 #endif 47 48 typedef enum { 49 P_READY, 50 P_W2_SEND_SERVICE_QUERY, 51 P_W4_SERVICE_QUERY_RESULT, 52 P_W2_SEND_SERVICE_WITH_UUID_QUERY, 53 P_W4_SERVICE_WITH_UUID_RESULT, 54 55 P_W2_SEND_ALL_CHARACTERISTICS_OF_SERVICE_QUERY, 56 P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT, 57 P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY, 58 P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT, 59 60 P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY, 61 P_W4_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT, 62 63 P_W2_SEND_INCLUDED_SERVICE_QUERY, 64 P_W4_INCLUDED_SERVICE_QUERY_RESULT, 65 P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY, 66 P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT, 67 68 P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY, 69 P_W4_READ_CHARACTERISTIC_VALUE_RESULT, 70 71 P_W2_SEND_READ_BLOB_QUERY, 72 P_W4_READ_BLOB_RESULT, 73 74 P_W2_SEND_READ_BY_TYPE_REQUEST, 75 P_W4_READ_BY_TYPE_RESPONSE, 76 77 P_W2_SEND_READ_MULTIPLE_REQUEST, 78 P_W4_READ_MULTIPLE_RESPONSE, 79 80 P_W2_SEND_WRITE_CHARACTERISTIC_VALUE, 81 P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT, 82 83 P_W2_PREPARE_WRITE, 84 P_W4_PREPARE_WRITE_RESULT, 85 P_W2_PREPARE_RELIABLE_WRITE, 86 P_W4_PREPARE_RELIABLE_WRITE_RESULT, 87 88 P_W2_EXECUTE_PREPARED_WRITE, 89 P_W4_EXECUTE_PREPARED_WRITE_RESULT, 90 P_W2_CANCEL_PREPARED_WRITE, 91 P_W4_CANCEL_PREPARED_WRITE_RESULT, 92 P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH, 93 P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT, 94 95 #ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY 96 P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY, 97 P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT, 98 #else 99 P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY, 100 P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT, 101 #endif 102 P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION, 103 P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT, 104 105 P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY, 106 P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT, 107 108 P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY, 109 P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT, 110 111 P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR, 112 P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT, 113 114 // all long writes use this 115 P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR, 116 P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT, 117 P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR, 118 P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT, 119 120 // gatt reliable write API use this (manual version of the above) 121 P_W2_PREPARE_WRITE_SINGLE, 122 P_W4_PREPARE_WRITE_SINGLE_RESULT, 123 124 P_W4_IDENTITY_RESOLVING, 125 P_W4_CMAC_READY, 126 P_W4_CMAC_RESULT, 127 P_W2_SEND_SIGNED_WRITE, 128 P_W4_SEND_SINGED_WRITE_DONE, 129 } gatt_client_state_t; 130 131 132 typedef enum{ 133 SEND_MTU_EXCHANGE, 134 SENT_MTU_EXCHANGE, 135 MTU_EXCHANGED, 136 MTU_AUTO_EXCHANGE_DISABLED 137 } gatt_client_mtu_t; 138 139 typedef struct gatt_client{ 140 btstack_linked_item_t item; 141 // TODO: rename gatt_client_state -> state 142 gatt_client_state_t gatt_client_state; 143 144 // user callback 145 btstack_packet_handler_t callback; 146 147 // can write without response callback 148 btstack_packet_handler_t write_without_response_callback; 149 150 hci_con_handle_t con_handle; 151 152 uint16_t mtu; 153 gatt_client_mtu_t mtu_state; 154 155 uint16_t uuid16; 156 uint8_t uuid128[16]; 157 158 uint16_t start_group_handle; 159 uint16_t end_group_handle; 160 161 uint16_t query_start_handle; 162 uint16_t query_end_handle; 163 164 uint8_t characteristic_properties; 165 uint16_t characteristic_start_handle; 166 167 uint16_t attribute_handle; 168 uint16_t attribute_offset; 169 uint16_t attribute_length; 170 uint8_t* attribute_value; 171 172 // read multiple characteristic values 173 uint16_t read_multiple_handle_count; 174 uint16_t * read_multiple_handles; 175 176 uint16_t client_characteristic_configuration_handle; 177 uint8_t client_characteristic_configuration_value[2]; 178 179 uint8_t filter_with_uuid; 180 uint8_t send_confirmation; 181 182 int le_device_index; 183 uint8_t cmac[8]; 184 185 btstack_timer_source_t gc_timeout; 186 187 uint8_t security_counter; 188 uint8_t wait_for_pairing_complete; 189 uint8_t pending_error_code; 190 191 bool reencryption_active; 192 uint8_t reencryption_result; 193 194 gap_security_level_t security_level; 195 196 } gatt_client_t; 197 198 typedef struct gatt_client_notification { 199 btstack_linked_item_t item; 200 btstack_packet_handler_t callback; 201 hci_con_handle_t con_handle; 202 uint16_t attribute_handle; 203 } gatt_client_notification_t; 204 205 /* API_START */ 206 207 typedef struct { 208 uint16_t start_group_handle; 209 uint16_t end_group_handle; 210 uint16_t uuid16; 211 uint8_t uuid128[16]; 212 } gatt_client_service_t; 213 214 typedef struct { 215 uint16_t start_handle; 216 uint16_t value_handle; 217 uint16_t end_handle; 218 uint16_t properties; 219 uint16_t uuid16; 220 uint8_t uuid128[16]; 221 } gatt_client_characteristic_t; 222 223 typedef struct { 224 uint16_t handle; 225 uint16_t uuid16; 226 uint8_t uuid128[16]; 227 } gatt_client_characteristic_descriptor_t; 228 229 /** 230 * @brief Set up GATT client. 231 */ 232 void gatt_client_init(void); 233 234 /** 235 * @brief Set minimum required security level for GATT Client 236 * @note The Bluetooth specification makes the GATT Server responsible to check for security. 237 * This allows an attacker to spoof existing devices with GATT Servers, but skip the authentication part 238 * If your application is exchanging sensitive data from a remote device, you would need to manually check 239 * the security level before sending/receive such data. This function allows to have the GATT Client post-pone 240 * any exchange until the required security level is established. 241 * @pram level, default LEVEL_0 (no encryption required) 242 */ 243 void gatt_client_set_required_security_level(gap_security_level_t level); 244 245 /** 246 * @brief MTU is available after the first query has completed. If status is equal to ERROR_CODE_SUCCESS, it returns the real value, otherwise the default value ATT_DEFAULT_MTU (see bluetooth.h). 247 * @param con_handle 248 * @param mtu 249 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 250 * GATT_CLIENT_IN_WRONG_STATE if MTU is not exchanged and MTU auto-exchange is disabled 251 * ERROR_CODE_SUCCESS if query is successfully registered 252 */ 253 uint8_t gatt_client_get_mtu(hci_con_handle_t con_handle, uint16_t * mtu); 254 255 /** 256 * @brief Sets whether a MTU Exchange Request shall be automatically send before the first attribute read request is send. Default is enabled. 257 * @param enabled 258 */ 259 void gatt_client_mtu_enable_auto_negotiation(uint8_t enabled); 260 261 /** 262 * @brief Sends a MTU Exchange Request, this allows for the client to exchange MTU when gatt_client_mtu_enable_auto_negotiation is disabled. 263 * @param callback 264 * @param con_handle 265 */ 266 void gatt_client_send_mtu_negotiation(btstack_packet_handler_t callback, hci_con_handle_t con_handle); 267 268 /** 269 * @brief Returns if the GATT client is ready to receive a query. It is used with daemon. 270 * @param con_handle 271 * @return is_ready_status 0 - if no GATT client for con_handle is found, or is not ready, otherwise 1 272 */ 273 int gatt_client_is_ready(hci_con_handle_t con_handle); 274 275 /** 276 * @brief Discovers all primary services. For each found service, an le_service_event_t with type set to GATT_EVENT_SERVICE_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t, with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of discovery. 277 * @param callback 278 * @param con_handle 279 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 280 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 281 * ERROR_CODE_SUCCESS , if query is successfully registered 282 */ 283 uint8_t gatt_client_discover_primary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle); 284 285 /** 286 * @brief Discovers a specific primary service given its UUID. This service may exist multiple times. For each found service, an le_service_event_t with type set to GATT_EVENT_SERVICE_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t, with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of discovery. 287 * @param callback 288 * @param con_handle 289 * @param uuid16 290 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 291 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 292 * ERROR_CODE_SUCCESS , if query is successfully registered 293 */ 294 uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16); 295 296 /** 297 * @brief Discovers a specific primary service given its UUID. This service may exist multiple times. For each found service, an le_service_event_t with type set to GATT_EVENT_SERVICE_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t, with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of discovery. 298 * @param callback 299 * @param con_handle 300 * @param uuid128 301 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 302 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 303 * ERROR_CODE_SUCCESS , if query is successfully registered 304 */ 305 uint8_t gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, const uint8_t * uuid128); 306 307 /** 308 * @brief Finds included services within the specified service. For each found included service, an le_service_event_t with type set to GATT_EVENT_INCLUDED_SERVICE_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of discovery. Information about included service type (primary/secondary) can be retrieved either by sending an ATT find information request for the returned start group handle (returning the handle and the UUID for primary or secondary service) or by comparing the service to the list of all primary services. 309 * @param callback 310 * @param con_handle 311 * @param service 312 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 313 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 314 * ERROR_CODE_SUCCESS , if query is successfully registered 315 */ 316 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); 317 318 /** 319 * @brief Discovers all characteristics within the specified service. For each found characteristic, an le_characteristics_event_t with type set to GATT_EVENT_CHARACTERISTIC_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of discovery. 320 * @param callback 321 * @param con_handle 322 * @param service 323 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 324 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 325 * ERROR_CODE_SUCCESS , if query is successfully registered 326 */ 327 uint8_t gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t *service); 328 329 /** 330 * @brief The following four functions are used to discover all characteristics within the specified service or handle range, and return those that match the given UUID. For each found characteristic, an le_characteristic_event_t with type set to GATT_EVENT_CHARACTERISTIC_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of discovery. 331 * @param callback 332 * @param con_handle 333 * @param start_handle 334 * @param end_handle 335 * @param uuid16 336 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 337 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 338 * ERROR_CODE_SUCCESS , if query is successfully registered 339 */ 340 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); 341 342 /** 343 * @brief The following four functions are used to discover all characteristics within the specified service or handle range, and return those that match the given UUID. For each found characteristic, an le_characteristic_event_t with type set to GATT_EVENT_CHARACTERISTIC_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of discovery. 344 * @param callback 345 * @param con_handle 346 * @param start_handle 347 * @param end_handle 348 * @param uuid128 349 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 350 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 351 * ERROR_CODE_SUCCESS , if query is successfully registered 352 */ 353 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); 354 355 /** 356 * @brief The following four functions are used to discover all characteristics within the specified service or handle range, and return those that match the given UUID. For each found characteristic, an le_characteristic_event_t with type set to GATT_EVENT_CHARACTERISTIC_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of discovery. 357 * @param callback 358 * @param con_handle 359 * @param service 360 * @param uuid16 361 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 362 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 363 * ERROR_CODE_SUCCESS , if query is successfully registered 364 */ 365 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); 366 367 /** 368 * @brief The following four functions are used to discover all characteristics within the specified service or handle range, and return those that match the given UUID. For each found characteristic, an le_characteristic_event_t with type set to GATT_EVENT_CHARACTERISTIC_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of discovery. 369 * @param callback 370 * @param con_handle 371 * @param service 372 * @param uuid128 373 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 374 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 375 * ERROR_CODE_SUCCESS , if query is successfully registered 376 */ 377 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, uint8_t * uuid128); 378 379 /** 380 * @brief Discovers attribute handle and UUID of a characteristic descriptor within the specified characteristic. For each found descriptor, an le_characteristic_descriptor_event_t with type set to GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of discovery. 381 * @param callback 382 * @param con_handle 383 * @param characteristic 384 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 385 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 386 * ERROR_CODE_SUCCESS , if query is successfully registered 387 */ 388 uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t *characteristic); 389 390 /** 391 * @brief Reads the characteristic value using the characteristic's value handle. If the characteristic value is found, an le_characteristic_value_event_t with type set to GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of read. 392 * @param callback 393 * @param con_handle 394 * @param characteristic 395 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 396 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 397 * ERROR_CODE_SUCCESS , if query is successfully registered 398 */ 399 uint8_t gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t *characteristic); 400 401 /** 402 * @brief Reads the characteristic value using the characteristic's value handle. If the characteristic value is found, an le_characteristic_value_event_t with type set to GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of read. 403 * @param callback 404 * @param con_handle 405 * @param characteristic_value_handle 406 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 407 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 408 * ERROR_CODE_SUCCESS , if query is successfully registered 409 */ 410 uint8_t gatt_client_read_value_of_characteristic_using_value_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t characteristic_value_handle); 411 412 /** 413 * @brief Reads the characteric value of all characteristics with the uuid. For each found, an le_characteristic_value_event_t with type set to GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of read. 414 * @param callback 415 * @param con_handle 416 * @param start_handle 417 * @param end_handle 418 * @param uuid16 419 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 420 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 421 * ERROR_CODE_SUCCESS , if query is successfully registered 422 */ 423 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); 424 425 /** 426 * @brief Reads the characteric value of all characteristics with the uuid. For each found, an le_characteristic_value_event_t with type set to GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of read. 427 * @param callback 428 * @param con_handle 429 * @param start_handle 430 * @param end_handle 431 * @param uuid128 432 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 433 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 434 * ERROR_CODE_SUCCESS , if query is successfully registered 435 */ 436 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); 437 438 /** 439 * @brief Reads the long characteristic value using the characteristic's value handle. The value will be returned in several blobs. For each blob, an le_characteristic_value_event_t with type set to GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT and updated value offset will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, mark the end of read. 440 * @param callback 441 * @param con_handle 442 * @param characteristic 443 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 444 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 445 * ERROR_CODE_SUCCESS , if query is successfully registered 446 */ 447 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); 448 449 /** 450 * @brief Reads the long characteristic value using the characteristic's value handle. The value will be returned in several blobs. For each blob, an le_characteristic_value_event_t with type set to GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT and updated value offset will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, mark the end of read. 451 * @param callback 452 * @param con_handle 453 * @param characteristic_value_handle 454 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 455 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 456 * ERROR_CODE_SUCCESS , if query is successfully registered 457 */ 458 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); 459 460 /** 461 * @brief Reads the long characteristic value using the characteristic's value handle. The value will be returned in several blobs. For each blob, an le_characteristic_value_event_t with type set to GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT and updated value offset will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, mark the end of read. 462 * @param callback 463 * @param con_handle 464 * @param characteristic_value_handle 465 * @param offset 466 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 467 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 468 * ERROR_CODE_SUCCESS , if query is successfully registered 469 */ 470 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); 471 472 /* 473 * @brief Read multiple characteristic values 474 * @param callback 475 * @param con_handle 476 * @param num_value_handles 477 * @param value_handles list of handles 478 */ 479 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); 480 481 /** 482 * @brief Writes the characteristic value using the characteristic's value handle without an acknowledgment that the write was successfully performed. 483 * @param con_handle 484 * @param characteristic_value_handle 485 * @param length of data 486 * @param data is not copied, make sure memory is accessible until write is done 487 * @return status BTSTACK_MEMORY_ALLOC_FAILED, if no GATT client for con_handle is found 488 * GATT_CLIENT_IN_WRONG_STATE , if GATT client is not ready 489 * BTSTACK_ACL_BUFFERS_FULL , if L2CAP cannot send, there are no free ACL slots 490 * ERROR_CODE_SUCCESS , if query is successfully registered 491 */ 492 uint8_t gatt_client_write_value_of_characteristic_without_response(hci_con_handle_t con_handle, uint16_t characteristic_value_handle, uint16_t length, uint8_t * data); 493 494 /** 495 * @brief Writes the authenticated characteristic value using the characteristic's value handle without an acknowledgment that the write was successfully performed. 496 * @note GATT_EVENT_QUERY_COMPLETE is emitted with 0 for success or ATT_ERROR_BONDING_INFORMATION_MISSING if there is no bonding information stored 497 * @param callback 498 * @param con_handle 499 * @param value_handle 500 * @param message_len 501 * @param message is not copied, make sure memory is accessible until write is done 502 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 503 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 504 * ERROR_CODE_SUCCESS if query is successfully registered 505 */ 506 uint8_t gatt_client_signed_write_without_response(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, uint16_t message_len, uint8_t * message); 507 508 /** 509 * @brief Writes the characteristic value using the characteristic's value handle. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of write. 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). 510 * @param callback 511 * @param con_handle 512 * @param characteristic_value_handle 513 * @param length of data 514 * @param data is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 515 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 516 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 517 * ERROR_CODE_SUCCESS if query is successfully registered 518 */ 519 uint8_t gatt_client_write_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t characteristic_value_handle, uint16_t length, uint8_t * data); 520 521 /** 522 * @brief Writes the characteristic value using the characteristic's value handle. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of write. 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). 523 * @param callback 524 * @param con_handle 525 * @param characteristic_value_handle 526 * @param length of data 527 * @param data is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 528 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 529 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 530 * ERROR_CODE_SUCCESS if query is successfully registered 531 */ 532 uint8_t gatt_client_write_long_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t characteristic_value_handle, uint16_t length, uint8_t * data); 533 534 /** 535 * @brief Writes the characteristic value using the characteristic's value handle. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of write. 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). 536 * @param callback 537 * @param con_handle 538 * @param characteristic_value_handle 539 * @param offset of value 540 * @param length of data 541 * @param data is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 542 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 543 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 544 * ERROR_CODE_SUCCESS if query is successfully registered 545 */ 546 uint8_t gatt_client_write_long_value_of_characteristic_with_offset(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t characteristic_value_handle, uint16_t offset, uint16_t length, uint8_t * data); 547 548 /** 549 * @brief Writes of the long characteristic value using the characteristic's value handle. It uses server response to validate that the write was correctly received. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE marks the end of write. 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). 550 * @param callback 551 * @param con_handle 552 * @param characteristic_value_handle 553 * @param length of data 554 * @param data is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 555 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 556 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 557 * ERROR_CODE_SUCCESS if query is successfully registered 558 */ 559 uint8_t gatt_client_reliable_write_long_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t characteristic_value_handle, uint16_t length, uint8_t * data); 560 561 /** 562 * @brief Reads the characteristic descriptor using its handle. If the characteristic descriptor is found, an le_characteristic_descriptor_event_t with type set to GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of read. 563 * @param callback 564 * @param con_handle 565 * @param descriptor 566 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 567 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 568 * ERROR_CODE_SUCCESS if query is successfully registered 569 */ 570 uint8_t gatt_client_read_characteristic_descriptor(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_descriptor_t * descriptor); 571 572 /** 573 * @brief Reads the characteristic descriptor using its handle. If the characteristic descriptor is found, an le_characteristic_descriptor_event_t with type set to GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of read. 574 * @param callback 575 * @param con_handle 576 * @param descriptor 577 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 578 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 579 * ERROR_CODE_SUCCESS if query is successfully registered 580 */ 581 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); 582 583 /** 584 * @brief Reads the long characteristic descriptor using its handle. It will be returned in several blobs. For each blob, an le_characteristic_descriptor_event_t with type set to GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of read. 585 * @param callback 586 * @param con_handle 587 * @param descriptor_handle 588 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 589 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 590 * ERROR_CODE_SUCCESS if query is successfully registered 591 */ 592 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); 593 594 /** 595 * @brief Reads the long characteristic descriptor using its handle. It will be returned in several blobs. For each blob, an le_characteristic_descriptor_event_t with type set to GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of read. 596 * @param callback 597 * @param con_handle 598 * @param descriptor_handle 599 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 600 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 601 * ERROR_CODE_SUCCESS if query is successfully registered 602 */ 603 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); 604 605 /** 606 * @brief Reads the long characteristic descriptor using its handle. It will be returned in several blobs. For each blob, an le_characteristic_descriptor_event_t with type set to GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of read. 607 * @param callback 608 * @param con_handle 609 * @param descriptor_handle 610 * @param offset 611 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 612 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 613 * ERROR_CODE_SUCCESS if query is successfully registered 614 */ 615 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); 616 617 /** 618 * @brief Writes the characteristic descriptor using its handle. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of write. 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). 619 * @param callback 620 * @param con_handle 621 * @param descriptor 622 * @param length of data 623 * @param data is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 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_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 * data); 629 630 /** 631 * @brief Writes the characteristic descriptor using its handle. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of write. 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). 632 * @param callback 633 * @param con_handle 634 * @param descriptor_handle 635 * @param length of data 636 * @param data is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 637 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 638 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 639 * ERROR_CODE_SUCCESS if query is successfully registered 640 */ 641 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); 642 643 /** 644 * @brief Writes the characteristic descriptor using its handle. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of write. 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). 645 * @param callback 646 * @param con_handle 647 * @param descriptor 648 * @param length of data 649 * @param data is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 650 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 651 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 652 * ERROR_CODE_SUCCESS if query is successfully registered 653 */ 654 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 * data); 655 656 /** 657 * @brief Writes the characteristic descriptor using its handle. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of write. 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). 658 * @param callback 659 * @param con_handle 660 * @param descriptor_handle 661 * @param length of data 662 * @param data is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 663 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 664 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 665 * ERROR_CODE_SUCCESS if query is successfully registered 666 */ 667 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); 668 669 /** 670 * @brief Writes the characteristic descriptor using its handle. The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of write. 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). 671 * @param callback 672 * @param con_handle 673 * @param descriptor_handle 674 * @param offset of value 675 * @param length of data 676 * @param data is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 677 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 678 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 679 * ERROR_CODE_SUCCESS if query is successfully registered 680 */ 681 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); 682 683 /** 684 * @brief Writes the client characteristic configuration of the specified characteristic. It is used to subscribe for notifications or indications of the characteristic value. 685 * For notifications or indications specify: GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION resp. GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION as configuration value. 686 * The gatt_complete_event_t with type set to GATT_EVENT_QUERY_COMPLETE, marks the end of write. The write is successfully performed, if the event's att_status field is set to ATT_ERROR_SUCCESS 687 * (see bluetooth.h for ATT_ERROR codes). 688 * @param callback 689 * @param con_handle 690 * @param characteristic 691 * @param configuration GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION 692 * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found 693 * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready 694 * GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED if configuring notification, but characteristic has no notification property set 695 * GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED if configuring indication, but characteristic has no indication property set 696 * ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE if configuration is invalid 697 * ERROR_CODE_SUCCESS if query is successfully registered 698 */ 699 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); 700 701 /** 702 * @brief Register for notifications and indications of a characteristic enabled by gatt_client_write_client_characteristic_configuration 703 * @param notification struct used to store registration 704 * @param callback 705 * @param con_handle or GATT_CLIENT_ANY_CONNECTION to receive updates from all connected devices 706 * @param characteristic or NULL to receive updates for all characteristics 707 */ 708 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); 709 710 /** 711 * @brief Stop listening to characteristic value updates registered with gatt_client_listen_for_characteristic_value_updates 712 * @param notification struct used in gatt_client_listen_for_characteristic_value_updates 713 */ 714 void gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification); 715 716 /** 717 * @brief Requests GATT_EVENT_CAN_WRITE_WITHOUT_RESPONSE that guarantees a single successful gatt_client_write_value_of_characteristic_without_response 718 * @param callback 719 * @param con_handle 720 * @returns status 721 */ 722 uint8_t gatt_client_request_can_write_without_response_event(btstack_packet_handler_t callback, hci_con_handle_t con_handle); 723 724 /** 725 * @brief Transactional write. It can be called as many times as it is needed to write the characteristics within the same transaction. Call gatt_client_execute_write to commit the transaction. 726 * @param callback 727 * @param con_handle 728 * @param attribute_handle 729 * @param offset of value 730 * @param length of data 731 * @param data is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received 732 */ 733 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); 734 735 /** 736 * @brief Commit transactional write. GATT_EVENT_QUERY_COMPLETE is received. 737 * @param callback 738 * @param con_handle 739 */ 740 uint8_t gatt_client_execute_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle); 741 742 /** 743 * @brief Abort transactional write. GATT_EVENT_QUERY_COMPLETE is received. 744 * @param callback 745 * @param con_handle 746 */ 747 uint8_t gatt_client_cancel_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle); 748 749 /* API_END */ 750 751 // used by generated btstack_event.c 752 753 void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t *service); 754 void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic); 755 void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor); 756 757 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 758 void gatt_client_att_packet_handler_fuzz(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size); 759 #endif 760 761 #if defined __cplusplus 762 } 763 #endif 764 765 #endif 766