Add option to specify initial LE connection PHY (1/3)

For whitelist connections we always use all possible PHYs, for direct
connection use PHY specified by client.

Test: manual
Bug: 30622771
Change-Id: I720f134e2800dc3d282135bb7ffbe3882117c680
diff --git a/bta/gatt/bta_gattc_act.cc b/bta/gatt/bta_gattc_act.cc
index e8f28ee..021fe3f 100644
--- a/bta/gatt/bta_gattc_act.cc
+++ b/bta/gatt/bta_gattc_act.cc
@@ -432,7 +432,8 @@
 
   /* open/hold a connection */
   if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, true,
-                    p_data->api_conn.transport, false)) {
+                    p_data->api_conn.transport, false,
+                    p_data->api_conn.initiating_phys)) {
     APPL_TRACE_ERROR("Connection open failure");
 
     bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data);
diff --git a/bta/gatt/bta_gattc_api.cc b/bta/gatt/bta_gattc_api.cc
index 820f96a..58eb834 100644
--- a/bta/gatt/bta_gattc_api.cc
+++ b/bta/gatt/bta_gattc_api.cc
@@ -34,6 +34,7 @@
 #include "bta_gatt_api.h"
 #include "bta_gattc_int.h"
 #include "bta_sys.h"
+#include "device/include/controller.h"
 
 /*****************************************************************************
  *  Constants
@@ -125,12 +126,17 @@
  *                  is_direct: direct connection or background auto connection
  *                  transport: Transport to be used for GATT connection
  *                             (BREDR/LE)
- *
- * Returns          void
+ *                  initiating_phys: LE PHY to use, optional
  *
  ******************************************************************************/
 void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, bool is_direct,
                     tBTA_GATT_TRANSPORT transport) {
+  uint8_t phy = controller_get_interface()->get_le_all_initiating_phys();
+  BTA_GATTC_Open(client_if, remote_bda, is_direct, transport, phy);
+}
+
+void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, bool is_direct,
+                    tBTA_GATT_TRANSPORT transport, uint8_t initiating_phys) {
   tBTA_GATTC_API_OPEN* p_buf =
       (tBTA_GATTC_API_OPEN*)osi_malloc(sizeof(tBTA_GATTC_API_OPEN));
 
@@ -138,6 +144,7 @@
   p_buf->client_if = client_if;
   p_buf->is_direct = is_direct;
   p_buf->transport = transport;
+  p_buf->initiating_phys = initiating_phys;
   memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
 
   bta_sys_sendmsg(p_buf);
diff --git a/bta/gatt/bta_gattc_int.h b/bta/gatt/bta_gattc_int.h
index 7001298..0c39b07 100644
--- a/bta/gatt/bta_gattc_int.h
+++ b/bta/gatt/bta_gattc_int.h
@@ -101,6 +101,7 @@
   tBTA_GATTC_IF client_if;
   bool is_direct;
   tBTA_TRANSPORT transport;
+  uint8_t initiating_phys;
 } tBTA_GATTC_API_OPEN;
 
 typedef tBTA_GATTC_API_OPEN tBTA_GATTC_API_CANCEL_OPEN;
diff --git a/bta/include/bta_gatt_api.h b/bta/include/bta_gatt_api.h
index ac09c18..187800e 100644
--- a/bta/include/bta_gatt_api.h
+++ b/bta/include/bta_gatt_api.h
@@ -635,12 +635,14 @@
  * Parameters       client_if: server interface.
  *                  remote_bda: remote device BD address.
  *                  is_direct: direct connection or background auto connection
- *
- * Returns          void
+ *                  initiating_phys: LE PHY to use, optional
  *
  ******************************************************************************/
 extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
                            bool is_direct, tBTA_GATT_TRANSPORT transport);
+extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
+                           bool is_direct, tBTA_GATT_TRANSPORT transport,
+                           uint8_t initiating_phys);
 
 /*******************************************************************************
  *
diff --git a/btif/src/btif_gatt_client.cc b/btif/src/btif_gatt_client.cc
index 4dad646..0a069bd 100644
--- a/btif/src/btif_gatt_client.cc
+++ b/btif/src/btif_gatt_client.cc
@@ -255,7 +255,7 @@
 }
 
 void btif_gattc_open_impl(int client_if, BD_ADDR address, bool is_direct,
-                          int transport_p) {
+                          int transport_p, int initiating_phys) {
   // Ensure device is in inquiry database
   int addr_type = 0;
   int device_type = 0;
@@ -308,19 +308,21 @@
   }
 
   // Connect!
-  BTIF_TRACE_DEBUG("%s Transport=%d, device type=%d", __func__, transport,
-                   device_type);
-  BTA_GATTC_Open(client_if, address, is_direct, transport);
+  BTIF_TRACE_DEBUG("%s Transport=%d, device type=%d, phy=%d", __func__,
+                   transport, device_type, initiating_phys);
+  BTA_GATTC_Open(client_if, address, is_direct, transport, initiating_phys);
 }
 
 bt_status_t btif_gattc_open(int client_if, const bt_bdaddr_t* bd_addr,
-                            bool is_direct, int transport) {
+                            bool is_direct, int transport,
+                            int initiating_phys) {
   CHECK_BTGATT_INIT();
   // Closure will own this value and free it.
   uint8_t* address = new BD_ADDR;
   bdcpy(address, bd_addr->address);
   return do_in_jni_thread(Bind(&btif_gattc_open_impl, client_if,
-                               base::Owned(address), is_direct, transport));
+                               base::Owned(address), is_direct, transport,
+                               initiating_phys));
 }
 
 void btif_gattc_close_impl(int client_if, BD_ADDR address, int conn_id) {
diff --git a/device/include/controller.h b/device/include/controller.h
index cfe7c80..a82e28c 100644
--- a/device/include/controller.h
+++ b/device/include/controller.h
@@ -82,6 +82,8 @@
   uint8_t (*get_ble_resolving_list_max_size)(void);
   void (*set_ble_resolving_list_max_size)(int resolving_list_max_size);
   uint8_t* (*get_local_supported_codecs)(uint8_t* number_of_codecs);
+  uint8_t (*get_le_all_initiating_phys)(void);
+
 } controller_t;
 
 const controller_t* controller_get_interface();
diff --git a/device/src/controller.cc b/device/src/controller.cc
index 2ef8a3b..d402b9c 100644
--- a/device/src/controller.cc
+++ b/device/src/controller.cc
@@ -476,6 +476,14 @@
   ble_resolving_list_max_size = resolving_list_max_size;
 }
 
+static uint8_t get_le_all_initiating_phys() {
+  uint8_t phy = PHY_LE_1M;
+  // TODO(jpawlowski): uncomment after next FW udpate
+  // if (supports_ble_2m_phy()) phy |= PHY_LE_2M;
+  // if (supports_ble_coded_phy()) phy |= PHY_LE_CODED;
+  return phy;
+}
+
 static const controller_t interface = {
     get_is_ready,
 
@@ -522,7 +530,8 @@
 
     get_ble_resolving_list_max_size,
     set_ble_resolving_list_max_size,
-    get_local_supported_codecs};
+    get_local_supported_codecs,
+    get_le_all_initiating_phys};
 
 const controller_t* controller_get_interface() {
   static bool loaded = false;
diff --git a/service/hal/fake_bluetooth_gatt_interface.cc b/service/hal/fake_bluetooth_gatt_interface.cc
index 930bcdb..7e426c5 100644
--- a/service/hal/fake_bluetooth_gatt_interface.cc
+++ b/service/hal/fake_bluetooth_gatt_interface.cc
@@ -41,7 +41,7 @@
 }
 
 bt_status_t FakeConnect(int client_if, const bt_bdaddr_t* bd_addr,
-                        bool is_direct, int transport) {
+                        bool is_direct, int transport, int phy) {
   if (g_client_handler)
     return g_client_handler->Connect(client_if, bd_addr, is_direct, transport);
 
diff --git a/service/low_energy_client.cc b/service/low_energy_client.cc
index dc99b6c..1e2d7f3 100644
--- a/service/low_energy_client.cc
+++ b/service/low_energy_client.cc
@@ -59,7 +59,7 @@
 
   bt_status_t status =
       hal::BluetoothGattInterface::Get()->GetClientHALInterface()->connect(
-          client_id_, &bda, is_direct, BT_TRANSPORT_LE);
+          client_id_, &bda, is_direct, BT_TRANSPORT_LE, PHY_LE_1M_MASK);
   if (status != BT_STATUS_SUCCESS) {
     LOG(ERROR) << "HAL call to connect failed";
     return false;
diff --git a/stack/btm/btm_ble_bgconn.cc b/stack/btm/btm_ble_bgconn.cc
index 3e40673..319fbfa 100644
--- a/stack/btm/btm_ble_bgconn.cc
+++ b/stack/btm/btm_ble_bgconn.cc
@@ -323,22 +323,31 @@
     uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
     uint8_t addr_type_peer, BD_ADDR bda_peer, uint8_t addr_type_own,
     uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
-    uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len) {
+    uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
+    uint8_t initiating_phys) {
   if (controller_get_interface()->supports_ble_extended_advertising()) {
-    EXT_CONN_PHY_CFG phy_cfg;
+    EXT_CONN_PHY_CFG phy_cfg[3];  // maximum three phys
 
-    phy_cfg.scan_int = scan_int;
-    phy_cfg.scan_win = scan_win;
-    phy_cfg.conn_int_min = conn_int_min;
-    phy_cfg.conn_int_max = conn_int_max;
-    phy_cfg.conn_latency = conn_latency;
-    phy_cfg.sup_timeout = conn_timeout;
-    phy_cfg.min_ce_len = min_ce_len;
-    phy_cfg.max_ce_len = max_ce_len;
+    int phy_cnt =
+        std::bitset<std::numeric_limits<uint8_t>::digits>(initiating_phys)
+            .count();
+
+    LOG_ASSERT(phy_cnt < 3) << "More than three phys provided";
+    // TODO(jpawlowski): tune parameters for different transports
+    for (int i = 0; i < phy_cnt; i++) {
+      phy_cfg[i].scan_int = scan_int;
+      phy_cfg[i].scan_win = scan_win;
+      phy_cfg[i].conn_int_min = conn_int_min;
+      phy_cfg[i].conn_int_max = conn_int_max;
+      phy_cfg[i].conn_latency = conn_latency;
+      phy_cfg[i].sup_timeout = conn_timeout;
+      phy_cfg[i].min_ce_len = min_ce_len;
+      phy_cfg[i].max_ce_len = max_ce_len;
+    }
 
     btsnd_hcic_ble_ext_create_conn(init_filter_policy, addr_type_own,
-                                   addr_type_peer, bda_peer,
-                                   0x01 /* LE 1M PHY */, &phy_cfg);
+                                   addr_type_peer, bda_peer, initiating_phys,
+                                   phy_cfg);
   } else {
     btsnd_hcic_ble_create_ll_conn(scan_int, scan_win, init_filter_policy,
                                   addr_type_peer, bda_peer, addr_type_own,
@@ -367,6 +376,10 @@
   uint8_t own_addr_type = p_cb->addr_mgnt_cb.own_addr_type;
   uint8_t peer_addr_type = BLE_ADDR_PUBLIC;
 
+  uint8_t phy = PHY_LE_1M;
+  if (controller_get_interface()->supports_ble_2m_phy()) phy |= PHY_LE_2M;
+  if (controller_get_interface()->supports_ble_coded_phy()) phy |= PHY_LE_CODED;
+
   if (start) {
     if (p_cb->conn_state == BLE_CONN_IDLE && background_connections_pending() &&
         btm_ble_topology_check(BTM_BLE_STATE_INIT)) {
@@ -404,7 +417,8 @@
           BTM_BLE_CONN_SLAVE_LATENCY_DEF, /* uint16_t conn_latency  */
           BTM_BLE_CONN_TIMEOUT_DEF,       /* uint16_t conn_timeout  */
           0,                              /* uint16_t min_len       */
-          0);                             /* uint16_t max_len       */
+          0,                              /* uint16_t max_len       */
+          phy);
       btm_ble_set_conn_st(BLE_BG_CONN);
     } else {
       exec = false;
diff --git a/stack/btm/btm_ble_int.h b/stack/btm/btm_ble_int.h
index 21d33f7..67af7d3 100644
--- a/stack/btm/btm_ble_int.h
+++ b/stack/btm/btm_ble_int.h
@@ -128,7 +128,8 @@
     uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
     uint8_t addr_type_peer, BD_ADDR bda_peer, uint8_t addr_type_own,
     uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
-    uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len);
+    uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
+    uint8_t phy);
 extern bool btm_ble_start_auto_conn(bool start);
 extern bool btm_ble_start_select_conn(bool start);
 extern bool btm_ble_renew_bg_conn_params(bool add, BD_ADDR bd_addr);
