mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-26 11:37:10 +00:00
hfp: start rewrite parser
This commit is contained in:
parent
783d2ff3ec
commit
b5b7d6dda3
146
src/hfp.c
146
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:
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
14
src/hfp_ag.c
14
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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user