From b5b7d6dda38358b2be169e2302c73a425a68fba5 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 14 Aug 2015 14:19:31 +0200 Subject: [PATCH 01/11] hfp: start rewrite parser --- src/hfp.c | 146 +++++++++++++++++++++++----------- src/hfp.h | 3 +- src/hfp_ag.c | 14 ++-- src/hfp_hf.c | 9 ++- test/hfp/hfp_ag_parser_test.c | 41 ++++++++-- test/hfp/hfp_hf_parser_test.c | 14 ++++ 6 files changed, 164 insertions(+), 63 deletions(-) diff --git a/src/hfp.c b/src/hfp.c index 621988117..d51020fc3 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -497,8 +497,53 @@ uint32_t fromBinary(char *s) { return (uint32_t) strtol(s, NULL, 2); } +static void hfp_parser_write_buffer(hfp_connection_t * context, uint8_t byte){ + // TODO: add limit + context->line_buffer[context->line_size++] = byte; + context->line_buffer[context->line_size] = 0; +} + +static int hfp_parser_reached_end_of_line(uint8_t byte){ + return byte == '\n' || byte == '\r'; +} + +static int hfp_parser_reached_sequence_separator(uint8_t byte){ + return byte == ','; +} + +static int hfp_parser_item_done(uint8_t byte){ + return byte == ',' || byte == '\n' || byte == '\r'; +} + +static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ + context->line_size = 0; + if (hfp_parser_reached_end_of_line(byte)){ + context->parser_item_index = 0; + context->parser_state = HFP_PARSER_CMD_HEADER; + return; + } + switch (context->parser_state){ + case HFP_PARSER_CMD_HEADER: + case HFP_PARSER_CMD_INDICATOR_NAME: + case HFP_PARSER_CMD_INDICATOR_MIN_RANGE: + case HFP_PARSER_SECOND_ITEM: + context->parser_state = (hfp_parser_state_t)((int)context->parser_state + 1); + break; + case HFP_PARSER_CMD_INDICATOR_MAX_RANGE: + case HFP_PARSER_CMD_INDICATOR_STATUS: + context->parser_state = HFP_PARSER_CMD_SEQUENCE; + break; + case HFP_PARSER_CMD_SEQUENCE: + break; + case HFP_PARSER_THIRD_ITEM: + context->parser_state = HFP_PARSER_CMD_HEADER; + + } +} + void hfp_parse(hfp_connection_t * context, uint8_t byte){ int value; + int reached_end = 0; context->line_buffer[context->line_size] = 0; if (byte == ' ') return; @@ -546,8 +591,9 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ context->parser_item_index = 0; return; } - - context->line_buffer[context->line_size++] = byte; + if (byte != '='){ + context->line_buffer[context->line_size++] = byte; + } break; case HFP_PARSER_CMD_SEQUENCE: // parse comma separated sequence, ignore breacktes @@ -640,28 +686,25 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ printf("Parsed status of the AG indicator %d, status ", context->parser_item_index); break; case HFP_CMD_QUERY_OPERATOR_SELECTION: - printf("Parsed Network operator: %s\n", context->line_buffer); - - if (context->operator_name_format == 1){ - if (context->line_size == 1 && context->line_buffer[0] == '3'){ - context->parser_state = HFP_PARSER_CMD_NETWORK_OPERATOR; - context->line_size = 0; - break; - } - // TODO emit ERROR, wrong format - break; - } - if (context->operator_name != 1) break; - - if (context->line_size == 0) { - printf("No operator found\n"); - context->network_operator.mode = 0; - context->network_operator.name[0] = 0; - break; - } - context->network_operator.mode = atoi((char *)&context->line_buffer[0]); + context->parser_state = HFP_PARSER_SECOND_ITEM; context->line_size = 0; - context->parser_state = HFP_PARSER_CMD_NETWORK_OPERATOR; + + if (context->operator_name_format == 1){ + if (context->line_buffer[0] == '3'){ + printf("Parsed Set network operator format : %s, ", context->line_buffer); + break; + } + // TODO emit ERROR, wrong format + printf("ERROR Set network operator format: index %s not supported\n", context->line_buffer); + break; + } + + if (context->operator_name == 1) { + context->network_operator.mode = atoi((char *)&context->line_buffer[0]); + printf("Parsed network operator mode: %d, ", context->network_operator.mode); + break; + } + break; default: @@ -678,35 +721,46 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ } context->line_buffer[context->line_size++] = byte; break; - case HFP_PARSER_CMD_NETWORK_OPERATOR: - if (context->operator_name_format == 1){ - if (context->line_size == 1 && context->line_buffer[0] == '0'){ - context->network_operator.format = 0; - break; - } - // TODO emit ERROR, wrong format - break; - } - - if (context->operator_name != 1) break; - if (byte == ','){ - context->line_size = 0; - context->line_buffer[context->line_size] = 0; + case HFP_PARSER_SECOND_ITEM: + if (!hfp_parser_item_done(byte)){ + hfp_parser_write_buffer(context, byte); break; } - if (byte == '\n' || byte == '\r'){ - context->line_buffer[context->line_size] = 0; - context->line_size = 0; - printf("opearator name %s\n", context->line_buffer); - strcpy(context->network_operator.name, (char *)context->line_buffer); - context->parser_state = HFP_PARSER_CMD_HEADER; - context->parser_item_index = 0; + switch (context->command){ + case HFP_CMD_QUERY_OPERATOR_SELECTION: + if (context->operator_name_format == 1) { + printf("format %s \n", context->line_buffer); + context->network_operator.format = atoi((char *)&context->line_buffer[0]); + break; + } + if (context->operator_name == 1){ + printf("format %s, ", context->line_buffer); + context->network_operator.format = atoi((char *)&context->line_buffer[0]); + } + break; + default: + break; + } + hfp_parser_next_state(context, byte); + break; + + case HFP_PARSER_THIRD_ITEM: + if (!hfp_parser_item_done(byte)){ + hfp_parser_write_buffer(context, byte); break; } - if (context->line_size < 16){ - context->line_buffer[context->line_size++] = byte; + switch (context->command){ + case HFP_CMD_QUERY_OPERATOR_SELECTION: + if (context->operator_name == 1){ + strcpy(context->network_operator.name, (char *)context->line_buffer); + printf("name %s\n", context->line_buffer); + } + break; + default: + break; } + hfp_parser_next_state(context, byte); break; case HFP_PARSER_CMD_INDICATOR_STATUS: diff --git a/src/hfp.h b/src/hfp.h index f80094282..a6a926999 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -143,7 +143,8 @@ typedef enum { HFP_PARSER_CMD_INDICATOR_MIN_RANGE, HFP_PARSER_CMD_INDICATOR_MAX_RANGE, HFP_PARSER_CMD_INDICATOR_STATUS, - HFP_PARSER_CMD_NETWORK_OPERATOR + HFP_PARSER_SECOND_ITEM, + HFP_PARSER_THIRD_ITEM } hfp_parser_state_t; diff --git a/src/hfp_ag.c b/src/hfp_ag.c index a07c2c9d2..70f759d8b 100644 --- a/src/hfp_ag.c +++ b/src/hfp_ag.c @@ -80,6 +80,7 @@ int get_hfp_generic_status_indicators_nr(); void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicators, int indicator_nr); hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * context){ + // TODO: save only value, and value changed in the context? if (context->ag_indicators_nr != hfp_ag_indicators_nr){ context->ag_indicators_nr = hfp_ag_indicators_nr; memcpy(context->ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); @@ -94,6 +95,7 @@ int get_hfp_ag_indicators_nr(hfp_connection_t * context){ } return context->ag_indicators_nr; } + void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr){ memcpy(hfp_ag_indicators, indicators, indicator_nr * sizeof(hfp_ag_indicator_t)); hfp_ag_indicators_nr = indicator_nr; @@ -383,16 +385,14 @@ void update_command(hfp_connection_t * context){ context->command = HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE; return; } - + if (strncmp((char *)context->line_buffer+2, HFP_QUERY_OPERATOR_SELECTION, strlen(HFP_QUERY_OPERATOR_SELECTION)) == 0){ context->command = HFP_CMD_QUERY_OPERATOR_SELECTION; - if (strncmp((char *)context->line_buffer+strlen(HFP_QUERY_OPERATOR_SELECTION)+2, "?", 1) == 0){ + context->operator_name_format = 0; + if (strncmp((char *)context->line_buffer+strlen(HFP_QUERY_OPERATOR_SELECTION)+2, "=", 1) == 0){ context->operator_name_format = 1; - context->operator_name = 0; - } else { - context->operator_name_format = 0; - context->operator_name = 1; - } + context->operator_name = 0; + } return; } } diff --git a/src/hfp_hf.c b/src/hfp_hf.c index 6e3119093..fe9259ed7 100644 --- a/src/hfp_hf.c +++ b/src/hfp_hf.c @@ -359,10 +359,17 @@ void update_command(hfp_connection_t * context){ return; } - if (strncmp((char *)context->line_buffer, HFP_TRANSFER_AG_INDICATOR_STATUS, strlen(HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS)) == 0){ + if (strncmp((char *)context->line_buffer, HFP_TRANSFER_AG_INDICATOR_STATUS, strlen(HFP_TRANSFER_AG_INDICATOR_STATUS)) == 0){ context->command = HFP_CMD_TRANSFER_AG_INDICATOR_STATUS; return; } + + if (strncmp((char *)context->line_buffer, HFP_QUERY_OPERATOR_SELECTION, strlen(HFP_QUERY_OPERATOR_SELECTION)) == 0){ + context->command = HFP_CMD_QUERY_OPERATOR_SELECTION; + context->operator_name = 1; + context->operator_name_format = 0; + return; + } } diff --git a/test/hfp/hfp_ag_parser_test.c b/test/hfp/hfp_ag_parser_test.c index 5ca0c3454..4dd89ab23 100644 --- a/test/hfp/hfp_ag_parser_test.c +++ b/test/hfp/hfp_ag_parser_test.c @@ -50,8 +50,8 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte); hfp_generic_status_indicator_t * get_hfp_generic_status_indicators(); void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicators, int indicator_nr); -hfp_ag_indicator_t * get_hfp_ag_indicators(); -int get_hfp_ag_indicators_nr(); +hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * context); +int get_hfp_ag_indicators_nr(hfp_connection_t * context); void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr); static int hf_indicators_nr = 3; @@ -149,8 +149,8 @@ TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE){ memcpy(context.ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t)); for (pos = 0; pos < hfp_ag_indicators_nr; pos++){ - CHECK_EQUAL(get_hfp_ag_indicators()[pos].index, hfp_ag_indicators[pos].index); - CHECK_EQUAL(get_hfp_ag_indicators()[pos].enabled, hfp_ag_indicators[pos].enabled); + CHECK_EQUAL(get_hfp_ag_indicators(&context)[pos].index, hfp_ag_indicators[pos].index); + CHECK_EQUAL(get_hfp_ag_indicators(&context)[pos].enabled, hfp_ag_indicators[pos].enabled); CHECK_EQUAL(context.ag_indicators[pos].index, hfp_ag_indicators[pos].index); CHECK_EQUAL(context.ag_indicators[pos].enabled, hfp_ag_indicators[pos].enabled); } @@ -163,11 +163,11 @@ TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE){ CHECK_EQUAL(HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, context.command); for (pos = 0; pos < hfp_ag_indicators_nr; pos++){ - if (get_hfp_ag_indicators()[pos].mandatory){ - CHECK_EQUAL(get_hfp_ag_indicators()[pos].enabled, 1); + if (get_hfp_ag_indicators(&context)[pos].mandatory){ + CHECK_EQUAL(get_hfp_ag_indicators(&context)[pos].enabled, 1); CHECK_EQUAL(context.ag_indicators[pos].enabled, 1); } else { - CHECK_EQUAL(get_hfp_ag_indicators()[pos].enabled, 0); + CHECK_EQUAL(get_hfp_ag_indicators(&context)[pos].enabled, 0); CHECK_EQUAL(context.ag_indicators[pos].enabled, 0); } } @@ -181,11 +181,36 @@ TEST(HFPParser, HFP_AG_ENABLE_INDIVIDUAL_INDICATOR_STATUS_UPDATE){ // CHECK_EQUAL(HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, context.command); // for (pos = 0; pos < hfp_ag_indicators_nr; pos++){ - // CHECK_EQUAL(get_hfp_ag_indicators()[pos].enabled, 1); + // CHECK_EQUAL(get_hfp_ag_indicators(&context)[pos].enabled, 1); // CHECK_EQUAL(context.ag_indicators[pos].enabled, 1); // } } +TEST(HFPParser, HFP_AG_HF_QUERY_OPERATOR_SELECTION){ + context.network_operator.format = 0xff; + sprintf(packet, "\r\nAT%s=3,0\r\n", HFP_QUERY_OPERATOR_SELECTION); + + for (pos = 0; pos < strlen(packet); pos++){ + hfp_parse(&context, packet[pos]); + } + CHECK_EQUAL(context.operator_name_format, 1); + CHECK_EQUAL(context.operator_name, 0); + CHECK_EQUAL(context.operator_name_changed, 0); + + CHECK_EQUAL(HFP_CMD_QUERY_OPERATOR_SELECTION, context.command); + CHECK_EQUAL(context.network_operator.format, 0); + CHECK_EQUAL(context.network_operator.mode, 0); + + sprintf(packet, "\r\nAT%s?\r\n", HFP_QUERY_OPERATOR_SELECTION); + + for (pos = 0; pos < strlen(packet); pos++){ + hfp_parse(&context, packet[pos]); + } + CHECK_EQUAL(context.operator_name_format, 0); + CHECK_EQUAL(context.operator_name, 0); + CHECK_EQUAL(context.operator_name_changed, 0); +} + int main (int argc, const char * argv[]){ return CommandLineTestRunner::RunAllTests(argc, argv); } diff --git a/test/hfp/hfp_hf_parser_test.c b/test/hfp/hfp_hf_parser_test.c index 5c09389da..f98023ff9 100644 --- a/test/hfp/hfp_hf_parser_test.c +++ b/test/hfp/hfp_hf_parser_test.c @@ -207,6 +207,20 @@ TEST(HFPParser, HFP_HF_AG_INDICATOR_STATUS_UPDATE){ CHECK_EQUAL(context.ag_indicators[index - 1].status, status); } +TEST(HFPParser, HFP_HF_AG_QUERY_OPERATOR_SELECTION){ + sprintf(packet, "\r\n%s=1,0,sunrise\r\n", HFP_QUERY_OPERATOR_SELECTION); + + for (pos = 0; pos < strlen(packet); pos++){ + hfp_parse(&context, packet[pos]); + } + + CHECK_EQUAL(context.command, HFP_CMD_QUERY_OPERATOR_SELECTION); + CHECK_EQUAL(context.operator_name_format, 0); + CHECK_EQUAL(context.operator_name, 1); + CHECK_EQUAL(context.operator_name_changed, 0); + CHECK_EQUAL( strcmp("sunrise", context.network_operator.name), 0); +} + int main (int argc, const char * argv[]){ return CommandLineTestRunner::RunAllTests(argc, argv); } From 99b9166836f562858edb5befaec4f53dbcefe48c Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 14 Aug 2015 14:48:02 +0200 Subject: [PATCH 02/11] hfp: rewrite parse indicator --- src/hfp.c | 92 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/src/hfp.c b/src/hfp.c index d51020fc3..7220543c5 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -497,11 +497,14 @@ uint32_t fromBinary(char *s) { return (uint32_t) strtol(s, NULL, 2); } -static void hfp_parser_write_buffer(hfp_connection_t * context, uint8_t byte){ +static void hfp_parser_store_byte(hfp_connection_t * context, uint8_t byte){ // TODO: add limit context->line_buffer[context->line_size++] = byte; context->line_buffer[context->line_size] = 0; } +static int hfp_parser_buffer_empty(hfp_connection_t * context){ + return context->line_size == 0; +} static int hfp_parser_reached_end_of_line(uint8_t byte){ return byte == '\n' || byte == '\r'; @@ -511,8 +514,11 @@ static int hfp_parser_reached_sequence_separator(uint8_t byte){ return byte == ','; } -static int hfp_parser_item_done(uint8_t byte){ - return byte == ',' || byte == '\n' || byte == '\r'; +static int hfp_parser_found_separator(hfp_connection_t * context, uint8_t byte){ + int found_separator = byte == ',' || byte == '\n' || byte == '\r' || + byte == ')' || byte == '(' || byte == ':' || + byte == '?' || byte == '-' || byte == '"'; + return found_separator; } static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ @@ -529,15 +535,18 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ case HFP_PARSER_SECOND_ITEM: context->parser_state = (hfp_parser_state_t)((int)context->parser_state + 1); break; + case HFP_PARSER_THIRD_ITEM: + context->parser_state = HFP_PARSER_CMD_HEADER; + break; case HFP_PARSER_CMD_INDICATOR_MAX_RANGE: - case HFP_PARSER_CMD_INDICATOR_STATUS: context->parser_state = HFP_PARSER_CMD_SEQUENCE; break; case HFP_PARSER_CMD_SEQUENCE: break; - case HFP_PARSER_THIRD_ITEM: + case HFP_PARSER_CMD_INDICATOR_STATUS: context->parser_state = HFP_PARSER_CMD_HEADER; - + break; + } } @@ -723,10 +732,12 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ break; case HFP_PARSER_SECOND_ITEM: - if (!hfp_parser_item_done(byte)){ - hfp_parser_write_buffer(context, byte); + if (!hfp_parser_found_separator(context, byte)){ + hfp_parser_store_byte(context, byte); break; } + if (hfp_parser_buffer_empty(context)) break; + switch (context->command){ case HFP_CMD_QUERY_OPERATOR_SELECTION: if (context->operator_name_format == 1) { @@ -746,10 +757,12 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ break; case HFP_PARSER_THIRD_ITEM: - if (!hfp_parser_item_done(byte)){ - hfp_parser_write_buffer(context, byte); + if (!hfp_parser_found_separator(context, byte)){ + hfp_parser_store_byte(context, byte); break; } + if (hfp_parser_buffer_empty(context)) break; + switch (context->command){ case HFP_CMD_QUERY_OPERATOR_SELECTION: if (context->operator_name == 1){ @@ -789,48 +802,43 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ break; case HFP_PARSER_CMD_INDICATOR_NAME: // parse indicator name - //if (byte == '\n' || byte == '\r') return; - if (byte == '"'){ - context->line_buffer[context->line_size] = 0; - context->line_size = 0; - printf("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer); - strcpy((char *)context->ag_indicators[context->parser_item_index].name, (char *)context->line_buffer); - context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1; + if (!hfp_parser_found_separator(context, byte)){ + hfp_parser_store_byte(context, byte); break; } - if (byte == '('){ // parse indicator range - context->parser_state = HFP_PARSER_CMD_INDICATOR_MIN_RANGE; - break; - } - context->line_buffer[context->line_size++] = byte; + if (hfp_parser_buffer_empty(context)) break; + + strcpy((char *)context->ag_indicators[context->parser_item_index].name, (char *)context->line_buffer); + context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1; + printf("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer); + + hfp_parser_next_state(context, byte); break; case HFP_PARSER_CMD_INDICATOR_MIN_RANGE: - //if (byte == '\n' || byte == '\r') return; - if (byte == ',' || byte == '-'){ // end min_range - context->parser_state = HFP_PARSER_CMD_INDICATOR_MAX_RANGE; - context->line_buffer[context->line_size] = 0; - printf("%d, ", atoi((char *)&context->line_buffer[0])); - context->ag_indicators[context->parser_item_index].min_range = atoi((char *)context->line_buffer); - context->line_size = 0; + if (!hfp_parser_found_separator(context, byte)){ + hfp_parser_store_byte(context, byte); break; } - // min. range - context->line_buffer[context->line_size++] = byte; + if (hfp_parser_buffer_empty(context)) break; + + context->ag_indicators[context->parser_item_index].min_range = atoi((char *)context->line_buffer); + printf("%s, ", context->line_buffer); + + hfp_parser_next_state(context, byte); break; case HFP_PARSER_CMD_INDICATOR_MAX_RANGE: - //if (byte == '\n' || byte == '\r') return; - if (byte == ')'){ // end max_range - context->parser_state = HFP_PARSER_CMD_SEQUENCE; - context->line_buffer[context->line_size] = 0; - printf("%d)\n", atoi((char *)&context->line_buffer[0])); - context->ag_indicators[context->parser_item_index].max_range = atoi((char *)context->line_buffer); - context->line_size = 0; - context->parser_item_index++; - context->ag_indicators_nr = context->parser_item_index; + if (!hfp_parser_found_separator(context, byte)){ + hfp_parser_store_byte(context, byte); break; } - - context->line_buffer[context->line_size++] = byte; + if (hfp_parser_buffer_empty(context)) break; + + context->ag_indicators[context->parser_item_index].max_range = atoi((char *)context->line_buffer); + context->parser_item_index++; + context->ag_indicators_nr = context->parser_item_index; + printf("%s)\n", context->line_buffer); + + hfp_parser_next_state(context, byte); break; } From 8acae519b04ddd3ca7ae3917738356001686786a Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 14 Aug 2015 14:53:43 +0200 Subject: [PATCH 03/11] hfp: rewrite parse indicator status --- src/hfp.c | 40 ++++++++++------------------------------ src/hfp.h | 1 - 2 files changed, 10 insertions(+), 31 deletions(-) diff --git a/src/hfp.c b/src/hfp.c index 7220543c5..540f1174a 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -543,9 +543,6 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ break; case HFP_PARSER_CMD_SEQUENCE: break; - case HFP_PARSER_CMD_INDICATOR_STATUS: - context->parser_state = HFP_PARSER_CMD_HEADER; - break; } } @@ -673,7 +670,7 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ if (context->retrieve_generic_status_indicators_state == 1){ // HF parses inital AG gen. ind. state printf("Parsed List generic status indicator %s state: ", context->line_buffer); - context->parser_state = HFP_PARSER_CMD_INDICATOR_STATUS; + context->parser_state = HFP_PARSER_SECOND_ITEM; context->parser_item_index = (uint8_t)atoi((char*)context->line_buffer); break; } @@ -691,7 +688,7 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: // indicators are indexed starting with 1 context->parser_item_index = atoi((char *)&context->line_buffer[0]) - 1; - context->parser_state = HFP_PARSER_CMD_INDICATOR_STATUS; + context->parser_state = HFP_PARSER_SECOND_ITEM; printf("Parsed status of the AG indicator %d, status ", context->parser_item_index); break; case HFP_CMD_QUERY_OPERATOR_SELECTION: @@ -737,7 +734,7 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ break; } if (hfp_parser_buffer_empty(context)) break; - + switch (context->command){ case HFP_CMD_QUERY_OPERATOR_SELECTION: if (context->operator_name_format == 1) { @@ -750,6 +747,13 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ context->network_operator.format = atoi((char *)&context->line_buffer[0]); } break; + case HFP_CMD_GENERIC_STATUS_INDICATOR: + context->generic_status_indicators[context->parser_item_index].state = (uint8_t)atoi((char*)context->line_buffer); + break; + case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: + context->ag_indicators[context->parser_item_index].status = (uint8_t)atoi((char*)context->line_buffer); + context->ag_indicators[context->parser_item_index].status_changed = 1; + break; default: break; } @@ -776,30 +780,6 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ hfp_parser_next_state(context, byte); break; - case HFP_PARSER_CMD_INDICATOR_STATUS: - context->line_buffer[context->line_size] = 0; - if (byte == ',') break; - if (byte == '\n' || byte == '\r'){ - context->line_buffer[context->line_size] = 0; - context->line_size = 0; - context->parser_state = HFP_PARSER_CMD_HEADER; - printf("%s\n", context->line_buffer); - // HF stores inital AG gen. ind. state - switch (context->command){ - case HFP_CMD_GENERIC_STATUS_INDICATOR: - context->generic_status_indicators[context->parser_item_index].state = (uint8_t)atoi((char*)context->line_buffer); - break; - case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: - context->ag_indicators[context->parser_item_index].status = (uint8_t)atoi((char*)context->line_buffer); - context->ag_indicators[context->parser_item_index].status_changed = 1; - break; - default: - break; - } - break; - } - context->line_buffer[context->line_size++] = byte; - break; case HFP_PARSER_CMD_INDICATOR_NAME: // parse indicator name if (!hfp_parser_found_separator(context, byte)){ diff --git a/src/hfp.h b/src/hfp.h index a6a926999..ea0fba1dc 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -142,7 +142,6 @@ typedef enum { HFP_PARSER_CMD_INDICATOR_NAME, HFP_PARSER_CMD_INDICATOR_MIN_RANGE, HFP_PARSER_CMD_INDICATOR_MAX_RANGE, - HFP_PARSER_CMD_INDICATOR_STATUS, HFP_PARSER_SECOND_ITEM, HFP_PARSER_THIRD_ITEM } hfp_parser_state_t; From 211b60e2b12550f4afdddb697d02fd9d75baa267 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 14 Aug 2015 15:01:30 +0200 Subject: [PATCH 04/11] hfp: rewrite parse sequence --- src/hfp.c | 221 ++++++++++++++++++++++++++---------------------------- 1 file changed, 108 insertions(+), 113 deletions(-) diff --git a/src/hfp.c b/src/hfp.c index 540f1174a..e98452fbc 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -605,127 +605,122 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ case HFP_PARSER_CMD_SEQUENCE: // parse comma separated sequence, ignore breacktes if (byte == '"'){ // indicators context->parser_state = HFP_PARSER_CMD_INDICATOR_NAME; - context->line_size = 0; break; } - - if (byte == '(' ){ // tuple separated mit comma + + if (!hfp_parser_found_separator(context, byte)){ + hfp_parser_store_byte(context, byte); break; } - - if (byte == ',' || byte == '\n' || byte == '\r' || byte == ')'){ - context->line_buffer[context->line_size] = 0; - - switch (context->command){ - case HFP_CMD_SUPPORTED_FEATURES: - context->remote_supported_features = atoi((char*)context->line_buffer); - printf("Parsed supported feature %d\n", context->remote_supported_features); - context->parser_state = HFP_PARSER_CMD_HEADER; - break; - case HFP_CMD_AVAILABLE_CODECS: - printf("Parsed codec %s\n", context->line_buffer); - context->remote_codecs[context->parser_item_index] = (uint16_t)atoi((char*)context->line_buffer); - context->parser_item_index++; - context->remote_codecs_nr = context->parser_item_index; - break; - case HFP_CMD_INDICATOR: - if (context->retrieve_ag_indicators_status == 0) break; - printf("Parsed Indicator %d with status: %s\n", context->parser_item_index+1, context->line_buffer); - context->ag_indicators[context->parser_item_index].status = atoi((char *) context->line_buffer); - context->parser_item_index++; - break; - case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: - if (context->parser_item_index == 3){ - printf("Parsed Enable indicators: %s\n", context->line_buffer); - value = atoi((char *)&context->line_buffer[0]); - context->enable_status_update_for_ag_indicators = (uint8_t) value; - } else { - context->parser_item_index++; - } - break; - case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES: - printf("Parsed Support call hold: %s\n", context->line_buffer); - if (context->line_size > 2 ) break; - strcpy((char *)context->remote_call_services[context->remote_call_services_nr].name, (char *)context->line_buffer); - context->remote_call_services_nr++; - - if (byte == ')'){ - context->parser_state = HFP_PARSER_CMD_HEADER; - context->parser_item_index = 0; - } - break; - case HFP_CMD_GENERIC_STATUS_INDICATOR: - printf("parser HFP_CMD_GENERIC_STATUS_INDICATOR 1 (%d, %d, %d)\n", - context->list_generic_status_indicators, - context->retrieve_generic_status_indicators, - context->retrieve_generic_status_indicators_state); - if (context->retrieve_generic_status_indicators == 1 || context->list_generic_status_indicators == 1){ - printf("Parsed Generic status indicator: %s\n", context->line_buffer); - context->generic_status_indicators[context->parser_item_index].uuid = (uint16_t)atoi((char*)context->line_buffer); - context->parser_item_index++; - context->generic_status_indicators_nr = context->parser_item_index; - break; - } - printf("parser HFP_CMD_GENERIC_STATUS_INDICATOR 2\n"); - if (context->retrieve_generic_status_indicators_state == 1){ - // HF parses inital AG gen. ind. state - printf("Parsed List generic status indicator %s state: ", context->line_buffer); - context->parser_state = HFP_PARSER_SECOND_ITEM; - context->parser_item_index = (uint8_t)atoi((char*)context->line_buffer); - break; - } - break; - - case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE: - // AG parses new gen. ind. state - printf("Parsed Enable ag indicator state: %s\n", context->line_buffer); - value = atoi((char *)&context->line_buffer[0]); - if (!context->ag_indicators[context->parser_item_index].mandatory){ - context->ag_indicators[context->parser_item_index].enabled = value; - } - context->parser_item_index++; - break; - case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: - // indicators are indexed starting with 1 - context->parser_item_index = atoi((char *)&context->line_buffer[0]) - 1; - context->parser_state = HFP_PARSER_SECOND_ITEM; - printf("Parsed status of the AG indicator %d, status ", context->parser_item_index); - break; - case HFP_CMD_QUERY_OPERATOR_SELECTION: - context->parser_state = HFP_PARSER_SECOND_ITEM; - context->line_size = 0; - - if (context->operator_name_format == 1){ - if (context->line_buffer[0] == '3'){ - printf("Parsed Set network operator format : %s, ", context->line_buffer); - break; - } - // TODO emit ERROR, wrong format - printf("ERROR Set network operator format: index %s not supported\n", context->line_buffer); - break; - } - - if (context->operator_name == 1) { - context->network_operator.mode = atoi((char *)&context->line_buffer[0]); - printf("Parsed network operator mode: %d, ", context->network_operator.mode); - break; - } - - break; - - default: - break; - } - context->line_size = 0; - - if (byte == '\n' || byte == '\r'){ + if (hfp_parser_buffer_empty(context)) break; + + switch (context->command){ + case HFP_CMD_SUPPORTED_FEATURES: + context->remote_supported_features = atoi((char*)context->line_buffer); + printf("Parsed supported feature %d\n", context->remote_supported_features); context->parser_state = HFP_PARSER_CMD_HEADER; - context->parser_item_index = 0; break; - } + case HFP_CMD_AVAILABLE_CODECS: + printf("Parsed codec %s\n", context->line_buffer); + context->remote_codecs[context->parser_item_index] = (uint16_t)atoi((char*)context->line_buffer); + context->parser_item_index++; + context->remote_codecs_nr = context->parser_item_index; + break; + case HFP_CMD_INDICATOR: + if (context->retrieve_ag_indicators_status == 0) break; + printf("Parsed Indicator %d with status: %s\n", context->parser_item_index+1, context->line_buffer); + context->ag_indicators[context->parser_item_index].status = atoi((char *) context->line_buffer); + context->parser_item_index++; + break; + case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: + if (context->parser_item_index == 3){ + printf("Parsed Enable indicators: %s\n", context->line_buffer); + value = atoi((char *)&context->line_buffer[0]); + context->enable_status_update_for_ag_indicators = (uint8_t) value; + } else { + context->parser_item_index++; + } + break; + case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES: + printf("Parsed Support call hold: %s\n", context->line_buffer); + if (context->line_size > 2 ) break; + strcpy((char *)context->remote_call_services[context->remote_call_services_nr].name, (char *)context->line_buffer); + context->remote_call_services_nr++; + + if (byte == ')'){ + context->parser_state = HFP_PARSER_CMD_HEADER; + context->parser_item_index = 0; + } + break; + case HFP_CMD_GENERIC_STATUS_INDICATOR: + printf("parser HFP_CMD_GENERIC_STATUS_INDICATOR 1 (%d, %d, %d)\n", + context->list_generic_status_indicators, + context->retrieve_generic_status_indicators, + context->retrieve_generic_status_indicators_state); + if (context->retrieve_generic_status_indicators == 1 || context->list_generic_status_indicators == 1){ + printf("Parsed Generic status indicator: %s\n", context->line_buffer); + context->generic_status_indicators[context->parser_item_index].uuid = (uint16_t)atoi((char*)context->line_buffer); + context->parser_item_index++; + context->generic_status_indicators_nr = context->parser_item_index; + break; + } + printf("parser HFP_CMD_GENERIC_STATUS_INDICATOR 2\n"); + if (context->retrieve_generic_status_indicators_state == 1){ + // HF parses inital AG gen. ind. state + printf("Parsed List generic status indicator %s state: ", context->line_buffer); + context->parser_state = HFP_PARSER_SECOND_ITEM; + context->parser_item_index = (uint8_t)atoi((char*)context->line_buffer); + break; + } + break; + + case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE: + // AG parses new gen. ind. state + printf("Parsed Enable ag indicator state: %s\n", context->line_buffer); + value = atoi((char *)&context->line_buffer[0]); + if (!context->ag_indicators[context->parser_item_index].mandatory){ + context->ag_indicators[context->parser_item_index].enabled = value; + } + context->parser_item_index++; + break; + case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: + // indicators are indexed starting with 1 + context->parser_item_index = atoi((char *)&context->line_buffer[0]) - 1; + context->parser_state = HFP_PARSER_SECOND_ITEM; + printf("Parsed status of the AG indicator %d, status ", context->parser_item_index); + break; + case HFP_CMD_QUERY_OPERATOR_SELECTION: + context->parser_state = HFP_PARSER_SECOND_ITEM; + context->line_size = 0; + + if (context->operator_name_format == 1){ + if (context->line_buffer[0] == '3'){ + printf("Parsed Set network operator format : %s, ", context->line_buffer); + break; + } + // TODO emit ERROR, wrong format + printf("ERROR Set network operator format: index %s not supported\n", context->line_buffer); + break; + } + + if (context->operator_name == 1) { + context->network_operator.mode = atoi((char *)&context->line_buffer[0]); + printf("Parsed network operator mode: %d, ", context->network_operator.mode); + break; + } + + break; + + default: + break; + } + + context->line_size = 0; + if (byte == '\n' || byte == '\r'){ + context->parser_state = HFP_PARSER_CMD_HEADER; + context->parser_item_index = 0; break; } - context->line_buffer[context->line_size++] = byte; break; case HFP_PARSER_SECOND_ITEM: From ec2675afd66d34e122a307e9f7435da970ba9514 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 14 Aug 2015 15:09:57 +0200 Subject: [PATCH 05/11] hfp: rewrite parse sequence --- src/hfp.c | 50 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/hfp.c b/src/hfp.c index e98452fbc..8f08670ea 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -529,8 +529,8 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ return; } switch (context->parser_state){ - case HFP_PARSER_CMD_HEADER: case HFP_PARSER_CMD_INDICATOR_NAME: + case HFP_PARSER_CMD_HEADER: case HFP_PARSER_CMD_INDICATOR_MIN_RANGE: case HFP_PARSER_SECOND_ITEM: context->parser_state = (hfp_parser_state_t)((int)context->parser_state + 1); @@ -783,10 +783,18 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ } if (hfp_parser_buffer_empty(context)) break; - strcpy((char *)context->ag_indicators[context->parser_item_index].name, (char *)context->line_buffer); - context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1; - printf("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer); - + switch (context->command){ + case HFP_CMD_INDICATOR: + if (context->retrieve_ag_indicators == 1){ + strcpy((char *)context->ag_indicators[context->parser_item_index].name, (char *)context->line_buffer); + context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1; + printf("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer); + } + break; + default: + break; + } + hfp_parser_next_state(context, byte); break; case HFP_PARSER_CMD_INDICATOR_MIN_RANGE: @@ -796,9 +804,17 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ } if (hfp_parser_buffer_empty(context)) break; - context->ag_indicators[context->parser_item_index].min_range = atoi((char *)context->line_buffer); - printf("%s, ", context->line_buffer); - + switch (context->command){ + case HFP_CMD_INDICATOR: + if (context->retrieve_ag_indicators == 1){ + context->ag_indicators[context->parser_item_index].min_range = atoi((char *)context->line_buffer); + printf("%s, ", context->line_buffer); + } + break; + default: + break; + } + hfp_parser_next_state(context, byte); break; case HFP_PARSER_CMD_INDICATOR_MAX_RANGE: @@ -808,11 +824,19 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ } if (hfp_parser_buffer_empty(context)) break; - context->ag_indicators[context->parser_item_index].max_range = atoi((char *)context->line_buffer); - context->parser_item_index++; - context->ag_indicators_nr = context->parser_item_index; - printf("%s)\n", context->line_buffer); - + switch (context->command){ + case HFP_CMD_INDICATOR: + if (context->retrieve_ag_indicators == 1){ + context->ag_indicators[context->parser_item_index].max_range = atoi((char *)context->line_buffer); + context->parser_item_index++; + context->ag_indicators_nr = context->parser_item_index; + printf("%s)\n", context->line_buffer); + } + break; + default: + break; + } + hfp_parser_next_state(context, byte); break; From f602d56c127de58034270da63fbb619c547ac22f Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 14 Aug 2015 15:12:31 +0200 Subject: [PATCH 06/11] hfp: rewrite parse sequence --- src/hfp.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/hfp.c b/src/hfp.c index 8f08670ea..dcf177eca 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -530,6 +530,8 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ } switch (context->parser_state){ case HFP_PARSER_CMD_INDICATOR_NAME: + context->parser_state = HFP_PARSER_SECOND_ITEM; + break; case HFP_PARSER_CMD_HEADER: case HFP_PARSER_CMD_INDICATOR_MIN_RANGE: case HFP_PARSER_SECOND_ITEM: @@ -749,6 +751,12 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ context->ag_indicators[context->parser_item_index].status = (uint8_t)atoi((char*)context->line_buffer); context->ag_indicators[context->parser_item_index].status_changed = 1; break; + case HFP_CMD_INDICATOR: + if (context->retrieve_ag_indicators == 1){ + context->ag_indicators[context->parser_item_index].min_range = atoi((char *)context->line_buffer); + printf("%s, ", context->line_buffer); + } + break; default: break; } @@ -769,6 +777,14 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ printf("name %s\n", context->line_buffer); } break; + case HFP_CMD_INDICATOR: + if (context->retrieve_ag_indicators == 1){ + context->ag_indicators[context->parser_item_index].max_range = atoi((char *)context->line_buffer); + context->parser_item_index++; + context->ag_indicators_nr = context->parser_item_index; + printf("%s)\n", context->line_buffer); + } + break; default: break; } @@ -805,12 +821,7 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ if (hfp_parser_buffer_empty(context)) break; switch (context->command){ - case HFP_CMD_INDICATOR: - if (context->retrieve_ag_indicators == 1){ - context->ag_indicators[context->parser_item_index].min_range = atoi((char *)context->line_buffer); - printf("%s, ", context->line_buffer); - } - break; + default: break; } @@ -825,14 +836,7 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ if (hfp_parser_buffer_empty(context)) break; switch (context->command){ - case HFP_CMD_INDICATOR: - if (context->retrieve_ag_indicators == 1){ - context->ag_indicators[context->parser_item_index].max_range = atoi((char *)context->line_buffer); - context->parser_item_index++; - context->ag_indicators_nr = context->parser_item_index; - printf("%s)\n", context->line_buffer); - } - break; + default: break; } From d28abd08a738c7aadc46d4bc18e1c18be133141a Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 14 Aug 2015 15:17:03 +0200 Subject: [PATCH 07/11] hfp: rewrite parse sequence --- src/hfp.c | 40 ++++------------------------------------ 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/src/hfp.c b/src/hfp.c index dcf177eca..f4dcc129b 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -533,16 +533,16 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ context->parser_state = HFP_PARSER_SECOND_ITEM; break; case HFP_PARSER_CMD_HEADER: - case HFP_PARSER_CMD_INDICATOR_MIN_RANGE: case HFP_PARSER_SECOND_ITEM: context->parser_state = (hfp_parser_state_t)((int)context->parser_state + 1); break; case HFP_PARSER_THIRD_ITEM: + if (context->command == HFP_CMD_INDICATOR && context->retrieve_ag_indicators){ + context->parser_state = HFP_PARSER_CMD_SEQUENCE; + break; + } context->parser_state = HFP_PARSER_CMD_HEADER; break; - case HFP_PARSER_CMD_INDICATOR_MAX_RANGE: - context->parser_state = HFP_PARSER_CMD_SEQUENCE; - break; case HFP_PARSER_CMD_SEQUENCE: break; @@ -791,7 +791,6 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ hfp_parser_next_state(context, byte); break; - case HFP_PARSER_CMD_INDICATOR_NAME: // parse indicator name if (!hfp_parser_found_separator(context, byte)){ hfp_parser_store_byte(context, byte); @@ -813,37 +812,6 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ hfp_parser_next_state(context, byte); break; - case HFP_PARSER_CMD_INDICATOR_MIN_RANGE: - if (!hfp_parser_found_separator(context, byte)){ - hfp_parser_store_byte(context, byte); - break; - } - if (hfp_parser_buffer_empty(context)) break; - - switch (context->command){ - - default: - break; - } - - hfp_parser_next_state(context, byte); - break; - case HFP_PARSER_CMD_INDICATOR_MAX_RANGE: - if (!hfp_parser_found_separator(context, byte)){ - hfp_parser_store_byte(context, byte); - break; - } - if (hfp_parser_buffer_empty(context)) break; - - switch (context->command){ - - default: - break; - } - - hfp_parser_next_state(context, byte); - break; - } } From 854e6efc25476404064fde7ea2b8a64d0cac2319 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 14 Aug 2015 15:30:40 +0200 Subject: [PATCH 08/11] hfp: remove indicator name for parser states --- src/hfp.c | 53 ++++++++++++++++++----------------------------------- src/hfp.h | 3 --- 2 files changed, 18 insertions(+), 38 deletions(-) diff --git a/src/hfp.c b/src/hfp.c index f4dcc129b..f468bbc99 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -529,9 +529,6 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ return; } switch (context->parser_state){ - case HFP_PARSER_CMD_INDICATOR_NAME: - context->parser_state = HFP_PARSER_SECOND_ITEM; - break; case HFP_PARSER_CMD_HEADER: case HFP_PARSER_SECOND_ITEM: context->parser_state = (hfp_parser_state_t)((int)context->parser_state + 1); @@ -544,8 +541,12 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ context->parser_state = HFP_PARSER_CMD_HEADER; break; case HFP_PARSER_CMD_SEQUENCE: + if (context->command == HFP_CMD_INDICATOR && context->retrieve_ag_indicators){ + context->parser_state = HFP_PARSER_SECOND_ITEM; + break; + } break; - + } } @@ -605,11 +606,6 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ break; case HFP_PARSER_CMD_SEQUENCE: // parse comma separated sequence, ignore breacktes - if (byte == '"'){ // indicators - context->parser_state = HFP_PARSER_CMD_INDICATOR_NAME; - break; - } - if (!hfp_parser_found_separator(context, byte)){ hfp_parser_store_byte(context, byte); break; @@ -629,10 +625,19 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ context->remote_codecs_nr = context->parser_item_index; break; case HFP_CMD_INDICATOR: - if (context->retrieve_ag_indicators_status == 0) break; - printf("Parsed Indicator %d with status: %s\n", context->parser_item_index+1, context->line_buffer); - context->ag_indicators[context->parser_item_index].status = atoi((char *) context->line_buffer); - context->parser_item_index++; + if (context->retrieve_ag_indicators == 1){ + context->parser_state = HFP_PARSER_SECOND_ITEM; + strcpy((char *)context->ag_indicators[context->parser_item_index].name, (char *)context->line_buffer); + context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1; + printf("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer); + } + + if (context->retrieve_ag_indicators_status == 1){ + printf("Parsed Indicator %d with status: %s\n", context->parser_item_index+1, context->line_buffer); + context->ag_indicators[context->parser_item_index].status = atoi((char *) context->line_buffer); + context->parser_item_index++; + break; + } break; case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: if (context->parser_item_index == 3){ @@ -790,28 +795,6 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ } hfp_parser_next_state(context, byte); break; - - case HFP_PARSER_CMD_INDICATOR_NAME: // parse indicator name - if (!hfp_parser_found_separator(context, byte)){ - hfp_parser_store_byte(context, byte); - break; - } - if (hfp_parser_buffer_empty(context)) break; - - switch (context->command){ - case HFP_CMD_INDICATOR: - if (context->retrieve_ag_indicators == 1){ - strcpy((char *)context->ag_indicators[context->parser_item_index].name, (char *)context->line_buffer); - context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1; - printf("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer); - } - break; - default: - break; - } - - hfp_parser_next_state(context, byte); - break; } } diff --git a/src/hfp.h b/src/hfp.h index ea0fba1dc..d7df96d81 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -139,9 +139,6 @@ typedef enum { typedef enum { HFP_PARSER_CMD_HEADER = 0, HFP_PARSER_CMD_SEQUENCE, - HFP_PARSER_CMD_INDICATOR_NAME, - HFP_PARSER_CMD_INDICATOR_MIN_RANGE, - HFP_PARSER_CMD_INDICATOR_MAX_RANGE, HFP_PARSER_SECOND_ITEM, HFP_PARSER_THIRD_ITEM } hfp_parser_state_t; From cb591d40935f38c6c98c6d0b1eb110532feb1a0c Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 14 Aug 2015 15:51:00 +0200 Subject: [PATCH 09/11] hfp: rewriten parse sequence --- src/hfp.c | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/hfp.c b/src/hfp.c index f468bbc99..132844d90 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -541,12 +541,27 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ context->parser_state = HFP_PARSER_CMD_HEADER; break; case HFP_PARSER_CMD_SEQUENCE: - if (context->command == HFP_CMD_INDICATOR && context->retrieve_ag_indicators){ - context->parser_state = HFP_PARSER_SECOND_ITEM; - break; + switch (context->command){ + case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: + case HFP_CMD_QUERY_OPERATOR_SELECTION: + context->parser_state = HFP_PARSER_SECOND_ITEM; + break; + case HFP_CMD_INDICATOR: + if (context->retrieve_ag_indicators == 1){ + context->parser_state = HFP_PARSER_SECOND_ITEM; + break; + } + break; + case HFP_CMD_GENERIC_STATUS_INDICATOR: + if (context->retrieve_generic_status_indicators_state == 1){ + context->parser_state = HFP_PARSER_SECOND_ITEM; + break; + } + break; + default: + break; } break; - } } @@ -616,7 +631,6 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ case HFP_CMD_SUPPORTED_FEATURES: context->remote_supported_features = atoi((char*)context->line_buffer); printf("Parsed supported feature %d\n", context->remote_supported_features); - context->parser_state = HFP_PARSER_CMD_HEADER; break; case HFP_CMD_AVAILABLE_CODECS: printf("Parsed codec %s\n", context->line_buffer); @@ -626,7 +640,6 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ break; case HFP_CMD_INDICATOR: if (context->retrieve_ag_indicators == 1){ - context->parser_state = HFP_PARSER_SECOND_ITEM; strcpy((char *)context->ag_indicators[context->parser_item_index].name, (char *)context->line_buffer); context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1; printf("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer); @@ -653,11 +666,6 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ if (context->line_size > 2 ) break; strcpy((char *)context->remote_call_services[context->remote_call_services_nr].name, (char *)context->line_buffer); context->remote_call_services_nr++; - - if (byte == ')'){ - context->parser_state = HFP_PARSER_CMD_HEADER; - context->parser_item_index = 0; - } break; case HFP_CMD_GENERIC_STATUS_INDICATOR: printf("parser HFP_CMD_GENERIC_STATUS_INDICATOR 1 (%d, %d, %d)\n", @@ -675,7 +683,6 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ if (context->retrieve_generic_status_indicators_state == 1){ // HF parses inital AG gen. ind. state printf("Parsed List generic status indicator %s state: ", context->line_buffer); - context->parser_state = HFP_PARSER_SECOND_ITEM; context->parser_item_index = (uint8_t)atoi((char*)context->line_buffer); break; } @@ -693,13 +700,9 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS: // indicators are indexed starting with 1 context->parser_item_index = atoi((char *)&context->line_buffer[0]) - 1; - context->parser_state = HFP_PARSER_SECOND_ITEM; printf("Parsed status of the AG indicator %d, status ", context->parser_item_index); break; case HFP_CMD_QUERY_OPERATOR_SELECTION: - context->parser_state = HFP_PARSER_SECOND_ITEM; - context->line_size = 0; - if (context->operator_name_format == 1){ if (context->line_buffer[0] == '3'){ printf("Parsed Set network operator format : %s, ", context->line_buffer); @@ -715,19 +718,13 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ printf("Parsed network operator mode: %d, ", context->network_operator.mode); break; } - break; - + default: break; } - context->line_size = 0; - if (byte == '\n' || byte == '\r'){ - context->parser_state = HFP_PARSER_CMD_HEADER; - context->parser_item_index = 0; - break; - } + hfp_parser_next_state(context, byte); break; case HFP_PARSER_SECOND_ITEM: From 67c47d0d10d9f9c53c37d5c616baae6c137ee4b5 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 14 Aug 2015 16:35:31 +0200 Subject: [PATCH 10/11] hfp: rewrite parse header --- src/hfp.c | 87 +++++++++++++++-------------------- src/hfp.h | 2 +- test/hfp/hfp_ag_parser_test.c | 2 +- test/hfp/hfp_hf_parser_test.c | 4 +- 4 files changed, 42 insertions(+), 53 deletions(-) diff --git a/src/hfp.c b/src/hfp.c index 132844d90..39fce1a99 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -510,6 +510,10 @@ static int hfp_parser_reached_end_of_line(uint8_t byte){ return byte == '\n' || byte == '\r'; } +static int hfp_parser_reached_end_of_header(uint8_t byte){ + return hfp_parser_reached_end_of_line(byte) || byte == ':' || byte == '?'; +} + static int hfp_parser_reached_sequence_separator(uint8_t byte){ return byte == ','; } @@ -517,8 +521,8 @@ static int hfp_parser_reached_sequence_separator(uint8_t byte){ static int hfp_parser_found_separator(hfp_connection_t * context, uint8_t byte){ int found_separator = byte == ',' || byte == '\n' || byte == '\r' || byte == ')' || byte == '(' || byte == ':' || - byte == '?' || byte == '-' || byte == '"'; - return found_separator; + byte == '-' || byte == '"' || byte == '?' || byte == '='; + return found_separator || context->keep_byte == 1; } static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ @@ -530,15 +534,11 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ } switch (context->parser_state){ case HFP_PARSER_CMD_HEADER: - case HFP_PARSER_SECOND_ITEM: - context->parser_state = (hfp_parser_state_t)((int)context->parser_state + 1); - break; - case HFP_PARSER_THIRD_ITEM: - if (context->command == HFP_CMD_INDICATOR && context->retrieve_ag_indicators){ - context->parser_state = HFP_PARSER_CMD_SEQUENCE; - break; + context->parser_state = HFP_PARSER_CMD_SEQUENCE; + if (context->keep_byte == 1){ + hfp_parser_store_byte(context, byte); + context->keep_byte = 0; } - context->parser_state = HFP_PARSER_CMD_HEADER; break; case HFP_PARSER_CMD_SEQUENCE: switch (context->command){ @@ -562,6 +562,16 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ break; } break; + case HFP_PARSER_SECOND_ITEM: + context->parser_state = HFP_PARSER_THIRD_ITEM; + break; + case HFP_PARSER_THIRD_ITEM: + if (context->command == HFP_CMD_INDICATOR && context->retrieve_ag_indicators){ + context->parser_state = HFP_PARSER_CMD_SEQUENCE; + break; + } + context->parser_state = HFP_PARSER_CMD_HEADER; + break; } } @@ -574,50 +584,29 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ switch (context->parser_state){ case HFP_PARSER_CMD_HEADER: // header - if (context->wait_question_mark == 1 ) { - context->wait_question_mark = 0; - if (byte != '?'){ - context->parser_state = HFP_PARSER_CMD_SEQUENCE; - context->line_buffer[context->line_size] = 0; - update_command(context); - - context->parser_item_index = 0; - context->line_size = 0; - context->line_buffer[context->line_size++] = byte; - break; - } + if (!hfp_parser_found_separator(context, byte)){ + hfp_parser_store_byte(context, byte); + break; + } + if (hfp_parser_buffer_empty(context)) break; + + if (byte == '='){ + context->keep_byte = 1; + hfp_parser_store_byte(context, byte); + break; + } + + if (byte == '?'){ + context->keep_byte = 0; + hfp_parser_store_byte(context, byte); + break; } - if (byte == '?' || byte == '='){ - context->line_buffer[context->line_size++] = byte; - if (byte == '='){ - context->wait_question_mark = 1; - } - } - - if (byte == ':' || byte == '?'){ - context->parser_state = HFP_PARSER_CMD_SEQUENCE; - context->line_buffer[context->line_size] = 0; + if (hfp_parser_reached_end_of_header(byte) || context->keep_byte == 1){ update_command(context); - - context->line_size = 0; - context->parser_item_index = 0; - context->wait_question_mark = 0; - return; } - if (byte == '\n' || byte == '\r'){ - context->line_buffer[context->line_size] = 0; - if (context->line_size == 2){ - update_command(context); - } - context->line_size = 0; - context->parser_item_index = 0; - return; - } - if (byte != '='){ - context->line_buffer[context->line_size++] = byte; - } + hfp_parser_next_state(context, byte); break; case HFP_PARSER_CMD_SEQUENCE: // parse comma separated sequence, ignore breacktes diff --git a/src/hfp.h b/src/hfp.h index d7df96d81..568ce72cb 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -255,7 +255,7 @@ typedef struct hfp_connection { // TODO: put these bit flags in a bitmap uint8_t wait_ok; - uint8_t wait_question_mark; + uint8_t keep_byte; uint8_t retrieve_ag_indicators; // HFP_CMD_INDICATOR, check if needed uint8_t retrieve_ag_indicators_status; diff --git a/test/hfp/hfp_ag_parser_test.c b/test/hfp/hfp_ag_parser_test.c index 4dd89ab23..26db87f90 100644 --- a/test/hfp/hfp_ag_parser_test.c +++ b/test/hfp/hfp_ag_parser_test.c @@ -91,7 +91,7 @@ TEST_GROUP(HFPParser){ TEST(HFPParser, HFP_AG_SUPPORTED_FEATURES){ sprintf(packet, "\r\nAT%s=159\r\n", HFP_SUPPORTED_FEATURES); - context.wait_question_mark = 0; + context.keep_byte = 0; for (pos = 0; pos < strlen(packet); pos++){ hfp_parse(&context, packet[pos]); } diff --git a/test/hfp/hfp_hf_parser_test.c b/test/hfp/hfp_hf_parser_test.c index f98023ff9..338a19405 100644 --- a/test/hfp/hfp_hf_parser_test.c +++ b/test/hfp/hfp_hf_parser_test.c @@ -198,7 +198,7 @@ TEST(HFPParser, HFP_HF_AG_INDICATOR_STATUS_UPDATE){ uint8_t index = 4; uint8_t status = 5; - sprintf(packet, "\r\n%s=%d,%d\r\n", HFP_TRANSFER_AG_INDICATOR_STATUS, index, status); + sprintf(packet, "\r\n%s:%d,%d\r\n", HFP_TRANSFER_AG_INDICATOR_STATUS, index, status); for (pos = 0; pos < strlen(packet); pos++){ hfp_parse(&context, packet[pos]); } @@ -208,7 +208,7 @@ TEST(HFPParser, HFP_HF_AG_INDICATOR_STATUS_UPDATE){ } TEST(HFPParser, HFP_HF_AG_QUERY_OPERATOR_SELECTION){ - sprintf(packet, "\r\n%s=1,0,sunrise\r\n", HFP_QUERY_OPERATOR_SELECTION); + sprintf(packet, "\r\n%s:1,0,sunrise\r\n", HFP_QUERY_OPERATOR_SELECTION); for (pos = 0; pos < strlen(packet); pos++){ hfp_parse(&context, packet[pos]); From e11a0e7d0f0790b6cd71c4165ca21bda624d3b15 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 14 Aug 2015 17:17:04 +0200 Subject: [PATCH 11/11] hfp: rewrite parser done --- src/hfp.c | 90 ++++++++++++----------------------- src/hfp.h | 2 +- test/hfp/hfp_ag_parser_test.c | 14 +++--- 3 files changed, 39 insertions(+), 67 deletions(-) diff --git a/src/hfp.c b/src/hfp.c index 39fce1a99..cc221ce76 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -502,32 +502,30 @@ static void hfp_parser_store_byte(hfp_connection_t * context, uint8_t byte){ context->line_buffer[context->line_size++] = byte; context->line_buffer[context->line_size] = 0; } -static int hfp_parser_buffer_empty(hfp_connection_t * context){ +static int hfp_parser_is_buffer_empty(hfp_connection_t * context){ return context->line_size == 0; } -static int hfp_parser_reached_end_of_line(uint8_t byte){ +static int hfp_parser_is_end_of_line(uint8_t byte){ return byte == '\n' || byte == '\r'; } -static int hfp_parser_reached_end_of_header(uint8_t byte){ - return hfp_parser_reached_end_of_line(byte) || byte == ':' || byte == '?'; -} - -static int hfp_parser_reached_sequence_separator(uint8_t byte){ - return byte == ','; +static int hfp_parser_is_end_of_header(uint8_t byte){ + return hfp_parser_is_end_of_line(byte) || byte == ':' || byte == '?'; } static int hfp_parser_found_separator(hfp_connection_t * context, uint8_t byte){ + if (context->keep_separator == 1) return 1; + int found_separator = byte == ',' || byte == '\n' || byte == '\r' || byte == ')' || byte == '(' || byte == ':' || byte == '-' || byte == '"' || byte == '?' || byte == '='; - return found_separator || context->keep_byte == 1; + return found_separator; } static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ context->line_size = 0; - if (hfp_parser_reached_end_of_line(byte)){ + if (hfp_parser_is_end_of_line(byte)){ context->parser_item_index = 0; context->parser_state = HFP_PARSER_CMD_HEADER; return; @@ -535,9 +533,9 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ switch (context->parser_state){ case HFP_PARSER_CMD_HEADER: context->parser_state = HFP_PARSER_CMD_SEQUENCE; - if (context->keep_byte == 1){ + if (context->keep_separator == 1){ hfp_parser_store_byte(context, byte); - context->keep_byte = 0; + context->keep_separator = 0; } break; case HFP_PARSER_CMD_SEQUENCE: @@ -577,45 +575,36 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){ void hfp_parse(hfp_connection_t * context, uint8_t byte){ int value; - int reached_end = 0; - context->line_buffer[context->line_size] = 0; - - if (byte == ' ') return; + // TODO: handle space inside word + if (byte == ' ') return; + + if (!hfp_parser_found_separator(context, byte)){ + hfp_parser_store_byte(context, byte); + return; + } + if (hfp_parser_is_buffer_empty(context)) return; + switch (context->parser_state){ case HFP_PARSER_CMD_HEADER: // header - if (!hfp_parser_found_separator(context, byte)){ - hfp_parser_store_byte(context, byte); - break; - } - if (hfp_parser_buffer_empty(context)) break; - if (byte == '='){ - context->keep_byte = 1; + context->keep_separator = 1; hfp_parser_store_byte(context, byte); - break; + return; } if (byte == '?'){ - context->keep_byte = 0; + context->keep_separator = 0; hfp_parser_store_byte(context, byte); - break; + return; } - if (hfp_parser_reached_end_of_header(byte) || context->keep_byte == 1){ + if (hfp_parser_is_end_of_header(byte) || context->keep_separator == 1){ update_command(context); } - - hfp_parser_next_state(context, byte); break; case HFP_PARSER_CMD_SEQUENCE: // parse comma separated sequence, ignore breacktes - if (!hfp_parser_found_separator(context, byte)){ - hfp_parser_store_byte(context, byte); - break; - } - if (hfp_parser_buffer_empty(context)) break; - switch (context->command){ case HFP_CMD_SUPPORTED_FEATURES: context->remote_supported_features = atoi((char*)context->line_buffer); @@ -642,13 +631,11 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ } break; case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE: - if (context->parser_item_index == 3){ - printf("Parsed Enable indicators: %s\n", context->line_buffer); - value = atoi((char *)&context->line_buffer[0]); - context->enable_status_update_for_ag_indicators = (uint8_t) value; - } else { - context->parser_item_index++; - } + context->parser_item_index++; + if (context->parser_item_index != 4) break; + printf("Parsed Enable indicators: %s\n", context->line_buffer); + value = atoi((char *)&context->line_buffer[0]); + context->enable_status_update_for_ag_indicators = (uint8_t) value; break; case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES: printf("Parsed Support call hold: %s\n", context->line_buffer); @@ -712,17 +699,9 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ default: break; } - - hfp_parser_next_state(context, byte); break; case HFP_PARSER_SECOND_ITEM: - if (!hfp_parser_found_separator(context, byte)){ - hfp_parser_store_byte(context, byte); - break; - } - if (hfp_parser_buffer_empty(context)) break; - switch (context->command){ case HFP_CMD_QUERY_OPERATOR_SELECTION: if (context->operator_name_format == 1) { @@ -751,17 +730,10 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ default: break; } - hfp_parser_next_state(context, byte); break; case HFP_PARSER_THIRD_ITEM: - if (!hfp_parser_found_separator(context, byte)){ - hfp_parser_store_byte(context, byte); - break; - } - if (hfp_parser_buffer_empty(context)) break; - - switch (context->command){ + switch (context->command){ case HFP_CMD_QUERY_OPERATOR_SELECTION: if (context->operator_name == 1){ strcpy(context->network_operator.name, (char *)context->line_buffer); @@ -779,9 +751,9 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){ default: break; } - hfp_parser_next_state(context, byte); break; } + hfp_parser_next_state(context, byte); } void hfp_init(uint16_t rfcomm_channel_nr){ diff --git a/src/hfp.h b/src/hfp.h index 568ce72cb..e4358c9f1 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -255,7 +255,7 @@ typedef struct hfp_connection { // TODO: put these bit flags in a bitmap uint8_t wait_ok; - uint8_t keep_byte; + uint8_t keep_separator; uint8_t retrieve_ag_indicators; // HFP_CMD_INDICATOR, check if needed uint8_t retrieve_ag_indicators_status; diff --git a/test/hfp/hfp_ag_parser_test.c b/test/hfp/hfp_ag_parser_test.c index 26db87f90..1926e840a 100644 --- a/test/hfp/hfp_ag_parser_test.c +++ b/test/hfp/hfp_ag_parser_test.c @@ -54,12 +54,12 @@ hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * context); int get_hfp_ag_indicators_nr(hfp_connection_t * context); void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr); -static int hf_indicators_nr = 3; -static hfp_generic_status_indicator_t hf_indicators[] = { - {1, 1}, - {2, 1}, - {3, 1} -}; +// static int hf_indicators_nr = 3; +// static hfp_generic_status_indicator_t hf_indicators[] = { +// {1, 1}, +// {2, 1}, +// {3, 1} +// }; static int hfp_ag_indicators_nr = 7; static hfp_ag_indicator_t hfp_ag_indicators[] = { @@ -91,7 +91,7 @@ TEST_GROUP(HFPParser){ TEST(HFPParser, HFP_AG_SUPPORTED_FEATURES){ sprintf(packet, "\r\nAT%s=159\r\n", HFP_SUPPORTED_FEATURES); - context.keep_byte = 0; + context.keep_separator = 0; for (pos = 0; pos < strlen(packet); pos++){ hfp_parse(&context, packet[pos]); }