mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-16 08:42:28 +00:00
move esco accept connection to the upper layers (hfp, hsp)
This commit is contained in:
parent
a33eb0c45b
commit
011577ab36
@ -518,6 +518,15 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
log_info("AG packet_handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size);
|
||||
|
||||
switch (hci_event_packet_get_type(packet)) {
|
||||
case HCI_EVENT_CONNECTION_REQUEST:
|
||||
// printf("hfp HCI_EVENT_CONNECTION_REQUEST\n");
|
||||
|
||||
hci_event_connection_request_get_bd_addr(packet, event_addr);
|
||||
hfp_connection = provide_hfp_connection_context_for_bd_addr(event_addr);
|
||||
|
||||
if (!hfp_connection) break;
|
||||
hfp_connection->ag_establish_eSCO = 1;
|
||||
break;
|
||||
|
||||
case RFCOMM_EVENT_INCOMING_CONNECTION:
|
||||
// data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
|
||||
@ -575,30 +584,27 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
break;
|
||||
|
||||
case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
|
||||
hci_event_synchronous_connection_complete_get_bd_addr(packet, event_addr);
|
||||
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
|
||||
if (!hfp_connection) {
|
||||
log_error("HFP: connection does not exist for remote with addr %s.", bd_addr_to_str(event_addr));
|
||||
return;
|
||||
}
|
||||
hfp_connection->ag_establish_eSCO = 0;
|
||||
|
||||
reverse_bd_addr(&packet[5], event_addr);
|
||||
int index = 2;
|
||||
status = packet[index++];
|
||||
|
||||
status = hci_event_synchronous_connection_complete_get_status(packet);
|
||||
if (status != 0){
|
||||
hfp_handle_failed_sco_connection(status);
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t sco_handle = little_endian_read_16(packet, index);
|
||||
index+=2;
|
||||
|
||||
reverse_bd_addr(&packet[index], event_addr);
|
||||
index+=6;
|
||||
|
||||
uint8_t link_type = packet[index++];
|
||||
uint8_t transmission_interval = packet[index++]; // measured in slots
|
||||
uint8_t retransmission_interval = packet[index++];// measured in slots
|
||||
uint16_t rx_packet_length = little_endian_read_16(packet, index); // measured in bytes
|
||||
index+=2;
|
||||
uint16_t tx_packet_length = little_endian_read_16(packet, index); // measured in bytes
|
||||
index+=2;
|
||||
uint8_t air_mode = packet[index];
|
||||
uint16_t sco_handle = hci_event_synchronous_connection_complete_get_handle(packet);
|
||||
uint8_t link_type = hci_event_synchronous_connection_complete_get_link_type(packet);
|
||||
uint8_t transmission_interval = hci_event_synchronous_connection_complete_get_transmission_interval(packet); // measured in slots
|
||||
uint8_t retransmission_interval = hci_event_synchronous_connection_complete_get_retransmission_interval(packet);// measured in slots
|
||||
uint16_t rx_packet_length = hci_event_synchronous_connection_complete_get_rx_packet_length(packet); // measured in bytes
|
||||
uint16_t tx_packet_length = hci_event_synchronous_connection_complete_get_tx_packet_length(packet); // measured in bytes
|
||||
uint8_t air_mode = hci_event_synchronous_connection_complete_get_air_mode(packet);
|
||||
|
||||
switch (link_type){
|
||||
case 0x00:
|
||||
|
@ -561,6 +561,7 @@ typedef struct hfp_connection {
|
||||
uint8_t send_response_and_hold_status; // 0 - don't send. BRTH:0 == 1, ..
|
||||
|
||||
// AG only
|
||||
uint8_t ag_establish_eSCO;
|
||||
uint8_t change_in_band_ring_tone_setting;
|
||||
uint8_t ag_ring;
|
||||
uint8_t ag_send_clip;
|
||||
|
@ -1626,6 +1626,23 @@ static void hfp_run_for_context(hfp_connection_t *hfp_connection){
|
||||
|
||||
if (!hfp_connection->rfcomm_cid) return;
|
||||
|
||||
if (hfp_connection->ag_establish_eSCO && hci_can_send_command_packet_now()){
|
||||
// remote supported feature eSCO is set if link type is eSCO
|
||||
// eSCO: S4 - max latency == transmission interval = 0x000c == 12 ms,
|
||||
uint16_t max_latency = 0x000c;
|
||||
uint8_t retransmission_effort = 0x02;
|
||||
uint16_t packet_types = 0x388;
|
||||
uint16_t sco_voice_setting = hci_get_sco_voice_setting();
|
||||
|
||||
if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
|
||||
sco_voice_setting = 0x0003; // Transparent data
|
||||
}
|
||||
log_info("HFP: sending hci_accept_connection_request, sco_voice_setting %02x", sco_voice_setting);
|
||||
hci_send_cmd(&hci_accept_synchronous_connection, hfp_connection->remote_addr, 8000, 8000, max_latency,
|
||||
sco_voice_setting, retransmission_effort, packet_types);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rfcomm_can_send_packet_now(hfp_connection->rfcomm_cid)) {
|
||||
log_info("hfp_run_for_context: request can send for 0x%02x", hfp_connection->rfcomm_cid);
|
||||
rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid);
|
||||
|
@ -76,6 +76,7 @@
|
||||
static const char default_hsp_ag_service_name[] = "Audio Gateway";
|
||||
|
||||
static bd_addr_t remote;
|
||||
static bd_addr_t sco_event_addr;
|
||||
static uint8_t channel_nr = 0;
|
||||
|
||||
static uint16_t mtu;
|
||||
@ -91,7 +92,7 @@ static uint8_t ag_send_ok = 0;
|
||||
static uint8_t ag_send_error = 0;
|
||||
static uint8_t ag_num_button_press_received = 0;
|
||||
static uint8_t ag_support_custom_commands = 0;
|
||||
|
||||
static uint8_t ag_establish_eSCO = 0;
|
||||
static uint8_t hsp_disconnect_rfcomm = 0;
|
||||
static uint8_t hsp_establish_audio_connection = 0;
|
||||
static uint8_t hsp_release_audio_connection = 0;
|
||||
@ -380,6 +381,11 @@ void hsp_ag_stop_ringing(void){
|
||||
}
|
||||
|
||||
static void hsp_run(void){
|
||||
if (ag_establish_eSCO && hci_can_send_command_packet_now()){
|
||||
log_info("HSP: sending hci_accept_connection_request.");
|
||||
hci_send_cmd(&hci_accept_synchronous_connection, sco_event_addr, 8000, 8000, 0xFFFF, hci_get_sco_voice_setting(), 0xFF, 0x003F);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ag_send_ok){
|
||||
if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
|
||||
@ -557,28 +563,29 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
|
||||
uint16_t handle;
|
||||
|
||||
switch (event) {
|
||||
case HCI_EVENT_CONNECTION_REQUEST:
|
||||
printf("hsp HCI_EVENT_CONNECTION_REQUEST\n");
|
||||
hci_event_connection_request_get_bd_addr(packet, sco_event_addr);
|
||||
ag_establish_eSCO = 1;
|
||||
break;
|
||||
case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
|
||||
int index = 2;
|
||||
uint8_t status = packet[index++];
|
||||
sco_handle = little_endian_read_16(packet, index);
|
||||
index+=2;
|
||||
bd_addr_t address;
|
||||
memcpy(address, &packet[index], 6);
|
||||
index+=6;
|
||||
uint8_t link_type = packet[index++];
|
||||
uint8_t transmission_interval = packet[index++]; // measured in slots
|
||||
uint8_t retransmission_interval = packet[index++];// measured in slots
|
||||
uint16_t rx_packet_length = little_endian_read_16(packet, index); // measured in bytes
|
||||
index+=2;
|
||||
uint16_t tx_packet_length = little_endian_read_16(packet, index); // measured in bytes
|
||||
index+=2;
|
||||
uint8_t air_mode = packet[index];
|
||||
|
||||
ag_establish_eSCO = 0;
|
||||
uint8_t status = hci_event_synchronous_connection_complete_get_status(packet);
|
||||
if (status != 0){
|
||||
log_error("(e)SCO Connection failed, status %u", status);
|
||||
emit_event_audio_connected(status, sco_handle);
|
||||
break;
|
||||
}
|
||||
|
||||
hci_event_synchronous_connection_complete_get_bd_addr(packet, event_addr);
|
||||
sco_handle = hci_event_synchronous_connection_complete_get_handle(packet);
|
||||
uint8_t link_type = hci_event_synchronous_connection_complete_get_link_type(packet);
|
||||
uint8_t transmission_interval = hci_event_synchronous_connection_complete_get_transmission_interval(packet); // measured in slots
|
||||
uint8_t retransmission_interval = hci_event_synchronous_connection_complete_get_retransmission_interval(packet);// measured in slots
|
||||
uint16_t rx_packet_length = hci_event_synchronous_connection_complete_get_rx_packet_length(packet); // measured in bytes
|
||||
uint16_t tx_packet_length = hci_event_synchronous_connection_complete_get_tx_packet_length(packet); // measured in bytes
|
||||
uint8_t air_mode = hci_event_synchronous_connection_complete_get_air_mode(packet);
|
||||
|
||||
switch (link_type){
|
||||
case 0x00:
|
||||
log_info("SCO Connection established.");
|
||||
@ -596,7 +603,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
|
||||
}
|
||||
log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, "
|
||||
" rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)", sco_handle,
|
||||
bd_addr_to_str(address), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode);
|
||||
bd_addr_to_str(event_addr), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode);
|
||||
|
||||
if (hsp_state == HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){
|
||||
hsp_state = HSP_W2_DISCONNECT_SCO;
|
||||
|
18
src/hci.c
18
src/hci.c
@ -2544,21 +2544,11 @@ static void hci_run(void){
|
||||
hci_send_cmd(&hci_accept_connection_request, connection->address, 1);
|
||||
} else {
|
||||
// remote supported feature eSCO is set if link type is eSCO
|
||||
uint16_t max_latency;
|
||||
uint8_t retransmission_effort;
|
||||
uint16_t packet_types;
|
||||
// remote supported feature eSCO is set if link type is eSCO
|
||||
if (connection->remote_supported_feature_eSCO){
|
||||
// eSCO: S4 - max latency == transmission interval = 0x000c == 12 ms,
|
||||
max_latency = 0x000c;
|
||||
retransmission_effort = 0x02;
|
||||
packet_types = 0x388;
|
||||
} else {
|
||||
if (connection->remote_supported_feature_eSCO) return;
|
||||
// SCO: max latency, retransmission interval: N/A. any packet type
|
||||
max_latency = 0xffff;
|
||||
retransmission_effort = 0xff;
|
||||
packet_types = 0x003f;
|
||||
}
|
||||
uint16_t max_latency = 0xffff;
|
||||
uint8_t retransmission_effort = 0xff;
|
||||
uint16_t packet_types = 0x003f;
|
||||
hci_send_cmd(&hci_accept_synchronous_connection, connection->address, 8000, 8000, max_latency, hci_stack->sco_voice_setting, retransmission_effort, packet_types);
|
||||
}
|
||||
return;
|
||||
|
@ -212,6 +212,10 @@ int hci_send_cmd(const hci_cmd_t *cmd, ...){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hci_can_send_command_packet_now(void){
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void sdp_query_complete_response(uint8_t status){
|
||||
uint8_t event[3];
|
||||
event[0] = SDP_EVENT_QUERY_COMPLETE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user