Interleave br/edr device discovery with BLE device scan for some targets

This change only applies to targets which do not support interleaved scan
in controller.
bug 8508849

Change-Id: Ia99faf92c942b4b33abfde2708eff25ec9cd5468
diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h
index dd1d298..e52e699 100644
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -283,6 +283,9 @@
     BOOLEAN             report_dup;     /* report duplicated inquiry response with higher RSSI value */
     tBTA_DM_INQ_FILT    filter_type;    /* Filter condition type. */
     tBTA_DM_INQ_COND    filter_cond;    /* Filter condition data. */
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+    UINT8               intl_duration[4];/*duration array storing the interleave scan's time portions*/
+#endif
 } tBTA_DM_INQ;
 
 typedef struct
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
index ca506ab..20089ac 100644
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -70,6 +70,13 @@
     #error "default btif local name size exceeds stack supported length"
 #endif
 
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+#define BTIF_DM_INTERLEAVE_DURATION_BR_ONE    2
+#define BTIF_DM_INTERLEAVE_DURATION_LE_ONE    2
+#define BTIF_DM_INTERLEAVE_DURATION_BR_TWO    3
+#define BTIF_DM_INTERLEAVE_DURATION_LE_TWO    4
+#endif
+
 typedef struct
 {
     bt_bond_state_t state;
@@ -1792,6 +1799,12 @@
     /* Set inquiry params and call API */
 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
     inq_params.mode = BTA_DM_GENERAL_INQUIRY|BTA_BLE_GENERAL_INQUIRY;
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+    inq_params.intl_duration[0]= BTIF_DM_INTERLEAVE_DURATION_BR_ONE;
+    inq_params.intl_duration[1]= BTIF_DM_INTERLEAVE_DURATION_LE_ONE;
+    inq_params.intl_duration[2]= BTIF_DM_INTERLEAVE_DURATION_BR_TWO;
+    inq_params.intl_duration[3]= BTIF_DM_INTERLEAVE_DURATION_LE_TWO;
+#endif
 #else
     inq_params.mode = BTA_DM_GENERAL_INQUIRY;
 #endif
diff --git a/include/bt_target.h b/include/bt_target.h
index 7363456..5a22fb8 100644
--- a/include/bt_target.h
+++ b/include/bt_target.h
@@ -53,7 +53,7 @@
 #include "dyn_mem.h"    /* defines static and/or dynamic memory for components */
 
 
-//------------------Added from Bluedroid buildcfg.h---------------------
+//------------------Added from bdroid_buildcfg.h---------------------
 #ifndef UNV_INCLUDED
 #define UNV_INCLUDED FALSE
 #endif
@@ -351,6 +351,11 @@
 #define AVDT_CONNECT_CP_ONLY  FALSE
 #endif
 
+/* This feature is used to eanble interleaved scan*/
+#ifndef BTA_HOST_INTERLEAVE_SEARCH
+#define BTA_HOST_INTERLEAVE_SEARCH FALSE
+#endif
+
 #ifndef BT_TRACE_PROTOCOL
 #define BT_TRACE_PROTOCOL  TRUE
 #endif
@@ -410,7 +415,8 @@
 #ifndef BTIF_DM_OOB_TEST
 #define BTIF_DM_OOB_TEST  TRUE
 #endif
-//------------------End added from Bluedroid buildcfg.h---------------------
+
+//------------------End added from bdroid_buildcfg.h---------------------
 
 
 
diff --git a/stack/btm/btm_inq.c b/stack/btm/btm_inq.c
index b1d9eac..4c5eecb 100644
--- a/stack/btm/btm_inq.c
+++ b/stack/btm/btm_inq.c
@@ -756,7 +756,9 @@
 {
     tBTM_STATUS           status = BTM_SUCCESS;
     tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
-
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+    UINT8 active_mode=p_inq->inq_active;
+#endif
     BTM_TRACE_API0 ("BTM_CancelInquiry called");
 
     /*** Make sure the device is ready ***/
@@ -782,13 +784,21 @@
          /* Initiate the cancel inquiry */
         else
         {
-            if ((p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK) != 0)
+            if (((p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK) != 0)
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+            &&(active_mode & BTM_BR_INQUIRY_MASK)
+#endif
+            )
             {
                 if (!btsnd_hcic_inq_cancel())
                     status = BTM_NO_RESOURCES;
             }
 #if BLE_INCLUDED == TRUE
-            if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
+            if (((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+            &&(active_mode & BTM_LE_INQ_ACTIVE_MASK)
+#endif
+            )
                 btm_ble_stop_scan();
 #endif
         }
@@ -865,6 +875,12 @@
         )
         return (BTM_ILLEGAL_VALUE);
 
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+        if(p_inq->next_state==BTM_FINISH)
+            return BTM_ILLEGAL_VALUE;
+#endif
+
+
     /* Save the inquiry parameters to be used upon the completion of setting/clearing the inquiry filter */
     p_inq->inqparms = *p_inqparms;
 
@@ -877,10 +893,40 @@
 
     BTM_TRACE_DEBUG1("BTM_StartInquiry: p_inq->inq_active = 0x%02x", p_inq->inq_active);
 
+/* interleave scan minimal conditions */
+#if (BLE_INCLUDED==TRUE && (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE))
+
+    /* check if both modes are present */
+    if((p_inqparms->mode & BTM_BLE_INQUIRY_MASK) && (p_inqparms->mode & BTM_BR_INQUIRY_MASK))
+    {
+        BTM_TRACE_API0("BTM:Interleave Inquiry Mode Set");
+        p_inqparms->duration=p_inqparms->intl_duration[p_inq->next_state];
+        p_inq->inqparms.duration=p_inqparms->duration;
+    }
+    else
+    {
+        BTM_TRACE_API1("BTM:Single Mode: No interleaving, Mode:0x%02x", p_inqparms->mode);
+        p_inq->next_state=BTM_NO_INTERLEAVING;
+    }
+#endif
+
+
+
 /* start LE inquiry here if requested */
 #if BLE_INCLUDED == TRUE
-    if (p_inqparms->mode & BTM_BLE_INQUIRY_MASK)
+    if ((p_inqparms->mode & BTM_BLE_INQUIRY_MASK)
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+        &&(p_inq->next_state==BTM_BLE_ONE || p_inq->next_state==BTM_BLE_TWO ||
+           p_inq->next_state==BTM_NO_INTERLEAVING)
+#endif
+        )
+
     {
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+        p_inq->inq_active = (p_inqparms->mode & BTM_BLE_INQUIRY_MASK);
+        BTM_TRACE_API2("BTM:Starting LE Scan with duration %d and activeMode:0x%02x",
+                       p_inqparms->duration, (p_inqparms->mode & BTM_BLE_INQUIRY_MASK));
+#endif
         if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
         {
             p_inq->inqparms.mode &= ~ BTM_BLE_INQUIRY_MASK;
@@ -893,8 +939,29 @@
             BTM_TRACE_ERROR0("Err Starting LE Inquiry.");
             p_inq->inqparms.mode &= ~ BTM_BLE_INQUIRY_MASK;
         }
-
+#if (!defined(BTA_HOST_INTERLEAVE_SEARCH) || BTA_HOST_INTERLEAVE_SEARCH == FALSE)
         p_inqparms->mode &= ~BTM_BLE_INQUIRY_MASK;
+#endif
+
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+        if(p_inq->next_state==BTM_NO_INTERLEAVING)
+        {
+            p_inq->next_state=BTM_FINISH;
+        }
+        else
+        {
+            BTM_TRACE_API1("BTM:Interleaving: started LE scan, Advancing to next state: %d",
+                           p_inq->next_state+1);
+            p_inq->next_state+=1;
+        }
+        /* reset next_state if status <> BTM_Started */
+        if(status!=BTM_CMD_STARTED)
+            p_inq->next_state=BTM_BR_ONE;
+
+        /* if interleave scan..return here */
+        return status;
+#endif
+
 
         BTM_TRACE_DEBUG1("BTM_StartInquiry: mode = %02x", p_inqparms->mode);
     }
@@ -904,6 +971,13 @@
     if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK) == BTM_INQUIRY_NONE)
         return status;
 
+    /* BR/EDR inquiry portion */
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+    if((p_inq->next_state==BTM_BR_ONE || p_inq->next_state==BTM_BR_TWO ||
+        p_inq->next_state==BTM_NO_INTERLEAVING ))
+    {
+        p_inq->inq_active = (p_inqparms->mode & BTM_BR_INQUIRY_MASK);
+#endif
 #if (defined(BTM_BYPASS_EVENT_FILTERING) && BTM_BYPASS_EVENT_FILTERING == TRUE)
     BTM_TRACE_WARNING0("BTM: Bypassing event filtering...");
     p_inq->inqfilt_active = FALSE;
@@ -934,9 +1008,32 @@
     }
 
     /* Before beginning the inquiry the current filter must be cleared, so initiate the command */
-    if ((status = btm_set_inq_event_filter (p_inqparms->filter_cond_type, &p_inqparms->filter_cond)) != BTM_CMD_STARTED)
+    if ((status = btm_set_inq_event_filter (p_inqparms->filter_cond_type,
+                                            &p_inqparms->filter_cond)) != BTM_CMD_STARTED)
         p_inq->state = BTM_INQ_INACTIVE_STATE;
 #endif
+
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+        if (p_inq->next_state==BTM_NO_INTERLEAVING)
+            p_inq->next_state=BTM_FINISH;
+        else
+        {
+            BTM_TRACE_API1("BTM:Interleaving: Started BTM inq, Advancing to next state: %d",
+                           p_inq->next_state+1);
+            p_inq->next_state+=1;
+        }
+     }
+     if (status!=BTM_CMD_STARTED)
+     {
+         /* Some error beginning the scan process.
+            Reset the next_state parameter.. Do we need to reset the inq_active also?
+         */
+        BTM_TRACE_API1("BTM:Interleaving: Error in Starting inquiry, status: 0x%02x", status);
+        p_inq->next_state=BTM_BR_ONE;
+     }
+#endif
+
+
     return (status);
 }
 
