Merge "Unable to connect to a Motorola s705 until Bluetooth was toggled of and back on" into klp-dev
diff --git a/stack/btm/btm_acl.c b/stack/btm/btm_acl.c
index ef552a6..629c8b4 100644
--- a/stack/btm/btm_acl.c
+++ b/stack/btm/btm_acl.c
@@ -49,6 +49,52 @@
/*******************************************************************************
**
+** Function btm_save_remote_device_role
+**
+** Description This function is to save remote device role
+**
+** Returns void
+**
+*******************************************************************************/
+static void btm_save_remote_device_role(BD_ADDR bd_addr, UINT8 role)
+{
+ UINT8 i, j;
+ if (role == BTM_ROLE_UNDEFINED) return;
+
+ for (i = 0; i < BTM_ROLE_DEVICE_NUM; i++) {
+ if ((btm_cb.previous_connected_role[i] != BTM_ROLE_UNDEFINED) &&
+ (!bdcmp(bd_addr, btm_cb.previous_connected_remote_addr[i]))) {
+ break;
+ }
+ }
+
+ if (i < BTM_ROLE_DEVICE_NUM) {
+ UINT8 end;
+ if (i < btm_cb.front) {
+ for (j = i; j > 0; j--) {
+ bdcpy(btm_cb.previous_connected_remote_addr[j],
+ btm_cb.previous_connected_remote_addr[j-1]);
+ }
+ bdcpy(btm_cb.previous_connected_remote_addr[0],
+ btm_cb.previous_connected_remote_addr[BTM_ROLE_DEVICE_NUM-1]);
+ end = BTM_ROLE_DEVICE_NUM-1;
+ } else {
+ end = i;
+ }
+
+ for (j = end; j > btm_cb.front; j--) {
+ bdcpy(btm_cb.previous_connected_remote_addr[j],
+ btm_cb.previous_connected_remote_addr[j-1]);
+ }
+ }
+
+ bdcpy(btm_cb.previous_connected_remote_addr[btm_cb.front], bd_addr);
+ btm_cb.previous_connected_role[btm_cb.front] = role;
+ btm_cb.front = (btm_cb.front + 1) % BTM_ROLE_DEVICE_NUM;
+}
+
+/*******************************************************************************
+**
** Function btm_acl_init
**
** Description This function is called at BTM startup to initialize
@@ -158,6 +204,7 @@
{
p->hci_handle = hci_handle;
p->link_role = link_role;
+ btm_save_remote_device_role(bda, link_role);
#if BLE_INCLUDED == TRUE
p->is_le_link = is_le_link;
#endif
@@ -175,6 +222,7 @@
p->in_use = TRUE;
p->hci_handle = hci_handle;
p->link_role = link_role;
+ btm_save_remote_device_role(bda, link_role);
p->link_up_issued = FALSE;
#if BLE_INCLUDED == TRUE
@@ -2196,7 +2244,7 @@
/* Update cached value */
p->link_role = new_role;
-
+ btm_save_remote_device_role(p_bda, new_role);
/* Reload LSTO: link supervision timeout is reset in the LM after a role switch */
if (new_role == BTM_ROLE_MASTER)
{
diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h
index 2f9b232..16a02e6 100644
--- a/stack/btm/btm_int.h
+++ b/stack/btm/btm_int.h
@@ -52,6 +52,10 @@
*/
#define BTM_MAX_SCN PORT_MAX_RFC_PORTS
+/* Definition for number of the remote device role saved
+*/
+#define BTM_ROLE_DEVICE_NUM 4
+
/* Define masks for supported and exception 2.0 ACL packet types
*/
#define BTM_ACL_SUPPORTED_PKTS_MASK (HCI_PKT_TYPES_MASK_DM1 | \
@@ -895,6 +899,9 @@
tBTM_PCM2_ACTION pcm2_action;
#endif
+ BD_ADDR previous_connected_remote_addr[BTM_ROLE_DEVICE_NUM];
+ UINT8 previous_connected_role[BTM_ROLE_DEVICE_NUM];
+ UINT8 front; /* front index of the role table */
} tBTM_CB;
diff --git a/stack/btm/btm_main.c b/stack/btm/btm_main.c
index f3037f6..869899d 100644
--- a/stack/btm/btm_main.c
+++ b/stack/btm/btm_main.c
@@ -48,6 +48,7 @@
*******************************************************************************/
void btm_init (void)
{
+ UINT8 i;
/* All fields are cleared; nonzero fields are reinitialized in appropriate function */
memset(&btm_cb, 0, sizeof(tBTM_CB));
@@ -56,6 +57,9 @@
#else
btm_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
#endif
+ for (i = 0; i < BTM_ROLE_DEVICE_NUM; i++) {
+ btm_cb.previous_connected_role[i] = BTM_ROLE_UNDEFINED;
+ }
/* Initialize BTM component structures */
btm_inq_db_init(); /* Inquiry Database and Structures */
btm_acl_init(); /* ACL Database and Structures */
diff --git a/stack/l2cap/l2c_int.h b/stack/l2cap/l2c_int.h
index f4eb008..a17c583 100644
--- a/stack/l2cap/l2c_int.h
+++ b/stack/l2cap/l2c_int.h
@@ -585,7 +585,7 @@
extern tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle);
extern void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding);
-extern UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb);
+extern UINT8 l2cu_get_conn_role (BD_ADDR bd_addr);
extern BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_after_rs);
extern void l2cu_enqueue_ccb (tL2C_CCB *p_ccb);
diff --git a/stack/l2cap/l2c_link.c b/stack/l2cap/l2c_link.c
index 1974bb2..ca563d9 100644
--- a/stack/l2cap/l2c_link.c
+++ b/stack/l2cap/l2c_link.c
@@ -98,7 +98,7 @@
if (!btm_dev_support_switch (bd_addr))
p_lcb->link_role = HCI_ROLE_SLAVE;
else
- p_lcb->link_role = l2cu_get_conn_role(p_lcb);
+ p_lcb->link_role = l2cu_get_conn_role(bd_addr);
}
/* Tell the other side we accept the connection */
@@ -119,7 +119,7 @@
if (!btm_dev_support_switch (bd_addr))
p_lcb->link_role = HCI_ROLE_SLAVE;
else
- p_lcb->link_role = l2cu_get_conn_role(p_lcb);
+ p_lcb->link_role = l2cu_get_conn_role(bd_addr);
btsnd_hcic_accept_conn (bd_addr, p_lcb->link_role);
diff --git a/stack/l2cap/l2c_utils.c b/stack/l2cap/l2c_utils.c
index 457ea2d..1add2b6 100644
--- a/stack/l2cap/l2c_utils.c
+++ b/stack/l2cap/l2c_utils.c
@@ -252,6 +252,8 @@
** Function l2cu_get_conn_role
**
** Description Determine the desired role (master or slave) of a link.
+** If it is the previous connected remote device, use the same
+** role as previous used role.
** If already got a slave link, this one must be a master. If
** already got at least 1 link where we are the master, make this
** also a master.
@@ -259,8 +261,17 @@
** Returns HCI_ROLE_MASTER or HCI_ROLE_SLAVE
**
*******************************************************************************/
-UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb)
+UINT8 l2cu_get_conn_role (BD_ADDR bd_addr)
{
+ UINT8 i;
+ for (i = 0; i < BTM_ROLE_DEVICE_NUM; i++) {
+ if ((btm_cb.previous_connected_role[i] != BTM_ROLE_UNDEFINED) &&
+ (!bdcmp(bd_addr, btm_cb.previous_connected_remote_addr[i]))) {
+ L2CAP_TRACE_WARNING1 ("l2cu_get_conn_role %d",
+ btm_cb.previous_connected_role[i]);
+ return btm_cb.previous_connected_role[i];
+ }
+ }
return l2cb.desire_role;
}