DO NOT MERGE Allow simultaneous LE Observe and BTM Inquiry/Scan

This patch allows BTM inquiry and LE observe to be launched
and overlap each others' occurance by redirecting results
and handling states accordingly.

CRs-Fixed: 579505

Conflicts:
	stack/btm/btm_ble_gap.c
bug 12939764

Change-Id: Ifde73f17f8d40e9ebfff3b49e409591189574ee0
diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c
index 47ee8cf..6e4ff9b 100644
--- a/stack/btm/btm_ble_gap.c
+++ b/stack/btm/btm_ble_gap.c
@@ -153,7 +153,7 @@
     tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
     tBTM_STATUS     status = BTM_NO_RESOURCES;
 
-    BTM_TRACE_EVENT0 ("BTM_BleObserve ");
+    BTM_TRACE_EVENT1 ("BTM_BleObserve : scan_type:%d",btm_cb.btm_inq_vars.scan_type);
 
     if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
         return BTM_ILLEGAL_VALUE;
@@ -162,10 +162,22 @@
     {
         /* shared inquiry database, do not allow observe if any inquiry is active */
         if (btm_cb.btm_inq_vars.inq_active || p_inq->proc_mode != BTM_BLE_INQUIRY_NONE)
-            return BTM_BUSY;
-
-        btm_cb.btm_inq_vars.p_inq_results_cb = p_results_cb;
-        btm_cb.btm_inq_vars.p_inq_cmpl_cb = p_cmpl_cb;
+        {
+            /*check if an interleave scan is already in progress*/
+            if(btm_cb.btm_inq_vars.scan_type == INQ_GENERAL
+                && btm_cb.btm_inq_vars.p_inq_results_cb != NULL)
+            {
+                BTM_TRACE_EVENT0 ("BTM_BleObserve general inq in progress, redirecting the results");
+                btm_cb.btm_inq_vars.p_inq_ble_results_cb = p_results_cb;
+                btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = p_cmpl_cb;
+                return BTM_SUCCESS;
+            }
+            else
+                return BTM_BUSY;
+        }
+        btm_cb.btm_inq_vars.scan_type = INQ_LE_OBSERVE;
+        btm_cb.btm_inq_vars.p_inq_ble_results_cb = p_results_cb;
+        btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = p_cmpl_cb;
         p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI: p_inq->scan_type;
 
         /* allow config scanning type */
@@ -190,10 +202,19 @@
             }
         }
     }
-    else if (p_inq->proc_mode == BTM_BLE_OBSERVE)
+    else/*start = 0*/
     {
-        btm_cb.btm_inq_vars.inq_active &= ~BTM_LE_OBSERVE_ACTIVE;
-        btm_ble_stop_scan();
+        if(btm_cb.btm_inq_vars.scan_type == INQ_GENERAL)
+        {
+            //Dont stop the scan. Just nullify the cbs
+            btm_cb.btm_inq_vars.p_inq_ble_results_cb = NULL;
+            btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = NULL;
+        }
+        else if (p_inq->proc_mode == BTM_BLE_OBSERVE)
+        {
+            btm_cb.btm_inq_vars.inq_active &= ~BTM_LE_OBSERVE_ACTIVE;
+            btm_ble_stop_scan();
+        }
     }
 
     return status;
@@ -1540,6 +1561,8 @@
     if ((btm_cb.ble_ctr_cb.inq_var.scan_type == BTM_BLE_SCAN_MODE_ACTI &&
          (evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_DISCOVER_EVT)))
     {
+        BTM_TRACE_DEBUG1("btm_ble_update_inq_result scan_rsp=false, to_report=false,\
+                              scan_type_active=%d", btm_cb.ble_ctr_cb.inq_var.scan_type);
         p_i->scan_rsp = FALSE;
         to_report = FALSE;
     }
@@ -1669,6 +1692,8 @@
          btm_cb.ble_ctr_cb.p_select_cback == NULL))
         return;
 
+    BTM_TRACE_DEBUG6("btm_ble_process_adv_pkt:bda= %0x:%0x:%0x:%0x:%0x:%0x",
+                                     bda[0],bda[1],bda[2],bda[3],bda[4],bda[5]);
     btm_ble_process_adv_pkt_cont(bda, addr_type, evt_type, p);
 }
 
