diff options
Diffstat (limited to 'bta/dm/bta_dm_act.c')
-rwxr-xr-x | bta/dm/bta_dm_act.c | 94 |
1 files changed, 89 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); + } } } |