Merge "support resolve BLE random mac address for both central and peripheral mode." into klp-modular-dev
diff --git a/include/bt_target.h b/include/bt_target.h
index 23e4fdb..8950207 100644
--- a/include/bt_target.h
+++ b/include/bt_target.h
@@ -1407,6 +1407,10 @@
 #define LOCAL_BLE_CONTROLLER_ID         (1)
 #endif
 
+#ifndef BTM_BLE_PRIVACY_SPT
+#define BTM_BLE_PRIVACY_SPT      TRUE
+#endif
+
 /******************************************************************************
 **
 ** ATT/GATT Protocol/Profile Settings
diff --git a/stack/btm/btm_acl.c b/stack/btm/btm_acl.c
index 68ac35f..0a4ed1a 100644
--- a/stack/btm/btm_acl.c
+++ b/stack/btm/btm_acl.c
@@ -179,6 +179,59 @@
     /* If here, no BD Addr found */
     return(xx);
 }
+
+#if BTM_BLE_PRIVACY_SPT == TRUE
+/*******************************************************************************
+**
+** Function         btm_ble_get_acl_remote_addr
+**
+** Description      This function reads the active remote address used for the
+**                  connection.
+**
+** Returns          success return TRUE, otherwise FALSE.
+**
+*******************************************************************************/
+BOOLEAN btm_ble_get_acl_remote_addr(tBTM_SEC_DEV_REC *p_dev_rec, BD_ADDR conn_addr,
+                                    tBLE_ADDR_TYPE *p_addr_type)
+{
+#if BLE_INCLUDED == TRUE
+    BOOLEAN         st = TRUE;
+
+    if (p_dev_rec == NULL)
+    {
+        BTM_TRACE_ERROR0("btm_ble_get_acl_remote_addr can not find device with matching address");
+        return FALSE;
+    }
+
+    switch (p_dev_rec->ble.active_addr_type)
+    {
+    case BTM_BLE_ADDR_PSEUDO:
+        memcpy(conn_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
+        * p_addr_type = p_dev_rec->ble.ble_addr_type;
+        break;
+
+    case BTM_BLE_ADDR_RRA:
+        memcpy(conn_addr, p_dev_rec->ble.cur_rand_addr, BD_ADDR_LEN);
+        * p_addr_type = BLE_ADDR_RANDOM;
+        break;
+
+    case BTM_BLE_ADDR_STATIC:
+        memcpy(conn_addr, p_dev_rec->ble.static_addr, BD_ADDR_LEN);
+        * p_addr_type = p_dev_rec->ble.static_addr_type;
+        break;
+
+    default:
+        BTM_TRACE_ERROR1("Unknown active address: %d", p_dev_rec->ble.active_addr_type);
+        st = FALSE;
+        break;
+    }
+
+    return st;
+#else
+    return FALSE;
+#endif
+}
+#endif
 /*******************************************************************************
 **
 ** Function         btm_acl_created
@@ -298,6 +351,10 @@
             /* If here, features are not known yet */
             if (p_dev_rec && is_le_link)
             {
+#if BTM_BLE_PRIVACY_SPT == TRUE
+                btm_ble_get_acl_remote_addr (p_dev_rec, p->active_remote_addr,
+                    &p->active_remote_addr_type);
+#endif
                 btm_establish_continue(p);
 
 #if (!defined(BTA_SKIP_BLE_READ_REMOTE_FEAT) || BTA_SKIP_BLE_READ_REMOTE_FEAT == FALSE)
diff --git a/stack/btm/btm_ble.c b/stack/btm/btm_ble.c
index 5e54499..5b61b76 100644
--- a/stack/btm/btm_ble.c
+++ b/stack/btm/btm_ble.c
@@ -35,6 +35,9 @@
 #include "btm_ble_api.h"
 #include "smp_api.h"
 #include "l2c_int.h"
+#if (defined BLE_BRCM_INCLUDED && BLE_BRCM_INCLUDED == TRUE)
+#include "brcm_ble.h"
+#endif
 #include "gap_api.h"
 #include "bt_utils.h"
 
@@ -341,12 +344,24 @@
 {
     BOOLEAN         st = TRUE;
     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_addr);
+#if BTM_BLE_PRIVACY_SPT == TRUE
+    tACL_CONN       *p = btm_bda_to_acl (pseudo_addr);
 
+    if (p == NULL)
+    {
+        BTM_TRACE_ERROR0("BTM_ReadRemoteConnectionAddr can not find matching address");
+        return FALSE;
+    }
+
+    memcpy(conn_addr, p->active_remote_addr, BD_ADDR_LEN);
+    *p_addr_type = p->active_remote_addr_type;
+#else
     memcpy(conn_addr, pseudo_addr, BD_ADDR_LEN);
     if (p_dev_rec != NULL)
     {
         *p_addr_type = p_dev_rec->ble.ble_addr_type;
     }
+#endif
     return st;
 }
 /*******************************************************************************
@@ -1462,6 +1477,61 @@
     return callback_rc;
 }
 
+#if (BTM_BLE_PRIVACY_SPT == TRUE )
+/*******************************************************************************
+**
+** Function         btm_ble_resolve_random_addr_on_conn_cmpl
+**
+** Description      resolve random address complete on connection complete event.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void btm_ble_resolve_random_addr_on_conn_cmpl(void * p_rec, void *p_data)
+{
+    UINT8   *p = (UINT8 *)p_data;
+    tBTM_SEC_DEV_REC    *match_rec = (tBTM_SEC_DEV_REC *) p_rec;
+    UINT8       role, status, bda_type;
+    UINT16      handle;
+    BD_ADDR     bda;
+    UINT16      conn_interval, conn_latency, conn_timeout;
+    BOOLEAN     match = FALSE;
+
+    STREAM_TO_UINT8   (status, p);
+    STREAM_TO_UINT16   (handle, p);
+    STREAM_TO_UINT8    (role, p);
+    STREAM_TO_UINT8    (bda_type, p);
+    STREAM_TO_BDADDR   (bda, p);
+    STREAM_TO_UINT16   (conn_interval, p);
+    STREAM_TO_UINT16   (conn_latency, p);
+    STREAM_TO_UINT16   (conn_timeout, p);
+
+    handle = HCID_GET_HANDLE (handle);
+
+    BTM_TRACE_EVENT0 ("btm_ble_resolve_random_addr_master_cmpl");
+
+    if (match_rec)
+    {
+        BTM_TRACE_ERROR0("Random match");
+        match = TRUE;
+        match_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA;
+        memcpy(match_rec->ble.cur_rand_addr, bda, BD_ADDR_LEN);
+        memcpy(bda, match_rec->bd_addr, BD_ADDR_LEN);
+    }
+    else
+    {
+        BTM_TRACE_ERROR0("Random unmatch");
+    }
+
+    btm_ble_connected(bda, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type, match);
+
+    l2cble_conn_comp (handle, role, bda, bda_type, conn_interval,
+                      conn_latency, conn_timeout);
+
+    return;
+}
+#endif
+
 /*******************************************************************************
 **
 ** Function         btm_ble_connected
@@ -1516,9 +1586,18 @@
     p_dev_rec->hci_handle = handle;
     p_dev_rec->ble.ble_addr_type = addr_type;
 
+    p_dev_rec->role_master = FALSE;
     if (role == HCI_ROLE_MASTER)
         p_dev_rec->role_master = TRUE;
 
+#if (defined BTM_BLE_PRIVACY_SPT && BTM_BLE_PRIVACY_SPT == TRUE)
+    if (!addr_matched)
+        p_dev_rec->ble.active_addr_type = BTM_BLE_ADDR_PSEUDO;
+
+    if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_RANDOM && !addr_matched)
+        memcpy(p_dev_rec->ble.cur_rand_addr, bda, BD_ADDR_LEN);
+#endif
+
     if (role == HCI_ROLE_SLAVE)
         p_cb->inq_var.adv_mode  = BTM_BLE_ADV_DISABLE;
     p_cb->inq_var.directed_conn = FALSE;
@@ -1534,6 +1613,9 @@
 ******************************************************************************/
 void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len)
 {
+#if (BTM_BLE_PRIVACY_SPT == TRUE )
+    UINT8       *p_data = p;
+#endif
     UINT8       role, status, bda_type;
     UINT16      handle;
     BD_ADDR     bda;
@@ -1549,14 +1631,25 @@
 
     if (status == 0)
     {
-        STREAM_TO_UINT16   (conn_interval, p);
-        STREAM_TO_UINT16   (conn_latency, p);
-        STREAM_TO_UINT16   (conn_timeout, p);
-        handle = HCID_GET_HANDLE (handle);
+#if (BTM_BLE_PRIVACY_SPT == TRUE )
+        /* possiblly receive connection complete with resolvable random on
+           slave role while the device has been paired */
+        if (!match && BTM_BLE_IS_RESOLVE_BDA(bda))
+        {
+            btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_on_conn_cmpl, p_data);
+        }
+        else
+#endif
+        {
+            STREAM_TO_UINT16   (conn_interval, p);
+            STREAM_TO_UINT16   (conn_latency, p);
+            STREAM_TO_UINT16   (conn_timeout, p);
+            handle = HCID_GET_HANDLE (handle);
 
-        btm_ble_connected(bda, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type, match);
-        l2cble_conn_comp (handle, role, bda, bda_type, conn_interval,
+            btm_ble_connected(bda, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type, match);
+            l2cble_conn_comp (handle, role, bda, bda_type, conn_interval,
                               conn_latency, conn_timeout);
+        }
     }
     else
     {
diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c
index 5e5b5db..6ab0415 100644
--- a/stack/btm/btm_ble_gap.c
+++ b/stack/btm/btm_ble_gap.c
@@ -288,6 +288,49 @@
 #endif
 }
 
+#if BTM_BLE_PRIVACY_SPT == TRUE
+/*******************************************************************************
+**
+** Function         btm_ble_resolve_random_addr_on_adv
+**
+** Description      resolve random address complete callback.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void btm_ble_resolve_random_addr_on_adv(void * p_rec, void *p)
+{
+    tBTM_SEC_DEV_REC    *match_rec = (tBTM_SEC_DEV_REC *) p_rec;
+    UINT8       addr_type = BLE_ADDR_RANDOM;
+    BD_ADDR     bda;
+    UINT8       *pp = (UINT8 *)p + 1;
+    UINT8           evt_type;
+
+    BTM_TRACE_EVENT0 ("btm_ble_resolve_random_addr_on_adv ");
+
+    STREAM_TO_UINT8    (evt_type, pp);
+    STREAM_TO_UINT8    (addr_type, pp);
+    STREAM_TO_BDADDR   (bda, pp);
+
+    if (match_rec)
+    {
+        BTM_TRACE_ERROR0("Random match");
+        match_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA;
+        memcpy(match_rec->ble.cur_rand_addr, bda, BD_ADDR_LEN);
+        memcpy(bda, match_rec->bd_addr, BD_ADDR_LEN);
+        addr_type = match_rec->ble.ble_addr_type;
+    }
+    else
+    {
+        BTM_TRACE_ERROR0("Random unmatch");
+    }
+
+    btm_ble_process_adv_pkt_cont(bda, addr_type, evt_type, pp);
+
+    return;
+}
+#endif
+
 /*******************************************************************************
 **
 ** Function         BTM_BleSetBgConnType
@@ -1672,6 +1715,9 @@
     BD_ADDR             bda;
     UINT8               evt_type = 0, *p = p_data;
     UINT8               addr_type = 0;
+#if (defined BTM_BLE_PRIVACY_SPT && BTM_BLE_PRIVACY_SPT == TRUE)
+    BOOLEAN             match = FALSE;
+#endif
 
     /* always get one device at a time */
     p ++;
@@ -1698,7 +1744,19 @@
          btm_cb.ble_ctr_cb.p_select_cback == NULL))
         return;
 
