diff --git a/src/hfp.c b/src/hfp.c index 34164129a..aed0568af 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -771,7 +771,7 @@ static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){ if (strncmp(line_buffer+strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)+offset, "=?", 2) == 0){ return HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES; } - if (strncmp(line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=", 1) == 0){ + if (strncmp(line_buffer+strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)+offset, "=", 1) == 0){ return HFP_CMD_CALL_HOLD; } @@ -779,8 +779,9 @@ static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){ } if (strncmp(line_buffer+offset, HFP_GENERIC_STATUS_INDICATOR, strlen(HFP_GENERIC_STATUS_INDICATOR)) == 0){ - if (isHandsFree) return HFP_CMD_UNKNOWN; - + if (isHandsFree) { + return HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS; + } if (strncmp(line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=?", 2) == 0){ return HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS; } @@ -827,12 +828,12 @@ static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){ } if (strncmp(line_buffer+offset, "AT+", 3) == 0){ - printf(" process unknown HF command %s \n", line_buffer); + log_info("process unknown HF command %s \n", line_buffer); return HFP_CMD_UNKNOWN; } if (strncmp(line_buffer+offset, "+", 1) == 0){ - printf(" process unknown AG command %s \n", line_buffer); + log_info(" process unknown AG command %s \n", line_buffer); return HFP_CMD_UNKNOWN; } @@ -1066,8 +1067,31 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree){ static void parse_sequence(hfp_connection_t * context){ int value; switch (context->command){ + case HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS: + value = atoi((char *)&context->line_buffer[0]); + int i; + switch (context->parser_item_index){ + case 0: + for (i=0;igeneric_status_indicators_nr;i++){ + if (context->generic_status_indicators[i].uuid == value){ + context->parser_indicator_index = i; + break; + } + } + break; + case 1: + if (context->parser_indicator_index <0) break; + context->generic_status_indicators[context->parser_indicator_index].state = value; + log_info("HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS set indicator at index %u, to %u\n", + context->parser_item_index, value); + break; + default: + break; + } + context->parser_item_index++; + break; + case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION: - // printf("HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION (%u), '%s'\n", context->parser_item_index, (char*)context->line_buffer); switch(context->parser_item_index){ case 0: strncpy(context->bnip_number, (char *)context->line_buffer, sizeof(context->bnip_number)); diff --git a/src/hfp.h b/src/hfp.h index 946e63252..fdace67ec 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -164,6 +164,7 @@ typedef enum { HFP_CMD_LIST_GENERIC_STATUS_INDICATORS, HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS, HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE, + HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS, HFP_CMD_TRANSFER_AG_INDICATOR_STATUS, @@ -482,17 +483,20 @@ typedef struct hfp_connection { // TODO: rename into hf_codecs_nr int remote_codecs_nr; uint16_t remote_codecs[HFP_MAX_INDICATOR_DESC_SIZE]; + int ag_indicators_nr; hfp_ag_indicator_t ag_indicators[HFP_MAX_INDICATOR_DESC_SIZE]; + uint32_t ag_indicators_status_update_bitmap; + uint8_t enable_status_update_for_ag_indicators; + int remote_call_services_nr; hfp_call_service_t remote_call_services[HFP_MAX_INDICATOR_DESC_SIZE]; // TODO: use bitmap. int generic_status_indicators_nr; + uint32_t generic_status_update_bitmap; hfp_generic_status_indicator_t generic_status_indicators[HFP_MAX_INDICATOR_DESC_SIZE]; - uint8_t enable_status_update_for_ag_indicators; - uint32_t ag_indicators_status_update_bitmap; hfp_network_opearator_t network_operator; // Retrieved during service level connection establishment, not used yet @@ -572,7 +576,7 @@ typedef struct hfp_connection { uint8_t hf_send_rrh; char hf_send_rrh_command; uint8_t hf_send_cnum; - + uint8_t hf_activate_call_waiting_notification; uint8_t hf_deactivate_call_waiting_notification; diff --git a/src/hfp_hf.c b/src/hfp_hf.c index 2b7c7da7e..352ab1efe 100644 --- a/src/hfp_hf.c +++ b/src/hfp_hf.c @@ -69,7 +69,8 @@ static uint8_t hfp_codecs[HFP_MAX_NUM_CODECS]; static uint8_t hfp_indicators_nr = 0; static uint8_t hfp_indicators[HFP_MAX_NUM_HF_INDICATORS]; -static uint8_t hfp_indicators_status; +static uint32_t hfp_indicators_value[HFP_MAX_NUM_HF_INDICATORS]; +static uint16_t hfp_indicators_status; static uint8_t hfp_hf_speaker_gain = 9; static uint8_t hfp_hf_microphone_gain = 9; @@ -742,6 +743,25 @@ static void hfp_run_for_context(hfp_connection_t * context){ return; } + // update HF indicators + if (context->generic_status_update_bitmap){ + int i; + for (i=0;igeneric_status_update_bitmap, i)){ + if (context->generic_status_indicators[i].state){ + context->ok_pending = 1; + context->generic_status_update_bitmap = store_bit(context->generic_status_update_bitmap, i, 0); + char buffer[30]; + sprintf(buffer, "AT%s=%u,%u\r\n", HFP_TRANSFER_HF_INDICATOR_STATUS, hfp_indicators[i], hfp_indicators_value[i]); + send_str_over_rfcomm(context->rfcomm_cid, buffer); + } else { + printf("Not sending HF indicator %u as it is disabled\n", hfp_indicators[i]); + } + return; + } + } + } + if (done) return; // deal with disconnect switch (context->state){ @@ -778,6 +798,12 @@ static void hfp_ag_slc_established(hfp_connection_t * context){ context->microphone_gain = hfp_hf_microphone_gain; context->send_microphone_gain = 1; hfp_emit_event(hfp_callback, HFP_SUBEVENT_MICROPHONE_VOLUME, hfp_hf_microphone_gain); + // enable all indicators + int i; + for (i=0;igeneric_status_indicators[i].uuid = hfp_indicators[i]; + context->generic_status_indicators[i].state = 1; + } } static void hfp_hf_switch_on_ok(hfp_connection_t *context){ @@ -1483,3 +1509,24 @@ void hfp_hf_query_subscriber_number(bd_addr_t addr) hfp_run_for_context(connection); } +/* + * @brief + */ +void hfp_hf_set_hf_indicator(bd_addr_t addr, int assigned_number, int value){ + hfp_hf_establish_service_level_connection(addr); + hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(addr); + // find index for assigned number + int i; + for (i = 0; i < hfp_indicators_nr ; i++){ + if (hfp_indicators[i] == assigned_number){ + // set value + hfp_indicators_value[i] = value; + // mark for update + connection->generic_status_update_bitmap |= (1<