@@ -1688,9 +1713,12 @@
 {
     tINQ_DB_ENT          *p_i;
     BOOLEAN              to_report = FALSE;
+    BOOLEAN              to_report_LE = TRUE; //var for reporting to LE observe
     tBTM_INQUIRY_VAR_ST  *p_inq = &btm_cb.btm_inq_vars;
     tBTM_INQ_RESULTS_CB  *p_inq_results_cb = p_inq->p_inq_results_cb;
+    tBTM_INQ_RESULTS_CB  *p_inq_ble_results_cb = p_inq->p_inq_ble_results_cb;
     tBTM_BLE_INQ_CB      *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
+    BTM_TRACE_DEBUG2("btm_ble_process_adv_pkt_cont: addr_type: %d, evt_type: %d", addr_type, evt_type);
 
     p_i = btm_inq_db_find (bda);
 
@@ -1710,11 +1738,10 @@
         }
         else
         {
-            /* if yes, skip it */
-            return; /* assumption: one result per event */
+            to_report = FALSE;
         }
     }
-    else /* not been processed int his round */
+    else /* not been processed in this round */
     {
         to_report = TRUE;
     }
@@ -1722,33 +1749,31 @@
     /* If existing entry, use that, else get  a new one (possibly reusing the oldest) */
     if (p_i == NULL)
     {
-        if (btm_ble_is_discoverable(bda, evt_type, p))
+        if ((p_i = btm_inq_db_new (bda)) != NULL)
         {
-            if ((p_i = btm_inq_db_new (bda)) != NULL)
-            {
-                p_inq->inq_cmpl_info.num_resp++;
-                to_report = TRUE;
-            }
-            else
-                return;
+            p_inq->inq_cmpl_info.num_resp++;
+        }
+        else
+            return;
+
+        if (to_report && btm_ble_is_discoverable(bda, evt_type, p))
+        {
+            to_report = TRUE;
         }
         else
         {
             BTM_TRACE_ERROR0("discard adv pkt");
-            return;
+            to_report = FALSE;
         }
     }
     else if (p_i->inq_count != p_inq->inq_counter) /* first time seen in this inquiry */
     {
         p_inq->inq_cmpl_info.num_resp++;
     }
-
     /* update the LE device information in inquiry database */
+    to_report_LE = btm_ble_update_inq_result(p_i, addr_type, evt_type, p);
     if (to_report)
-    {
-        to_report = btm_ble_update_inq_result(p_i, addr_type, evt_type, p);
-    }
-
+        to_report = to_report_LE;
 #if BTM_USE_INQ_RESULTS_FILTER == TRUE
     /* If the number of responses found and limited, issue a cancel inquiry */
     if (p_inq->inqparms.max_resps &&
@@ -1776,6 +1801,8 @@
     }
 #endif
 
+    BTM_TRACE_DEBUG2("btm_ble_process_adv_pkt_cont: to_report =%d, to_report_le=%d",
+                                                               to_report, to_report_LE);
     /* background connection in selective connection mode */
     if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE)
     {
@@ -1787,9 +1814,13 @@
             BTM_TRACE_DEBUG0("None LE device, can not initiate selective connection");
         }
     }
-    else if (p_inq_results_cb && to_report)
+    else if (to_report || to_report_LE)
     {
-        (p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
+        if(p_inq_results_cb && to_report)
+            (p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
+        if(p_inq_ble_results_cb && to_report_LE)
+            (p_inq_ble_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results,
+                                                      p_le_inq_cb->adv_data_cache);
     }
 }
 
diff --git a/stack/btm/btm_inq.c b/stack/btm/btm_inq.c
index 4c5eecb..24f91a8 100644
--- a/stack/btm/btm_inq.c
+++ b/stack/btm/btm_inq.c
@@ -810,8 +810,8 @@
          */
 #endif
 
-        p_inq->inq_counter++;
-        btm_clr_inq_result_flt();
+         p_inq->inq_counter++;
+         btm_clr_inq_result_flt();
     }
 
     return (status);
@@ -860,7 +860,27 @@
     /* Only one active inquiry is allowed in this implementation.
        Also do not allow an inquiry if the inquiry filter is being updated */
     if (p_inq->inq_active || p_inq->inqfilt_active)
