diff --git a/src/classic/hfp.c b/src/classic/hfp.c index c654462b0..cfa056c87 100644 --- a/src/classic/hfp.c +++ b/src/classic/hfp.c @@ -157,6 +157,41 @@ static void (*hfp_hf_run_for_context)(hfp_connection_t * hfp_connection); static hfp_connection_t * sco_establishment_active; +static uint16_t hfp_parse_indicator_index(hfp_connection_t * hfp_connection){ + uint16_t index = btstack_atoi((char *)&hfp_connection->line_buffer[0]); + + if (index > HFP_MAX_NUM_INDICATORS){ + log_info("ignoring invalid indicator index bigger then HFP_MAX_NUM_INDICATORS"); + return HFP_MAX_NUM_INDICATORS - 1; + } + + // indicator index enumeration starts with 1, we substract 1 to store in array with starting index 0 + if (index > 0){ + index -= 1; + } else { + log_info("ignoring invalid indicator index 0"); + return 0; + } + return index; +} + +static void hfp_next_indicators_index(hfp_connection_t * hfp_connection){ + if (hfp_connection->parser_item_index < HFP_MAX_NUM_INDICATORS - 1){ + hfp_connection->parser_item_index++; + } else { + log_info("Ignoring additional indicator"); + } +} + +static void hfp_next_codec_index(hfp_connection_t * hfp_connection){ + if (hfp_connection->parser_item_index < HFP_MAX_NUM_CODECS - 1){ + hfp_connection->parser_item_index++; + } else { + log_info("Ignoring additional codec index"); + } +} + + const char * hfp_hf_feature(int index){ if (index > HFP_HF_FEATURES_SIZE){ return hfp_hf_features[HFP_HF_FEATURES_SIZE]; @@ -1167,8 +1202,8 @@ static bool hfp_parse_byte(hfp_connection_t * hfp_connection, uint8_t byte, int break; case HFP_CMD_RETRIEVE_AG_INDICATORS: hfp_connection->ag_indicators[hfp_connection->parser_item_index].max_range = btstack_atoi((char *)hfp_connection->line_buffer); - hfp_connection->parser_item_index++; - hfp_connection->ag_indicators_nr++; + hfp_next_indicators_index(hfp_connection); + hfp_connection->ag_indicators_nr = hfp_connection->parser_item_index; log_info("%s)\n", hfp_connection->line_buffer); break; default: @@ -1226,7 +1261,7 @@ static void parse_sequence(hfp_connection_t * hfp_connection){ default: break; } - hfp_connection->parser_item_index++; + hfp_next_indicators_index(hfp_connection); break; case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: @@ -1319,7 +1354,7 @@ static void parse_sequence(hfp_connection_t * hfp_connection){ case HFP_CMD_AVAILABLE_CODECS: log_info("Parsed codec %s\n", hfp_connection->line_buffer); hfp_connection->remote_codecs[hfp_connection->parser_item_index] = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer); - hfp_connection->parser_item_index++; + hfp_next_codec_index(hfp_connection); hfp_connection->remote_codecs_nr = hfp_connection->parser_item_index; break; case HFP_CMD_RETRIEVE_AG_INDICATORS: @@ -1331,10 +1366,10 @@ static void parse_sequence(hfp_connection_t * hfp_connection){ case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS: log_info("Parsed Indicator %d with status: %s\n", hfp_connection->parser_item_index+1, hfp_connection->line_buffer); hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = btstack_atoi((char *) hfp_connection->line_buffer); - hfp_connection->parser_item_index++; + hfp_next_indicators_index(hfp_connection); break; case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: - hfp_connection->parser_item_index++; + hfp_next_indicators_index(hfp_connection); if (hfp_connection->parser_item_index != 4) break; log_info("Parsed Enable indicators: %s\n", hfp_connection->line_buffer); value = btstack_atoi((char *)&hfp_connection->line_buffer[0]); @@ -1343,24 +1378,24 @@ static void parse_sequence(hfp_connection_t * hfp_connection){ case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES: log_info("Parsed Support call hold: %s\n", hfp_connection->line_buffer); if (hfp_connection->line_size > 2 ) break; - strncpy((char *)hfp_connection->remote_call_services[hfp_connection->remote_call_services_nr].name, (char *)hfp_connection->line_buffer, HFP_CALL_SERVICE_SIZE); - hfp_connection->remote_call_services[hfp_connection->remote_call_services_nr].name[HFP_CALL_SERVICE_SIZE - 1] = 0; - hfp_connection->remote_call_services_nr++; + strncpy((char *)hfp_connection->remote_call_services[hfp_connection->remote_call_services_index].name, (char *)hfp_connection->line_buffer, HFP_CALL_SERVICE_SIZE); + hfp_connection->remote_call_services[hfp_connection->remote_call_services_index].name[HFP_CALL_SERVICE_SIZE - 1] = 0; + hfp_connection->remote_call_services_index++; break; case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS: case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS: log_info("Parsed Generic status indicator: %s\n", hfp_connection->line_buffer); hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].uuid = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer); - hfp_connection->parser_item_index++; + hfp_next_indicators_index(hfp_connection); hfp_connection->generic_status_indicators_nr = hfp_connection->parser_item_index; break; case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE: // HF parses inital AG gen. ind. state log_info("Parsed List generic status indicator %s state: ", hfp_connection->line_buffer); - hfp_connection->parser_item_index = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); + hfp_connection->parser_item_index = hfp_parse_indicator_index(hfp_connection); break; case HFP_CMD_HF_INDICATOR_STATUS: - hfp_connection->parser_indicator_index = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer); + hfp_connection->parser_indicator_index = hfp_parse_indicator_index(hfp_connection); log_info("Parsed HF indicator index %u", hfp_connection->parser_indicator_index); break; case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE: @@ -1379,11 +1414,11 @@ static void parse_sequence(hfp_connection_t * hfp_connection){ log_info("Parsed Enable AG indicator pos %u('%s'): %u\n", hfp_connection->parser_item_index, hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, value); } - hfp_connection->parser_item_index++; + hfp_next_indicators_index(hfp_connection); break; case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: // indicators are indexed starting with 1 - hfp_connection->parser_item_index = btstack_atoi((char *)&hfp_connection->line_buffer[0]) - 1; + hfp_connection->parser_item_index = hfp_parse_indicator_index(hfp_connection); log_info("Parsed status of the AG indicator %d, status ", hfp_connection->parser_item_index); break; case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME: diff --git a/src/classic/hfp.h b/src/classic/hfp.h index 2e2729e11..8a131ae91 100644 --- a/src/classic/hfp.h +++ b/src/classic/hfp.h @@ -108,12 +108,14 @@ extern "C" { #define HFP_DEFAULT_HF_SUPPORTED_FEATURES 0x0000 #define HFP_DEFAULT_AG_SUPPORTED_FEATURES 0x0009 -#define HFP_MAX_NUM_CODECS 20 -#define HFP_MAX_NUM_AG_INDICATORS 20 -#define HFP_MAX_NUM_HF_INDICATORS 20 +#define HFP_MAX_NUM_INDICATORS 10 +#define HFP_MAX_NUM_CALL_SERVICES 20 +#define HFP_CALL_SERVICE_SIZE 3 +#define HFP_MAX_NUM_CODECS 10 + #define HFP_MAX_INDICATOR_DESC_SIZE 20 #define HFP_MAX_NETWORK_OPERATOR_NAME_SIZE 17 -#define HFP_CALL_SERVICE_SIZE 3 + #define HFP_SUPPORTED_FEATURES "+BRSF" #define HFP_AVAILABLE_CODECS "+BAC" @@ -509,22 +511,21 @@ typedef struct hfp_connection { uint32_t remote_supported_features; - // TODO: rename into hf_codecs_nr - int remote_codecs_nr; - uint8_t remote_codecs[HFP_MAX_INDICATOR_DESC_SIZE]; + uint16_t remote_codecs_nr; + uint8_t remote_codecs[HFP_MAX_NUM_CODECS]; - int ag_indicators_nr; - hfp_ag_indicator_t ag_indicators[HFP_MAX_INDICATOR_DESC_SIZE]; + uint16_t ag_indicators_nr; + hfp_ag_indicator_t ag_indicators[HFP_MAX_NUM_INDICATORS]; uint32_t ag_indicators_status_update_bitmap; uint8_t enable_status_update_for_ag_indicators; - int remote_call_services_nr; - hfp_call_service_t remote_call_services[HFP_MAX_INDICATOR_DESC_SIZE]; + uint16_t remote_call_services_index; + hfp_call_service_t remote_call_services[HFP_MAX_NUM_CALL_SERVICES]; // TODO: use bitmap. - int generic_status_indicators_nr; + uint16_t generic_status_indicators_nr; uint32_t generic_status_update_bitmap; - hfp_generic_status_indicator_t generic_status_indicators[HFP_MAX_INDICATOR_DESC_SIZE]; + hfp_generic_status_indicator_t generic_status_indicators[HFP_MAX_NUM_INDICATORS]; hfp_network_opearator_t network_operator; diff --git a/src/classic/hfp_ag.c b/src/classic/hfp_ag.c index 97be3238b..91a39d07f 100644 --- a/src/classic/hfp_ag.c +++ b/src/classic/hfp_ag.c @@ -92,10 +92,10 @@ static uint8_t hfp_codecs_nr = 0; static uint8_t hfp_codecs[HFP_MAX_NUM_CODECS]; static int hfp_ag_indicators_nr = 0; -static hfp_ag_indicator_t hfp_ag_indicators[HFP_MAX_NUM_AG_INDICATORS]; +static hfp_ag_indicator_t hfp_ag_indicators[HFP_MAX_NUM_INDICATORS]; static int hfp_generic_status_indicators_nr = 0; -static hfp_generic_status_indicator_t hfp_generic_status_indicators[HFP_MAX_NUM_HF_INDICATORS]; +static hfp_generic_status_indicator_t hfp_generic_status_indicators[HFP_MAX_NUM_INDICATORS]; static int hfp_ag_call_hold_services_nr = 0; static char *hfp_ag_call_hold_services[6]; @@ -2096,7 +2096,7 @@ void hfp_ag_init_ag_indicators(int ag_indicators_nr, hfp_ag_indicator_t * ag_ind } void hfp_ag_init_hf_indicators(int hf_indicators_nr, hfp_generic_status_indicator_t * hf_indicators){ - if (hf_indicators_nr > HFP_MAX_NUM_HF_INDICATORS) return; + if (hf_indicators_nr > HFP_MAX_NUM_INDICATORS) return; hfp_generic_status_indicators_nr = hf_indicators_nr; (void)memcpy(hfp_generic_status_indicators, hf_indicators, hf_indicators_nr * sizeof(hfp_generic_status_indicator_t)); diff --git a/src/classic/hfp_hf.c b/src/classic/hfp_hf.c index a88595fa6..b83ea1767 100644 --- a/src/classic/hfp_hf.c +++ b/src/classic/hfp_hf.c @@ -74,8 +74,8 @@ static uint8_t hfp_codecs_nr = 0; static uint8_t hfp_codecs[HFP_MAX_NUM_CODECS]; static uint8_t hfp_indicators_nr = 0; -static uint8_t hfp_indicators[HFP_MAX_NUM_HF_INDICATORS]; -static uint32_t hfp_indicators_value[HFP_MAX_NUM_HF_INDICATORS]; +static uint8_t hfp_indicators[HFP_MAX_NUM_INDICATORS]; +static uint32_t hfp_indicators_value[HFP_MAX_NUM_INDICATORS]; static uint8_t hfp_hf_speaker_gain = 9; static uint8_t hfp_hf_microphone_gain = 9; diff --git a/test/hfp/hfp_at_parser_test.c b/test/hfp/hfp_at_parser_test.c index d2a1b52d1..5d79a5a99 100644 --- a/test/hfp/hfp_at_parser_test.c +++ b/test/hfp/hfp_at_parser_test.c @@ -177,7 +177,7 @@ TEST(HFPParser, HFP_HF_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES){ sprintf(packet, "\r\n%s:(1,1x,2,2x,3)\r\n\r\nOK\r\n", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES); parse_hf(packet); CHECK_EQUAL(HFP_CMD_OK, context.command); - CHECK_EQUAL(5, context.remote_call_services_nr); + CHECK_EQUAL(5, context.remote_call_services_index); STRCMP_EQUAL("1", (char*)context.remote_call_services[0].name); STRCMP_EQUAL("1x", (char*)context.remote_call_services[1].name);