diff --git a/src/hfp.c b/src/hfp.c index ffe3a450b..4597aee45 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -606,139 +606,116 @@ void hfp_handle_hci_event(hfp_callback_t callback, uint8_t packet_type, uint8_t } // translates command string into hfp_command_t CMD and flags to distinguish between CMD=, CMD?, CMD=? -static hfp_command_t process_command(hfp_connection_t * context, int isHandsFree){ +static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){ int offset = isHandsFree ? 0 : 2; - hfp_command_t command = context->command; - - char * line_buffer = (char *)context->line_buffer; if (strncmp(line_buffer+offset, HFP_CALL_ANSWERED, strlen(HFP_CALL_ANSWERED)) == 0){ - command = HFP_CMD_CALL_ANSWERED; - return command; + return HFP_CMD_CALL_ANSWERED; } - if (strncmp(line_buffer, "AT", 2) == 0){ - offset = 2; - isHandsFree = 0; - } - if (strncmp(line_buffer+offset, HFP_ERROR, strlen(HFP_ERROR)) == 0){ - command = HFP_CMD_ERROR; - return command; + return HFP_CMD_ERROR; } if (isHandsFree && strncmp(line_buffer+offset, HFP_OK, strlen(HFP_OK)) == 0){ - //printf("parsed HFP_CMD_OK \n"); - command = HFP_CMD_OK; - return command; + return HFP_CMD_OK; } if (strncmp(line_buffer+offset, HFP_SUPPORTED_FEATURES, strlen(HFP_SUPPORTED_FEATURES)) == 0){ - command = HFP_CMD_SUPPORTED_FEATURES; - return command; + return HFP_CMD_SUPPORTED_FEATURES; } if (strncmp(line_buffer+offset, HFP_INDICATOR, strlen(HFP_INDICATOR)) == 0){ if (strncmp(line_buffer+strlen(HFP_INDICATOR)+offset, "?", 1) == 0){ - command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; + return HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; } if (strncmp(line_buffer+strlen(HFP_INDICATOR)+offset, "=?", 2) == 0){ - command = HFP_CMD_RETRIEVE_AG_INDICATORS; + return HFP_CMD_RETRIEVE_AG_INDICATORS; } - return command; } if (strncmp(line_buffer+offset, HFP_AVAILABLE_CODECS, strlen(HFP_AVAILABLE_CODECS)) == 0){ - command = HFP_CMD_AVAILABLE_CODECS; - return command; + return HFP_CMD_AVAILABLE_CODECS; } if (strncmp(line_buffer+offset, HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS, strlen(HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS)) == 0){ - command = HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE; - return command; + return HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE; } if (strncmp(line_buffer+offset, HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)) == 0){ - command = HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES; - return command; + return HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES; } if (strncmp(line_buffer+offset, HFP_GENERIC_STATUS_INDICATOR, strlen(HFP_GENERIC_STATUS_INDICATOR)) == 0){ - if (isHandsFree) return command; + if (isHandsFree) return HFP_CMD_UNKNOWN; if (strncmp(line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=?", 2) == 0){ - command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; - } else if (strncmp(line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=", 1) == 0){ - command = HFP_CMD_LIST_GENERIC_STATUS_INDICATORS; - } else { - command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; + return HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; + } + + if (strncmp(line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=", 1) == 0){ + return HFP_CMD_LIST_GENERIC_STATUS_INDICATORS; + } + + { + return HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; } - return command; } if (strncmp(line_buffer+offset, HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS, strlen(HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS)) == 0){ - command = HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE; - return command; + return HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE; } if (strncmp(line_buffer+offset, HFP_QUERY_OPERATOR_SELECTION, strlen(HFP_QUERY_OPERATOR_SELECTION)) == 0){ - command = HFP_CMD_QUERY_OPERATOR_SELECTION_NAME; - if (isHandsFree) return command; + if (isHandsFree) return HFP_CMD_QUERY_OPERATOR_SELECTION_NAME; if (strncmp(line_buffer+strlen(HFP_QUERY_OPERATOR_SELECTION)+offset, "=", 1) == 0){ - command = HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT; + return HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT; } - return command; + return HFP_CMD_QUERY_OPERATOR_SELECTION_NAME; } if (strncmp(line_buffer+offset, HFP_TRANSFER_AG_INDICATOR_STATUS, strlen(HFP_TRANSFER_AG_INDICATOR_STATUS)) == 0){ - command = HFP_CMD_TRANSFER_AG_INDICATOR_STATUS; - return command; + return HFP_CMD_TRANSFER_AG_INDICATOR_STATUS; } if (isHandsFree && strncmp(line_buffer+offset, HFP_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){ - command = HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR; - return command; + return HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR; } if (!isHandsFree && strncmp(line_buffer+offset, HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){ - command = HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR; - return command; + return HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR; } if (strncmp(line_buffer+offset, HFP_TRIGGER_CODEC_CONNECTION_SETUP, strlen(HFP_TRIGGER_CODEC_CONNECTION_SETUP)) == 0){ - command = HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP; - return command; + return HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP; } if (strncmp(line_buffer+offset, HFP_CONFIRM_COMMON_CODEC, strlen(HFP_CONFIRM_COMMON_CODEC)) == 0){ if (isHandsFree){ - command = HFP_CMD_AG_SUGGESTED_CODEC; + return HFP_CMD_AG_SUGGESTED_CODEC; } else { - command = HFP_CMD_HF_CONFIRMED_CODEC; + return HFP_CMD_HF_CONFIRMED_CODEC; } - return command; } if (strncmp(line_buffer+offset, "AT+", 3) == 0){ - command = HFP_CMD_UNKNOWN; - printf(" process unknown HF command %s \n", context->line_buffer); - return command; + printf(" process unknown HF command %s \n", line_buffer); + return HFP_CMD_UNKNOWN; } + if (strncmp(line_buffer+offset, "+", 1) == 0){ - command = HFP_CMD_UNKNOWN; - printf(" process unknown AG command %s \n", context->line_buffer); - return command; + printf(" process unknown AG command %s \n", line_buffer); + return HFP_CMD_UNKNOWN; } if (strncmp(line_buffer+offset, "NOP", 3) == 0){ - command = HFP_CMD_NONE; - return command; + return HFP_CMD_NONE; } - command = HFP_CMD_NONE; - return command; + + return HFP_CMD_NONE; } #if 0 @@ -852,7 +829,31 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree){ // printf(" parse header 2 %s, keep separator $ %d\n", context->line_buffer, context->keep_separator); if (hfp_parser_is_end_of_header(byte) || context->keep_separator == 1){ // printf(" parse header 3 %s, keep separator $ %d\n", context->line_buffer, context->keep_separator); - context->command = process_command(context, isHandsFree); + char * line_buffer = (char *)context->line_buffer; + context->command = parse_command(line_buffer, isHandsFree); + + /* resolve command name according to context */ + if (context->command == HFP_CMD_UNKNOWN){ + switch(context->state){ + case HFP_W4_LIST_GENERIC_STATUS_INDICATORS: + context->command = HFP_CMD_LIST_GENERIC_STATUS_INDICATORS; + break; + case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS: + context->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; + break; + case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: + context->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; + break; + case HFP_W4_RETRIEVE_INDICATORS_STATUS: + context->command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; + break; + case HFP_W4_RETRIEVE_INDICATORS: + context->command = HFP_CMD_RETRIEVE_AG_INDICATORS; + break; + default: + break; + } + } } break; diff --git a/src/hfp_ag.c b/src/hfp_ag.c index 15c6f40c6..4a20a8200 100644 --- a/src/hfp_ag.c +++ b/src/hfp_ag.c @@ -708,25 +708,25 @@ static void hfp_run_for_context(hfp_connection_t *context){ if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return; if (context->command == HFP_CMD_UNKNOWN){ - hfp_ag_error(context->rfcomm_cid); context->ok_pending = 0; context->send_error = 0; context->command = HFP_CMD_NONE; + hfp_ag_error(context->rfcomm_cid); return; } if (context->ok_pending){ - hfp_ag_ok(context->rfcomm_cid); context->ok_pending = 0; context->command = HFP_CMD_NONE; + hfp_ag_ok(context->rfcomm_cid); return; } if (context->send_error){ - hfp_ag_error(context->rfcomm_cid); context->send_error = 0; context->command = HFP_CMD_NONE; + hfp_ag_error(context->rfcomm_cid); return; } diff --git a/src/hfp_hf.c b/src/hfp_hf.c index 6879f0994..b4a59a60e 100644 --- a/src/hfp_hf.c +++ b/src/hfp_hf.c @@ -266,14 +266,11 @@ static int hfp_hf_run_for_context_service_level_connection(hfp_connection_t * co hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid); break; case HFP_RETRIEVE_INDICATORS: - hfp_hf_cmd_retrieve_indicators(context->rfcomm_cid); - done = 1; context->state = HFP_W4_RETRIEVE_INDICATORS; - context->command = HFP_CMD_RETRIEVE_AG_INDICATORS; + hfp_hf_cmd_retrieve_indicators(context->rfcomm_cid); break; case HFP_RETRIEVE_INDICATORS_STATUS: context->state = HFP_W4_RETRIEVE_INDICATORS_STATUS; - context->command = HFP_CMD_RETRIEVE_AG_INDICATORS; hfp_hf_cmd_retrieve_indicators_status(context->rfcomm_cid); break; case HFP_ENABLE_INDICATORS_STATUS_UPDATE: @@ -286,17 +283,14 @@ static int hfp_hf_run_for_context_service_level_connection(hfp_connection_t * co break; case HFP_LIST_GENERIC_STATUS_INDICATORS: context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS; - context->command = HFP_CMD_LIST_GENERIC_STATUS_INDICATORS; hfp_hf_cmd_list_supported_generic_status_indicators(context->rfcomm_cid); break; case HFP_RETRIEVE_GENERIC_STATUS_INDICATORS: context->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS; - context->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; hfp_hf_cmd_retrieve_supported_generic_status_indicators(context->rfcomm_cid); break; case HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS: context->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; - context->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; hfp_hf_cmd_list_initital_supported_generic_status_indicators(context->rfcomm_cid); break; default: diff --git a/test/hfp/hfp_hf_parser_test.c b/test/hfp/hfp_hf_parser_test.c index c46e2f6bd..586b1ba0f 100644 --- a/test/hfp/hfp_hf_parser_test.c +++ b/test/hfp/hfp_hf_parser_test.c @@ -107,7 +107,8 @@ TEST(HFPParser, HFP_HF_INDICATORS){ } offset += snprintf(packet+offset, sizeof(packet)-offset, "\"%s\", (%d, %d)\r\n\r\nOK\r\n", hfp_ag_indicators[pos].name, hfp_ag_indicators[pos].min_range, hfp_ag_indicators[pos].max_range); - context.command = HFP_CMD_RETRIEVE_AG_INDICATORS; + //context.command = HFP_CMD_RETRIEVE_AG_INDICATORS; + context.state = HFP_W4_RETRIEVE_INDICATORS; for (pos = 0; pos < strlen(packet); pos++){ hfp_parse(&context, packet[pos], 1); @@ -131,8 +132,9 @@ TEST(HFPParser, HFP_HF_INDICATOR_STATUS){ } offset += snprintf(packet+offset, sizeof(packet)-offset, "%d\r\n\r\nOK\r\n", hfp_ag_indicators[pos].status); - context.command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; - + //context.command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS; + context.state = HFP_W4_RETRIEVE_INDICATORS_STATUS; + for (pos = 0; pos < strlen(packet); pos++){ hfp_parse(&context, packet[pos], 1); } @@ -161,8 +163,9 @@ TEST(HFPParser, HFP_HF_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES){ TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR){ sprintf(packet, "\r\n%s:0,1,2,3,4\r\n\r\nOK\r\n", HFP_GENERIC_STATUS_INDICATOR); - context.command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; - + //context.command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; + context.state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS; + for (pos = 0; pos < strlen(packet); pos++){ hfp_parse(&context, packet[pos], 1); } @@ -177,8 +180,9 @@ TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR){ TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR_STATE){ sprintf(packet, "\r\n%s:0,1\r\n\r\nOK\r\n", HFP_GENERIC_STATUS_INDICATOR); - context.command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; - + // context.command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE; + context.state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS; + for (pos = 0; pos < strlen(packet); pos++){ hfp_parse(&context, packet[pos], 1); }