Loading system/device/include/interop.h +6 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,12 @@ typedef enum { // Some A2DP Sink devices report SUCCESS to the AVDTP RECONFIGURE command, // but fail to play the reconfigured audio stream. INTEROP_DISABLE_AVDTP_RECONFIGURE, // Create dynamic blacklist to disable role switch. // Some car kits indicate that role switch is supported, but then reject // role switch attempts. After rejecting several role switch attempts, // such car kits will go into bad state. INTEROP_DYNAMIC_ROLE_SWITCH } interop_feature_t; // Check if a given |addr| matches a known interoperability workaround as Loading system/device/src/interop.cc +1 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,7 @@ static const char* interop_feature_string_(const interop_feature_t feature) { CASE_RETURN_STR(INTEROP_HID_PREF_CONN_SUP_TIMEOUT_3S) CASE_RETURN_STR(INTEROP_GATTC_NO_SERVICE_CHANGED_IND) CASE_RETURN_STR(INTEROP_DISABLE_AVDTP_RECONFIGURE) CASE_RETURN_STR(INTEROP_DYNAMIC_ROLE_SWITCH) } return "UNKNOWN"; Loading system/stack/btm/btm_acl.cc +58 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ #include "btm_int.h" #include "btu.h" #include "device/include/controller.h" #include "device/include/interop.h" #include "hcidefs.h" #include "hcimsgs.h" #include "l2c_int.h" Loading Loading @@ -224,6 +225,7 @@ void btm_acl_created(const RawAddress& bda, DEV_CLASS dc, BD_NAME bdn, p->conn_addr = *controller_get_interface()->get_address(); #endif p->switch_role_failed_attempts = 0; p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE; btm_pm_sm_alloc(xx); Loading Loading @@ -569,6 +571,12 @@ tBTM_STATUS BTM_SwitchRole(const RawAddress& remote_bd_addr, uint8_t new_role, return (BTM_BUSY); } if (interop_match_addr(INTEROP_DYNAMIC_ROLE_SWITCH, &remote_bd_addr)) { BTM_TRACE_DEBUG("%s, Device blacklisted under INTEROP_DYNAMIC_ROLE_SWITCH.", __func__); return BTM_DEV_BLACKLISTED; } status = BTM_ReadPowerMode(p->remote_addr, &pwr_mode); if (status != BTM_SUCCESS) return (status); Loading Loading @@ -1351,6 +1359,56 @@ void btm_process_clk_off_comp_evt(uint16_t hci_handle, uint16_t clock_offset) { if (xx < MAX_L2CAP_LINKS) btm_cb.acl_db[xx].clock_offset = clock_offset; } /******************************************************************************* * * Function btm_blacklist_role_change_device * * Description This function is used to blacklist the device if the role * switch fails for maximum number of times. It also removes * the device from the black list if the role switch succeeds. * * Input Parms bd_addr - remote BD addr * hci_status - role switch status * * Returns void * *******************************************************************************/ void btm_blacklist_role_change_device(const RawAddress& bd_addr, uint8_t hci_status) { tACL_CONN* p = btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR); tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (!p || !p_dev_rec) { return; } if (hci_status == HCI_SUCCESS) { p->switch_role_failed_attempts = 0; return; } /* check for carkits */ const uint32_t cod_audio_device = (BTM_COD_SERVICE_AUDIO | BTM_COD_MAJOR_AUDIO) << 8; const uint32_t cod = ((p_dev_rec->dev_class[0] << 16) | (p_dev_rec->dev_class[1] << 8) | p_dev_rec->dev_class[2]) & 0xffffff; if ((hci_status != HCI_SUCCESS) && ((p->switch_role_state == BTM_ACL_SWKEY_STATE_SWITCHING) || (p->switch_role_state == BTM_ACL_SWKEY_STATE_IN_PROGRESS)) && ((cod & cod_audio_device) == cod_audio_device) && (!interop_match_addr(INTEROP_DYNAMIC_ROLE_SWITCH, &bd_addr))) { p->switch_role_failed_attempts++; if (p->switch_role_failed_attempts == BTM_MAX_SW_ROLE_FAILED_ATTEMPTS) { BTM_TRACE_WARNING( "%s: Device %s blacklisted for role switching - " "multiple role switch failed attempts: %u", __func__, to_string(bd_addr).c_str(), p->switch_role_failed_attempts); interop_database_add(INTEROP_DYNAMIC_ROLE_SWITCH, &bd_addr, 3); } } } /******************************************************************************* * * Function btm_acl_role_changed Loading system/stack/btm/btm_int.h +2 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,8 @@ extern void btm_process_clk_off_comp_evt(uint16_t hci_handle, uint16_t clock_offset); extern void btm_acl_role_changed(uint8_t hci_status, const RawAddress* bd_addr, uint8_t new_role); extern void btm_blacklist_role_change_device(const RawAddress& bd_addr, uint8_t hci_status); extern void btm_acl_encrypt_change(uint16_t handle, uint8_t status, uint8_t encr_enable); extern uint16_t btm_get_acl_disc_reason_code(void); Loading system/stack/btm/btm_int_types.h +3 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,9 @@ typedef struct { #define BTM_ACL_SWKEY_STATE_IN_PROGRESS 5 uint8_t switch_role_state; #define BTM_MAX_SW_ROLE_FAILED_ATTEMPTS 3 uint8_t switch_role_failed_attempts; #define BTM_ACL_ENCRYPT_STATE_IDLE 0 #define BTM_ACL_ENCRYPT_STATE_ENCRYPT_OFF 1 /* encryption turning off */ #define BTM_ACL_ENCRYPT_STATE_TEMP_FUNC \ Loading Loading
system/device/include/interop.h +6 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,12 @@ typedef enum { // Some A2DP Sink devices report SUCCESS to the AVDTP RECONFIGURE command, // but fail to play the reconfigured audio stream. INTEROP_DISABLE_AVDTP_RECONFIGURE, // Create dynamic blacklist to disable role switch. // Some car kits indicate that role switch is supported, but then reject // role switch attempts. After rejecting several role switch attempts, // such car kits will go into bad state. INTEROP_DYNAMIC_ROLE_SWITCH } interop_feature_t; // Check if a given |addr| matches a known interoperability workaround as Loading
system/device/src/interop.cc +1 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,7 @@ static const char* interop_feature_string_(const interop_feature_t feature) { CASE_RETURN_STR(INTEROP_HID_PREF_CONN_SUP_TIMEOUT_3S) CASE_RETURN_STR(INTEROP_GATTC_NO_SERVICE_CHANGED_IND) CASE_RETURN_STR(INTEROP_DISABLE_AVDTP_RECONFIGURE) CASE_RETURN_STR(INTEROP_DYNAMIC_ROLE_SWITCH) } return "UNKNOWN"; Loading
system/stack/btm/btm_acl.cc +58 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ #include "btm_int.h" #include "btu.h" #include "device/include/controller.h" #include "device/include/interop.h" #include "hcidefs.h" #include "hcimsgs.h" #include "l2c_int.h" Loading Loading @@ -224,6 +225,7 @@ void btm_acl_created(const RawAddress& bda, DEV_CLASS dc, BD_NAME bdn, p->conn_addr = *controller_get_interface()->get_address(); #endif p->switch_role_failed_attempts = 0; p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE; btm_pm_sm_alloc(xx); Loading Loading @@ -569,6 +571,12 @@ tBTM_STATUS BTM_SwitchRole(const RawAddress& remote_bd_addr, uint8_t new_role, return (BTM_BUSY); } if (interop_match_addr(INTEROP_DYNAMIC_ROLE_SWITCH, &remote_bd_addr)) { BTM_TRACE_DEBUG("%s, Device blacklisted under INTEROP_DYNAMIC_ROLE_SWITCH.", __func__); return BTM_DEV_BLACKLISTED; } status = BTM_ReadPowerMode(p->remote_addr, &pwr_mode); if (status != BTM_SUCCESS) return (status); Loading Loading @@ -1351,6 +1359,56 @@ void btm_process_clk_off_comp_evt(uint16_t hci_handle, uint16_t clock_offset) { if (xx < MAX_L2CAP_LINKS) btm_cb.acl_db[xx].clock_offset = clock_offset; } /******************************************************************************* * * Function btm_blacklist_role_change_device * * Description This function is used to blacklist the device if the role * switch fails for maximum number of times. It also removes * the device from the black list if the role switch succeeds. * * Input Parms bd_addr - remote BD addr * hci_status - role switch status * * Returns void * *******************************************************************************/ void btm_blacklist_role_change_device(const RawAddress& bd_addr, uint8_t hci_status) { tACL_CONN* p = btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR); tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (!p || !p_dev_rec) { return; } if (hci_status == HCI_SUCCESS) { p->switch_role_failed_attempts = 0; return; } /* check for carkits */ const uint32_t cod_audio_device = (BTM_COD_SERVICE_AUDIO | BTM_COD_MAJOR_AUDIO) << 8; const uint32_t cod = ((p_dev_rec->dev_class[0] << 16) | (p_dev_rec->dev_class[1] << 8) | p_dev_rec->dev_class[2]) & 0xffffff; if ((hci_status != HCI_SUCCESS) && ((p->switch_role_state == BTM_ACL_SWKEY_STATE_SWITCHING) || (p->switch_role_state == BTM_ACL_SWKEY_STATE_IN_PROGRESS)) && ((cod & cod_audio_device) == cod_audio_device) && (!interop_match_addr(INTEROP_DYNAMIC_ROLE_SWITCH, &bd_addr))) { p->switch_role_failed_attempts++; if (p->switch_role_failed_attempts == BTM_MAX_SW_ROLE_FAILED_ATTEMPTS) { BTM_TRACE_WARNING( "%s: Device %s blacklisted for role switching - " "multiple role switch failed attempts: %u", __func__, to_string(bd_addr).c_str(), p->switch_role_failed_attempts); interop_database_add(INTEROP_DYNAMIC_ROLE_SWITCH, &bd_addr, 3); } } } /******************************************************************************* * * Function btm_acl_role_changed Loading
system/stack/btm/btm_int.h +2 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,8 @@ extern void btm_process_clk_off_comp_evt(uint16_t hci_handle, uint16_t clock_offset); extern void btm_acl_role_changed(uint8_t hci_status, const RawAddress* bd_addr, uint8_t new_role); extern void btm_blacklist_role_change_device(const RawAddress& bd_addr, uint8_t hci_status); extern void btm_acl_encrypt_change(uint16_t handle, uint8_t status, uint8_t encr_enable); extern uint16_t btm_get_acl_disc_reason_code(void); Loading
system/stack/btm/btm_int_types.h +3 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,9 @@ typedef struct { #define BTM_ACL_SWKEY_STATE_IN_PROGRESS 5 uint8_t switch_role_state; #define BTM_MAX_SW_ROLE_FAILED_ATTEMPTS 3 uint8_t switch_role_failed_attempts; #define BTM_ACL_ENCRYPT_STATE_IDLE 0 #define BTM_ACL_ENCRYPT_STATE_ENCRYPT_OFF 1 /* encryption turning off */ #define BTM_ACL_ENCRYPT_STATE_TEMP_FUNC \ Loading