hfp: enhanced audio recognition, HF ready for audio

This commit is contained in:
Milanka Ringwald 2021-07-08 14:24:27 +02:00
parent 6b67407d5d
commit de9e0ea7a7
9 changed files with 178 additions and 92 deletions

View File

@ -70,7 +70,7 @@ const uint8_t rfcomm_channel_nr = 1;
const char hfp_ag_service_name[] = "HFP AG Demo";
static bd_addr_t device_addr;
static const char * device_addr_string = "00:02:72:DC:31:C1";
static const char * device_addr_string = "00:1A:7D:DA:71:13";
#ifdef ENABLE_HFP_WIDE_BAND_SPEECH
static uint8_t codecs[] = {HFP_CODEC_CVSD, HFP_CODEC_MSBC};
@ -549,43 +549,29 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even
case HFP_SUBEVENT_VOICE_RECOGNITION_STATUS:
status = hfp_subevent_voice_recognition_status_get_status(event);
if (status != ERROR_CODE_SUCCESS){
printf("Voice Recognition command failed with status 0x%02x\n", status);
printf("Voice Recognition command failed\n");
break;
}
printf("\n");
switch(hfp_subevent_voice_recognition_status_get_state(event)){
case 0:
printf("Voice recognition status DEACTIVATED\n");
printf("\nVoice recognition status DEACTIVATED\n\n");
break;
case 1:
printf("Voice recognition status ACTIVATED\n");
printf("\nVoice recognition status ACTIVATED\n\n");
break;
default:
btstack_assert(false);
break;
}
printf("\n");
break;
case HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_STATUS:
status = hfp_subevent_voice_recognition_status_get_status(event);
case HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_HF_READY_FOR_AUDIO:
status = hfp_subevent_enhanced_voice_recognition_hf_ready_for_audio_get_status(event);
if (status != ERROR_CODE_SUCCESS){
printf("Enhanced Voice Recognition command failed with status 0x%02x\n", status);
printf("Enhanced Voice recognition READY FOR AUDIO cmd failed\n");
break;
}
printf("\n");
switch(hfp_subevent_voice_recognition_status_get_state(event)){
case 0:
printf("Enhanced Voice recognition status DEACTIVATED\n");
break;
case 1:
printf("Enhanced Voice recognition status ACTIVATED\n");
break;
default:
btstack_assert(false);
break;
}
printf("\n");
printf("\nEnhanced Voice recognition status READY FOR AUDIO\n\n");
break;
default:
break;

View File

