hfp: track pending HF command

This commit is contained in:
Milanka Ringwald 2021-07-13 11:34:36 +02:00
parent 4d839c2641
commit e2c3b58d3f
2 changed files with 130 additions and 115 deletions

View File

@ -648,6 +648,8 @@ typedef struct hfp_connection {
int next_call_index; int next_call_index;
// HF only // HF only
hfp_command_t hf_ok_pending_for_command;
hfp_hf_query_operator_state_t hf_query_operator_state; hfp_hf_query_operator_state_t hf_query_operator_state;
uint8_t hf_answer_incoming_call; uint8_t hf_answer_incoming_call;
uint8_t hf_initiate_outgoing_call; uint8_t hf_initiate_outgoing_call;
@ -679,7 +681,6 @@ typedef struct hfp_connection {
uint8_t hf_activate_calling_line_notification; uint8_t hf_activate_calling_line_notification;
uint8_t hf_deactivate_calling_line_notification; uint8_t hf_deactivate_calling_line_notification;
uint8_t hf_activate_echo_canceling_and_noise_reduction;
uint8_t hf_deactivate_echo_canceling_and_noise_reduction; uint8_t hf_deactivate_echo_canceling_and_noise_reduction;
hfp_voice_recognition_activation_status_t vra_state; hfp_voice_recognition_activation_status_t vra_state;

View File

@ -368,10 +368,6 @@ static int hfp_hf_set_calling_line_notification_cmd(uint16_t cid, uint8_t activa
return hfp_hf_send_cmd_with_int(cid, HFP_ENABLE_CLIP, activate); return hfp_hf_send_cmd_with_int(cid, HFP_ENABLE_CLIP, activate);
} }
static int hfp_hf_set_echo_canceling_and_noise_reduction_cmd(uint16_t cid, uint8_t activate){
return hfp_hf_send_cmd_with_int(cid, HFP_TURN_OFF_EC_AND_NR, activate);
}
static int hfp_hf_set_voice_recognition_notification_cmd(uint16_t cid, uint8_t activate){ static int hfp_hf_set_voice_recognition_notification_cmd(uint16_t cid, uint8_t activate){
return hfp_hf_send_cmd_with_int(cid, HFP_ACTIVATE_VOICE_RECOGNITION, activate); return hfp_hf_send_cmd_with_int(cid, HFP_ACTIVATE_VOICE_RECOGNITION, activate);
} }
@ -780,8 +776,10 @@ static void hfp_hf_run_for_context(hfp_connection_t * hfp_connection){
done = call_setup_state_machine(hfp_connection); done = call_setup_state_machine(hfp_connection);
} }
// don't send a new command while ok still pending // don't send a new command while ok still pending or SLC is not established
if (hfp_connection->ok_pending) return; if (hfp_connection->ok_pending || (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED)){
return;
}
if (hfp_connection->send_microphone_gain){ if (hfp_connection->send_microphone_gain){
hfp_connection->send_microphone_gain = 0; hfp_connection->send_microphone_gain = 0;
@ -813,15 +811,9 @@ static void hfp_hf_run_for_context(hfp_connection_t * hfp_connection){
if (hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction){ if (hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction){
hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction = 0; hfp_connection->hf_deactivate_echo_canceling_and_noise_reduction = 0;
hfp_connection->hf_ok_pending_for_command = HFP_CMD_TURN_OFF_EC_AND_NR;
hfp_connection->ok_pending = 1; hfp_connection->ok_pending = 1;
hfp_hf_set_echo_canceling_and_noise_reduction_cmd(hfp_connection->rfcomm_cid, 0); hfp_hf_send_cmd_with_int(hfp_connection->rfcomm_cid, HFP_TURN_OFF_EC_AND_NR, 0);
return;
}
if (hfp_connection->hf_activate_echo_canceling_and_noise_reduction){
hfp_connection->hf_activate_echo_canceling_and_noise_reduction = 0;
hfp_connection->ok_pending = 1;
hfp_hf_set_echo_canceling_and_noise_reduction_cmd(hfp_connection->rfcomm_cid, 1);
return; return;
} }
@ -1042,7 +1034,16 @@ static void hfp_hf_handle_suggested_codec(hfp_connection_t * hfp_connection){
} }
} }
static void hfp_hf_switch_on_ok(hfp_connection_t *hfp_connection){ static bool hfp_hf_switch_on_ok_pending(hfp_connection_t *hfp_connection, uint8_t status){
bool event_emited = true;
switch (hfp_connection->hf_ok_pending_for_command){
case HFP_CMD_TURN_OFF_EC_AND_NR:
hfp_emit_event(hfp_connection, HFP_SUBEVENT_ECHO_CANCELING_AND_NOISE_REDUCTION_DEACTIVATE, status);
break;
default:
event_emited = false;
switch (hfp_connection->state){ switch (hfp_connection->state){
case HFP_W4_EXCHANGE_SUPPORTED_FEATURES: case HFP_W4_EXCHANGE_SUPPORTED_FEATURES:
if (has_codec_negotiation_feature(hfp_connection)){ if (has_codec_negotiation_feature(hfp_connection)){
@ -1143,10 +1144,14 @@ static void hfp_hf_switch_on_ok(hfp_connection_t *hfp_connection){
default: default:
break; break;
} }
break;
}
// done // done
hfp_connection->hf_ok_pending_for_command = HFP_CMD_NONE;
hfp_connection->ok_pending = 0; hfp_connection->ok_pending = 0;
hfp_connection->command = HFP_CMD_NONE; hfp_connection->command = HFP_CMD_NONE;
return event_emited;
} }
@ -1173,6 +1178,8 @@ static void hfp_hf_handle_transfer_ag_indicator_status(hfp_connection_t * hfp_co
static void hfp_hf_handle_rfcomm_command(hfp_connection_t * hfp_connection){ static void hfp_hf_handle_rfcomm_command(hfp_connection_t * hfp_connection){
int value; int value;
int i; int i;
bool event_emited;
switch (hfp_connection->command){ switch (hfp_connection->command){
case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
hfp_connection->command = HFP_CMD_NONE; hfp_connection->command = HFP_CMD_NONE;
@ -1233,23 +1240,30 @@ static void hfp_hf_handle_rfcomm_command(hfp_connection_t * hfp_connection){
default: default:
break; break;
} }
// handle error response for voice activation (HF initiated) // handle error response for voice activation (HF initiated)
switch(hfp_connection->vra_state_requested){ switch(hfp_connection->vra_state_requested){
case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO: case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO:
hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR); hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR);
break; break;
default: default:
if (hfp_connection->vra_state_requested == hfp_connection->vra_state){
break;
}
hfp_connection->vra_state_requested = hfp_connection->vra_state; hfp_connection->vra_state_requested = hfp_connection->vra_state;
hfp_emit_voice_recognition_state_event(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR); hfp_emit_voice_recognition_state_event(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR);
hfp_reset_context_flags(hfp_connection); hfp_reset_context_flags(hfp_connection);
return; return;
} }
event_emited = hfp_hf_switch_on_ok_pending(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR);
if (!event_emited){
hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 1); hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 1);
}
hfp_reset_context_flags(hfp_connection); hfp_reset_context_flags(hfp_connection);
break; break;
case HFP_CMD_OK: case HFP_CMD_OK:
hfp_hf_switch_on_ok(hfp_connection); hfp_hf_switch_on_ok_pending(hfp_connection, ERROR_CODE_SUCCESS);
break; break;
case HFP_CMD_RING: case HFP_CMD_RING:
hfp_connection->command = HFP_CMD_NONE; hfp_connection->command = HFP_CMD_NONE;