@@ -2287,8 +2384,26 @@
     tBTM_INQ_INFO  *p_cur;
     UINT8           tempstate;
 #endif
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+    /* inquiry inactive case happens when inquiry is cancelled.
+       Make mode 0 for no further inquiries from the current inquiry process
+    */
+    if(status!=HCI_SUCCESS || p_inq->next_state==BTM_FINISH || !p_inq->inq_active)
+    {
+        /* re-initialize for next inquiry request */
+        p_inq->next_state=BTM_BR_ONE;
+        /* make the mode 0 here */
+        p_inq->inqparms.mode &= ~(p_inq->inqparms.mode);
 
+    }
+#endif
+
+#if (!defined(BTA_HOST_INTERLEAVE_SEARCH) || BTA_HOST_INTERLEAVE_SEARCH == FALSE)
     p_inq->inqparms.mode &= ~(mode);
+#endif
+
+
+
 
 #if (BTM_INQ_DEBUG == TRUE)
     BTM_TRACE_DEBUG3 ("btm_process_inq_complete inq_active:0x%x state:%d inqfilt_active:%d",
@@ -2351,7 +2466,15 @@
             if (p_inq_cb)
                 (p_inq_cb)((tBTM_INQUIRY_CMPL *) &p_inq->inq_cmpl_info);
         }