-        return (BTM_BUSY);
+    {
+#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
+        /*check if LE observe is already running*/
+        if(p_inq->scan_type==INQ_LE_OBSERVE && p_inq->p_inq_ble_results_cb!=NULL)
+        {
+            BTM_TRACE_API0("BTM_StartInquiry: LE observe in progress");
+            p_inq->scan_type = INQ_GENERAL;
+            p_inq->inq_active = BTM_INQUIRY_INACTIVE;
+            btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
+            btm_cb.ble_ctr_cb.inq_var.proc_mode = BTM_BLE_INQUIRY_NONE;
+            btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
+        }
+        else
+#endif
+        {
+            return (BTM_BUSY);
+            BTM_TRACE_API0("BTM_StartInquiry: return BUSY");
+        }
+    }
+    else
+        p_inq->scan_type = INQ_GENERAL;
 
         /*** Make sure the device is ready ***/
     if (!BTM_IsDeviceUp())
@@ -2402,7 +2422,13 @@
     p_inq->inqparms.mode &= ~(mode);
 #endif
 
-
+    if(p_inq->scan_type == INQ_LE_OBSERVE && !p_inq->inq_active)
+    {
+        /*end of LE observe*/
+        p_inq->p_inq_ble_results_cb = (tBTM_INQ_RESULTS_CB *) NULL;
+        p_inq->p_inq_ble_cmpl_cb = (tBTM_CMPL_CB *) NULL;
+        p_inq->scan_type=INQ_NONE;
+    }
 
 
 #if (BTM_INQ_DEBUG == TRUE)
@@ -2473,9 +2499,22 @@
                 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
                 /* call the inquiry again */
                 BTM_StartInquiry(&p_inq->inqparms,p_inq->p_inq_results_cb,p_inq->p_inq_cmpl_cb);
+                return;
             }
 #endif
     }
+    if(p_inq->inqparms.mode == 0 && p_inq->scan_type == INQ_GENERAL)//this inquiry is complete
+    {
+        p_inq->scan_type = INQ_NONE;
+#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
+        /* check if the LE observe is pending */
+        if(p_inq->p_inq_ble_results_cb != NULL)
+        {
+            BTM_TRACE_DEBUG0("BTM Inq Compl: resuming a pending LE scan");
+            BTM_BleObserve(1,0, p_inq->p_inq_ble_results_cb, p_inq->p_inq_ble_cmpl_cb);
+        }
+#endif
+    }
 #if (BTM_INQ_DEBUG == TRUE)
     BTM_TRACE_DEBUG3 ("inq_active:0x%x state:%d inqfilt_active:%d",
         btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h
index 16a02e6..e449d48 100644
--- a/stack/btm/btm_int.h
+++ b/stack/btm/btm_int.h
@@ -271,6 +271,14 @@
 } tINQ_DB_ENT;
 
 
+enum
+{
+    INQ_NONE,
+    INQ_LE_OBSERVE,
+    INQ_GENERAL
+};
+typedef UINT8 tBTM_INQ_TYPE;
+
 typedef struct
 {
     tBTM_CMPL_CB *p_remname_cmpl_cb;
@@ -288,6 +296,7 @@
     UINT16           inq_scan_period;
     UINT16           inq_scan_type;
     UINT16           page_scan_type;        /* current page scan type */
+    tBTM_INQ_TYPE    scan_type;
 
     BD_ADDR          remname_bda;           /* Name of bd addr for active remote name request */
 #define BTM_RMT_NAME_INACTIVE       0
@@ -298,6 +307,8 @@
 
     tBTM_CMPL_CB    *p_inq_cmpl_cb;
     tBTM_INQ_RESULTS_CB *p_inq_results_cb;
+    tBTM_CMPL_CB    *p_inq_ble_cmpl_cb;     /*completion callback exclusively for LE Observe*/
+    tBTM_INQ_RESULTS_CB *p_inq_ble_results_cb;/*results callback exclusively for LE observe*/
     tBTM_CMPL_CB    *p_inqfilter_cmpl_cb;   /* Called (if not NULL) after inquiry filter completed */
     tBTM_INQ_DB_CHANGE_CB *p_inq_change_cb; /* Inquiry database changed callback    */
     UINT32           inq_counter;           /* Counter incremented each time an inquiry completes */