@ -68,7 +68,7 @@ const char hfp_hf_service_name[] = "HFP HF Demo";
#ifdef HAVE_BTSTACK_STDIN
// static const char * device_addr_string = "6C:72:E7:10:22:EE";
static const char * device_addr_string = "00:1A:7D:DA:71:13";
static const char * device_addr_string = "00:02:72:DC:31:C1";
#endif
static bd_addr_t device_addr;
@ -150,6 +150,8 @@ static void show_usage(void){
printf("m/M - deactivate/activate echo canceling and noise reduction\n");
printf("n/N - deactivate/activate voice recognition\n");
printf("z/Z - deactivate/activate enhanced voice recognition\n");
printf("h - start new audio enhanced voice recognition session\n");
printf("0123456789#*-+ - send DTMF dial tones\n");
printf("x - request phone number for voice tag | X - current call status (ECS)\n");
printf("y - release call with index 2 (ECC) | Y - private consultation with call 2(ECC)\n");
@ -325,6 +327,11 @@ static void stdin_process(char c){
printf("Activate enhanced voice recognition %s\n", bd_addr_to_str(device_addr));
status = hfp_hf_activate_enhanced_voice_recognition(acl_handle);
break;
case 'h':
log_info("USER:\'%c\'", cmd);
printf("Start new audio enhanced voice recognition session %s\n", bd_addr_to_str(device_addr));
status = hfp_hf_enhanced_voice_recognition_report_ready_for_audio(acl_handle);
break;
case 'o':
log_info("USER:\'%c\'", cmd);
printf("Set speaker gain to 0 (minimum)\n");
@ -576,43 +583,29 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even
case HFP_SUBEVENT_VOICE_RECOGNITION_STATUS:
status = hfp_subevent_voice_recognition_status_get_status(event);
if (status != ERROR_CODE_SUCCESS){
printf("Voice Recognition command failed with status 0x%02x\n", status);
printf("Voice Recognition command failed\n");
break;
}
printf("\n");
switch(hfp_subevent_voice_recognition_status_get_state(event)){
case 0:
printf("Voice recognition status DEACTIVATED\n");
printf("\nVoice recognition status DEACTIVATED\n\n");
break;
case 1:
printf("Voice recognition status ACTIVATED\n");
printf("\nVoice recognition status ACTIVATED\n\n");
break;
default:
btstack_assert(false);
break;
}
printf("\n");
break;
case HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_STATUS:
status = hfp_subevent_voice_recognition_status_get_status(event);
case HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_HF_READY_FOR_AUDIO:
status = hfp_subevent_enhanced_voice_recognition_hf_ready_for_audio_get_status(event);
if (status != ERROR_CODE_SUCCESS){
printf("Enhanced Voice Recognition command failed with status 0x%02x\n", status);
printf("Enhanced Voice recognition READY FOR AUDIO cmd failed\n");
break;
}
printf("\n");
switch(hfp_subevent_voice_recognition_status_get_state(event)){
case 0:
printf("Enhanced Voice recognition status DEACTIVATED\n");
break;
case 1:
printf("Enhanced Voice recognition status ACTIVATED\n");
break;
default:
btstack_assert(false);
break;
}
printf("\n");
printf("\nEnhanced Voice recognition status READY FOR AUDIO\n\n");
break;
default:

View File

@ -1781,13 +1781,12 @@ typedef uint8_t sm_key_t[16];
#define HFP_SUBEVENT_VOICE_RECOGNITION_STATUS 0x1E
/**
* @format 1H11
* @format 1H1
* @param subevent_code
* @param acl_handle
* @param status
* @param state
*/
#define HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_STATUS 0x1F
#define HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_HF_READY_FOR_AUDIO 0x1F
/**
* @format 1H211LV

View File

@ -4746,32 +4746,23 @@ static inline uint8_t hfp_subevent_voice_recognition_status_get_state(const uint
}
/**
* @brief Get field acl_handle from event HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_STATUS
* @brief Get field acl_handle from event HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_HF_READY_FOR_AUDIO
* @param event packet
* @return acl_handle
* @note: btstack_type H
*/
static inline hci_con_handle_t hfp_subevent_enhanced_voice_recognition_status_get_acl_handle(const uint8_t * event){
static inline hci_con_handle_t hfp_subevent_enhanced_voice_recognition_hf_ready_for_audio_get_acl_handle(const uint8_t * event){
return little_endian_read_16(event, 3);
}
/**
* @brief Get field status from event HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_STATUS
* @brief Get field status from event HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_HF_READY_FOR_AUDIO
* @param event packet
* @return status
* @note: btstack_type 1
*/
static inline uint8_t hfp_subevent_enhanced_voice_recognition_status_get_status(const uint8_t * event){
static inline uint8_t hfp_subevent_enhanced_voice_recognition_hf_ready_for_audio_get_status(const uint8_t * event){
return event[5];
}
/**
* @brief Get field state from event HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_STATUS
* @param event packet
* @return state
* @note: btstack_type 1
*/
static inline uint8_t hfp_subevent_enhanced_voice_recognition_status_get_state(const uint8_t * event){
return event[6];
}
/**
* @brief Get field acl_handle from event HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_TEXT

View File

@ -355,11 +355,8 @@ void hfp_emit_voice_recognition_state_event(hfp_connection_t * hfp_connection, u
uint8_t event[7];
event[0] = HCI_EVENT_HFP_META;
event[1] = sizeof(event) - 2;
if (hfp_connection->enhanced_voice_recognition_enabled){
event[2] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_STATUS;
} else {
event[2] = HFP_SUBEVENT_VOICE_RECOGNITION_STATUS;
}
event[2] = HFP_SUBEVENT_VOICE_RECOGNITION_STATUS;
little_endian_store_16(event, 3, acl_handle);
event[5] = status; // 0:success
@ -367,6 +364,9 @@ void hfp_emit_voice_recognition_state_event(hfp_connection_t * hfp_connection, u
case HFP_VRA_VOICE_RECOGNITION_ACTIVATED:
event[6] = 1;
break;
case HFP_VRA_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO:
event[6] = 2;
break;
default:
event[6] = 0;
break;
@ -374,6 +374,18 @@ void hfp_emit_voice_recognition_state_event(hfp_connection_t * hfp_connection, u
hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
}
void hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection_t * hfp_connection, uint8_t status){
hci_con_handle_t acl_handle = (hfp_connection != NULL) ? hfp_connection->acl_handle : HCI_CON_HANDLE_INVALID;
uint8_t event[6];
event[0] = HCI_EVENT_HFP_META;
event[1] = sizeof(event) - 2;
event[2] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_HF_READY_FOR_AUDIO;
little_endian_store_16(event, 3, acl_handle);
event[5] = status;
hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
}
void hfp_emit_slc_connection_event(hfp_connection_t * hfp_connection, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr){
btstack_assert(hfp_connection != NULL);
uint8_t event[12];
@ -762,6 +774,8 @@ static void hfp_reset_voice_recognition(hfp_connection_t * hfp_connection){
hfp_connection->vra_state = HFP_VRA_VOICE_RECOGNITION_OFF;
hfp_connection->vra_state_requested = HFP_VRA_VOICE_RECOGNITION_OFF;
hfp_connection->ag_vra_status = 0;
hfp_connection->activate_voice_recognition = false;
hfp_connection->deactivate_voice_recognition = false;
hfp_connection->enhanced_voice_recognition_enabled = false;
hfp_connection->ag_vra_state = HFP_VOICE_RECOGNITION_STATE_AG_READY;
}

View File

@ -406,9 +406,8 @@ typedef enum {
HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_MSG,
HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_STATUS,
HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_STATUS,
HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_STATUS
HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_NEW_SESSION,
} hfp_voice_recognition_activation_status_t;
typedef struct {
@ -690,7 +689,9 @@ typedef struct hfp_connection {
hfp_voice_recognition_activation_status_t vra_state;
hfp_voice_recognition_activation_status_t vra_state_requested;
bool deactivate_voice_recognition;
bool activate_voice_recognition;
uint8_t ag_vra_status;
hfp_voice_recognition_state_t ag_vra_state;
bool enhanced_voice_recognition_enabled;
@ -754,6 +755,7 @@ void hfp_emit_slc_connection_event(hfp_connection_t * hfp_connection, uint8_t st
* @param state 0 if deactivated, 1 if activated
*/
void hfp_emit_voice_recognition_state_event(hfp_connection_t * hfp_connection, uint8_t status);
void hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection_t * hfp_connection, uint8_t status);
hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid);
hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr, hfp_role_t hfp_role);

View File

@ -781,6 +781,9 @@ static uint8_t hfp_ag_voice_recognition_session_active(hfp_connection_t * hfp_co
return ERROR_CODE_COMMAND_DISALLOWED;
}
if (hfp_connection->vra_state != HFP_VRA_VOICE_RECOGNITION_ACTIVATED){
if (hfp_connection->vra_state == HFP_VRA_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO){
return ERROR_CODE_SUCCESS;
}
return ERROR_CODE_COMMAND_DISALLOWED;
}
return ERROR_CODE_SUCCESS;
@ -826,16 +829,29 @@ static int hfp_ag_voice_recognition_state_machine(hfp_connection_t * hfp_connect
case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION:
// HF initiatied voice recognition, parser extracted activation value
if (hfp_connection->ag_activate_voice_recognition_value == 0){
if (hfp_ag_voice_recognition_session_active(hfp_connection, hfp_connection->enhanced_voice_recognition_enabled) == ERROR_CODE_SUCCESS){
hfp_connection->vra_state_requested = HFP_VRA_W2_SEND_VOICE_RECOGNITION_OFF;
done = hfp_ag_send_ok(hfp_connection->rfcomm_cid);
}
} else {
if (hfp_ag_can_activate_voice_recognition(hfp_connection, hfp_connection->enhanced_voice_recognition_enabled) == ERROR_CODE_SUCCESS){
hfp_connection->vra_state_requested = HFP_VRA_W2_SEND_VOICE_RECOGNITION_ACTIVATED;
done = hfp_ag_send_ok(hfp_connection->rfcomm_cid);
}
switch (hfp_connection->ag_activate_voice_recognition_value){
case 0:
if (hfp_ag_voice_recognition_session_active(hfp_connection, hfp_connection->enhanced_voice_recognition_enabled) == ERROR_CODE_SUCCESS){
hfp_connection->vra_state_requested = HFP_VRA_W2_SEND_VOICE_RECOGNITION_OFF;
done = hfp_ag_send_ok(hfp_connection->rfcomm_cid);
}
break;
case 1:
if (hfp_ag_can_activate_voice_recognition(hfp_connection, hfp_connection->enhanced_voice_recognition_enabled) == ERROR_CODE_SUCCESS){
hfp_connection->vra_state_requested = HFP_VRA_W2_SEND_VOICE_RECOGNITION_ACTIVATED;
done = hfp_ag_send_ok(hfp_connection->rfcomm_cid);
}
break;
case 2:
if (hfp_ag_voice_recognition_session_active(hfp_connection, hfp_connection->enhanced_voice_recognition_enabled) == ERROR_CODE_SUCCESS){
hfp_connection->vra_state_requested = HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO;
done = hfp_ag_send_ok(hfp_connection->rfcomm_cid);
}
break;
default:
break;
}
if (done == 0){
hfp_connection->vra_state_requested = hfp_connection->vra_state;
@ -849,6 +865,22 @@ static int hfp_ag_voice_recognition_state_machine(hfp_connection_t * hfp_connect
}
switch (hfp_connection->vra_state_requested){
case HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO:
if (!hfp_ag_is_audio_connection_active(hfp_connection)){
status = hfp_ag_setup_audio_connection(hfp_connection);
if (status != ERROR_CODE_SUCCESS){
hfp_connection->vra_state_requested = hfp_connection->vra_state;
hfp_emit_voice_recognition_state_event(hfp_connection, status);
return 0;
}
}
hfp_connection->enhanced_voice_recognition_enabled = true;
hfp_connection->vra_state = HFP_VRA_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO;
hfp_connection->vra_state_requested = hfp_connection->vra_state;
hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection, ERROR_CODE_SUCCESS);
break;
case HFP_VRA_W2_SEND_VOICE_RECOGNITION_OFF:
hfp_connection->vra_state = HFP_VRA_VOICE_RECOGNITION_OFF;
hfp_connection->vra_state_requested = hfp_connection->vra_state;

View File

@ -490,6 +490,7 @@ static int hfp_hf_voice_recognition_state_machine(hfp_connection_t * hfp_connect
switch(hfp_connection->vra_state_requested){
case HFP_VRA_W4_VOICE_RECOGNITION_ACTIVATED:
case HFP_VRA_W4_VOICE_RECOGNITION_OFF:
case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO:
// ignore AG command, continue to wait for OK
return 0;
default:
@ -521,11 +522,6 @@ static int hfp_hf_voice_recognition_state_machine(hfp_connection_t * hfp_connect
}
return 1;
case HFP_VRA_W4_VOICE_RECOGNITION_OFF:
hfp_connection->vra_state = HFP_VRA_VOICE_RECOGNITION_OFF;
hfp_connection->vra_state_requested = hfp_connection->vra_state;
hfp_emit_voice_recognition_state_event(hfp_connection, ERROR_CODE_SUCCESS);
break;
case HFP_VRA_W2_SEND_VOICE_RECOGNITION_ACTIVATED:
done = hfp_hf_set_voice_recognition_notification_cmd(hfp_connection->rfcomm_cid, 1);
@ -536,20 +532,50 @@ static int hfp_hf_voice_recognition_state_machine(hfp_connection_t * hfp_connect
}
break;
case HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO:
done = hfp_hf_set_voice_recognition_notification_cmd(hfp_connection->rfcomm_cid, 2);
if (done != 0){
hfp_connection->vra_state_requested = HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO;
hfp_connection->ok_pending = 1;
return 1;
}
break;
case HFP_VRA_W4_VOICE_RECOGNITION_OFF:
hfp_connection->vra_state = HFP_VRA_VOICE_RECOGNITION_OFF;
hfp_connection->vra_state_requested = hfp_connection->vra_state;
hfp_connection->activate_voice_recognition = false;
if (hfp_connection->activate_voice_recognition){
hfp_hf_activate_voice_recognition(hfp_connection->acl_handle);
} else {
hfp_emit_voice_recognition_state_event(hfp_connection, ERROR_CODE_SUCCESS);
}
break;
case HFP_VRA_W4_VOICE_RECOGNITION_ACTIVATED:
hfp_connection->vra_state = HFP_VRA_VOICE_RECOGNITION_ACTIVATED;
hfp_connection->vra_state_requested = hfp_connection->vra_state;
hfp_emit_voice_recognition_state_event(hfp_connection, ERROR_CODE_SUCCESS);
hfp_connection->activate_voice_recognition = false;
if (hfp_connection->deactivate_voice_recognition){
hfp_hf_deactivate_voice_recognition(hfp_connection->acl_handle);
} else {
hfp_emit_voice_recognition_state_event(hfp_connection, ERROR_CODE_SUCCESS);
}
break;
case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO:
hfp_connection->vra_state = HFP_VRA_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO;
hfp_connection->vra_state_requested = hfp_connection->vra_state;
hfp_emit_voice_recognition_state_event(hfp_connection, ERROR_CODE_SUCCESS);
hfp_connection->activate_voice_recognition = false;
if (hfp_connection->deactivate_voice_recognition){
hfp_hf_deactivate_voice_recognition(hfp_connection->acl_handle);
} else {
hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection, ERROR_CODE_SUCCESS);
}
break;
default:
break;
}
return done;
@ -1168,8 +1194,8 @@ static void hfp_hf_handle_rfcomm_command(hfp_connection_t * hfp_connection){
}
// handle error response for voice activation (HF initiated)
switch(hfp_connection->vra_state_requested){
case HFP_VRA_VOICE_RECOGNITION_ACTIVATED:
case HFP_VRA_VOICE_RECOGNITION_OFF:
case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO:
hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR);
break;
default:
hfp_connection->vra_state_requested = hfp_connection->vra_state;
@ -1742,10 +1768,14 @@ static uint8_t activate_voice_recognition(hci_con_handle_t acl_handle, bool enha
switch (hfp_connection->vra_state){
case HFP_VRA_VOICE_RECOGNITION_OFF:
case HFP_VRA_W2_SEND_VOICE_RECOGNITION_OFF:
hfp_connection->command = HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION;
hfp_connection->vra_state_requested = HFP_VRA_W2_SEND_VOICE_RECOGNITION_ACTIVATED;
hfp_connection->enhanced_voice_recognition_enabled = enhanced;
break;
case HFP_VRA_W4_VOICE_RECOGNITION_OFF:
hfp_connection->activate_voice_recognition = true;
break;
default:
return ERROR_CODE_COMMAND_DISALLOWED;
}
@ -1760,18 +1790,30 @@ static uint8_t deactivate_voice_recognition(hci_con_handle_t acl_handle, bool en
if (!hfp_connection) {
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
}
if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED || hfp_connection->state > HFP_AUDIO_CONNECTION_ESTABLISHED){
if (hfp_connection->state != HFP_AUDIO_CONNECTION_ESTABLISHED){
return ERROR_CODE_COMMAND_DISALLOWED;
}
if (!hfp_hf_voice_recognition_supported(hfp_connection, enhanced)){
return ERROR_CODE_COMMAND_DISALLOWED;
}
switch (hfp_connection->vra_state){
case HFP_VRA_W2_SEND_VOICE_RECOGNITION_ACTIVATED:
case HFP_VRA_VOICE_RECOGNITION_ACTIVATED:
case HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO:
case HFP_VRA_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO:
hfp_connection->command = HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION;
hfp_connection->vra_state_requested = HFP_VRA_W2_SEND_VOICE_RECOGNITION_OFF;
break;
case HFP_VRA_W4_VOICE_RECOGNITION_ACTIVATED:
case HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO:
hfp_connection->deactivate_voice_recognition = true;
break;
case HFP_VRA_VOICE_RECOGNITION_OFF:
case HFP_VRA_W2_SEND_VOICE_RECOGNITION_OFF:
case HFP_VRA_W4_VOICE_RECOGNITION_OFF:
default:
return ERROR_CODE_COMMAND_DISALLOWED;
}
@ -1788,6 +1830,32 @@ uint8_t hfp_hf_activate_enhanced_voice_recognition(hci_con_handle_t acl_handle){
return activate_voice_recognition(acl_handle, true);
}
uint8_t hfp_hf_enhanced_voice_recognition_report_ready_for_audio(hci_con_handle_t acl_handle){
hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle);
if (!hfp_connection) {
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
}
if (hfp_connection->state != HFP_AUDIO_CONNECTION_ESTABLISHED){
return ERROR_CODE_COMMAND_DISALLOWED;
}
if (!hfp_hf_voice_recognition_supported(hfp_connection, true)){
return ERROR_CODE_COMMAND_DISALLOWED;
}
switch (hfp_connection->vra_state){
case HFP_VRA_VOICE_RECOGNITION_ACTIVATED:
case HFP_VRA_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO:
hfp_connection->command = HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION;
hfp_connection->vra_state_requested = HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO;
break;
default:
return ERROR_CODE_COMMAND_DISALLOWED;
}
hfp_hf_run_for_context(hfp_connection);
return ERROR_CODE_SUCCESS;
}
uint8_t hfp_hf_deactivate_voice_recognition(hci_con_handle_t acl_handle){
return deactivate_voice_recognition(acl_handle, false);
@ -1797,6 +1865,7 @@ uint8_t hfp_hf_deactivate_enhanced_voice_recognition(hci_con_handle_t acl_handle
return deactivate_voice_recognition(acl_handle, true);
}
uint8_t hfp_hf_set_microphone_gain(hci_con_handle_t acl_handle, int gain){
hfp_connection_t * hfp_connection = get_hfp_hf_connection_context_for_acl_handle(acl_handle);
if (!hfp_connection) {

View File

@ -408,7 +408,7 @@ uint8_t hfp_hf_activate_enhanced_voice_recognition(hci_con_handle_t acl_handle);
* @return status ERROR_CODE_SUCCESS if successful, otherwise:
* - ERROR_CODE_COMMAND_DISALLOWED if HF does not support it, or wrong VRA status
*/
uint8_t hfp_hf_enhanced_voice_recognition_ready_to_accept_audio(hci_con_handle_t acl_handle);
uint8_t hfp_hf_enhanced_voice_recognition_report_ready_for_audio(hci_con_handle_t acl_handle);
/**
* @brief Deactivate enhanced voice recognition (EVR) and emit HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_STATUS event with status ERROR_CODE_SUCCESS