mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-24 15:02:43 +00:00
hfp: handle command status error when opening sco connection
This commit is contained in:
parent
473ac565d5
commit
eddcd3084a
@ -99,6 +99,8 @@ static void parse_sequence(hfp_connection_t * context);
|
|||||||
static hfp_callback_t hfp_callback;
|
static hfp_callback_t hfp_callback;
|
||||||
static btstack_packet_handler_t rfcomm_packet_handler;
|
static btstack_packet_handler_t rfcomm_packet_handler;
|
||||||
|
|
||||||
|
static hfp_connection_t * sco_establishment_active;
|
||||||
|
|
||||||
void hfp_set_callback(hfp_callback_t callback){
|
void hfp_set_callback(hfp_callback_t callback){
|
||||||
hfp_callback = callback;
|
hfp_callback = callback;
|
||||||
}
|
}
|
||||||
@ -438,13 +440,48 @@ static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hfp_handle_failed_sco_connection(uint8_t status){
|
||||||
|
|
||||||
|
if (!sco_establishment_active){
|
||||||
|
log_error("(e)SCO Connection failed but not started by us");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log_error("(e)SCO Connection failed status %u", status);
|
||||||
|
|
||||||
|
// invalid params / unspecified error
|
||||||
|
if (status != 0x11 && status != 0x1f) return;
|
||||||
|
|
||||||
|
switch (sco_establishment_active->link_setting){
|
||||||
|
case HFP_LINK_SETTINGS_D0:
|
||||||
|
return; // no other option left
|
||||||
|
case HFP_LINK_SETTINGS_D1:
|
||||||
|
sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D0;
|
||||||
|
break;
|
||||||
|
case HFP_LINK_SETTINGS_S1:
|
||||||
|
sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D1;
|
||||||
|
break;
|
||||||
|
case HFP_LINK_SETTINGS_S2:
|
||||||
|
case HFP_LINK_SETTINGS_S3:
|
||||||
|
case HFP_LINK_SETTINGS_S4:
|
||||||
|
sco_establishment_active->link_setting = HFP_LINK_SETTINGS_S1;
|
||||||
|
break;
|
||||||
|
case HFP_LINK_SETTINGS_T1:
|
||||||
|
case HFP_LINK_SETTINGS_T2:
|
||||||
|
sco_establishment_active->link_setting = HFP_LINK_SETTINGS_S3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sco_establishment_active->establish_audio_connection = 1;
|
||||||
|
sco_establishment_active = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||||
bd_addr_t event_addr;
|
bd_addr_t event_addr;
|
||||||
uint16_t rfcomm_cid, handle;
|
uint16_t rfcomm_cid, handle;
|
||||||
hfp_connection_t * hfp_connection = NULL;
|
hfp_connection_t * hfp_connection = NULL;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
|
|
||||||
// printf("AG packet_handler type %u, event type %x, size %u\n", packet_type, hci_event_packet_get_type(packet), size);
|
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)) {
|
switch (hci_event_packet_get_type(packet)) {
|
||||||
|
|
||||||
@ -494,6 +531,12 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case HCI_EVENT_COMMAND_STATUS:
|
||||||
|
if (hci_event_command_status_get_command_opcode(packet) == hci_setup_synchronous_connection.opcode) {
|
||||||
|
hfp_handle_failed_sco_connection(hci_event_command_status_get_status(packet));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
|
case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
|
||||||
|
|
||||||
reverse_bd_addr(&packet[5], event_addr);
|
reverse_bd_addr(&packet[5], event_addr);
|
||||||
@ -501,32 +544,7 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
|||||||
status = packet[index++];
|
status = packet[index++];
|
||||||
|
|
||||||
if (status != 0){
|
if (status != 0){
|
||||||
log_error("(e)SCO Connection failed status %u", status);
|
hfp_handle_failed_sco_connection(status);
|
||||||
// if outgoing && link_setting != d0 && appropriate error
|
|
||||||
if (status != 0x11 && status != 0x1f) break; // invalid params / unspecified error
|
|
||||||
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
|
|
||||||
if (!hfp_connection) break;
|
|
||||||
switch (hfp_connection->link_setting){
|
|
||||||
case HFP_LINK_SETTINGS_D0:
|
|
||||||
return; // no other option left
|
|
||||||
case HFP_LINK_SETTINGS_D1:
|
|
||||||
// hfp_connection->link_setting = HFP_LINK_SETTINGS_D0;
|
|
||||||
// break;
|
|
||||||
case HFP_LINK_SETTINGS_S1:
|
|
||||||
// hfp_connection->link_setting = HFP_LINK_SETTINGS_D1;
|
|
||||||
// break;
|
|
||||||
case HFP_LINK_SETTINGS_S2:
|
|
||||||
case HFP_LINK_SETTINGS_S3:
|
|
||||||
case HFP_LINK_SETTINGS_S4:
|
|
||||||
// hfp_connection->link_setting = HFP_LINK_SETTINGS_S1;
|
|
||||||
// break;
|
|
||||||
case HFP_LINK_SETTINGS_T1:
|
|
||||||
case HFP_LINK_SETTINGS_T2:
|
|
||||||
// hfp_connection->link_setting = HFP_LINK_SETTINGS_S3;
|
|
||||||
hfp_connection->link_setting = HFP_LINK_SETTINGS_D0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
hfp_connection->establish_audio_connection = 1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1332,10 +1350,12 @@ static const struct link_settings {
|
|||||||
{ 0x000d, 0x02, 0x0380 } // HFP_LINK_SETTINGS_T2, 2-EV3
|
{ 0x000d, 0x02, 0x0380 } // HFP_LINK_SETTINGS_T2, 2-EV3
|
||||||
};
|
};
|
||||||
|
|
||||||
void hfp_setup_synchronous_connection(hci_con_handle_t handle, hfp_link_setttings_t setting){
|
void hfp_setup_synchronous_connection(hfp_connection_t * hfp_connection){
|
||||||
// all packet types, fixed bandwidth
|
// all packet types, fixed bandwidth
|
||||||
|
int setting = hfp_connection->link_setting;
|
||||||
log_info("hfp_setup_synchronous_connection using setting nr %u", setting);
|
log_info("hfp_setup_synchronous_connection using setting nr %u", setting);
|
||||||
hci_send_cmd(&hci_setup_synchronous_connection, handle, 8000, 8000, hfp_link_settings[setting].max_latency,
|
sco_establishment_active = hfp_connection;
|
||||||
|
hci_send_cmd(&hci_setup_synchronous_connection, hfp_connection->acl_handle, 8000, 8000, hfp_link_settings[setting].max_latency,
|
||||||
hci_get_sco_voice_setting(), hfp_link_settings[setting].retransmission_effort, hfp_link_settings[setting].packet_types); // all types 0x003f, only 2-ev3 0x380
|
hci_get_sco_voice_setting(), hfp_link_settings[setting].retransmission_effort, hfp_link_settings[setting].packet_types); // all types 0x003f, only 2-ev3 0x380
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,7 +645,7 @@ void hfp_reset_context_flags(hfp_connection_t * connection);
|
|||||||
|
|
||||||
void hfp_release_audio_connection(hfp_connection_t * connection);
|
void hfp_release_audio_connection(hfp_connection_t * connection);
|
||||||
|
|
||||||
void hfp_setup_synchronous_connection(hci_con_handle_t handle, hfp_link_setttings_t link_settings);
|
void hfp_setup_synchronous_connection(hfp_connection_t * connection);
|
||||||
|
|
||||||
const char * hfp_hf_feature(int index);
|
const char * hfp_hf_feature(int index);
|
||||||
const char * hfp_ag_feature(int index);
|
const char * hfp_ag_feature(int index);
|
||||||
|
@ -812,7 +812,7 @@ static int hfp_ag_run_for_audio_connection(hfp_connection_t * hfp_connection){
|
|||||||
if (hfp_connection->establish_audio_connection){
|
if (hfp_connection->establish_audio_connection){
|
||||||
hfp_connection->state = HFP_W4_SCO_CONNECTED;
|
hfp_connection->state = HFP_W4_SCO_CONNECTED;
|
||||||
hfp_connection->establish_audio_connection = 0;
|
hfp_connection->establish_audio_connection = 0;
|
||||||
hfp_setup_synchronous_connection(hfp_connection->acl_handle, hfp_connection->link_setting);
|
hfp_setup_synchronous_connection(hfp_connection);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user