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 6963e2a..608fa7e 100644
--- a/stack/btm/btm_ble_gap.c
+++ b/stack/btm/btm_ble_gap.c
@@ -157,7 +157,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;
@@ -166,10 +166,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 */
@@ -194,10 +206,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;
@@ -1595,6 +1616,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;
}
@@ -1748,6 +1771,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]);
#if (defined BTM_BLE_PRIVACY_SPT && BTM_BLE_PRIVACY_SPT == TRUE)
#if SMP_INCLUDED == TRUE
/* always do RRA resolution on host */
@@ -1779,9 +1804,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);
@@ -1801,11 +1829,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;
}
@@ -1813,33 +1840,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 &&
@@ -1867,6 +1892,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)
{
@@ -1878,9 +1905,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 5129efc..7865b3e 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 */