Avoid premature LE connection notifaction to app

To avoid premature connection notification to app, always wait for
LE read remote feature complete with success before the connection
event is sent to application.

This patch also deprecates the BTA_SKIP_BLE_READ_REMOTE_FEAT flag.
Since the remote feature request is now serialized and start encryption
won't be called until the connection is up, this flag is no longer
necessary and interferes with the new behaviour.

This is an extension of previous CL

Bug: 17326529
Change-Id: Icfd4c5dfdd9f89d1318ef429e132eb005abb1f64
diff --git a/bta/gatt/bta_gattc_utils.c b/bta/gatt/bta_gattc_utils.c
index 244269f..a7a9557 100644
--- a/bta/gatt/bta_gattc_utils.c
+++ b/bta/gatt/bta_gattc_utils.c
@@ -947,15 +947,14 @@
     tGATT_DISCONN_REASON    reason = p_msg->int_conn.reason;
 
     bta_gattc_conn_dealloc(p_msg->int_conn.remote_bda);
-    /* connection attempt timeout, send connection callback event */
-    if (reason == GATT_CONN_CANCEL || reason == GATT_CONN_L2C_FAILURE
-        || reason == GATT_CONN_FAIL_ESTABLISH)
+    if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL)
     {
+        /* connection attempt failed, send connection callback event */
         p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
                                             p_msg->int_conn.remote_bda,
                                             p_msg->int_conn.transport);
     }
-    else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL)
+    if (p_clcb == NULL)
     {
         APPL_TRACE_DEBUG(" disconnection ID: [%d] not used by BTA",
             p_msg->int_conn.hdr.layer_specific);
diff --git a/include/bt_target.h b/include/bt_target.h
index 4239cc7..9f08e79 100644
--- a/include/bt_target.h
+++ b/include/bt_target.h
@@ -260,11 +260,6 @@
 #define BTA_HOST_INTERLEAVE_SEARCH FALSE
 #endif
 
-/* This feature is used to skip query of ble read remote features*/
-#ifndef BTA_SKIP_BLE_READ_REMOTE_FEAT
-#define BTA_SKIP_BLE_READ_REMOTE_FEAT FALSE
-#endif
-
 #ifndef BT_TRACE_PROTOCOL
 #define BT_TRACE_PROTOCOL  TRUE
 #endif
diff --git a/stack/btm/btm_acl.c b/stack/btm/btm_acl.c
index febca85..0d65249 100644
--- a/stack/btm/btm_acl.c
+++ b/stack/btm/btm_acl.c
@@ -374,15 +374,15 @@
                     &p->active_remote_addr_type);
 #endif
 
-#if (!defined(BTA_SKIP_BLE_READ_REMOTE_FEAT) || BTA_SKIP_BLE_READ_REMOTE_FEAT == FALSE)
                 if (HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(btm_cb.devcb.local_le_features)
                     || link_role == HCI_ROLE_MASTER)
                 {
                     btsnd_hcic_ble_read_remote_feat(p->hci_handle);
                 }
                 else
-#endif
-                btm_establish_continue(p);
+                {
+                    btm_establish_continue(p);
+                }
             }
             else
 #endif
diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c
index 2f38fbd..ccd3775 100644
--- a/stack/btm/btm_ble_gap.c
+++ b/stack/btm/btm_ble_gap.c
@@ -3009,8 +3009,7 @@
             if ((p_acl_cb->in_use) && (p_acl_cb->hci_handle == handle))
             {
                 STREAM_TO_ARRAY(p_acl_cb->peer_le_features, p, BD_FEATURES_LEN);
-                /* notify link up here */
-                btm_establish_continue(p_acl_cb);
+                /*notify link up here */
                 l2cble_notify_le_connection (p_acl_cb->remote_addr);
                 break;
             }
diff --git a/stack/l2cap/l2c_ble.c b/stack/l2cap/l2c_ble.c
index 673f5b7..2b933e8 100644
--- a/stack/l2cap/l2c_ble.c
+++ b/stack/l2cap/l2c_ble.c
@@ -280,9 +280,16 @@
 void l2cble_notify_le_connection (BD_ADDR bda)
 {
     tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
+    tACL_CONN *p_acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE) ;
 
-    if (p_lcb != NULL)
+    if (p_lcb != NULL && p_acl != NULL && p_lcb->link_state != LST_CONNECTED)
+    {
+        /* update link status */
+        btm_establish_continue(p_acl);
+        /* update l2cap link status and send callback */
+        p_lcb->link_state = LST_CONNECTED;
         l2cu_process_fixed_chnl_resp (p_lcb);
+    }
 }
 
 /*******************************************************************************
@@ -340,7 +347,6 @@
     p_lcb->handle = handle;
 
     /* Connected OK. Change state to connected, we were scanning so we are master */
-    p_lcb->link_state = LST_CONNECTED;
     p_lcb->link_role  = HCI_ROLE_MASTER;
     p_lcb->transport  = BT_TRANSPORT_LE;
 
@@ -373,15 +379,8 @@
     /* Tell BTM Acl management about the link */
     btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE);
 
-#if(defined(BTA_SKIP_BLE_READ_REMOTE_FEAT) && BTA_SKIP_BLE_READ_REMOTE_FEAT == TRUE)
-    {
-            l2cu_process_fixed_chnl_resp (p_lcb);
-    }
-#endif
-
     p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
 
-
     btm_ble_set_conn_st(BLE_CONN_IDLE);
 }
 
@@ -434,7 +433,6 @@
     p_lcb->handle = handle;
 
     /* Connected OK. Change state to connected, we were advertising, so we are slave */
