mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-02 16:20:31 +00:00
hfp: rewrite parser done
This commit is contained in:
parent
67c47d0d10
commit
e11a0e7d0f
90
src/hfp.c
90
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++] = byte;
|
||||||
context->line_buffer[context->line_size] = 0;
|
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;
|
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';
|
return byte == '\n' || byte == '\r';
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hfp_parser_reached_end_of_header(uint8_t byte){
|
static int hfp_parser_is_end_of_header(uint8_t byte){
|
||||||
return hfp_parser_reached_end_of_line(byte) || byte == ':' || byte == '?';
|
return hfp_parser_is_end_of_line(byte) || byte == ':' || byte == '?';
|
||||||
}
|
|
||||||
|
|
||||||
static int hfp_parser_reached_sequence_separator(uint8_t byte){
|
|
||||||
return byte == ',';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hfp_parser_found_separator(hfp_connection_t * context, uint8_t 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' ||
|
int found_separator = byte == ',' || byte == '\n' || byte == '\r' ||
|
||||||
byte == ')' || byte == '(' || byte == ':' ||
|
byte == ')' || byte == '(' || byte == ':' ||
|
||||||
byte == '-' || 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){
|
static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){
|
||||||
context->line_size = 0;
|
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_item_index = 0;
|
||||||
context->parser_state = HFP_PARSER_CMD_HEADER;
|
context->parser_state = HFP_PARSER_CMD_HEADER;
|
||||||
return;
|
return;
|
||||||
@ -535,9 +533,9 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){
|
|||||||
switch (context->parser_state){
|
switch (context->parser_state){
|
||||||
case HFP_PARSER_CMD_HEADER:
|
case HFP_PARSER_CMD_HEADER:
|
||||||
context->parser_state = HFP_PARSER_CMD_SEQUENCE;
|
context->parser_state = HFP_PARSER_CMD_SEQUENCE;
|
||||||
if (context->keep_byte == 1){
|
if (context->keep_separator == 1){
|
||||||
hfp_parser_store_byte(context, byte);
|
hfp_parser_store_byte(context, byte);
|
||||||
context->keep_byte = 0;
|
context->keep_separator = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HFP_PARSER_CMD_SEQUENCE:
|
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){
|
void hfp_parse(hfp_connection_t * context, uint8_t byte){
|
||||||
int value;
|
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){
|
switch (context->parser_state){
|
||||||
case HFP_PARSER_CMD_HEADER: // header
|
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 == '='){
|
if (byte == '='){
|
||||||
context->keep_byte = 1;
|
context->keep_separator = 1;
|
||||||
hfp_parser_store_byte(context, byte);
|
hfp_parser_store_byte(context, byte);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (byte == '?'){
|
if (byte == '?'){
|
||||||
context->keep_byte = 0;
|
context->keep_separator = 0;
|
||||||
hfp_parser_store_byte(context, byte);
|
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);
|
update_command(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
hfp_parser_next_state(context, byte);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HFP_PARSER_CMD_SEQUENCE: // parse comma separated sequence, ignore breacktes
|
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){
|
switch (context->command){
|
||||||
case HFP_CMD_SUPPORTED_FEATURES:
|
case HFP_CMD_SUPPORTED_FEATURES:
|
||||||
context->remote_supported_features = atoi((char*)context->line_buffer);
|
context->remote_supported_features = atoi((char*)context->line_buffer);
|
||||||
@ -642,13 +631,11 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE:
|
case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE:
|
||||||
if (context->parser_item_index == 3){
|
context->parser_item_index++;
|
||||||
printf("Parsed Enable indicators: %s\n", context->line_buffer);
|
if (context->parser_item_index != 4) break;
|
||||||
value = atoi((char *)&context->line_buffer[0]);
|
printf("Parsed Enable indicators: %s\n", context->line_buffer);
|
||||||
context->enable_status_update_for_ag_indicators = (uint8_t) value;
|
value = atoi((char *)&context->line_buffer[0]);
|
||||||
} else {
|
context->enable_status_update_for_ag_indicators = (uint8_t) value;
|
||||||
context->parser_item_index++;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES:
|
case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES:
|
||||||
printf("Parsed Support call hold: %s\n", context->line_buffer);
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hfp_parser_next_state(context, byte);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HFP_PARSER_SECOND_ITEM:
|
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){
|
switch (context->command){
|
||||||
case HFP_CMD_QUERY_OPERATOR_SELECTION:
|
case HFP_CMD_QUERY_OPERATOR_SELECTION:
|
||||||
if (context->operator_name_format == 1) {
|
if (context->operator_name_format == 1) {
|
||||||
@ -751,17 +730,10 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
hfp_parser_next_state(context, byte);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HFP_PARSER_THIRD_ITEM:
|
case HFP_PARSER_THIRD_ITEM:
|
||||||
if (!hfp_parser_found_separator(context, byte)){
|
switch (context->command){
|
||||||
hfp_parser_store_byte(context, byte);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (hfp_parser_buffer_empty(context)) break;
|
|
||||||
|
|
||||||
switch (context->command){
|
|
||||||
case HFP_CMD_QUERY_OPERATOR_SELECTION:
|
case HFP_CMD_QUERY_OPERATOR_SELECTION:
|
||||||
if (context->operator_name == 1){
|
if (context->operator_name == 1){
|
||||||
strcpy(context->network_operator.name, (char *)context->line_buffer);
|
strcpy(context->network_operator.name, (char *)context->line_buffer);
|
||||||
@ -779,9 +751,9 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
hfp_parser_next_state(context, byte);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
hfp_parser_next_state(context, byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hfp_init(uint16_t rfcomm_channel_nr){
|
void hfp_init(uint16_t rfcomm_channel_nr){
|
||||||
|
@ -255,7 +255,7 @@ typedef struct hfp_connection {
|
|||||||
// TODO: put these bit flags in a bitmap
|
// TODO: put these bit flags in a bitmap
|
||||||
uint8_t wait_ok;
|
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; // HFP_CMD_INDICATOR, check if needed
|
||||||
uint8_t retrieve_ag_indicators_status;
|
uint8_t retrieve_ag_indicators_status;
|
||||||
|
@ -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);
|
int get_hfp_ag_indicators_nr(hfp_connection_t * context);
|
||||||
void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr);
|
void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr);
|
||||||
|
|
||||||
static int hf_indicators_nr = 3;
|
// static int hf_indicators_nr = 3;
|
||||||
static hfp_generic_status_indicator_t hf_indicators[] = {
|
// static hfp_generic_status_indicator_t hf_indicators[] = {
|
||||||
{1, 1},
|
// {1, 1},
|
||||||
{2, 1},
|
// {2, 1},
|
||||||
{3, 1}
|
// {3, 1}
|
||||||
};
|
// };
|
||||||
|
|
||||||
static int hfp_ag_indicators_nr = 7;
|
static int hfp_ag_indicators_nr = 7;
|
||||||
static hfp_ag_indicator_t hfp_ag_indicators[] = {
|
static hfp_ag_indicator_t hfp_ag_indicators[] = {
|
||||||
@ -91,7 +91,7 @@ TEST_GROUP(HFPParser){
|
|||||||
|
|
||||||
TEST(HFPParser, HFP_AG_SUPPORTED_FEATURES){
|
TEST(HFPParser, HFP_AG_SUPPORTED_FEATURES){
|
||||||
sprintf(packet, "\r\nAT%s=159\r\n", HFP_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++){
|
for (pos = 0; pos < strlen(packet); pos++){
|
||||||
hfp_parse(&context, packet[pos]);
|
hfp_parse(&context, packet[pos]);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user