summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGanesh Ganapathi Batta <ganeshg@broadcom.com>2012-08-23 18:04:49 -0700
committerMatthew Xie <mattx@google.com>2012-08-24 14:09:03 -0700
commite9d957443d3e5d7427c5d09a306e2b5e99d26201 (patch)
tree749e154e4c3bcdb36aed8adbb6d0d4f408ab09b6
parent30cd3fe33a8735c0b6096a1ff9470f6b0e62b5f1 (diff)
downloadexternal_bluetooth_bluedroid-e9d957443d3e5d7427c5d09a306e2b5e99d26201.zip
external_bluetooth_bluedroid-e9d957443d3e5d7427c5d09a306e2b5e99d26201.tar.gz
external_bluetooth_bluedroid-e9d957443d3e5d7427c5d09a306e2b5e99d26201.tar.bz2
Delay the role switch after the connection with devices that are blacklisted for immediate role switch
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 Bug 6992300 Change-Id: I71c7d94bc4cf03f2383b6c1956bba8697f6c2a8b
-rwxr-xr-xbta/dm/bta_dm_act.c94
-rwxr-xr-x[-rw-r--r--]bta/dm/bta_dm_int.h8
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;