mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-25 16:43:28 +00:00
hfp: update hf test
This commit is contained in:
parent
964cdcb17a
commit
d89553ebba
@ -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
|
||||
|
20
src/hfp.c
20
src/hfp.c
@ -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;
|
||||
|
55
src/hfp_hf.c
55
src/hfp_hf.c
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user