From 245852b74911e6b330125cab942a8665bb04d143 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 16 Apr 2021 09:40:01 +0200 Subject: [PATCH] hfp_ag: send NO CARRIER if network goes away during active call --- src/classic/hfp.h | 19 +++++++------------ src/classic/hfp_ag.c | 38 ++++++++++++++++++++++++++++++++------ 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/classic/hfp.h b/src/classic/hfp.h index 98c5aedd5..53ba42107 100644 --- a/src/classic/hfp.h +++ b/src/classic/hfp.h @@ -168,33 +168,27 @@ typedef enum { HFP_CMD_UNKNOWN, HFP_CMD_OK, HFP_CMD_RING, - HFP_CMD_SUPPORTED_FEATURES, + HFP_CMD_SUPPORTED_FEATURES, // 5 HFP_CMD_AVAILABLE_CODECS, - HFP_CMD_RETRIEVE_AG_INDICATORS_GENERIC, HFP_CMD_RETRIEVE_AG_INDICATORS, HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS, - - HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE, + HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE, // 10 HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, HFP_CMD_ENABLE_CLIP, HFP_CMD_AG_SENT_CLIP_INFORMATION, - HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION, + HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION, // 15 HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE, - HFP_CMD_LIST_GENERIC_STATUS_INDICATORS, HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS, HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE, - HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS, - + HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS, // 20 HFP_CMD_TRANSFER_AG_INDICATOR_STATUS, - HFP_CMD_QUERY_OPERATOR_SELECTION_NAME, HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT, - HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, - HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR, + HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR, // 25 HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP, HFP_CMD_AG_SEND_COMMON_CODEC, HFP_CMD_AG_SUGGESTED_CODEC, @@ -594,7 +588,8 @@ typedef struct hfp_connection { uint8_t ag_call_hold_action; uint8_t ag_response_and_hold_action; uint8_t ag_dtmf_code; - + bool ag_send_no_carrier; + int send_status_of_current_calls; int next_call_index; diff --git a/src/classic/hfp_ag.c b/src/classic/hfp_ag.c index 0c8aa02fe..a93546ce0 100644 --- a/src/classic/hfp_ag.c +++ b/src/classic/hfp_ag.c @@ -211,6 +211,13 @@ static int hfp_ag_send_ring(uint16_t cid){ return send_str_over_rfcomm(cid, (char *) "\r\nRING\r\n"); } +static int hfp_ag_send_no_carrier(uint16_t cid){ + char buffer[15]; + snprintf(buffer, sizeof(buffer), "\r\nNO CARRIER\r\n"); + buffer[sizeof(buffer) - 1] = 0; + return send_str_over_rfcomm(cid, buffer); +} + static int hfp_ag_send_clip(uint16_t cid){ char buffer[50]; snprintf(buffer, sizeof(buffer), "\r\n%s: \"%s\",%u\r\n", HFP_ENABLE_CLIP, @@ -925,7 +932,6 @@ static void hfp_ag_transfer_callheld_state(void){ } static void hfp_ag_hf_accept_call(hfp_connection_t * source){ - int call_indicator_index = get_ag_indicator_index_for_name("call"); int callsetup_indicator_index = get_ag_indicator_index_for_name("callsetup"); @@ -958,7 +964,6 @@ static void hfp_ag_hf_accept_call(hfp_connection_t * source){ } static void hfp_ag_ag_accept_call(void){ - int call_indicator_index = get_ag_indicator_index_for_name("call"); int callsetup_indicator_index = get_ag_indicator_index_for_name("callsetup"); @@ -1693,6 +1698,12 @@ static int hfp_ag_send_commands(hfp_connection_t *hfp_connection){ } } + if (hfp_connection->ag_send_no_carrier){ + hfp_connection->ag_send_no_carrier = false; + hfp_ag_send_no_carrier(hfp_connection->rfcomm_cid); + return 1; + } + if (hfp_connection->ag_ring){ hfp_connection->ag_ring = 0; hfp_connection->command = HFP_CMD_NONE; @@ -2345,23 +2356,38 @@ static void hfp_ag_set_ag_indicator(const char * name, int value){ if (indicator_index < 0) return; hfp_ag_indicators[indicator_index].status = value; - btstack_linked_list_iterator_t it; btstack_linked_list_iterator_init(&it, hfp_get_connections()); while (btstack_linked_list_iterator_has_next(&it)){ hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); if (hfp_connection->local_role != HFP_ROLE_AG) continue; - if (! hfp_connection->ag_indicators[indicator_index].enabled) { - log_info("AG indicator '%s' changed to %u but not enabled", hfp_ag_indicators[indicator_index].name, value); + if (!hfp_connection->ag_indicators[indicator_index].enabled) { + log_info("Requested AG indicator '%s' update to %u, but it is not enabled", hfp_ag_indicators[indicator_index].name, value); continue; } - log_info("AG indicator '%s' changed to %u, request transfer statur", hfp_ag_indicators[indicator_index].name, value); + log_info("AG indicator '%s' changed to %u, request transfer status", hfp_ag_indicators[indicator_index].name, value); hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, indicator_index, 1); hfp_ag_run_for_context(hfp_connection); } } void hfp_ag_set_registration_status(int status){ + if ( (status == 0) && (hfp_gsm_call_status() == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT)){ + + // if network goes away wihle a call is active: + // - the call gets dropped + // - we send NO CARRIER + // NOTE: the CALL=0 has to be sent before NO CARRIER + + hfp_ag_call_sm(HFP_AG_CALL_DROPPED, NULL); + + btstack_linked_list_iterator_t it; + btstack_linked_list_iterator_init(&it, hfp_get_connections()); + while (btstack_linked_list_iterator_has_next(&it)){ + hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it); + hfp_connection->ag_send_no_carrier = true; + } + } hfp_ag_set_ag_indicator("service", status); }