hfp: support HF indicator updates by AT+BIEV

This commit is contained in:
Matthias Ringwald 2015-11-26 16:02:36 +01:00
parent 2ba203686e
commit 11a5c01e22
3 changed files with 68 additions and 8 deletions

View File

@ -693,9 +693,22 @@ static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){
return HFP_CMD_SUPPORTED_FEATURES;
}
if (strncmp(line_buffer+offset, HFP_TRANSFER_HF_INDICATOR_STATUS, strlen(HFP_TRANSFER_HF_INDICATOR_STATUS)) == 0){
return HFP_CMD_HF_INDICATOR_STATUS;
}
if (strncmp(line_buffer+offset, HFP_RESPONSE_AND_HOLD, strlen(HFP_RESPONSE_AND_HOLD)) == 0){
if (strncmp(line_buffer+strlen(HFP_RESPONSE_AND_HOLD)+offset, "?", 1) == 0){
return HFP_CMD_RESPONSE_AND_HOLD_QUERY;
}
if (strncmp(line_buffer+strlen(HFP_RESPONSE_AND_HOLD)+offset, "=", 1) == 0){
return HFP_CMD_RESPONSE_AND_HOLD_COMMAND;
}
}
if (strncmp(line_buffer+offset, HFP_INDICATOR, strlen(HFP_INDICATOR)) == 0){
if (strncmp(line_buffer+strlen(HFP_INDICATOR)+offset, "?", 1) == 0){
printf("HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS\n");
return HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS;
}
@ -851,12 +864,9 @@ static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){
case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
context->parser_state = HFP_PARSER_SECOND_ITEM;
break;
case HFP_CMD_RETRIEVE_AG_INDICATORS:
context->parser_state = HFP_PARSER_SECOND_ITEM;
break;
case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
case HFP_CMD_HF_INDICATOR_STATUS:
context->parser_state = HFP_PARSER_SECOND_ITEM;
break;
default:
@ -1033,6 +1043,10 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree){
log_info("Parsed List generic status indicator %s state: ", context->line_buffer);
context->parser_item_index = (uint8_t)atoi((char*)context->line_buffer);
break;
case HFP_CMD_HF_INDICATOR_STATUS:
context->parser_indicator_index = (uint8_t)atoi((char*)context->line_buffer);
log_info("Parsed HF indicator index %u", context->parser_indicator_index);
break;
case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE:
// AG parses new gen. ind. state
if (context->line_size<1){

View File

@ -114,6 +114,7 @@ extern "C" {
#define HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES "+CHLD"
#define HFP_GENERIC_STATUS_INDICATOR "+BIND"
#define HFP_TRANSFER_AG_INDICATOR_STATUS "+CIEV" // +CIEV: <index>,<value>
#define HFP_TRANSFER_HF_INDICATOR_STATUS "+BIEV" // +BIEC: <index>,<value>
#define HFP_QUERY_OPERATOR_SELECTION "+COPS" // +COPS: <mode>,0,<opearator>
#define HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR "+CMEE"
#define HFP_EXTENDED_AUDIO_GATEWAY_ERROR "+CME ERROR"
@ -132,7 +133,7 @@ extern "C" {
#define HFP_TRANSMIT_DTMF_CODES "+VTS"
#define HFP_SUBSCRIBER_NUMBER_INFORMATION "+CNUM"
#define HFP_LIST_CURRENT_CALLS "+CLCC"
#define HFP_RESPONSE_AND_HOLD "+BTRH"
#define HFP_OK "OK"
#define HFP_ERROR "ERROR"
@ -189,8 +190,10 @@ typedef enum {
HFP_CMD_SET_MICROPHONE_GAIN,
HFP_CMD_SET_SPEAKER_GAIN,
HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION,
HFP_CMD_LIST_CURRENT_CALLS
HFP_CMD_LIST_CURRENT_CALLS,
HFP_CMD_RESPONSE_AND_HOLD_QUERY,
HFP_CMD_RESPONSE_AND_HOLD_COMMAND,
HFP_CMD_HF_INDICATOR_STATUS
} hfp_command_t;
@ -435,6 +438,7 @@ typedef struct hfp_connection {
hfp_command_t command;
hfp_parser_state_t parser_state;
int parser_item_index;
int parser_indicator_index;
uint8_t line_buffer[HFP_MAX_INDICATOR_DESC_SIZE];
int line_size;

View File

@ -1381,6 +1381,16 @@ static void hfp_run_for_context(hfp_connection_t *context){
context->command = HFP_CMD_NONE;
}
}
static hfp_generic_status_indicator_t *get_hf_indicator_by_number(int number){
int i;
for (i=0;i< get_hfp_generic_status_indicators_nr();i++){
hfp_generic_status_indicator_t * indicator = &get_hfp_generic_status_indicators()[i];
if (indicator->uuid == number){
return indicator;
}
}
return NULL;
}
static void hfp_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
hfp_connection_t * context = get_hfp_connection_context_for_rfcomm_cid(channel);
@ -1389,7 +1399,39 @@ static void hfp_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_
for (pos = 0; pos < size ; pos++){
hfp_parse(context, packet[pos], 0);
}
hfp_generic_status_indicator_t * indicator;
int value;
switch(context->command){
case HFP_CMD_HF_INDICATOR_STATUS:
context->command = HFP_CMD_NONE;
// find indicator by assigned number
indicator = get_hf_indicator_by_number(context->parser_indicator_index);
if (!indicator){
context->send_error = 1;
break;
}
value = atoi((char *)&context->line_buffer[0]);
switch (indicator->uuid){
case 1: // enhanced security
if (value > 1) {
context->send_error = 1;
return;
}
printf("HF Indicator 'enhanced security' set to %u\n", value);
break;
case 2: // battery level
if (value > 100){
context->send_error = 1;
return;
}
printf("HF Indicator 'battery' set to %u\n", value);
break;
default:
printf("HF Indicator unknown set to %u\n", value);
break;
}
context->ok_pending = 1;
break;
case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS:
// expected by SLC state machine
if (context->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) break;