From 40faeb84f8b4da73ab0a98e48bed751325c25bfc Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Tue, 10 Jan 2023 15:59:38 +0100 Subject: [PATCH] gatt_client: return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER for invalid connection handle --- CHANGELOG.md | 1 + src/ble/gatt_client.c | 376 ++++++++++++++++++-------- src/ble/gatt_client.h | 55 ++-- test/gatt_client/gatt_client_test.cpp | 75 ++--- 4 files changed, 345 insertions(+), 162 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba5e4a1a4..b03b66935 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Fixed - btstack_stdin_embedded: use timer to poll RTT input, fix for tickless RTOS +- gatt_client: return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER for invalid connection handle ## Changed diff --git a/src/ble/gatt_client.c b/src/ble/gatt_client.c index e1d1a3cc4..55b5ed18a 100644 --- a/src/ble/gatt_client.c +++ b/src/ble/gatt_client.c @@ -154,18 +154,27 @@ static gatt_client_t * gatt_client_get_context_for_handle(uint16_t handle){ // @return gatt_client context // returns existing one, or tries to setup new one -static gatt_client_t * gatt_client_provide_context_for_handle(hci_con_handle_t con_handle){ +static uint8_t gatt_client_provide_context_for_handle(hci_con_handle_t con_handle, gatt_client_t ** out_gatt_client){ gatt_client_t * gatt_client = gatt_client_get_context_for_handle(con_handle); - if (gatt_client != NULL) return gatt_client; + + if (gatt_client != NULL){ + *out_gatt_client = gatt_client; + return ERROR_CODE_SUCCESS; + } // bail if no such hci connection hci_connection_t * hci_connection = hci_connection_for_handle(con_handle); if (hci_connection == NULL){ log_error("No connection for handle 0x%04x", con_handle); - return NULL; + *out_gatt_client = NULL; + return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; } + gatt_client = btstack_memory_gatt_client_get(); - if (!gatt_client) return NULL; + if (gatt_client == NULL){ + *out_gatt_client = NULL; + return ERROR_CODE_MEMORY_CAPACITY_EXCEEDED; + } // init state gatt_client->con_handle = con_handle; gatt_client->mtu = ATT_DEFAULT_MTU; @@ -183,15 +192,17 @@ static gatt_client_t * gatt_client_provide_context_for_handle(hci_con_handle_t c gatt_client->mtu = hci_connection->att_connection.mtu; gatt_client->mtu_state = MTU_EXCHANGED; } - - return gatt_client; + *out_gatt_client = gatt_client; + return ERROR_CODE_SUCCESS; } -static gatt_client_t * gatt_client_provide_context_for_handle_and_start_timer(hci_con_handle_t con_handle){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle(con_handle); - if (gatt_client == NULL) return NULL; - gatt_client_timeout_start(gatt_client); - return gatt_client; +static uint8_t gatt_client_provide_context_for_handle_and_start_timer(hci_con_handle_t con_handle, gatt_client_t ** out_gatt_client){ + uint8_t status = gatt_client_provide_context_for_handle(con_handle, out_gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + gatt_client_timeout_start(*out_gatt_client); + return status; } static bool is_ready(gatt_client_t * gatt_client){ @@ -199,8 +210,11 @@ static bool is_ready(gatt_client_t * gatt_client){ } int gatt_client_is_ready(hci_con_handle_t con_handle){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle(con_handle); - if (gatt_client == NULL) return 0; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return 0; + } return is_ready(gatt_client) ? 1 : 0; } @@ -209,8 +223,11 @@ void gatt_client_mtu_enable_auto_negotiation(uint8_t enabled){ } uint8_t gatt_client_get_mtu(hci_con_handle_t con_handle, uint16_t * mtu){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } if ((gatt_client->mtu_state == MTU_EXCHANGED) || (gatt_client->mtu_state == MTU_AUTO_EXCHANGE_DISABLED)){ *mtu = gatt_client->mtu; @@ -1331,7 +1348,7 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, report_gatt_notification(handle, little_endian_read_16(packet,1u), &packet[3], size-3u); return; case ATT_HANDLE_VALUE_INDICATION: - gatt_client = gatt_client_provide_context_for_handle(handle); + gatt_client_provide_context_for_handle(handle, &gatt_client); break; default: gatt_client = gatt_client_get_context_for_handle(handle); @@ -1824,9 +1841,14 @@ static void att_signed_write_handle_cmac_result(uint8_t hash[8]){ } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->attribute_handle = value_handle; @@ -1839,9 +1861,14 @@ uint8_t gatt_client_signed_write_without_response(btstack_packet_handler_t callb #endif uint8_t gatt_client_discover_primary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->start_group_handle = 0x0001; @@ -1853,9 +1880,14 @@ uint8_t gatt_client_discover_primary_services(btstack_packet_handler_t callback, } uint8_t gatt_client_discover_secondary_services(btstack_packet_handler_t callback, hci_con_handle_t con_handle){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->start_group_handle = 0x0001; @@ -1867,9 +1899,14 @@ uint8_t gatt_client_discover_secondary_services(btstack_packet_handler_t callbac } uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->start_group_handle = 0x0001; @@ -1882,9 +1919,14 @@ uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t } uint8_t gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, const uint8_t * uuid128){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->start_group_handle = 0x0001; @@ -1897,9 +1939,14 @@ uint8_t gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_ } uint8_t gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->start_group_handle = service->start_group_handle; @@ -1912,9 +1959,14 @@ uint8_t gatt_client_discover_characteristics_for_service(btstack_packet_handler_ } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->start_group_handle = service->start_group_handle; gatt_client->end_group_handle = service->end_group_handle; @@ -1925,9 +1977,14 @@ uint8_t gatt_client_find_included_services_for_service(btstack_packet_handler_t } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->start_group_handle = start_handle; @@ -1942,9 +1999,14 @@ uint8_t gatt_client_discover_characteristics_for_handle_range_by_uuid16(btstack_ } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->start_group_handle = start_handle; @@ -1968,9 +2030,14 @@ uint8_t gatt_client_discover_characteristics_for_service_by_uuid128(btstack_pack } uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } if (characteristic->value_handle == characteristic->end_handle){ emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS); @@ -1985,9 +2052,14 @@ uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->attribute_handle = value_handle; @@ -1998,9 +2070,14 @@ uint8_t gatt_client_read_value_of_characteristic_using_value_handle(btstack_pack } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->start_group_handle = start_handle; @@ -2015,9 +2092,14 @@ uint8_t gatt_client_read_value_of_characteristics_by_uuid16(btstack_packet_handl } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->start_group_handle = start_handle; @@ -2037,9 +2119,14 @@ uint8_t gatt_client_read_value_of_characteristic(btstack_packet_handler_t callba } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->attribute_handle = value_handle; @@ -2058,9 +2145,14 @@ uint8_t gatt_client_read_long_value_of_characteristic(btstack_packet_handler_t c } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->read_multiple_handle_count = num_value_handles; @@ -2071,8 +2163,11 @@ uint8_t gatt_client_read_multiple_characteristic_values(btstack_packet_handler_t } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } if (value_length > (gatt_client->mtu - 3u)) return GATT_CLIENT_VALUE_TOO_LONG; if (!att_dispatch_client_can_send_now(gatt_client->con_handle)) return GATT_CLIENT_BUSY; @@ -2081,9 +2176,14 @@ uint8_t gatt_client_write_value_of_characteristic_without_response(hci_con_handl } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->attribute_handle = value_handle; @@ -2095,9 +2195,14 @@ uint8_t gatt_client_write_value_of_characteristic(btstack_packet_handler_t callb } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->attribute_handle = value_handle; @@ -2114,9 +2219,14 @@ uint8_t gatt_client_write_long_value_of_characteristic(btstack_packet_handler_t } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->attribute_handle = value_handle; @@ -2129,9 +2239,14 @@ uint8_t gatt_client_reliable_write_long_value_of_characteristic(btstack_packet_h } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } if ( (configuration & GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION) && ((characteristic->properties & ATT_PROPERTY_NOTIFY) == 0u)) { @@ -2158,9 +2273,14 @@ uint8_t gatt_client_write_client_characteristic_configuration(btstack_packet_han } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->attribute_handle = descriptor_handle; @@ -2175,9 +2295,14 @@ uint8_t gatt_client_read_characteristic_descriptor(btstack_packet_handler_t call } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->attribute_handle = descriptor_handle; @@ -2196,9 +2321,14 @@ uint8_t gatt_client_read_long_characteristic_descriptor(btstack_packet_handler_t } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->attribute_handle = descriptor_handle; @@ -2215,9 +2345,14 @@ uint8_t gatt_client_write_characteristic_descriptor(btstack_packet_handler_t cal } 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->attribute_handle = descriptor_handle; @@ -2241,9 +2376,14 @@ uint8_t gatt_client_write_long_characteristic_descriptor(btstack_packet_handler_ * @brief -> gatt complete event */ 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){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->attribute_handle = attribute_handle; @@ -2259,10 +2399,14 @@ uint8_t gatt_client_prepare_write(btstack_packet_handler_t callback, hci_con_han * @brief -> gatt complete event */ uint8_t gatt_client_execute_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE; @@ -2274,9 +2418,14 @@ uint8_t gatt_client_execute_write(btstack_packet_handler_t callback, hci_con_han * @brief -> gatt complete event */ uint8_t gatt_client_cancel_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle){ - gatt_client_t * gatt_client = gatt_client_provide_context_for_handle_and_start_timer(con_handle); - if (gatt_client == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (is_ready(gatt_client) == 0) return GATT_CLIENT_IN_WRONG_STATE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle_and_start_timer(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (is_ready(gatt_client) == 0){ + return GATT_CLIENT_IN_WRONG_STATE; + } gatt_client->callback = callback; gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE; @@ -2319,21 +2468,29 @@ void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, i } void gatt_client_send_mtu_negotiation(btstack_packet_handler_t callback, hci_con_handle_t con_handle){ - gatt_client_t * context = gatt_client_provide_context_for_handle(con_handle); - if (context == NULL) return; - if (context->mtu_state == MTU_AUTO_EXCHANGE_DISABLED){ - context->callback = callback; - context->mtu_state = SEND_MTU_EXCHANGE; + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return; + } + if (gatt_client->mtu_state == MTU_AUTO_EXCHANGE_DISABLED){ + gatt_client->callback = callback; + gatt_client->mtu_state = SEND_MTU_EXCHANGE; gatt_client_run(); } } uint8_t gatt_client_request_can_write_without_response_event(btstack_packet_handler_t callback, hci_con_handle_t con_handle){ - gatt_client_t * context = gatt_client_provide_context_for_handle(con_handle); - if (context == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; - if (context->write_without_response_callback != NULL) return GATT_CLIENT_IN_WRONG_STATE; - context->write_without_response_callback = callback; - att_dispatch_client_request_can_send_now_event(context->con_handle); + gatt_client_t * gatt_client; + uint8_t status = gatt_client_provide_context_for_handle(con_handle, &gatt_client); + if (status != ERROR_CODE_SUCCESS){ + return status; + } + if (gatt_client->write_without_response_callback != NULL){ + return GATT_CLIENT_IN_WRONG_STATE; + } + gatt_client->write_without_response_callback = callback; + att_dispatch_client_request_can_send_now_event(gatt_client->con_handle); return ERROR_CODE_SUCCESS; } @@ -2342,7 +2499,8 @@ void gatt_client_att_packet_handler_fuzz(uint8_t packet_type, uint16_t handle, u gatt_client_att_packet_handler(packet_type, handle, packet, size); } -gatt_client_t * gatt_client_get_client(hci_con_handle_t con_handle){ - return gatt_client_provide_context_for_handle(con_handle); +uint8_t gatt_client_get_client(hci_con_handle_t con_handle, gatt_client_t ** out_gatt_client){ + uint8_t status = gatt_client_provide_context_for_handle(con_handle, out_gatt_client); + return status; } #endif diff --git a/src/ble/gatt_client.h b/src/ble/gatt_client.h index 47bd085c2..104b2c581 100644 --- a/src/ble/gatt_client.h +++ b/src/ble/gatt_client.h @@ -253,7 +253,8 @@ void gatt_client_set_required_security_level(gap_security_level_t level); * otherwise the default value ATT_DEFAULT_MTU (see bluetooth.h). * @param con_handle * @param mtu - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if MTU is not exchanged and MTU auto-exchange is disabled * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -575,7 +576,8 @@ uint8_t gatt_client_write_value_of_characteristic_without_response(hci_con_handl * @param value_handle * @param message_len * @param message is not copied, make sure memory is accessible until write is done - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -591,7 +593,8 @@ uint8_t gatt_client_signed_write_without_response(btstack_packet_handler_t callb * @param value_handle * @param value_length * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -606,7 +609,8 @@ uint8_t gatt_client_write_value_of_characteristic(btstack_packet_handler_t callb * @param value_handle * @param value_length * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -622,7 +626,8 @@ uint8_t gatt_client_write_long_value_of_characteristic(btstack_packet_handler_t * @param offset of value * @param value_length * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -638,7 +643,8 @@ uint8_t gatt_client_write_long_value_of_characteristic_with_offset(btstack_packe * @param value_handle * @param value_length * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -651,7 +657,8 @@ uint8_t gatt_client_reliable_write_long_value_of_characteristic(btstack_packet_h * @param callback * @param con_handle * @param descriptor - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -664,7 +671,8 @@ uint8_t gatt_client_read_characteristic_descriptor(btstack_packet_handler_t call * @param callback * @param con_handle * @param descriptor - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -677,7 +685,8 @@ uint8_t gatt_client_read_characteristic_descriptor_using_descriptor_handle(btsta * @param callback * @param con_handle * @param descriptor - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -690,7 +699,8 @@ uint8_t gatt_client_read_long_characteristic_descriptor(btstack_packet_handler_t * @param callback * @param con_handle * @param descriptor_handle - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -704,7 +714,8 @@ uint8_t gatt_client_read_long_characteristic_descriptor_using_descriptor_handle( * @param con_handle * @param descriptor_handle * @param offset - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -719,7 +730,8 @@ uint8_t gatt_client_read_long_characteristic_descriptor_using_descriptor_handle_ * @param descriptor * @param value_length * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -734,7 +746,8 @@ uint8_t gatt_client_write_characteristic_descriptor(btstack_packet_handler_t cal * @param descriptor_handle * @param value_length * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -749,7 +762,8 @@ uint8_t gatt_client_write_characteristic_descriptor_using_descriptor_handle(btst * @param descriptor * @param value_length * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -764,7 +778,8 @@ uint8_t gatt_client_write_long_characteristic_descriptor(btstack_packet_handler_ * @param descriptor_handle * @param value_length * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -780,7 +795,8 @@ uint8_t gatt_client_write_long_characteristic_descriptor_using_descriptor_handle * @param offset of value * @param value_length * @param value is not copied, make sure memory is accessible until write is done, i.e. GATT_EVENT_QUERY_COMPLETE is received - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * ERROR_CODE_SUCCESS if query is successfully registered */ @@ -797,7 +813,8 @@ uint8_t gatt_client_write_long_characteristic_descriptor_using_descriptor_handle * @param con_handle * @param characteristic * @param configuration GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION - * @return status BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle is found + * @return status ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if no HCI connection for con_handle is found + * BTSTACK_MEMORY_ALLOC_FAILED if no GATT client for con_handle could be allocated * GATT_CLIENT_IN_WRONG_STATE if GATT client is not ready * GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED if configuring notification, but characteristic has no notification property set * GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED if configuring indication, but characteristic has no indication property set @@ -848,6 +865,7 @@ uint8_t gatt_client_prepare_write(btstack_packet_handler_t callback, hci_con_han * @brief Commit transactional write. GATT_EVENT_QUERY_COMPLETE is received. * @param callback * @param con_handle + * @return status */ uint8_t gatt_client_execute_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle); @@ -855,6 +873,7 @@ uint8_t gatt_client_execute_write(btstack_packet_handler_t callback, hci_con_han * @brief Abort transactional write. GATT_EVENT_QUERY_COMPLETE is received. * @param callback * @param con_handle + * @return status */ uint8_t gatt_client_cancel_write(btstack_packet_handler_t callback, hci_con_handle_t con_handle); @@ -868,7 +887,7 @@ void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, i #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION void gatt_client_att_packet_handler_fuzz(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size); -gatt_client_t * gatt_client_get_client(hci_con_handle_t con_handle); +uint8_t gatt_client_get_client(hci_con_handle_t con_handle, gatt_client_t ** gatt_client); #endif #if defined __cplusplus diff --git a/test/gatt_client/gatt_client_test.cpp b/test/gatt_client/gatt_client_test.cpp index e48d6803d..e71d3785a 100644 --- a/test/gatt_client/gatt_client_test.cpp +++ b/test/gatt_client/gatt_client_test.cpp @@ -303,9 +303,16 @@ TEST_GROUP(GATTClient){ hci_setup_le_connection(gatt_client_handle); } + gatt_client_t * get_gatt_client(hci_con_handle_t con_handle){ + gatt_client_t * gatt_client; + (void) gatt_client_get_client(gatt_client_handle, &gatt_client); + return gatt_client; + } + void reset_query_state(void){ - gatt_client_t * gatt_client = gatt_client_get_client(gatt_client_handle); + gatt_client_t * gatt_client = get_gatt_client(gatt_client_handle); gatt_client->gatt_client_state = P_READY; + gatt_client_set_required_security_level(LEVEL_0); gatt_client_mtu_enable_auto_negotiation(1); @@ -315,7 +322,7 @@ TEST_GROUP(GATTClient){ } void set_wrong_gatt_client_state(void){ - gatt_client_t * gatt_client = gatt_client_get_client(gatt_client_handle); + gatt_client_t * gatt_client = get_gatt_client(gatt_client_handle); CHECK_TRUE(gatt_client != NULL); gatt_client->gatt_client_state = P_W2_SEND_SERVICE_QUERY; } @@ -335,7 +342,7 @@ TEST(GATTClient, gatt_client_is_ready_mtu_exchange_disabled){ TEST(GATTClient, TestDiscoverPrimaryServices){ test = DISCOVER_PRIMARY_SERVICES; status = gatt_client_discover_primary_services(handle_ble_client_event, HCI_CON_HANDLE_INVALID); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_discover_primary_services(handle_ble_client_event, gatt_client_handle); @@ -369,7 +376,7 @@ TEST(GATTClient, TestDiscoverPrimaryServicesByUUID128){ // invalid con handle status = gatt_client_discover_primary_services_by_uuid128(handle_ble_client_event, HCI_CON_HANDLE_INVALID, primary_service_uuid128); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_discover_primary_services_by_uuid128(handle_ble_client_event, gatt_client_handle, primary_service_uuid128); @@ -405,7 +412,7 @@ TEST(GATTClient, TestFindIncludedServicesForServiceWithUUID128){ // invalid con handle status = gatt_client_find_included_services_for_service(handle_ble_client_event, HCI_CON_HANDLE_INVALID, &services[0]); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_find_included_services_for_service(handle_ble_client_event, gatt_client_handle, &services[0]); @@ -427,7 +434,7 @@ TEST(GATTClient, TestDiscoverCharacteristicsForService){ // invalid con handle status = gatt_client_discover_characteristics_for_service(handle_ble_client_event, HCI_CON_HANDLE_INVALID, &services[0]); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_discover_characteristics_for_service(handle_ble_client_event, gatt_client_handle, &services[0]); @@ -444,7 +451,7 @@ TEST(GATTClient, TestDiscoverCharacteristicsByUUID16){ // invalid con handle status = gatt_client_discover_characteristics_for_handle_range_by_uuid16(handle_ble_client_event, HCI_CON_HANDLE_INVALID, 0x30, 0x32, 0xF102); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_discover_characteristics_for_handle_range_by_uuid16(handle_ble_client_event, gatt_client_handle, 0x30, 0x32, 0xF102); @@ -461,7 +468,7 @@ TEST(GATTClient, TestDiscoverCharacteristicsByUUID128){ // invalid con handle status = gatt_client_discover_characteristics_for_handle_range_by_uuid128(handle_ble_client_event, HCI_CON_HANDLE_INVALID, characteristic_handles[1][0], characteristic_handles[1][1], characteristic_uuids[1]); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_discover_characteristics_for_handle_range_by_uuid128(handle_ble_client_event, gatt_client_handle, characteristic_handles[1][0], characteristic_handles[1][1], characteristic_uuids[1]); @@ -518,7 +525,7 @@ TEST(GATTClient, TestDiscoverCharacteristicDescriptor){ reset_query_state(); // invalid con handle status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, HCI_CON_HANDLE_INVALID, service_uuid16); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); @@ -563,7 +570,7 @@ TEST(GATTClient, TestWriteClientCharacteristicConfiguration){ // invalid con handle status = gatt_client_write_client_characteristic_configuration(handle_ble_client_event, HCI_CON_HANDLE_INVALID, &characteristics[0], GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_write_client_characteristic_configuration(handle_ble_client_event, gatt_client_handle, &characteristics[0], GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION); @@ -608,7 +615,7 @@ TEST(GATTClient, TestReadCharacteristicDescriptor){ // invalid con handle status = gatt_client_discover_characteristic_descriptors(handle_ble_client_event, HCI_CON_HANDLE_INVALID, &characteristics[0]); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_discover_characteristic_descriptors(handle_ble_client_event, gatt_client_handle, &characteristics[0]); @@ -629,7 +636,7 @@ TEST(GATTClient, TestReadCharacteristicDescriptor){ // invalid con handle status = gatt_client_read_characteristic_descriptor(handle_ble_client_event, HCI_CON_HANDLE_INVALID, &descriptors[0]); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_read_characteristic_descriptor(handle_ble_client_event, gatt_client_handle, &descriptors[0]); @@ -652,7 +659,7 @@ TEST(GATTClient, gatt_client_read_value_of_characteristic_using_value_handle){ // invalid con handle status = gatt_client_read_value_of_characteristic_using_value_handle(handle_ble_client_event, HCI_CON_HANDLE_INVALID, characteristics[0].value_handle); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_read_value_of_characteristic_using_value_handle(handle_ble_client_event, gatt_client_handle, characteristics[0].value_handle); @@ -676,7 +683,7 @@ TEST(GATTClient, gatt_client_read_long_value_of_characteristic_using_value_handl // invalid con handle status = gatt_client_read_long_value_of_characteristic_using_value_handle_with_offset(handle_ble_client_event, HCI_CON_HANDLE_INVALID, characteristics[0].value_handle, 0); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_read_long_value_of_characteristic_using_value_handle_with_offset(handle_ble_client_event, gatt_client_handle, characteristics[0].value_handle, 0); @@ -706,7 +713,7 @@ TEST(GATTClient, gatt_client_read_value_of_characteristics_by_uuid16){ // invalid con handle status = gatt_client_read_value_of_characteristics_by_uuid16(handle_ble_client_event, HCI_CON_HANDLE_INVALID, characteristics[0].start_handle, characteristics[0].end_handle, characteristics[0].uuid16); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_read_value_of_characteristics_by_uuid16(handle_ble_client_event, gatt_client_handle, characteristics[0].start_handle, characteristics[0].end_handle, characteristics[0].uuid16); @@ -735,7 +742,7 @@ TEST(GATTClient, gatt_client_read_value_of_characteristics_by_uuid128){ // invalid con handle status = gatt_client_read_value_of_characteristics_by_uuid128(handle_ble_client_event, HCI_CON_HANDLE_INVALID, characteristics[0].start_handle, characteristics[0].end_handle, characteristics[0].uuid128); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_read_value_of_characteristics_by_uuid128(handle_ble_client_event, gatt_client_handle, characteristics[0].start_handle, characteristics[0].end_handle, characteristics[0].uuid128); @@ -770,7 +777,7 @@ TEST(GATTClient, gatt_client_write_characteristic_descriptor_using_descriptor_ha // invalid con handle status = gatt_client_write_characteristic_descriptor_using_descriptor_handle(handle_ble_client_event, HCI_CON_HANDLE_INVALID, descriptors[0].handle, characteristics[0].end_handle, characteristics[0].uuid128); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_write_characteristic_descriptor_using_descriptor_handle(handle_ble_client_event, gatt_client_handle, descriptors[0].handle, characteristics[0].end_handle, characteristics[0].uuid128); @@ -797,7 +804,7 @@ TEST(GATTClient, gatt_client_prepare_write){ // invalid con handle status = gatt_client_prepare_write(handle_ble_client_event, HCI_CON_HANDLE_INVALID, characteristics[0].value_handle, 0, short_value_length, (uint8_t*)short_value); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_prepare_write(handle_ble_client_event, gatt_client_handle, characteristics[0].value_handle, 0, short_value_length, (uint8_t*)short_value); @@ -812,7 +819,7 @@ TEST(GATTClient, gatt_client_execute_write){ // invalid con handle status = gatt_client_execute_write(handle_ble_client_event, HCI_CON_HANDLE_INVALID); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_execute_write(handle_ble_client_event, gatt_client_handle); @@ -827,7 +834,7 @@ TEST(GATTClient, gatt_client_cancel_write){ // invalid con handle status = gatt_client_cancel_write(handle_ble_client_event, HCI_CON_HANDLE_INVALID); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_cancel_write(handle_ble_client_event, gatt_client_handle); @@ -872,7 +879,7 @@ TEST(GATTClient, TestWriteCharacteristicValue){ // invalid con handle status = gatt_client_write_value_of_characteristic(handle_ble_client_event, HCI_CON_HANDLE_INVALID, characteristics[0].value_handle, short_value_length, (uint8_t*)short_value); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_write_value_of_characteristic(handle_ble_client_event, gatt_client_handle, characteristics[0].value_handle, short_value_length, (uint8_t*)short_value); @@ -1025,7 +1032,7 @@ TEST(GATTClient, TestWriteReliableLongCharacteristicValue){ // invalid con handle status = gatt_client_reliable_write_long_value_of_characteristic(handle_ble_client_event, HCI_CON_HANDLE_INVALID, characteristics[0].value_handle, long_value_length, (uint8_t*)long_value); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); set_wrong_gatt_client_state(); status = gatt_client_reliable_write_long_value_of_characteristic(handle_ble_client_event, gatt_client_handle, characteristics[0].value_handle, long_value_length, (uint8_t*)long_value); @@ -1057,7 +1064,7 @@ TEST(GATTClient, gatt_client_write_long_value_of_characteristic_with_offset){ reset_query_state(); // invalid con handle status = gatt_client_write_long_value_of_characteristic_with_offset(handle_ble_client_event, HCI_CON_HANDLE_INVALID, characteristics[0].value_handle, 0, long_value_length, (uint8_t*)long_value); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); reset_query_state(); set_wrong_gatt_client_state(); @@ -1089,7 +1096,7 @@ TEST(GATTClient, gatt_client_read_long_characteristic_descriptor_using_descripto reset_query_state(); // invalid con handle status = gatt_client_read_long_characteristic_descriptor_using_descriptor_handle_with_offset(handle_ble_client_event, HCI_CON_HANDLE_INVALID, descriptors[0].handle, 0); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); reset_query_state(); set_wrong_gatt_client_state(); @@ -1119,7 +1126,7 @@ TEST(GATTClient, gatt_client_read_multiple_characteristic_values){ reset_query_state(); // invalid con handle status = gatt_client_read_multiple_characteristic_values(handle_ble_client_event, HCI_CON_HANDLE_INVALID, 1, value_handles); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); reset_query_state(); set_wrong_gatt_client_state(); @@ -1140,12 +1147,10 @@ TEST(GATTClient, gatt_client_write_value_of_characteristic_without_response){ CHECK_EQUAL(1, gatt_query_complete); CHECK_EQUAL(1, result_counter); - uint16_t value_handles[] = {characteristics[0].value_handle}; - reset_query_state(); // invalid con handle status = gatt_client_write_value_of_characteristic_without_response(HCI_CON_HANDLE_INVALID, characteristics[0].value_handle, long_value_length, (uint8_t*)long_value); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); reset_query_state(); set_wrong_gatt_client_state(); @@ -1205,7 +1210,7 @@ TEST(GATTClient, gatt_client_signed_write_without_response){ reset_query_state(); // invalid con handle status = gatt_client_signed_write_without_response(handle_ble_client_event, HCI_CON_HANDLE_INVALID, characteristics[0].value_handle, long_value_length, (uint8_t*)long_value); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); reset_query_state(); set_wrong_gatt_client_state(); @@ -1222,7 +1227,7 @@ TEST(GATTClient, gatt_client_discover_secondary_services){ reset_query_state(); // invalid con handle status = gatt_client_discover_secondary_services(handle_ble_client_event, HCI_CON_HANDLE_INVALID); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); reset_query_state(); set_wrong_gatt_client_state(); @@ -1237,9 +1242,9 @@ TEST(GATTClient, gatt_client_discover_secondary_services){ TEST(GATTClient, gatt_client_request_can_write_without_response_event){ int status = gatt_client_request_can_write_without_response_event(handle_ble_client_event, HCI_CON_HANDLE_INVALID); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); - gatt_client_t * gatt_client = gatt_client_get_client(gatt_client_handle); + gatt_client_t * gatt_client = get_gatt_client(gatt_client_handle); CHECK_TRUE(gatt_client != NULL); btstack_packet_handler_t write_without_response_callback; gatt_client->write_without_response_callback = write_without_response_callback; @@ -1256,7 +1261,7 @@ TEST(GATTClient, gatt_client_send_mtu_negotiation){ gatt_client_send_mtu_negotiation(handle_ble_client_event, gatt_client_handle); - gatt_client_t * gatt_client = gatt_client_get_client(gatt_client_handle); + gatt_client_t * gatt_client = get_gatt_client(gatt_client_handle); CHECK_TRUE(gatt_client != NULL); gatt_client->mtu_state = MTU_AUTO_EXCHANGE_DISABLED; gatt_client_send_mtu_negotiation(handle_ble_client_event, gatt_client_handle); @@ -1268,13 +1273,13 @@ TEST(GATTClient, gatt_client_get_mtu){ reset_query_state(); uint16_t mtu; int status = gatt_client_get_mtu(HCI_CON_HANDLE_INVALID, &mtu); - CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); + CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); status = gatt_client_get_mtu(gatt_client_handle, &mtu); CHECK_EQUAL(GATT_CLIENT_IN_WRONG_STATE, status); CHECK_EQUAL(ATT_DEFAULT_MTU, mtu); - gatt_client_t * gatt_client = gatt_client_get_client(gatt_client_handle); + gatt_client_t * gatt_client = get_gatt_client(gatt_client_handle); CHECK_TRUE(gatt_client != NULL); gatt_client->mtu = 30;