hfp: update hf test

This commit is contained in:
Milanka Ringwald 2015-08-19 17:00:49 +02:00
parent 964cdcb17a
commit d89553ebba
5 changed files with 92 additions and 34 deletions

View File

@ -624,6 +624,7 @@ extern "C" {
#define HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED 0x02
#define HFP_SUBEVENT_COMPLETE 0x03
#define HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED 0x04
#define HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED 0x05
// ANCS Client
#define ANCS_CLIENT_CONNECTED 0xF0

View File

@ -493,6 +493,8 @@ void hfp_handle_hci_event(hfp_callback_t callback, uint8_t packet_type, uint8_t
// translates command string into hfp_command_t CMD and flags to distinguish between CMD=, CMD?, CMD=?
void process_command(hfp_connection_t * context){
if (context->line_size < 2) return;
// printf("process_command %s\n", context->line_buffer);
context->command = HFP_CMD_NONE;
int offset = 0;
int isHandsFree = 1;
@ -508,6 +510,7 @@ void process_command(hfp_connection_t * context){
}
if (strncmp((char *)context->line_buffer+offset, HFP_OK, strlen(HFP_OK)) == 0){
//printf("parsed HFP_CMD_OK \n");
context->command = HFP_CMD_OK;
return;
}
@ -518,6 +521,7 @@ void process_command(hfp_connection_t * context){
}
if (strncmp((char *)context->line_buffer+offset, HFP_INDICATOR, strlen(HFP_INDICATOR)) == 0){
//printf("parsed HFP_INDICATOR \n");
context->command = HFP_CMD_INDICATOR;
if (isHandsFree) return;
@ -615,9 +619,9 @@ static int hfp_parser_is_end_of_header(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 == '=';
return found_separator;
}
@ -625,7 +629,7 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){
context->line_size = 0;
if (hfp_parser_is_end_of_line(byte)){
context->parser_item_index = 0;
context->parser_state = HFP_PARSER_CMD_HEADER;
context->parser_state = HFP_PARSER_CMD_HEADER;
return;
}
switch (context->parser_state){
@ -681,10 +685,17 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){
hfp_parser_store_byte(context, byte);
return;
}
if (hfp_parser_is_end_of_line(byte)) {
if (hfp_parser_is_buffer_empty(context)){
context->parser_state = HFP_PARSER_CMD_HEADER;
}
}
if (hfp_parser_is_buffer_empty(context)) return;
switch (context->parser_state){
case HFP_PARSER_CMD_HEADER: // header
// printf(" parse header 1 \n");
if (byte == '='){
context->keep_separator = 1;
hfp_parser_store_byte(context, byte);
@ -696,8 +707,9 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte){
hfp_parser_store_byte(context, byte);
return;
}
// printf(" parse header 2 %s, keep separator $ %d\n", context->line_buffer, context->keep_separator);
if (hfp_parser_is_end_of_header(byte) || context->keep_separator == 1){
// printf(" parse header 3 %s, keep separator $ %d\n", context->line_buffer, context->keep_separator);
process_command(context);
}
break;

View File

@ -201,14 +201,28 @@ int hfp_hs_query_operator_name_cmd(uint16_t cid){
}
static void hfp_emit_ag_indicator_event(hfp_callback_t callback, hfp_ag_indicator_t indicator){
static void hfp_emit_ag_indicator_event(hfp_callback_t callback, int status, hfp_ag_indicator_t indicator){
if (!callback) return;
uint8_t event[5];
uint8_t event[6];
event[0] = HCI_EVENT_HFP_META;
event[1] = sizeof(event) - 2;
event[2] = HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED;
event[3] = indicator.index;
event[4] = indicator.status;
event[3] = status;
event[4] = indicator.index;
event[5] = indicator.status;
(*callback)(event, sizeof(event));
}
static void hfp_emit_network_operator_event(hfp_callback_t callback, int status, hfp_network_opearator_t network_operator){
if (!callback) return;
uint8_t event[24];
event[0] = HCI_EVENT_HFP_META;
event[1] = sizeof(event) - 2;
event[2] = HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED;
event[3] = status;
event[4] = network_operator.mode;
event[5] = network_operator.format;
strcpy((char*)&event[6], network_operator.name);
(*callback)(event, sizeof(event));
}
@ -276,7 +290,7 @@ static void hfp_run_for_context(hfp_connection_t * context){
int i;
for (i = 0; i < context->ag_indicators_nr; i++){
if (context->ag_indicators[i].status_changed == 1) {
hfp_emit_ag_indicator_event(hfp_callback, context->ag_indicators[i]);
hfp_emit_ag_indicator_event(hfp_callback, 0, context->ag_indicators[i]);
context->ag_indicators[i].status_changed = 0;
break;
}
@ -287,7 +301,6 @@ static void hfp_run_for_context(hfp_connection_t * context){
if (context->enable_status_update_for_ag_indicators != 0xFF){
hfp_hs_activate_status_update_for_all_ag_indicators_cmd(context->rfcomm_cid, context->enable_status_update_for_ag_indicators);
context->wait_ok = 1;
context->enable_status_update_for_ag_indicators = 0xFF;
break;
};
if (context->change_status_update_for_individual_ag_indicators == 1){
@ -295,21 +308,17 @@ static void hfp_run_for_context(hfp_connection_t * context){
context->ag_indicators_status_update_bitmap,
context->ag_indicators_nr);
context->wait_ok = 1;
context->change_status_update_for_individual_ag_indicators = 0;
break;
}
if (context->operator_name_format == 1){
hfp_hs_query_operator_name_format_cmd(context->rfcomm_cid);
context->operator_name_format = 0;
context->operator_name = 1;
context->wait_ok = 1;
break;
}
if (context->operator_name == 1){
hfp_hs_query_operator_name_cmd(context->rfcomm_cid);
context->wait_ok = 1;
context->operator_name = 0;
}
break;
}
@ -383,8 +392,29 @@ void handle_switch_on_ok(hfp_connection_t *context){
case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
context->wait_ok = 0;
hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
if (context->enable_status_update_for_ag_indicators != 0xFF){
context->enable_status_update_for_ag_indicators = 0xFF;
hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
break;
};
if (context->change_status_update_for_individual_ag_indicators == 1){
context->change_status_update_for_individual_ag_indicators = 0;
hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
break;
}
if (context->operator_name_format == 1){
context->operator_name_format = 0;
context->operator_name = 1;
break;
}
if (context->operator_name == 1){
context->operator_name = 0;
hfp_emit_network_operator_event(hfp_callback, 0, context->network_operator);
break;
}
break;
default:
break;
@ -404,7 +434,6 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8
for (pos = 0; pos < size ; pos++){
hfp_parse(context, packet[pos]);
// trigger next action after CMD received
if (context->command == HFP_CMD_ERROR){
if (context->state == HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED){
context->wait_ok = 0;

View File

@ -76,6 +76,7 @@ TEST_GROUP(HFPParser){
}
};
TEST(HFPParser, HFP_HF_OK){
sprintf(packet, "\r\n%s\r\n", HFP_OK);
for (pos = 0; pos < strlen(packet); pos++){
@ -85,21 +86,22 @@ TEST(HFPParser, HFP_HF_OK){
}
TEST(HFPParser, HFP_HF_SUPPORTED_FEATURES){
sprintf(packet, "\r\n%s:1007\r\n", HFP_SUPPORTED_FEATURES);
sprintf(packet, "\r\n%s:1007\r\n\r\nOK\r\n", HFP_SUPPORTED_FEATURES);
for (pos = 0; pos < strlen(packet); pos++){
hfp_parse(&context, packet[pos]);
}
CHECK_EQUAL(HFP_CMD_SUPPORTED_FEATURES, context.command);
CHECK_EQUAL(HFP_CMD_OK, context.command);
CHECK_EQUAL(1007, context.remote_supported_features);
}
TEST(HFPParser, HFP_HF_INDICATORS){
offset = 0;
offset += snprintf(packet, sizeof(packet), "%s:", HFP_INDICATOR);
for (pos = 0; pos < hfp_ag_indicators_nr - 1; pos++){
offset += snprintf(packet+offset, sizeof(packet)-offset, "\"%s\", (%d, %d),", hfp_ag_indicators[pos].name, hfp_ag_indicators[pos].min_range, hfp_ag_indicators[pos].max_range);
}
offset += snprintf(packet+offset, sizeof(packet)-offset, "\"%s\", (%d, %d)\r\n", hfp_ag_indicators[pos].name, hfp_ag_indicators[pos].min_range, hfp_ag_indicators[pos].max_range);
offset += snprintf(packet+offset, sizeof(packet)-offset, "\"%s\", (%d, %d)\r\n\r\nOK\r\n", hfp_ag_indicators[pos].name, hfp_ag_indicators[pos].min_range, hfp_ag_indicators[pos].max_range);
context.command = HFP_CMD_INDICATOR;
context.retrieve_ag_indicators = 1;
@ -108,7 +110,7 @@ TEST(HFPParser, HFP_HF_INDICATORS){
for (pos = 0; pos < strlen(packet); pos++){
hfp_parse(&context, packet[pos]);
}
CHECK_EQUAL(HFP_CMD_INDICATOR, context.command);
CHECK_EQUAL(HFP_CMD_OK, context.command);
CHECK_EQUAL(hfp_ag_indicators_nr, context.ag_indicators_nr);
for (pos = 0; pos < hfp_ag_indicators_nr; pos++){
CHECK_EQUAL(hfp_ag_indicators[pos].index, context.ag_indicators[pos].index);
@ -125,7 +127,7 @@ TEST(HFPParser, HFP_HF_INDICATOR_STATUS){
for (pos = 0; pos < hfp_ag_indicators_nr - 1; pos++){
offset += snprintf(packet+offset, sizeof(packet)-offset, "%d,", hfp_ag_indicators[pos].status);
}
offset += snprintf(packet+offset, sizeof(packet)-offset, "%d\r\n", hfp_ag_indicators[pos].status);
offset += snprintf(packet+offset, sizeof(packet)-offset, "%d\r\n\r\nOK\r\n", hfp_ag_indicators[pos].status);
context.command = HFP_CMD_INDICATOR;
context.retrieve_ag_indicators_status = 1;
@ -135,18 +137,19 @@ TEST(HFPParser, HFP_HF_INDICATOR_STATUS){
hfp_parse(&context, packet[pos]);
}
CHECK_EQUAL(HFP_CMD_INDICATOR, context.command);
CHECK_EQUAL(HFP_CMD_OK, context.command);
for (pos = 0; pos < hfp_ag_indicators_nr; pos++){
CHECK_EQUAL(hfp_ag_indicators[pos].status, context.ag_indicators[pos].status);
}
}
TEST(HFPParser, HFP_HF_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES){
sprintf(packet, "\r\n%s:(1,1x,2,2x,3)\r\n", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES);
sprintf(packet, "\r\n%s:(1,1x,2,2x,3)\r\n\r\nOK\r\n", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES);
for (pos = 0; pos < strlen(packet); pos++){
hfp_parse(&context, packet[pos]);
}
CHECK_EQUAL(HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, context.command);
CHECK_EQUAL(HFP_CMD_OK, context.command);
CHECK_EQUAL(5, context.remote_call_services_nr);
CHECK_EQUAL(0, strcmp("1", (char*)context.remote_call_services[0].name));
@ -157,7 +160,7 @@ TEST(HFPParser, HFP_HF_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES){
}
TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR){
sprintf(packet, "\r\n%s:0,1,2,3,4\r\n", HFP_GENERIC_STATUS_INDICATOR);
sprintf(packet, "\r\n%s:0,1,2,3,4\r\n\r\nOK\r\n", HFP_GENERIC_STATUS_INDICATOR);
context.command = HFP_CMD_GENERIC_STATUS_INDICATOR;
context.list_generic_status_indicators = 0;
@ -168,7 +171,7 @@ TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR){
hfp_parse(&context, packet[pos]);
}
CHECK_EQUAL(HFP_CMD_GENERIC_STATUS_INDICATOR, context.command);
CHECK_EQUAL(HFP_CMD_OK, context.command);
CHECK_EQUAL(5, context.generic_status_indicators_nr);
for (pos = 0; pos < context.generic_status_indicators_nr; pos++){
@ -177,7 +180,7 @@ TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR){
}
TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR_STATE){
sprintf(packet, "\r\n%s:0,1\r\n", HFP_GENERIC_STATUS_INDICATOR);
sprintf(packet, "\r\n%s:0,1\r\n\r\nOK\r\n", HFP_GENERIC_STATUS_INDICATOR);
context.command = HFP_CMD_GENERIC_STATUS_INDICATOR;
context.list_generic_status_indicators = 0;
context.retrieve_generic_status_indicators = 0;
@ -187,7 +190,7 @@ TEST(HFPParser, HFP_HF_GENERIC_STATUS_INDICATOR_STATE){
hfp_parse(&context, packet[pos]);
}
CHECK_EQUAL(HFP_CMD_GENERIC_STATUS_INDICATOR, context.command);
CHECK_EQUAL(HFP_CMD_OK, context.command);
CHECK_EQUAL(1, context.generic_status_indicators[0].state);
}
@ -198,23 +201,23 @@ 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\r\nOK\r\n", HFP_TRANSFER_AG_INDICATOR_STATUS, index, status);
for (pos = 0; pos < strlen(packet); pos++){
hfp_parse(&context, packet[pos]);
}
CHECK_EQUAL(HFP_CMD_TRANSFER_AG_INDICATOR_STATUS, context.command);
CHECK_EQUAL(HFP_CMD_OK, context.command);
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);
sprintf(packet, "\r\n%s:1,0,sunrise\r\n\r\nOK\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.command, HFP_CMD_OK);
CHECK_EQUAL(context.operator_name_format, 0);
CHECK_EQUAL(context.operator_name, 1);
CHECK_EQUAL(context.operator_name_changed, 0);

View File

@ -93,6 +93,9 @@ static void show_usage(void){
printf("e - establish HFP connection to local mac\n");
printf("r - enable registration status update\n");
printf("d - release HFP connection\n");
printf("i - enabling HFP AG registration status update for individual indicators\n");
printf("o - query network operator\n");
printf("---\n");
printf("Ctrl-c - exit\n");
printf("---\n");
@ -123,6 +126,11 @@ static int stdin_process(struct data_source *ds){
printf("Enabling HFP AG registration status update for individual indicators.\n");
hfp_hf_enable_status_update_for_individual_ag_indicators(device_addr, 63);
break;
case 'o':
printf("Query network operator.\n");
hfp_hf_query_operator_selection(device_addr);
break;
default:
show_usage();
break;
@ -150,12 +158,17 @@ void packet_handler(uint8_t * event, uint16_t event_size){
case 'r':
printf("HFP AG registration status update enabled.\n");
break;
case 'i':
printf("HFP AG registration status update for individual indicators set.\n");
default:
break;
}
break;
case HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED:
printf("AG_INDICATOR_STATUS_CHANGED, AG indicator index: %d, status %d\n", event[3], event[4]);
printf("AG_INDICATOR_STATUS_CHANGED, AG indicator index: %d, status: %d\n", event[4], event[5]);
break;
case HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED:
printf("HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED, operator mode: %d, format: %d, name: %s\n", event[4], event[5], (char *) &event[6]);
break;
default:
printf("event not handled %u\n", event[2]);