hfp: start rewrite parser

This commit is contained in:
Milanka Ringwald 2015-08-14 14:19:31 +02:00
parent 783d2ff3ec
commit b5b7d6dda3
6 changed files with 164 additions and 63 deletions

146
src/hfp.c
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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