mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-16 06:39:51 +00:00
hfp: handle AG send EVR message
This commit is contained in:
parent
f1c30c367e
commit
b95cac54e2
@ -106,6 +106,10 @@ static hfp_generic_status_indicator_t hf_indicators[] = {
|
||||
{2, 1},
|
||||
};
|
||||
|
||||
static hfp_voice_recognition_message_t msg = {
|
||||
0xABCD, HFP_TEXT_TYPE_MESSAGE_FROM_AG, HFP_TEXT_OPERATION_REPLACE, "test message"
|
||||
};
|
||||
|
||||
#define INQUIRY_INTERVAL 5
|
||||
|
||||
enum STATE {INIT, W4_INQUIRY_MODE_COMPLETE, ACTIVE} ;
|
||||
@ -168,7 +172,7 @@ static void show_usage(void){
|
||||
printf("n - Disable Voice Recognition | N - Enable Voice Recognition\n");
|
||||
printf("z - Disable Enhanced Voice Recognition | Z - Enable Enhanced Voice Recognition\n");
|
||||
printf("1 - EVR report starting sound | 2 - EVR report ready for input\n");
|
||||
printf("3 - EVR report processing input | 4 - EVR report message\n");
|
||||
printf("3 - EVR report processing input | 4 - EVR send message\n");
|
||||
|
||||
printf("o - Set speaker volume to 0 (minimum) | O - Set speaker volume to 9 (default)\n");
|
||||
printf("p - Set speaker volume to 12 (higher) | P - Set speaker volume to 15 (maximum)\n");
|
||||
@ -353,8 +357,8 @@ static void stdin_process(char cmd){
|
||||
break;
|
||||
case '4':
|
||||
log_info("USER:\'%c\'", cmd);
|
||||
printf("Enhanced_Voice Recognition: report message\n");
|
||||
// status = hfp_ag_enhanced_voice_recognition_report_message(acl_handle);
|
||||
printf("Enhanced_Voice Recognition: send message\n");
|
||||
status = hfp_ag_enhanced_voice_recognition_send_message(acl_handle, HFP_VOICE_RECOGNITION_STATE_AG_READY_TO_ACCEPT_AUDIO_INPUT, msg);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
@ -592,37 +596,46 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even
|
||||
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 READY FOR AUDIO cmd failed\n");
|
||||
printf("Enhanced Voice recognition: READY FOR AUDIO cmd failed\n");
|
||||
break;
|
||||
}
|
||||
printf("\nEnhanced Voice recognition status READY FOR AUDIO\n\n");
|
||||
printf("\nEnhanced Voice recognition: READY FOR AUDIO\n\n");
|
||||
break;
|
||||
|
||||
case HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_READY_TO_ACCEPT_AUDIO_INPUT:
|
||||
status = hfp_subevent_enhanced_voice_recognition_hf_ready_for_audio_get_status(event);
|
||||
status = hfp_subevent_enhanced_voice_recognition_ag_ready_to_accept_audio_input_get_status(event);
|
||||
if (status != ERROR_CODE_SUCCESS){
|
||||
printf("Enhanced Voice recognition AG READY TO ACCEPT AUDIO INPU cmd failed\n");
|
||||
printf("Enhanced Voice recognition: AG READY TO ACCEPT AUDIO INPU cmd failed\n");
|
||||
break;
|
||||
}
|
||||
printf("\nEnhanced Voice recognition AG status: AG READY TO ACCEPT AUDIO INPUT\n\n");
|
||||
printf("\nEnhanced Voice recognition: AG READY TO ACCEPT AUDIO INPUT\n\n");
|
||||
break;
|
||||
|
||||
case HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_IS_STARTING_SOUND:
|
||||
status = hfp_subevent_enhanced_voice_recognition_hf_ready_for_audio_get_status(event);
|
||||
status = hfp_subevent_enhanced_voice_recognition_ag_is_starting_sound_get_status(event);
|
||||
if (status != ERROR_CODE_SUCCESS){
|
||||
printf("Enhanced Voice recognition AG IS STARTING SOUND cmd failed\n");
|
||||
printf("Enhanced Voice recognition: AG IS STARTING SOUND cmd failed\n");
|
||||
break;
|
||||
}
|
||||
printf("\nEnhanced Voice recognition AG status: AG IS STARTING SOUND\n\n");
|
||||
printf("\nEnhanced Voice recognition: AG IS STARTING SOUND\n\n");
|
||||
break;
|
||||
|
||||
case HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_IS_PROCESSING_AUDIO_INPUT:
|
||||
status = hfp_subevent_enhanced_voice_recognition_hf_ready_for_audio_get_status(event);
|
||||
status = hfp_subevent_enhanced_voice_recognition_ag_is_processing_audio_input_get_status(event);
|
||||
if (status != ERROR_CODE_SUCCESS){
|
||||
printf("Enhanced Voice recognition AG IS PROCESSING AUDIO INPUT cmd failed\n");
|
||||
printf("Enhanced Voice recognition: AG IS PROCESSING AUDIO INPUT cmd failed\n");
|
||||
break;
|
||||
}
|
||||
printf("\nEnhanced Voice recognition AG status: AG IS PROCESSING AUDIO INPUT\n\n");
|
||||
printf("\nEnhanced Voice recognition: AG IS PROCESSING AUDIO INPUT\n\n");
|
||||
break;
|
||||
|
||||
case HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_MESSAGE_SENT:
|
||||
status = hfp_subevent_enhanced_voice_recognition_ag_message_sent_get_status(event);
|
||||
if (status != ERROR_CODE_SUCCESS){
|
||||
printf("Enhanced Voice recognition: AG SEND MSG cmd failed\n");
|
||||
break;
|
||||
}
|
||||
printf("\nEnhanced Voice recognition: AG SEND MSG \'%s\'\n\n", msg.text);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -617,7 +617,12 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * even
|
||||
case HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_IS_PROCESSING_AUDIO_INPUT:
|
||||
printf("\nEnhanced Voice recognition AG status: AG IS PROCESSING AUDIO INPUT\n\n");
|
||||
break;
|
||||
|
||||
|
||||
case HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_MESSAGE:
|
||||
printf("\nEnhanced Voice recognition AG message: \'%s\'\n", hfp_subevent_enhanced_voice_recognition_ag_message_get_text(event));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -405,7 +405,6 @@ void hfp_emit_enhanced_voice_recognition_state_event(hfp_connection_t * hfp_conn
|
||||
default:
|
||||
btstack_unreachable();
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
little_endian_store_16(event, 3, acl_handle);
|
||||
@ -477,30 +476,6 @@ void hfp_emit_string_event(hfp_connection_t * hfp_connection, uint8_t event_subt
|
||||
hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
|
||||
}
|
||||
|
||||
static void hfp_emit_enhanced_voice_recognition_text(hfp_connection_t * hfp_connection, uint16_t value_length, uint8_t * value){
|
||||
btstack_assert(hfp_connection != NULL);
|
||||
uint8_t event[HFP_MAX_VR_TEXT_SIZE];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_HFP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_TEXT;
|
||||
little_endian_store_16(event, pos, hfp_connection->acl_handle);
|
||||
pos += 2;
|
||||
little_endian_store_16(event, pos, hfp_connection->ag_msg.text_id);
|
||||
pos += 2;
|
||||
event[pos++] = hfp_connection->ag_msg.text_operation;
|
||||
event[pos++] = hfp_connection->ag_msg.text_type;
|
||||
|
||||
// length, zero ending
|
||||
uint16_t size = btstack_min(value_length, sizeof(event) - pos - 2 - 1);
|
||||
little_endian_store_16(event, pos, size+1);
|
||||
pos += 2;
|
||||
memcpy(&event[pos], value, size);
|
||||
event[pos + size] = 0;
|
||||
pos += size + 1;
|
||||
hfp_emit_event_for_context(hfp_connection, event, pos);
|
||||
}
|
||||
|
||||
btstack_linked_list_t * hfp_get_connections(void){
|
||||
return (btstack_linked_list_t *) &hfp_connections;
|
||||
}
|
||||
@ -1712,7 +1687,7 @@ static void parse_sequence(hfp_connection_t * hfp_connection){
|
||||
hfp_connection->ag_msg.text_type = (hfp_text_type_t) btstack_atoi((char *)&hfp_connection->line_buffer[0]);
|
||||
break;
|
||||
case 5:
|
||||
hfp_emit_enhanced_voice_recognition_text(hfp_connection, hfp_connection->line_size, &hfp_connection->line_buffer[0]);
|
||||
hfp_connection->ag_vra_msg_length = hfp_connection->line_size;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -402,17 +402,14 @@ typedef enum {
|
||||
HFP_VRA_ENHANCED_VOICE_RECOGNITION_READY_FOR_AUDIO,
|
||||
|
||||
HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_STATUS,
|
||||
HFP_VRA_W4_ENHANCED_VOICE_RECOGNITION_STATUS,
|
||||
|
||||
// TODO delete
|
||||
HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_MSG,
|
||||
HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_MSG
|
||||
} hfp_voice_recognition_activation_status_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t text_id;
|
||||
hfp_text_type_t text_type;
|
||||
hfp_text_operation_t text_operation;
|
||||
uint8_t * text;
|
||||
const char * text;
|
||||
} hfp_voice_recognition_message_t;
|
||||
|
||||
typedef enum {
|
||||
@ -695,6 +692,7 @@ typedef struct hfp_connection {
|
||||
uint8_t ag_vra_status;
|
||||
hfp_voice_recognition_state_t ag_vra_state;
|
||||
hfp_voice_recognition_message_t ag_msg;
|
||||
uint16_t ag_vra_msg_length;
|
||||
|
||||
uint8_t clcc_idx;
|
||||
uint8_t clcc_dir;
|
||||
|
@ -815,6 +815,18 @@ static bool hfp_ag_is_audio_connection_active(hfp_connection_t * hfp_connection)
|
||||
}
|
||||
}
|
||||
|
||||
static void hfp_ag_emit_enhanced_voice_recognition_msg_sent_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_AG_TEXT_SENT;
|
||||
little_endian_store_16(event, 3, acl_handle);
|
||||
event[5] = status;
|
||||
(*hfp_ag_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
static int hfp_ag_voice_recognition_state_machine(hfp_connection_t * hfp_connection){
|
||||
if (hfp_connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) {
|
||||
return 0;
|
||||
@ -825,6 +837,16 @@ static int hfp_ag_voice_recognition_state_machine(hfp_connection_t * hfp_connect
|
||||
switch (hfp_connection->command){
|
||||
case HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION:
|
||||
switch (hfp_connection->vra_state_requested){
|
||||
case HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_MSG:
|
||||
done = hfp_ag_send_enhanced_voice_recognition_msg_cmd(hfp_connection);
|
||||
if (done == 0){
|
||||
hfp_ag_emit_enhanced_voice_recognition_msg_sent_event(hfp_connection, ERROR_CODE_UNSPECIFIED_ERROR);
|
||||
} else {
|
||||
hfp_ag_emit_enhanced_voice_recognition_msg_sent_event(hfp_connection, ERROR_CODE_SUCCESS);
|
||||
}
|
||||
hfp_connection->vra_state_requested = hfp_connection->vra_state;
|
||||
return done;
|
||||
|
||||
case HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_STATUS:
|
||||
done = hfp_ag_send_enhanced_voice_recognition_state_cmd(hfp_connection);
|
||||
if (done == 0){
|
||||
@ -833,7 +855,8 @@ static int hfp_ag_voice_recognition_state_machine(hfp_connection_t * hfp_connect
|
||||
hfp_emit_enhanced_voice_recognition_state_event(hfp_connection, ERROR_CODE_SUCCESS);
|
||||
}
|
||||
hfp_connection->vra_state_requested = hfp_connection->vra_state;
|
||||
break;
|
||||
return done;
|
||||
|
||||
default:
|
||||
done = hfp_ag_send_voice_recognition_cmd(hfp_connection, hfp_connection->ag_activate_voice_recognition_value);
|
||||
if (done == 0){
|
||||
@ -926,11 +949,6 @@ static int hfp_ag_voice_recognition_state_machine(hfp_connection_t * hfp_connect
|
||||
hfp_emit_voice_recognition_state_event(hfp_connection, ERROR_CODE_SUCCESS);
|
||||
break;
|
||||
|
||||
case HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_MSG:
|
||||
hfp_connection->ag_vra_status = HFP_VRA_VOICE_RECOGNITION_ACTIVATED;
|
||||
done = hfp_ag_send_enhanced_voice_recognition_msg_cmd(hfp_connection);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2743,23 +2761,6 @@ uint8_t hfp_ag_deactivate_enhanced_voice_recognition(hci_con_handle_t acl_handle
|
||||
return deactivate_voice_recognition(acl_handle, true);
|
||||
}
|
||||
|
||||
uint8_t hfp_ag_enhanced_voice_recognition_report_message(hci_con_handle_t acl_handle, hfp_voice_recognition_state_t state, hfp_voice_recognition_message_t msg){
|
||||
hfp_connection_t * hfp_connection = get_hfp_ag_connection_context_for_acl_handle(acl_handle);
|
||||
if (!hfp_connection){
|
||||
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||
}
|
||||
|
||||
uint8_t status = hfp_ag_can_send_enahnced_voice_recognition_message(hfp_connection, true);
|
||||
if (status == ERROR_CODE_SUCCESS){
|
||||
hfp_connection->command = HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION;
|
||||
hfp_connection->vra_state_requested = HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_STATUS;
|
||||
hfp_connection->ag_msg = msg;
|
||||
hfp_connection->ag_vra_state = state;
|
||||
hfp_ag_run_for_context(hfp_connection);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static uint8_t hfp_ag_enhanced_voice_recognition_send_state(hci_con_handle_t acl_handle, hfp_voice_recognition_state_t state){
|
||||
hfp_connection_t * hfp_connection = get_hfp_ag_connection_context_for_acl_handle(acl_handle);
|
||||
if (!hfp_connection){
|
||||
@ -2786,6 +2787,25 @@ uint8_t hfp_ag_enhanced_voice_recognition_report_processing_input(hci_con_handle
|
||||
return hfp_ag_enhanced_voice_recognition_send_state(acl_handle, HFP_VOICE_RECOGNITION_STATE_AG_IS_PROCESSING_AUDIO_INPUT);
|
||||
}
|
||||
|
||||
|
||||
uint8_t hfp_ag_enhanced_voice_recognition_send_message(hci_con_handle_t acl_handle, hfp_voice_recognition_state_t state, hfp_voice_recognition_message_t msg){
|
||||
hfp_connection_t * hfp_connection = get_hfp_ag_connection_context_for_acl_handle(acl_handle);
|
||||
if (!hfp_connection){
|
||||
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
|
||||
}
|
||||
|
||||
uint8_t status = hfp_ag_can_send_enahnced_voice_recognition_message(hfp_connection, true);
|
||||
if (status == ERROR_CODE_SUCCESS){
|
||||
hfp_connection->command = HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION;
|
||||
hfp_connection->vra_state_requested = HFP_VRA_W2_SEND_ENHANCED_VOICE_RECOGNITION_MSG;
|
||||
hfp_connection->ag_msg = msg;
|
||||
hfp_connection->ag_vra_state = state;
|
||||
hfp_ag_run_for_context(hfp_connection);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
uint8_t hfp_ag_set_microphone_gain(hci_con_handle_t acl_handle, int gain){
|
||||
hfp_connection_t * hfp_connection = get_hfp_ag_connection_context_for_acl_handle(acl_handle);
|
||||
if (!hfp_connection){
|
||||
|
@ -339,7 +339,7 @@ uint8_t hfp_ag_enhanced_voice_recognition_report_processing_input(hci_con_handle
|
||||
* - ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER if connection does not exist, or
|
||||
* - ERROR_CODE_COMMAND_DISALLOWED if AG or HF does not support enhanced voice recognition
|
||||
*/
|
||||
uint8_t hfp_ag_enhanced_voice_recognition_report_message(hci_con_handle_t acl_handle, hfp_voice_recognition_state_t state, hfp_voice_recognition_message_t msg);
|
||||
uint8_t hfp_ag_enhanced_voice_recognition_send_message(hci_con_handle_t acl_handle, hfp_voice_recognition_state_t state, hfp_voice_recognition_message_t msg);
|
||||
|
||||
/**
|
||||
* @brief Deactivate enhanced voice recognition (EVR) and emit HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_STATUS event with status ERROR_CODE_SUCCESS
|
||||
|
@ -212,6 +212,33 @@ static void hfp_emit_network_operator_event(const hfp_connection_t * hfp_connect
|
||||
(*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
|
||||
static void hfp_hf_emit_enhanced_voice_recognition_text(hfp_connection_t * hfp_connection){
|
||||
btstack_assert(hfp_connection != NULL);
|
||||
uint8_t event[HFP_MAX_VR_TEXT_SIZE];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_HFP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_MESSAGE;
|
||||
little_endian_store_16(event, pos, hfp_connection->acl_handle);
|
||||
pos += 2;
|
||||
little_endian_store_16(event, pos, hfp_connection->ag_msg.text_id);
|
||||
pos += 2;
|
||||
event[pos++] = hfp_connection->ag_msg.text_operation;
|
||||
event[pos++] = hfp_connection->ag_msg.text_type;
|
||||
|
||||
// length, zero ending
|
||||
uint16_t value_length = hfp_connection->ag_vra_msg_length;
|
||||
uint8_t * value = &hfp_connection->line_buffer[0];
|
||||
uint16_t size = btstack_min(value_length, sizeof(event) - pos - 2 - 1);
|
||||
little_endian_store_16(event, pos, size+1);
|
||||
pos += 2;
|
||||
memcpy(&event[pos], value, size);
|
||||
event[pos + size] = 0;
|
||||
pos += size + 1;
|
||||
(*hfp_hf_callback)(HCI_EVENT_PACKET, 0, event, pos);
|
||||
}
|
||||
|
||||
/* send commands */
|
||||
|
||||
static inline int hfp_hf_send_cmd(uint16_t cid, const char * cmd){
|
||||
@ -495,7 +522,11 @@ static int hfp_hf_voice_recognition_state_machine(hfp_connection_t * hfp_connect
|
||||
return 0;
|
||||
|
||||
default:
|
||||
printf("status %d state %d\n", hfp_connection->ag_vra_status, hfp_connection->ag_vra_state);
|
||||
if (hfp_connection->ag_vra_msg_length > 0){
|
||||
hfp_hf_emit_enhanced_voice_recognition_text(hfp_connection);
|
||||
hfp_connection->ag_vra_msg_length = 0;
|
||||
break;
|
||||
}
|
||||
switch(hfp_connection->ag_vra_state){
|
||||
case HFP_VOICE_RECOGNITION_STATE_AG_READY:
|
||||
switch (hfp_connection->ag_vra_status){
|
||||
|
Loading…
x
Reference in New Issue
Block a user