diff --git a/stack/gatt/gatt_api.cc b/stack/gatt/gatt_api.cc
index af16df7..d6803d2 100644
--- a/stack/gatt/gatt_api.cc
+++ b/stack/gatt/gatt_api.cc
@@ -29,6 +29,7 @@
 #include "bt_common.h"
 #include "btm_int.h"
 #include "btu.h"
+#include "device/include/controller.h"
 #include "gatt_api.h"
 #include "gatt_int.h"
 #include "l2c_api.h"
@@ -1252,6 +1253,14 @@
  ******************************************************************************/
 bool GATT_Connect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct,
                   tBT_TRANSPORT transport, bool opportunistic) {
+  uint8_t phy = controller_get_interface()->get_le_all_initiating_phys();
+  return GATT_Connect(gatt_if, bd_addr, is_direct, transport, opportunistic,
+                      phy);
+}
+
+bool GATT_Connect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct,
+                  tBT_TRANSPORT transport, bool opportunistic,
+                  uint8_t initiating_phys) {
   tGATT_REG* p_reg;
   bool status = false;
 
@@ -1265,7 +1274,8 @@
   }
 
   if (is_direct)
-    status = gatt_act_connect(p_reg, bd_addr, transport, opportunistic);
+    status = gatt_act_connect(p_reg, bd_addr, transport, opportunistic,
+                              initiating_phys);
   else {
     if (transport == BT_TRANSPORT_LE)
       status = gatt_update_auto_connect_dev(gatt_if, true, bd_addr);
diff --git a/stack/gatt/gatt_int.h b/stack/gatt/gatt_int.h
index 44c5d91..be29fe4 100644
--- a/stack/gatt/gatt_int.h
+++ b/stack/gatt/gatt_int.h
@@ -448,9 +448,10 @@
 /* from gatt_main.cc */
 extern bool gatt_disconnect(tGATT_TCB* p_tcb);
 extern bool gatt_act_connect(tGATT_REG* p_reg, BD_ADDR bd_addr,
-                             tBT_TRANSPORT transport, bool opportunistic);
+                             tBT_TRANSPORT transport, bool opportunistic,
+                             int8_t initiating_phys);
 extern bool gatt_connect(BD_ADDR rem_bda, tGATT_TCB* p_tcb,
-                         tBT_TRANSPORT transport);
+                         tBT_TRANSPORT transport, uint8_t initiating_phys);
 extern void gatt_data_process(tGATT_TCB* p_tcb, BT_HDR* p_buf);
 extern void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
                                           bool is_add, bool check_acl_link);
