From 4eb3f1d888912cdcda915d037f318a0b138a37d9 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Thu, 24 Jun 2021 14:51:43 +0200 Subject: [PATCH] hfp: return status code for establish_service_level_connection --- src/classic/hfp.c | 45 +++++++++++++++++++------------------------- src/classic/hfp.h | 10 +++++++++- src/classic/hfp_ag.c | 4 ++-- src/classic/hfp_ag.h | 6 +++++- src/classic/hfp_hf.c | 4 ++-- src/classic/hfp_hf.h | 5 ++++- 6 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/classic/hfp.c b/src/classic/hfp.c index ae6da9281..f49f0d9d4 100644 --- a/src/classic/hfp.c +++ b/src/classic/hfp.c @@ -554,7 +554,7 @@ void hfp_finalize_connection_context(hfp_connection_t * hfp_connection){ btstack_memory_hfp_connection_free(hfp_connection); } -static hfp_connection_t * provide_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr, hfp_role_t local_role){ +static hfp_connection_t * hfp_create_connection(bd_addr_t bd_addr, hfp_role_t local_role){ hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr, local_role); if (hfp_connection) return hfp_connection; hfp_connection = create_hfp_connection_context(); @@ -919,7 +919,7 @@ void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *pac case RFCOMM_EVENT_INCOMING_CONNECTION: // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr); - hfp_connection = provide_hfp_connection_context_for_bd_addr(event_addr, local_role); + hfp_connection = hfp_create_connection(event_addr, local_role); if (!hfp_connection){ log_info("hfp: no memory to accept incoming connection - decline"); rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet)); @@ -1663,33 +1663,26 @@ static void hfp_handle_start_sdp_client_query(void * context){ } } -void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid, hfp_role_t local_role){ - hfp_connection_t * hfp_connection = provide_hfp_connection_context_for_bd_addr(bd_addr, local_role); - log_info("hfp_connect %s, hfp_connection %p", bd_addr_to_str(bd_addr), hfp_connection); - - if (!hfp_connection) { - log_error("hfp_establish_service_level_connection for addr %s failed", bd_addr_to_str(bd_addr)); - return; +uint8_t hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid, hfp_role_t local_role){ + hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr, local_role); + if (connection){ + return ERROR_CODE_COMMAND_DISALLOWED; } - switch (hfp_connection->state){ - case HFP_W2_DISCONNECT_RFCOMM: - hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED; - return; - case HFP_W4_RFCOMM_DISCONNECTED: - hfp_connection->state = HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART; - return; - case HFP_IDLE: - (void)memcpy(hfp_connection->remote_addr, bd_addr, 6); - hfp_connection->state = HFP_W2_SEND_SDP_QUERY; - hfp_connection->service_uuid = service_uuid; - hfp_handle_sdp_client_query_request.callback = &hfp_handle_start_sdp_client_query; - // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback - (void) sdp_client_register_query_callback(&hfp_handle_sdp_client_query_request); - break; - default: - break; + connection = hfp_create_connection(bd_addr, local_role); + if (!connection){ + return BTSTACK_MEMORY_ALLOC_FAILED; } + + connection->state = HFP_W2_SEND_SDP_QUERY; + + bd_addr_copy(connection->remote_addr, bd_addr); + connection->service_uuid = service_uuid; + + hfp_handle_sdp_client_query_request.callback = &hfp_handle_start_sdp_client_query; + // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback + (void) sdp_client_register_query_callback(&hfp_handle_sdp_client_query_request); + return ERROR_CODE_SUCCESS; } void hfp_release_service_level_connection(hfp_connection_t * hfp_connection){ diff --git a/src/classic/hfp.h b/src/classic/hfp.h index ec47d43cf..88b742c08 100644 --- a/src/classic/hfp.h +++ b/src/classic/hfp.h @@ -742,8 +742,16 @@ hfp_connection_t * get_hfp_connection_context_for_acl_handle(uint16_t handle, hf btstack_linked_list_t * hfp_get_connections(void); void hfp_parse(hfp_connection_t * connection, uint8_t byte, int isHandsFree); -void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid, hfp_role_t local_role); void hfp_release_service_level_connection(hfp_connection_t * connection); +/** + * @brief Establish RFCOMM connection, and perform service level connection agreement: + * @param bd_addr + * @return status ERROR_CODE_SUCCESS if successful, otherwise: + * - ERROR_CODE_COMMAND_DISALLOWED if connection already exists, or + * - BTSTACK_MEMORY_ALLOC_FAILED + */ +uint8_t hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid, hfp_role_t local_role); + void hfp_reset_context_flags(hfp_connection_t * connection); void hfp_release_audio_connection(hfp_connection_t * connection); diff --git a/src/classic/hfp_ag.c b/src/classic/hfp_ag.c index d67437921..0de7adcc3 100644 --- a/src/classic/hfp_ag.c +++ b/src/classic/hfp_ag.c @@ -2284,8 +2284,8 @@ void hfp_ag_deinit(void){ (void) memset(&hfp_ag_response_and_hold_state, 0, sizeof(hfp_response_and_hold_state_t)); } -void hfp_ag_establish_service_level_connection(bd_addr_t bd_addr){ - hfp_establish_service_level_connection(bd_addr, BLUETOOTH_SERVICE_CLASS_HANDSFREE, HFP_ROLE_AG); +uint8_t hfp_ag_establish_service_level_connection(bd_addr_t bd_addr){ + return hfp_establish_service_level_connection(bd_addr, BLUETOOTH_SERVICE_CLASS_HANDSFREE, HFP_ROLE_AG); } void hfp_ag_release_service_level_connection(hci_con_handle_t acl_handle){ diff --git a/src/classic/hfp_ag.h b/src/classic/hfp_ag.h index 01edcd030..1c2d1b318 100644 --- a/src/classic/hfp_ag.h +++ b/src/classic/hfp_ag.h @@ -137,8 +137,12 @@ void hfp_ag_set_use_in_band_ring_tone(int use_in_band_ring_tone); * HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED. * * @param bd_addr Bluetooth address of the HF + * @return status ERROR_CODE_SUCCESS if successful, otherwise: + * - ERROR_CODE_COMMAND_DISALLOWED if connection already exists or connection in wrong state, or + * - BTSTACK_MEMORY_ALLOC_FAILED + * */ -void hfp_ag_establish_service_level_connection(bd_addr_t bd_addr); +uint8_t hfp_ag_establish_service_level_connection(bd_addr_t bd_addr); /** * @brief Release the RFCOMM channel and the audio connection between the HF and the AG. diff --git a/src/classic/hfp_hf.c b/src/classic/hfp_hf.c index 8c8673a6a..eaa63cc05 100644 --- a/src/classic/hfp_hf.c +++ b/src/classic/hfp_hf.c @@ -1306,8 +1306,8 @@ void hfp_hf_init_hf_indicators(int indicators_nr, const uint16_t * indicators){ } } -void hfp_hf_establish_service_level_connection(bd_addr_t bd_addr){ - hfp_establish_service_level_connection(bd_addr, BLUETOOTH_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY, HFP_ROLE_HF); +uint8_t hfp_hf_establish_service_level_connection(bd_addr_t bd_addr){ + return hfp_establish_service_level_connection(bd_addr, BLUETOOTH_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY, HFP_ROLE_HF); } void hfp_hf_release_service_level_connection(hci_con_handle_t acl_handle){ diff --git a/src/classic/hfp_hf.h b/src/classic/hfp_hf.h index a380311d7..0ebaa4f92 100644 --- a/src/classic/hfp_hf.h +++ b/src/classic/hfp_hf.h @@ -113,8 +113,11 @@ void hfp_hf_register_packet_handler(btstack_packet_handler_t callback); * HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED. * * @param bd_addr Bluetooth address of the AG + * @return status ERROR_CODE_SUCCESS if successful, otherwise: + * - ERROR_CODE_COMMAND_DISALLOWED if connection already exists or connection in wrong state, or + * - BTSTACK_MEMORY_ALLOC_FAILED */ -void hfp_hf_establish_service_level_connection(bd_addr_t bd_addr); +uint8_t hfp_hf_establish_service_level_connection(bd_addr_t bd_addr); /** * @brief Release the RFCOMM channel and the audio connection between the HF and the AG.