-    btm_ble_process_adv_pkt_cont(bda, addr_type, evt_type, p);
+#if (defined BTM_BLE_PRIVACY_SPT && BTM_BLE_PRIVACY_SPT == TRUE)
+#if SMP_INCLUDED == TRUE
+    /* always do RRA resolution on host */
+    if (!match && BTM_BLE_IS_RESOLVE_BDA(bda))
+    {
+        btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_on_adv, p_data);
+    }
+    else
+#endif
+#endif
+    {
+        btm_ble_process_adv_pkt_cont(bda, addr_type, evt_type, p);
+    }
 }
 
 /*******************************************************************************
diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h
index b030c2a..5129efc 100644
--- a/stack/btm/btm_int.h
+++ b/stack/btm/btm_int.h
@@ -493,6 +493,14 @@
     tBLE_ADDR_TYPE      ble_addr_type;  /* LE device type: public or random address */
     tBLE_ADDR_TYPE      static_addr_type;   /* static address type */
     BD_ADDR             static_addr;    /* static address */
+#if BTM_BLE_PRIVACY_SPT == TRUE
+    BD_ADDR             cur_rand_addr;  /* current random address */
+
+#define BTM_BLE_ADDR_PSEUDO         0   /* address index device record */
+#define BTM_BLE_ADDR_RRA            1   /* cur_rand_addr */
+#define BTM_BLE_ADDR_STATIC         2   /* static_addr  */
+    UINT8               active_addr_type;
+#endif
 
 #if SMP_INCLUDED == TRUE
     tBTM_LE_KEY_TYPE    key_type;       /* bit mask of valid key types in record */
diff --git a/stack/l2cap/l2c_ble.c b/stack/l2cap/l2c_ble.c
index 2f2646e..ba0d7ec 100644
--- a/stack/l2cap/l2c_ble.c
+++ b/stack/l2cap/l2c_ble.c
@@ -616,6 +616,14 @@
     init_addr_type = p_lcb->ble_addr_type;
     memcpy(init_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
 
+#if BTM_BLE_PRIVACY_SPT == TRUE
+    if (p_dev_rec->ble.active_addr_type == BTM_BLE_ADDR_RRA)
+    {
+        init_addr_type = BLE_ADDR_RANDOM;
+        memcpy(init_addr, p_dev_rec->ble.cur_rand_addr, BD_ADDR_LEN);
+    }
+#endif
+
     if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int      */
                                         scan_win, /* UINT16 scan_win      */
                                         FALSE,                   /* UINT8 white_list     */