Unable to connect to a Motorola s705 until Bluetooth was toggled of and back on

we should use the same role as the previous connection, if phone walk out of range,
and reconnect back from remote device.
bug:10648781

Change-Id: I6abd77067d26769067ba2fbd45d9e8f75cf7c764
diff --git a/stack/btm/btm_acl.c b/stack/btm/btm_acl.c
index ea1c68e..8310ae1 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
@@ -2194,7 +2242,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 42bd3ad..c74c294 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        | \
@@ -892,6 +896,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;
 }