diff options
-rwxr-xr-x | bta/dm/bta_dm_act.c | 94 | ||||
-rwxr-xr-x[-rw-r--r--] | bta/dm/bta_dm_int.h | 8 |
2 files changed, 97 insertions, 5 deletions
diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c index 8f88573..c087dc8 100755 --- a/bta/dm/bta_dm_act.c +++ b/bta/dm/bta_dm_act.c @@ -67,7 +67,7 @@ static void bta_dm_search_timer_cback (TIMER_LIST_ENT *p_tle); static void bta_dm_disable_timer_cback (TIMER_LIST_ENT *p_tle); static void bta_dm_disable_conn_down_timer_cback (TIMER_LIST_ENT *p_tle); static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr); -static void bta_dm_adjust_roles(void); +static void bta_dm_adjust_roles(BOOLEAN delay_role_switch); static char *bta_dm_get_remname(void); static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result); @@ -76,6 +76,10 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr); static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status ); +static BOOLEAN bta_dm_dev_blacklisted_for_switch (BD_ADDR remote_bd_addr); +static void bta_dm_delay_role_switch_cback (TIMER_LIST_ENT *p_tle); + + #if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) #if ((defined SMP_INCLUDED) && (SMP_INCLUDED == TRUE)) static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data); @@ -193,6 +197,17 @@ const tBTM_APPL_INFO bta_security = }; +/* TBD... To be moved to some conf file..? */ +#define BTA_DM_MAX_ROLE_SWITCH_BLACKLIST_COUNT 5 +const tBTA_DM_LMP_VER_INFO bta_role_switch_blacklist[BTA_DM_MAX_ROLE_SWITCH_BLACKLIST_COUNT] = +{ + {0x000F,0x2000,0x04}, + {0x00,0x00,0x00}, + {0x00,0x00,0x00}, + {0x00,0x00,0x00}, + {0x00,0x00,0x00} +}; + #define MAX_DISC_RAW_DATA_BUF (4096) UINT8 g_disc_raw_data_buf[MAX_DISC_RAW_DATA_BUF]; @@ -3318,7 +3333,7 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data) } } - bta_dm_adjust_roles(); + bta_dm_adjust_roles(TRUE); } /******************************************************************************* @@ -3471,12 +3486,64 @@ static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, } - bta_dm_adjust_roles(); + bta_dm_adjust_roles(FALSE); } /******************************************************************************* ** +** Function bta_dm_dev_blacklisted_for_switch +** +** Description Checks if the device is blacklisted for immediate role switch after connection. +** +** Returns TRUE if dev is blacklisted else FALSE +** +*******************************************************************************/ +static BOOLEAN bta_dm_dev_blacklisted_for_switch (BD_ADDR remote_bd_addr) +{ + UINT16 manufacturer = 0; + UINT16 lmp_sub_version = 0; + UINT8 lmp_version = 0; + UINT8 i = 0; + + if (BTM_ReadRemoteVersion(remote_bd_addr, &lmp_version, + &manufacturer, &lmp_sub_version) == BTM_SUCCESS) + { + /* Check if this device version info matches with is + blacklisted versions for role switch */ + for (i = 0; i < BTA_DM_MAX_ROLE_SWITCH_BLACKLIST_COUNT; i++) + { + if ((bta_role_switch_blacklist[i].lmp_version == lmp_version) && + (bta_role_switch_blacklist[i].manufacturer == manufacturer)&& + ((bta_role_switch_blacklist[i].lmp_sub_version & lmp_sub_version) == + bta_role_switch_blacklist[i].lmp_sub_version)) + { + APPL_TRACE_EVENT0("Black list F/W version matches.. Delay Role Switch..."); + return TRUE; + } + + } + } + return FALSE; +} + +/******************************************************************************* +** +** Function bta_dm_delay_role_switch_cback +** +** Description Callback from btm to delay a role switch +** +** Returns void +** +*******************************************************************************/ +static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle) +{ + APPL_TRACE_EVENT0("bta_dm_delay_role_switch_cback: initiating Delayed RS"); + bta_dm_adjust_roles (FALSE); +} + +/******************************************************************************* +** ** Function bta_dm_adjust_roles ** ** Description Adjust roles @@ -3485,7 +3552,7 @@ static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, ** Returns void ** *******************************************************************************/ -static void bta_dm_adjust_roles(void) +static void bta_dm_adjust_roles(BOOLEAN delay_role_switch) { UINT8 i; @@ -3520,8 +3587,25 @@ static void bta_dm_adjust_roles(void) || (bta_dm_cb.device_list.count > 1)) { - BTM_SwitchRole (bta_dm_cb.device_list.peer_device[i].peer_bdaddr, HCI_ROLE_MASTER, NULL); + /* Initiating immediate role switch with certain remote devices + has caused issues due to role switch colliding with link encryption setup and + causing encryption (and in turn the link) to fail . These device . Firmware + versions are stored in a blacklist and role switch with these devices are + delayed to avoid the collision with link encryption setup */ + if ((delay_role_switch == FALSE) || + (bta_dm_dev_blacklisted_for_switch( + bta_dm_cb.device_list.peer_device[i].peer_bdaddr) == FALSE)) + { + BTM_SwitchRole (bta_dm_cb.device_list.peer_device[i].peer_bdaddr, + HCI_ROLE_MASTER, NULL); + } + else + { + bta_dm_cb.switch_delay_timer.p_cback = + (TIMER_CBACK*)&bta_dm_delay_role_switch_cback; + bta_sys_start_timer(&bta_dm_cb.switch_delay_timer, 0, 500); + } } } diff --git a/bta/dm/bta_dm_int.h b/bta/dm/bta_dm_int.h index 6d220e7..0d8dc6a 100644..100755 --- a/bta/dm/bta_dm_int.h +++ b/bta/dm/bta_dm_int.h @@ -705,6 +705,7 @@ typedef struct tBTA_DM_ENCRYPT_CBACK *p_encrypt_cback; tBTA_DM_BLE_SEC_ACT sec_act; + TIMER_LIST_ENT switch_delay_timer; } tBTA_DM_CB; @@ -838,6 +839,13 @@ typedef struct UINT16 min_loc_to; } tBTA_DM_SSR_SPEC; +typedef struct +{ + UINT16 manufacturer; + UINT16 lmp_sub_version; + UINT8 lmp_version; +}tBTA_DM_LMP_VER_INFO; + extern tBTA_DM_PM_CFG *p_bta_dm_pm_cfg; extern tBTA_DM_PM_SPEC *p_bta_dm_pm_spec; extern tBTM_PM_PWR_MD *p_bta_dm_pm_md; |