From 95822773931c28cbbe8dd81387dc804ec8dba0de Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Thu, 26 Nov 2015 14:24:30 +0100 Subject: [PATCH] hfp: prepare hf answer inciming call --- src/hfp.h | 3 +++ src/hfp_hf.c | 74 +++++++++++++++++++++++++++++++++++++--------------- src/hfp_hf.h | 4 +++ 3 files changed, 60 insertions(+), 21 deletions(-) diff --git a/src/hfp.h b/src/hfp.h index e375d691a..a20dd4ac7 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -501,6 +501,9 @@ typedef struct hfp_connection { int next_subscriber_number_to_send; int send_status_of_current_calls; + + uint8_t hf_answer_incoming_call; + timer_source_t hfp_timeout; } hfp_connection_t; diff --git a/src/hfp_hf.c b/src/hfp_hf.c index ff04b2cc3..eab130b90 100644 --- a/src/hfp_hf.c +++ b/src/hfp_hf.c @@ -73,6 +73,10 @@ static uint8_t hfp_indicators_status; static hfp_callback_t hfp_callback; +static hfp_call_status_t hfp_call_state; +static hfp_callsetup_status_t hfp_callsetup_state; +static hfp_callheld_status_t hfp_callheld_state; + void hfp_hf_register_packet_handler(hfp_callback_t callback){ hfp_callback = callback; if (callback == NULL){ @@ -226,6 +230,12 @@ static int hfp_hf_cmd_confirm_codec(uint16_t cid, uint8_t codec){ return send_str_over_rfcomm(cid, buffer); } +static int hfp_hf_cmd_ata(uint16_t cid){ + char buffer[10]; + sprintf(buffer, "%s\r\n", HFP_CALL_ANSWERED); + return send_str_over_rfcomm(cid, buffer); +} + static void hfp_emit_ag_indicator_event(hfp_callback_t callback, int status, hfp_ag_indicator_t indicator){ if (!callback) return; uint8_t event[6]; @@ -416,6 +426,15 @@ static int hfp_hf_run_for_audio_connection(hfp_connection_t * context){ return codecs_exchange_state_machine(context); } +static int call_setup_state_machine(hfp_connection_t * context){ + if (context->hf_answer_incoming_call){ + hfp_hf_cmd_ata(context->rfcomm_cid); + context->hf_answer_incoming_call = 0; + return 1; + } + return 0; +} + static void hfp_run_for_context(hfp_connection_t * context){ if (!context) return; if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return; @@ -427,7 +446,10 @@ static void hfp_run_for_context(hfp_connection_t * context){ if (!done){ done = hfp_hf_run_for_audio_connection(context); } - + if (!done){ + done = call_setup_state_machine(context); + } + if (done) return; // deal with disconnect switch (context->state){ @@ -559,31 +581,32 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8 //printf("\nHF received: %s", packet+2); for (pos = 0; pos < size ; pos++){ hfp_parse(context, packet[pos], 1); - + } // emit indicators status changed - for (i = 0; i < context->ag_indicators_nr; i++){ - if (context->ag_indicators[i].status_changed) { - context->ag_indicators[i].status_changed = 0; - hfp_emit_ag_indicator_event(hfp_callback, 0, context->ag_indicators[i]); - break; - } + for (i = 0; i < context->ag_indicators_nr; i++){ + if (context->ag_indicators[i].status_changed) { + context->ag_indicators[i].status_changed = 0; + hfp_emit_ag_indicator_event(hfp_callback, 0, context->ag_indicators[i]); + break; } + } - if (context->command == HFP_CMD_ERROR){ - context->ok_pending = 0; - hfp_reset_context_flags(context); - hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 1); - return; - } - if (context->command == HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR){ + switch (context->command){ + case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR: context->ok_pending = 0; context->extended_audio_gateway_error = 0; hfp_emit_event(hfp_callback, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, context->extended_audio_gateway_error); - return; - } - - if (context->command != HFP_CMD_OK) continue; - hfp_hf_switch_on_ok(context); + break; + case HFP_CMD_ERROR: + context->ok_pending = 0; + hfp_reset_context_flags(context); + hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 1); + break; + case HFP_CMD_OK: + hfp_hf_switch_on_ok(context); + break; + default: + break; } } @@ -733,4 +756,13 @@ void hfp_hf_release_audio_connection(bd_addr_t bd_addr){ hfp_run_for_context(connection); } - +void hfp_hf_answer_incoming_call(bd_addr_t bd_addr){ + hfp_hf_establish_service_level_connection(bd_addr); + hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + + if (hfp_callsetup_state == HFP_CALLSETUP_STATUS_INCOMING_CALL_SETUP_IN_PROGRESS){ + connection->hf_answer_incoming_call = 1; + } else { + log_error("HFP HF: answering incoming call in wrong callsetup state %u", hfp_callsetup_state); + } +} diff --git a/src/hfp_hf.h b/src/hfp_hf.h index 9529c3ab5..1582690a1 100644 --- a/src/hfp_hf.h +++ b/src/hfp_hf.h @@ -148,6 +148,10 @@ void hfp_hf_establish_audio_connection(bd_addr_t bd_addr); */ void hfp_hf_release_audio_connection(bd_addr_t bd_addr); +/** + * @brief + */ +void hfp_hf_answer_incoming_call(bd_addr_t bd_addr); /* API_END */