diff --git a/system/bta/csis/csis_client.cc b/system/bta/csis/csis_client.cc index 187a1fcb309249a6dcf8928b46246b9546d963bf..a615c87d0220fc7839d00ef7a368b7fe50c2cf68 100644 --- a/system/bta/csis/csis_client.cc +++ b/system/bta/csis/csis_client.cc @@ -1281,7 +1281,7 @@ class CsisClientImpl : public CsisClient { instance->OnActiveScanResult(&p_data->inq_res); }); - BTA_DmBleScan(enable, bluetooth::csis::kDefaultScanDurationS); + BTA_DmBleScan(enable, bluetooth::csis::kDefaultScanDurationS, true); /* Need to call it by ourselfs */ if (!enable) { diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc index 61e022086714a3f6c2ca7ac7768fbf8215756add..a17058eb2165fca9408a26827ee51acc05789522 100644 --- a/system/bta/dm/bta_dm_act.cc +++ b/system/bta/dm/bta_dm_act.cc @@ -4016,9 +4016,11 @@ void bta_dm_ble_config_local_privacy(bool privacy_enable) { BTM_BleConfigPrivacy(privacy_enable); } -static void bta_dm_start_scan(uint8_t duration_sec) { - tBTM_STATUS status = BTM_BleObserve( - true, duration_sec, bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb); +static void bta_dm_start_scan(uint8_t duration_sec, + bool low_latency_scan = false) { + tBTM_STATUS status = + BTM_BleObserve(true, duration_sec, bta_dm_observe_results_cb, + bta_dm_observe_cmpl_cb, low_latency_scan); if (status != BTM_CMD_STARTED) { tBTA_DM_SEARCH data = { @@ -4051,7 +4053,8 @@ void bta_dm_ble_observe(bool start, uint8_t duration, bta_dm_start_scan(duration); } -void bta_dm_ble_scan(bool start, uint8_t duration_sec) { +void bta_dm_ble_scan(bool start, uint8_t duration_sec, + bool low_latency_scan = false) { /* Start or stop only if there is no active main scanner */ if (bta_dm_search_cb.p_scan_cback != NULL) return; @@ -4060,7 +4063,7 @@ void bta_dm_ble_scan(bool start, uint8_t duration_sec) { return; } - bta_dm_start_scan(duration_sec); + bta_dm_start_scan(duration_sec, low_latency_scan); } void bta_dm_ble_csis_observe(bool observe, tBTA_DM_SEARCH_CBACK* p_cback) { diff --git a/system/bta/dm/bta_dm_api.cc b/system/bta/dm/bta_dm_api.cc index 325d82ef75ba63e007a0285ace50d02a108ae8c2..72a99d47faeaba442eabe92c5cec7ecdc361d3c6 100644 --- a/system/bta/dm/bta_dm_api.cc +++ b/system/bta/dm/bta_dm_api.cc @@ -605,14 +605,16 @@ void BTA_DmBleObserve(bool start, uint8_t duration, * Parameters start: start or stop the scan procedure, * duration_sec: Duration of the scan. Continuous scan if 0 is * passed, + * low_latency_scan: whether this is an low latency scan, + * default is false. * * Returns void * ******************************************************************************/ -void BTA_DmBleScan(bool start, uint8_t duration_sec) { +void BTA_DmBleScan(bool start, uint8_t duration_sec, bool low_latency_scan) { APPL_TRACE_API("%s:start = %d ", __func__, start); - do_in_main_thread(FROM_HERE, - base::Bind(bta_dm_ble_scan, start, duration_sec)); + do_in_main_thread(FROM_HERE, base::Bind(bta_dm_ble_scan, start, duration_sec, + low_latency_scan)); } /******************************************************************************* diff --git a/system/bta/dm/bta_dm_int.h b/system/bta/dm/bta_dm_int.h index 947d5ab5a7b695c39c0b0c6e62e1aef5af150f74..96f1f16ad0a1cb38de02916ea6ec30ec33f45f7c 100644 --- a/system/bta/dm/bta_dm_int.h +++ b/system/bta/dm/bta_dm_int.h @@ -538,7 +538,7 @@ void bta_dm_ble_set_conn_params(const RawAddress&, uint16_t, uint16_t, uint16_t, uint16_t); void bta_dm_close_gatt_conn(tBTA_DM_MSG* p_data); void bta_dm_ble_observe(bool, uint8_t, tBTA_DM_SEARCH_CBACK*); -void bta_dm_ble_scan(bool, uint8_t); +void bta_dm_ble_scan(bool, uint8_t, bool); void bta_dm_ble_csis_observe(bool, tBTA_DM_SEARCH_CBACK*); void bta_dm_ble_update_conn_params(const RawAddress&, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t); diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h index 97a574873161b46ccc55b149613ef04f7a5a5304..c395672f55f477542da47c772001e23825d9f0f9 100644 --- a/system/bta/include/bta_api.h +++ b/system/bta/include/bta_api.h @@ -1146,11 +1146,13 @@ void BTA_DmBleObserve(bool start, uint8_t duration, * Parameters start: start or stop the scan procedure, * duration_sec: Duration of the scan. Continuous scan if 0 is * passed, + * low_latency_scan: whether this is a low latency scan, + * default is false, * * Returns void * ******************************************************************************/ -void BTA_DmBleScan(bool start, uint8_t duration); +void BTA_DmBleScan(bool start, uint8_t duration, bool low_latency_scan = false); /******************************************************************************* * diff --git a/system/bta/test/common/bta_dm_api_mock.cc b/system/bta/test/common/bta_dm_api_mock.cc index 6a89920fee0f024c44a49ac4cdc846533025cb4c..e0c9941e3ff6eab6b11183bec3a9ea6dd7ea712f 100644 --- a/system/bta/test/common/bta_dm_api_mock.cc +++ b/system/bta/test/common/bta_dm_api_mock.cc @@ -23,9 +23,9 @@ void dm::SetMockBtaDmInterface(MockBtaDmInterface* mock_bta_dm_interface) { dm_interface = mock_bta_dm_interface; } -void BTA_DmBleScan(bool start, uint8_t duration) { +void BTA_DmBleScan(bool start, uint8_t duration, bool low_latency_scan) { LOG_ASSERT(dm_interface) << "Mock BTA DM interface not set!"; - return dm_interface->BTA_DmBleScan(start, duration); + return dm_interface->BTA_DmBleScan(start, duration, low_latency_scan); } void BTA_DmBleCsisObserve(bool observe, tBTA_DM_SEARCH_CBACK* p_results_cb) { diff --git a/system/bta/test/common/bta_dm_api_mock.h b/system/bta/test/common/bta_dm_api_mock.h index 9be98faaca2da501759351beebb41ce2d39410ec..9093bd3b296ca1ace2468cd8483e6d773bf2a725 100644 --- a/system/bta/test/common/bta_dm_api_mock.h +++ b/system/bta/test/common/bta_dm_api_mock.h @@ -26,7 +26,8 @@ namespace dm { class BtaDmInterface { public: - virtual void BTA_DmBleScan(bool start, uint8_t duration) = 0; + virtual void BTA_DmBleScan(bool start, uint8_t duration, + bool low_latency_scan) = 0; virtual void BTA_DmBleCsisObserve(bool observe, tBTA_DM_SEARCH_CBACK* p_results_cb) = 0; virtual ~BtaDmInterface() = default; @@ -34,7 +35,8 @@ class BtaDmInterface { class MockBtaDmInterface : public BtaDmInterface { public: - MOCK_METHOD((void), BTA_DmBleScan, (bool start, uint8_t duration)); + MOCK_METHOD((void), BTA_DmBleScan, + (bool start, uint8_t duration, bool low_latency_scan)); MOCK_METHOD((void), BTA_DmBleCsisObserve, (bool observe, tBTA_DM_SEARCH_CBACK* p_results_cb)); }; diff --git a/system/stack/btm/btm_ble_gap.cc b/system/stack/btm/btm_ble_gap.cc index 40440259a94e925a734a754619b04ae811661037..0f630763846f2ba0385c533506cd2b4ba8037570 100644 --- a/system/stack/btm/btm_ble_gap.cc +++ b/system/stack/btm/btm_ble_gap.cc @@ -492,13 +492,15 @@ void BTM_BleTargetAnnouncementObserve(bool enable, * duration: how long the scan should last, in seconds. 0 means * scan without timeout. Starting the scan second time without * timeout will disable the timer. + * low_latency_scan: whether this is a low latency scan, + * default is false. * * Returns void * ******************************************************************************/ tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration, tBTM_INQ_RESULTS_CB* p_results_cb, - tBTM_CMPL_CB* p_cmpl_cb) { + tBTM_CMPL_CB* p_cmpl_cb, bool low_latency_scan) { tBTM_BLE_INQ_CB* p_inq = &btm_cb.ble_ctr_cb.inq_var; tBTM_STATUS status = BTM_WRONG_MODE; @@ -507,13 +509,21 @@ tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration, uint32_t scan_window = !p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window; + // use low latency scanning if the scanning is active + if (low_latency_scan) { + scan_interval = BTM_BLE_LOW_LATENCY_SCAN_INT; + scan_window = BTM_BLE_LOW_LATENCY_SCAN_WIN; + } + BTM_TRACE_EVENT("%s : scan_type:%d, %d, %d", __func__, p_inq->scan_type, - p_inq->scan_interval, p_inq->scan_window); + scan_interval, scan_window); if (!controller_get_interface()->supports_ble()) return BTM_ILLEGAL_VALUE; if (start) { - /* shared inquiry database, do not allow observe if any inquiry is active */ + /* shared inquiry database, do not allow observe if any inquiry is active. + * except we are doing CSIS active scanning + */ if (btm_cb.ble_ctr_cb.is_ble_observe_active()) { if (duration == 0) { if (alarm_is_scheduled(btm_cb.ble_ctr_cb.observer_timer)) { @@ -522,12 +532,26 @@ tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration, BTM_TRACE_ERROR("%s Scan with no duration started twice!", __func__); } } else { - if (alarm_is_scheduled(btm_cb.ble_ctr_cb.observer_timer)) { + if (!low_latency_scan && + alarm_is_scheduled(btm_cb.ble_ctr_cb.observer_timer)) { BTM_TRACE_ERROR("%s Scan with duration started twice!", __func__); } } - BTM_TRACE_WARNING("%s Observer was already active", __func__); - return BTM_CMD_STARTED; + /* + * we stop current observation request for below scenarios + * 1. if the scan we wish to start is not low latency + * 2. current ongoing scanning is low latency + */ + bool is_ongoing_low_latency = + p_inq->scan_interval == BTM_BLE_GAP_DISC_SCAN_INT && + p_inq->scan_window == BTM_BLE_LOW_LATENCY_SCAN_WIN; + if (!low_latency_scan || is_ongoing_low_latency) { + BTM_TRACE_WARNING("%s Observer was already active, is_low_latency: %d", + __func__, is_ongoing_low_latency); + return BTM_CMD_STARTED; + } + // stop any scan without low latency config + btm_ble_stop_observe(); } btm_cb.ble_ctr_cb.p_obs_results_cb = p_results_cb; @@ -552,7 +576,10 @@ tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration, .start_time_ms = timestamper_in_milliseconds.GetTimestamp(), .results = 0, }; - BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "Le observe started"); + + BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "Le observe started", + base::StringPrintf("low latency scanning enabled: %d", + low_latency_scan)); if (status == BTM_CMD_STARTED) { btm_cb.ble_ctr_cb.set_ble_observe_active(); diff --git a/system/stack/include/btm_ble_api.h b/system/stack/include/btm_ble_api.h index dadfdaf64172993f587a5146e4ea6157027bf621..d204dc2582b17ac8ae51a36a19810fdd3c2129b4 100644 --- a/system/stack/include/btm_ble_api.h +++ b/system/stack/include/btm_ble_api.h @@ -165,13 +165,16 @@ void BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK* p_track_cback, * duration: how long the scan should last, in seconds. 0 means * scan without timeout. Starting the scan second time without * timeout will disable the timer. + * low_latency_scan: whether this is a low latency scan, + * default is false. * * Returns void * ******************************************************************************/ tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration, tBTM_INQ_RESULTS_CB* p_results_cb, - tBTM_CMPL_CB* p_cmpl_cb); + tBTM_CMPL_CB* p_cmpl_cb, + bool low_latency_scan = false); /******************************************************************************* * diff --git a/system/stack/include/btm_client_interface.h b/system/stack/include/btm_client_interface.h index ca333dfe7db6960448910eb9c14480609cd4f691..24669beef29b7a48744b84fbe8171c9ac04645bc 100644 --- a/system/stack/include/btm_client_interface.h +++ b/system/stack/include/btm_client_interface.h @@ -166,7 +166,8 @@ struct btm_client_interface_t { tBTM_STATUS (*BTM_BleGetEnergyInfo)(tBTM_BLE_ENERGY_INFO_CBACK* callback); tBTM_STATUS (*BTM_BleObserve)(bool start, uint8_t duration, tBTM_INQ_RESULTS_CB* p_results_cb, - tBTM_CMPL_CB* p_cmpl_cb); + tBTM_CMPL_CB* p_cmpl_cb, + bool low_latency_scan); tBTM_STATUS (*BTM_SetBleDataLength)(const RawAddress& bd_addr, uint16_t tx_pdu_length); void (*BTM_BleConfirmReply)(const RawAddress& bd_addr, uint8_t res); diff --git a/system/test/mock/mock_bta_dm_api.cc b/system/test/mock/mock_bta_dm_api.cc index c61070b715913bcb875cf537a2d648c5abe2195d..8b54c5896270cc0b0c236c6cc7eb6f3c3a033254 100644 --- a/system/test/mock/mock_bta_dm_api.cc +++ b/system/test/mock/mock_bta_dm_api.cc @@ -123,9 +123,9 @@ void BTA_DmBleRequestMaxTxDataLength(const RawAddress& remote_device) { inc_func_call_count(__func__); test::mock::bta_dm_api::BTA_DmBleRequestMaxTxDataLength(remote_device); } -void BTA_DmBleScan(bool start, uint8_t duration) { +void BTA_DmBleScan(bool start, uint8_t duration, bool low_latency_scan) { inc_func_call_count(__func__); - test::mock::bta_dm_api::BTA_DmBleScan(start, duration); + test::mock::bta_dm_api::BTA_DmBleScan(start, duration, low_latency_scan); } void BTA_DmBleSecurityGrant(const RawAddress& bd_addr, tBTA_DM_BLE_SEC_GRANT res) { diff --git a/system/test/mock/mock_bta_dm_api.h b/system/test/mock/mock_bta_dm_api.h index cd3473ee745da7ed47a5b0d30633e158d755beb8..1be9353e0253169ab0a19dea76bc102a4391de8e 100644 --- a/system/test/mock/mock_bta_dm_api.h +++ b/system/test/mock/mock_bta_dm_api.h @@ -186,12 +186,14 @@ struct BTA_DmBleRequestMaxTxDataLength { extern struct BTA_DmBleRequestMaxTxDataLength BTA_DmBleRequestMaxTxDataLength; // Name: BTA_DmBleScan -// Params: bool start, uint8_t duration +// Params: bool start, uint8_t duration, bool low_latency_scan // Return: void struct BTA_DmBleScan { - std::function<void(bool start, uint8_t duration)> body{ - [](bool start, uint8_t duration) {}}; - void operator()(bool start, uint8_t duration) { body(start, duration); }; + std::function<void(bool start, uint8_t duration, bool low_latency_scan)> body{ + [](bool start, uint8_t duration, bool low_latency_scan) {}}; + void operator()(bool start, uint8_t duration, bool low_latency_scan) { + body(start, duration, low_latency_scan); + }; }; extern struct BTA_DmBleScan BTA_DmBleScan; diff --git a/system/test/mock/mock_stack_btm.cc b/system/test/mock/mock_stack_btm.cc index 90a8669d1d9596dd4d2ef04d0c28007e67cb8c43..475a45780c79422c803931b1e638477b1442f1d2 100644 --- a/system/test/mock/mock_stack_btm.cc +++ b/system/test/mock/mock_stack_btm.cc @@ -203,7 +203,8 @@ struct btm_client_interface_t btm_client_interface = { tBTM_BLE_LOCAL_KEYS* p_key) {}, .BTM_BleObserve = [](bool start, uint8_t duration, tBTM_INQ_RESULTS_CB* p_results_cb, - tBTM_CMPL_CB* p_cmpl_cb) -> tBTM_STATUS { return BTM_SUCCESS; }, + tBTM_CMPL_CB* p_cmpl_cb, + bool low_latency_scan) -> tBTM_STATUS { return BTM_SUCCESS; }, .BTM_BlePasskeyReply = [](const RawAddress& bd_addr, uint8_t res, uint32_t passkey) {}, .BTM_BleReadControllerFeatures = diff --git a/system/test/mock/mock_stack_btm_ble_gap.cc b/system/test/mock/mock_stack_btm_ble_gap.cc index a69a0e642d863fd5a7a6dd92a982b4fd119a308b..82c99df7bb1dc4df67dc6bdf5ef98cd3c88ca31b 100644 --- a/system/test/mock/mock_stack_btm_ble_gap.cc +++ b/system/test/mock/mock_stack_btm_ble_gap.cc @@ -90,7 +90,7 @@ bool btm_ble_topology_check(tBTM_BLE_STATE_MASK request_state_mask) { } tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration, tBTM_INQ_RESULTS_CB* p_results_cb, - tBTM_CMPL_CB* p_cmpl_cb) { + tBTM_CMPL_CB* p_cmpl_cb, bool low_latency_scan) { inc_func_call_count(__func__); return BTM_SUCCESS; }