hfp: improve indicator and codec parsing

This commit is contained in:
Milanka Ringwald 2020-06-19 14:26:20 +02:00
parent 4700518231
commit 25789943f3
5 changed files with 69 additions and 33 deletions

View File

@ -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:

View File

@ -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;

View File

@ -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));

View File

@ -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;

View File

@ -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);