-    p_lcb->link_state = LST_CONNECTED;
     p_lcb->link_role  = HCI_ROLE_SLAVE;
     p_lcb->transport  = BT_TRANSPORT_LE;
 
@@ -445,16 +443,11 @@
 
     p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
 
-#if (defined(BTA_SKIP_BLE_READ_REMOTE_FEAT) && BTA_SKIP_BLE_READ_REMOTE_FEAT == TRUE)
-    {
-        l2cu_process_fixed_chnl_resp (p_lcb);
-    }
-#else
     if (!HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(btm_cb.devcb.local_le_features))
     {
+        p_lcb->link_state = LST_CONNECTED;
         l2cu_process_fixed_chnl_resp (p_lcb);
     }
-#endif
 
     /* when adv and initiating are both active, cancel the direct connection */
     if (l2cb.is_ble_connecting && memcmp(bda, l2cb.ble_connecting_bda, BD_ADDR_LEN) == 0)
diff --git a/stack/l2cap/l2c_link.c b/stack/l2cap/l2c_link.c
index 3ebc81b..aa8f66c 100644
--- a/stack/l2cap/l2c_link.c
+++ b/stack/l2cap/l2c_link.c
@@ -418,38 +418,40 @@
          */
         if (p_lcb->ccb_queue.p_first_ccb != NULL || p_lcb->p_pending_ccb)
         {
-#if (L2CAP_NUM_FIXED_CHNLS > 0)
-            /* If we are going to re-use the LCB without dropping it, release all fixed channels here */
-            int         xx;
-            for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
-            {
-                if (p_lcb->p_fixed_ccbs[xx] && p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb)
-                {
+            L2CAP_TRACE_DEBUG("l2c_link_hci_disc_comp: Restarting pending ACL request");
 #if BLE_INCLUDED == TRUE
-                    (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE,
-                                                             p_lcb->disc_reason, p_lcb->transport);
+            /* for LE link, always drop and re-open to ensure to get LE remote feature */
+            if (p_lcb->transport == BT_TRANSPORT_LE)
+            {
+                l2cu_release_lcb (p_lcb);
+                p_lcb->in_use = TRUE;
+                transport = BT_TRANSPORT_LE;
+            }
+            else
+#endif
+       {
+          #if (L2CAP_NUM_FIXED_CHNLS > 0)
+          /* If we are going to re-use the LCB without dropping it, release all fixed channels
+          here */
+          int xx;
+          for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
+          {
+              if (p_lcb->p_fixed_ccbs[xx] && p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb)
+              {
+#if BLE_INCLUDED == TRUE
+                  (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE,
+                       p_lcb->disc_reason, p_lcb->transport);
 #else
-                    (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE,
-                                                          p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
+                  (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE,
+                       p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
 #endif
                     l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
 
                     p_lcb->p_fixed_ccbs[xx] = NULL;
-                }
-#if BLE_INCLUDED == TRUE
-                else if (p_lcb->p_fixed_ccbs[xx] && p_lcb->p_fixed_ccbs[xx] ==
-                                    p_lcb->p_pending_ccb)
-                {
-                    if (p_lcb->p_fixed_ccbs[xx]->local_cid >= L2CAP_ATT_CID &&
-                        p_lcb->p_fixed_ccbs[xx]->local_cid <= L2CAP_SMP_CID)
-                        transport = BT_TRANSPORT_LE;
-                }
+              }
+          }
 #endif
-
-            }
-#endif
-            L2CAP_TRACE_DEBUG("l2c_link_hci_disc_comp: Restarting pending ACL request");
-
+        }
             if (l2cu_create_conn(p_lcb, transport))
                 lcb_is_free = FALSE; /* still using this lcb */
         }
diff --git a/stack/l2cap/l2c_main.c b/stack/l2cap/l2c_main.c
index 96ff2d5..a2cc14c 100644
--- a/stack/l2cap/l2c_main.c
+++ b/stack/l2cap/l2c_main.c
@@ -267,8 +267,12 @@
              (l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb != NULL) )
     {
         /* If no CCB for this channel, allocate one */
-        if (l2cu_initialize_fixed_ccb (p_lcb, rcv_cid, &l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
+        if (p_lcb && l2cu_initialize_fixed_ccb (p_lcb, rcv_cid,
+                &l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
         {
+#if(defined BLE_INCLUDED && (BLE_INCLUDED == TRUE))
+            l2cble_notify_le_connection(p_lcb->remote_bd_addr);
+#endif
             p_ccb = p_lcb->p_fixed_ccbs[rcv_cid - L2CAP_FIRST_FIXED_CHNL];
 
             if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
diff --git a/stack/l2cap/l2c_utils.c b/stack/l2cap/l2c_utils.c
index 242b25f..d0abbdd 100644
--- a/stack/l2cap/l2c_utils.c
+++ b/stack/l2cap/l2c_utils.c
@@ -132,6 +132,9 @@
     p_lcb->in_use     = FALSE;
     p_lcb->is_bonding = FALSE;
 
+#if (BLE_INCLUDED == TRUE)
+    btu_stop_timer(&p_lcb->conn_param_enb);
+#endif
     /* Stop timers */
     btu_stop_timer (&p_lcb->timer_entry);
     btu_stop_timer (&p_lcb->info_timer_entry);
@@ -2899,13 +2902,16 @@
     {
         if (p_lcb->p_fixed_ccbs[xx])
         {
-            l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
-            p_lcb->p_fixed_ccbs[xx] = NULL;
+            if (p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb)
+            {
+                l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
+                p_lcb->p_fixed_ccbs[xx] = NULL;
 #if BLE_INCLUDED == TRUE
             (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
 #else
             (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
 #endif
+           }
         }
         else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
                && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) )