From 24cb5699a0003498baa2a4da5d18922b3793c8fa Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Mon, 23 Nov 2015 16:22:27 +0100 Subject: [PATCH] hfp: add voice recognition activation to ag --- src/hfp.c | 10 ++++++++++ src/hfp.h | 12 +++++++++--- src/hfp_ag.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- src/hfp_ag.h | 6 ++++++ 4 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/hfp.c b/src/hfp.c index 12345f096..1feb55f96 100644 --- a/src/hfp.c +++ b/src/hfp.c @@ -621,6 +621,11 @@ void hfp_handle_hci_event(hfp_callback_t callback, uint8_t packet_type, uint8_t static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){ int offset = isHandsFree ? 0 : 2; + if (strncmp(line_buffer, HFP_ACTIVATE_VOICE_RECOGNITION, strlen(HFP_ACTIVATE_VOICE_RECOGNITION))){ + if (isHandsFree) return HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION; + return HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION; + } + if (strncmp(line_buffer, HFP_TURN_OFF_EC_AND_NR, strlen(HFP_TURN_OFF_EC_AND_NR))){ return HFP_CMD_TURN_OFF_EC_AND_NR; } @@ -916,6 +921,11 @@ void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree){ case HFP_PARSER_CMD_SEQUENCE: // parse comma separated sequence, ignore breacktes switch (context->command){ + case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION: + value = atoi((char *)&context->line_buffer[0]); + context->ag_activate_voice_recognition = value; + log_info("hfp parse HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION %d\n", value); + break; case HFP_CMD_TURN_OFF_EC_AND_NR: value = atoi((char *)&context->line_buffer[0]); context->ag_echo_and_noise_reduction = value; diff --git a/src/hfp.h b/src/hfp.h index f606312be..e881debca 100644 --- a/src/hfp.h +++ b/src/hfp.h @@ -89,6 +89,7 @@ extern "C" { */ #define HFP_AGSF_THREE_WAY_CALLING 0 #define HFP_AGSF_EC_NR_FUNCTION 1 +#define HFP_AGSF_VOICE_RECOGNITION_FUNCTION 2 #define HFP_AGSF_IN_BAND_RING_TONE 3 #define HFP_AGSF_CODEC_NEGOTIATION 9 #define HFP_AGSF_HF_INDICATORS 10 @@ -122,7 +123,9 @@ extern "C" { #define HFP_CHANGE_IN_BAND_RING_TONE_SETTING "+BSIR" #define HFP_CALL_PHONE_NUMBER "ATD" #define HFP_REDIAL_LAST_NUMBER "AT+BLDN" -#define HFP_TURN_OFF_EC_AND_NR "AT+NREC" // EC (Echo CAnceling), NR (Noise Reduction) +#define HFP_TURN_OFF_EC_AND_NR "+NREC" // EC (Echo CAnceling), NR (Noise Reduction) +#define HFP_ACTIVATE_VOICE_RECOGNITION "+BVRA" // EC (Echo CAnceling), NR (Noise Reduction) + #define HFP_OK "OK" #define HFP_ERROR "ERROR" @@ -170,7 +173,9 @@ typedef enum { HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING, HFP_CMD_CALL_PHONE_NUMBER, HFP_CMD_REDIAL_LAST_NUMBER, - HFP_CMD_TURN_OFF_EC_AND_NR + HFP_CMD_TURN_OFF_EC_AND_NR, + HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION, + HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION, } hfp_command_t; typedef enum { @@ -438,7 +443,8 @@ typedef struct hfp_connection { uint8_t ag_ring; uint8_t ag_send_clip; uint8_t ag_echo_and_noise_reduction; - + uint8_t ag_activate_voice_recognition; + timer_source_t hfp_timeout; } hfp_connection_t; diff --git a/src/hfp_ag.c b/src/hfp_ag.c index 2c58e34b0..e196f67d0 100644 --- a/src/hfp_ag.c +++ b/src/hfp_ag.c @@ -86,6 +86,7 @@ static char clip_number[25]; // static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); static void hfp_run_for_context(hfp_connection_t *context); +static void hfp_ag_setup_audio_connection(hfp_connection_t * connection); hfp_generic_status_indicator_t * get_hfp_generic_status_indicators(); int get_hfp_generic_status_indicators_nr(); @@ -94,7 +95,6 @@ void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr); int get_hfp_ag_indicators_nr(hfp_connection_t * context); hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * context); - hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * context){ // TODO: save only value, and value changed in the context? if (context->ag_indicators_nr != hfp_ag_indicators_nr){ @@ -397,6 +397,12 @@ static int hfp_ag_cmd_suggest_codec(uint16_t cid, uint8_t codec){ return send_str_over_rfcomm(cid, buffer); } +static int hfp_ag_activate_voice_recognition_cmd(uint16_t cid, uint8_t activate_voice_recognition){ + char buffer[30]; + sprintf(buffer, "\r\n%s:%d\r\n", HFP_ACTIVATE_VOICE_RECOGNITION, activate_voice_recognition); + return send_str_over_rfcomm(cid, buffer); +} + static uint8_t hfp_ag_suggest_codec(hfp_connection_t *context){ int i,j; uint8_t codec = HFP_CODEC_CVSD; @@ -587,6 +593,19 @@ static int hfp_ag_run_for_context_service_level_connection_queries(hfp_connectio // printf(" -> State machine: SLC Queries\n"); switch(context->command){ + case HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION: + hfp_supported_features = store_bit(hfp_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION, context->ag_activate_voice_recognition); + hfp_ag_activate_voice_recognition_cmd(context->rfcomm_cid, context->ag_activate_voice_recognition); + return 1; + case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION: + if (get_bit(hfp_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION)){ + hfp_supported_features = store_bit(hfp_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION, context->ag_activate_voice_recognition); + hfp_ag_ok(context->rfcomm_cid); + hfp_ag_setup_audio_connection(context); + } else { + hfp_ag_error(context->rfcomm_cid); + } + return 1; case HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING: hfp_ag_change_in_band_ring_tone_setting_cmd(context->rfcomm_cid); return 1; @@ -1478,12 +1497,7 @@ void hfp_ag_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, h hfp_run_for_context(connection); } - -void hfp_ag_establish_audio_connection(bd_addr_t bd_addr){ - hfp_ag_establish_service_level_connection(bd_addr); - hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); - - connection->establish_audio_connection = 0; +static void hfp_ag_setup_audio_connection(hfp_connection_t * connection){ if (connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return; if (connection->state >= HFP_W2_DISCONNECT_SCO) return; @@ -1504,7 +1518,14 @@ void hfp_ag_establish_audio_connection(bd_addr_t bd_addr){ default: break; } +} +void hfp_ag_establish_audio_connection(bd_addr_t bd_addr){ + hfp_ag_establish_service_level_connection(bd_addr); + hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + + connection->establish_audio_connection = 0; + hfp_ag_setup_audio_connection(connection); hfp_run_for_context(connection); } @@ -1618,3 +1639,19 @@ void hfp_ag_set_roaming_status(int status){ void hfp_ag_set_battery_level(int level){ hfp_ag_set_ag_indicator("battchg", level); } + +/* + * @brief + */ +void hfp_ag_activate_voice_recognition(bd_addr_t bd_addr, int activate){ + if (!get_bit(hfp_supported_features, HFP_AGSF_VOICE_RECOGNITION_FUNCTION)) return; + + hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr); + if (connection->ag_activate_voice_recognition == activate) return; + + connection->ag_activate_voice_recognition = activate; + connection->command = HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION; + hfp_run_for_context(connection); +} + + diff --git a/src/hfp_ag.h b/src/hfp_ag.h index 5e93236c3..3bacd807f 100644 --- a/src/hfp_ag.h +++ b/src/hfp_ag.h @@ -235,6 +235,12 @@ void hfp_ag_set_roaming_status(int status); */ void hfp_ag_set_battery_level(int level); + +/* + * @brief + */ +void hfp_ag_activate_voice_recognition(bd_addr_t bd_addr, int activate); + /* API_END */ #if defined __cplusplus