-
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+            if(p_inq->inqparms.mode != 0 && !(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE))
+            {
+                /* make inquiry inactive for next iteration */
+                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);
+            }
+#endif
     }
 #if (BTM_INQ_DEBUG == TRUE)
     BTM_TRACE_DEBUG3 ("inq_active:0x%x state:%d inqfilt_active:%d",
diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h
index 42bd3ad..2f9b232 100644
--- a/stack/btm/btm_int.h
+++ b/stack/btm/btm_int.h
@@ -326,6 +326,9 @@
     UINT8            state;             /* Current state that the inquiry process is in */
     UINT8            inq_active;        /* Bit Mask indicating type of inquiry is active */
     BOOLEAN          no_inc_ssp;        /* TRUE, to stop inquiry on incoming SSP */
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+    btm_inq_state    next_state;        /*interleaving state to determine next mode to be inquired*/
+#endif
 } tBTM_INQUIRY_VAR_ST;
 
 /* The MSB of the clock offset field indicates that the offset is valid if TRUE */
diff --git a/stack/include/btm_api.h b/stack/include/btm_api.h
index 2181f31..f4b17d4 100644
--- a/stack/include/btm_api.h
+++ b/stack/include/btm_api.h
@@ -67,6 +67,20 @@
 };
 typedef UINT8 tBTM_STATUS;
 
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+typedef enum
+{
+    BTM_BR_ONE,                         /*0 First state or BR/EDR scan 1*/
+    BTM_BLE_ONE,                        /*1BLE scan 1*/
+    BTM_BR_TWO,                         /*2 BR/EDR scan 2*/
+    BTM_BLE_TWO,                        /*3 BLE scan 2*/
+    BTM_FINISH,                         /*4 End of Interleave Scan, or normal scan*/
+    BTM_NO_INTERLEAVING                 /*5 No Interleaving*/
+}btm_inq_state;
+#endif
+
+
+
 /*************************
 **  Device Control Types
 **************************/
@@ -568,6 +582,9 @@
     BOOLEAN report_dup;                 /* report duplicated inquiry response with higher RSSI value */
     UINT8   filter_cond_type;           /* new devices, BD ADDR, COD, or No filtering */
     tBTM_INQ_FILT_COND  filter_cond;    /* filter value based on filter cond type */
+#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
+    UINT8   intl_duration[4];              /*duration array storing the interleave scan's time portions*/
+#endif
 } tBTM_INQ_PARMS;
 
 #define BTM_INQ_RESULT_BR       0x01