diff --git a/stack/gatt/gatt_main.cc b/stack/gatt/gatt_main.cc
index 7c2ab7a..638b3d7 100644
--- a/stack/gatt/gatt_main.cc
+++ b/stack/gatt/gatt_main.cc
@@ -185,7 +185,8 @@
  * Returns          true if connection is started, otherwise return false.
  *
  ******************************************************************************/
-bool gatt_connect(BD_ADDR rem_bda, tGATT_TCB* p_tcb, tBT_TRANSPORT transport) {
+bool gatt_connect(BD_ADDR rem_bda, tGATT_TCB* p_tcb, tBT_TRANSPORT transport,
+                  uint8_t initiating_phys) {
   bool gatt_ret = false;
 
   if (gatt_get_ch_state(p_tcb) != GATT_CH_OPEN)
@@ -193,7 +194,7 @@
 
   if (transport == BT_TRANSPORT_LE) {
     p_tcb->att_lcid = L2CAP_ATT_CID;
-    gatt_ret = L2CA_ConnectFixedChnl(L2CAP_ATT_CID, rem_bda);
+    gatt_ret = L2CA_ConnectFixedChnl(L2CAP_ATT_CID, rem_bda, initiating_phys);
   } else {
     p_tcb->att_lcid = L2CA_ConnectReq(BT_PSM_ATT, rem_bda);
     if (p_tcb->att_lcid != 0) gatt_ret = true;
@@ -341,7 +342,8 @@
  *
  ******************************************************************************/
 bool gatt_act_connect(tGATT_REG* p_reg, BD_ADDR bd_addr,
-                      tBT_TRANSPORT transport, bool opportunistic) {
+                      tBT_TRANSPORT transport, bool opportunistic,
+                      int8_t initiating_phys) {
   bool ret = false;
   tGATT_TCB* p_tcb;
   uint8_t st;
@@ -354,7 +356,8 @@
     /* before link down, another app try to open a GATT connection */
     if (st == GATT_CH_OPEN && gatt_num_apps_hold_link(p_tcb) == 0 &&
         transport == BT_TRANSPORT_LE) {
-      if (!gatt_connect(bd_addr, p_tcb, transport)) ret = false;
+      if (!gatt_connect(bd_addr, p_tcb, transport, initiating_phys))
+        ret = false;
     } else if (st == GATT_CH_CLOSING) {
       /* need to complete the closing first */
       ret = false;
@@ -362,7 +365,7 @@
   } else {
     p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, transport);
     if (p_tcb != NULL) {
-      if (!gatt_connect(bd_addr, p_tcb, transport)) {
+      if (!gatt_connect(bd_addr, p_tcb, transport, initiating_phys)) {
         GATT_TRACE_ERROR("gatt_connect failed");
         fixed_queue_free(p_tcb->pending_enc_clcb, NULL);
         fixed_queue_free(p_tcb->pending_ind_q, NULL);
diff --git a/stack/include/bt_types.h b/stack/include/bt_types.h
index 4704937..da0baac 100644
--- a/stack/include/bt_types.h
+++ b/stack/include/bt_types.h
@@ -738,6 +738,10 @@
 #define BT_TRANSPORT_LE 2
 typedef uint8_t tBT_TRANSPORT;
 
+#define PHY_LE_1M_MASK 1
+#define PHY_LE_2M_MASK 2
+#define PHY_LE_CODED_MASK 4
+
 #define BLE_ADDR_IS_STATIC(x) (((x)[0] & 0xC0) == 0xC0)
 
 typedef struct {
diff --git a/stack/include/gatt_api.h b/stack/include/gatt_api.h
index 631cdfc..12b26da 100644
--- a/stack/include/gatt_api.h
+++ b/stack/include/gatt_api.h
@@ -1007,6 +1007,9 @@
  ******************************************************************************/
 extern bool GATT_Connect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct,
                          tBT_TRANSPORT transport, bool opportunistic);
+extern bool GATT_Connect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct,
+                         tBT_TRANSPORT transport, bool opportunistic,
+                         uint8_t initiating_phys);
 
 /*******************************************************************************
  *
diff --git a/stack/include/l2c_api.h b/stack/include/l2c_api.h
index a1c72a7..6ac7c4b 100644
--- a/stack/include/l2c_api.h
+++ b/stack/include/l2c_api.h
@@ -1079,6 +1079,8 @@
  *
  ******************************************************************************/
 extern bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, BD_ADDR bd_addr);
+extern bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, BD_ADDR bd_addr,
+                                  uint8_t initiating_phys);
 
 /*******************************************************************************
  *
diff --git a/stack/l2cap/l2c_api.cc b/stack/l2cap/l2c_api.cc
index 2e208ed..d85bea4 100644
--- a/stack/l2cap/l2c_api.cc
+++ b/stack/l2cap/l2c_api.cc
@@ -33,6 +33,7 @@
 #include "bt_types.h"
 #include "btm_api.h"
 #include "btu.h"
+#include "device/include/controller.h"
 #include "hcidefs.h"
 #include "hcimsgs.h"
 #include "l2c_int.h"
@@ -1606,6 +1607,12 @@
  *
  ******************************************************************************/
 bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, BD_ADDR rem_bda) {
+  uint8_t phy = controller_get_interface()->get_le_all_initiating_phys();
+  return L2CA_ConnectFixedChnl(fixed_cid, rem_bda, phy);
+}
+
+bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, BD_ADDR rem_bda,
+                           uint8_t initiating_phys) {
   tL2C_LCB* p_lcb;
   tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
 
@@ -1695,7 +1702,7 @@
     return false;
   }
 
-  if (!l2cu_create_conn(p_lcb, transport)) {
+  if (!l2cu_create_conn(p_lcb, transport, initiating_phys)) {
     L2CAP_TRACE_WARNING("%s() - create_conn failed", __func__);
     l2cu_release_lcb(p_lcb);
     return false;
diff --git a/stack/l2cap/l2c_ble.cc b/stack/l2cap/l2c_ble.cc
index a5004a8..e8fb722 100644
--- a/stack/l2cap/l2c_ble.cc
+++ b/stack/l2cap/l2c_ble.cc
@@ -903,7 +903,8 @@
               ? p_dev_rec->conn_params.supervision_tout
               : BTM_BLE_CONN_TIMEOUT_DEF), /* conn_timeout */
       0,                                   /* uint16_t min_len       */
-      0);                                  /* uint16_t max_len       */
+      0,                                   /* uint16_t max_len       */
+      p_lcb->initiating_phys);
 
   p_lcb->link_state = LST_CONNECTING;
   l2cb.is_ble_connecting = true;
diff --git a/stack/l2cap/l2c_int.h b/stack/l2cap/l2c_int.h
index 05a026a..d6758bb 100644
--- a/stack/l2cap/l2c_int.h
+++ b/stack/l2cap/l2c_int.h
@@ -433,6 +433,7 @@
 #endif
 
   tBT_TRANSPORT transport;
+  uint8_t initiating_phys;  // LE PHY used for connection initiation
   tBLE_ADDR_TYPE ble_addr_type;
   uint16_t tx_data_len; /* tx data length used in data length extension */
   fixed_queue_t* le_sec_pending_q; /* LE coc channels waiting for security check
@@ -696,6 +697,8 @@
 extern bool l2cu_lcb_disconnecting(void);
 
 extern bool l2cu_create_conn(tL2C_LCB* p_lcb, tBT_TRANSPORT transport);
+extern bool l2cu_create_conn(tL2C_LCB* p_lcb, tBT_TRANSPORT transport,
+                             uint8_t initiating_phys);
 extern bool l2cu_create_conn_after_switch(tL2C_LCB* p_lcb);
 extern BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb);
 extern void l2cu_resubmit_pending_sec_req(BD_ADDR p_bda);
diff --git a/stack/l2cap/l2c_utils.cc b/stack/l2cap/l2c_utils.cc
index dd323f5..75bef4c 100644
--- a/stack/l2cap/l2c_utils.cc
+++ b/stack/l2cap/l2c_utils.cc
@@ -2096,6 +2096,12 @@
  *
  ******************************************************************************/
 bool l2cu_create_conn(tL2C_LCB* p_lcb, tBT_TRANSPORT transport) {
+  uint8_t phy = controller_get_interface()->get_le_all_initiating_phys();
+  return l2cu_create_conn(p_lcb, transport, phy);
+}
+
+bool l2cu_create_conn(tL2C_LCB* p_lcb, tBT_TRANSPORT transport,
+                      uint8_t initiating_phys) {
   int xx;
   tL2C_LCB* p_lcb_cur = &l2cb.lcb_pool[0];
 #if (BTM_SCO_INCLUDED == TRUE)
@@ -2112,6 +2118,7 @@
 
     p_lcb->ble_addr_type = addr_type;
     p_lcb->transport = BT_TRANSPORT_LE;
+    p_lcb->initiating_phys = initiating_phys;
 
     return (l2cble_create_conn(p_lcb));
   }