diff options
-rw-r--r-- | framework/api/system-current.txt | 2 | ||||
-rw-r--r-- | framework/java/android/bluetooth/BluetoothLeAudio.java | 2 | ||||
-rw-r--r-- | system/blueberry/tests/gd/cert/gd_device.py | 48 | ||||
-rw-r--r-- | system/blueberry/tests/gd/rust/topshim/facade/topshim_device.py | 5 | ||||
-rwxr-xr-x | system/gd/cert/run_topshim | 2 | ||||
-rw-r--r-- | system/gd/hci/le_scanning_callback.h | 1 | ||||
-rw-r--r-- | system/gd/rust/common/src/sys_prop.rs | 2 | ||||
-rw-r--r-- | system/main/shim/ble_scanner_interface_impl.h | 129 | ||||
-rw-r--r-- | system/main/shim/le_scanning_manager.cc | 910 | ||||
-rw-r--r-- | system/main/shim/le_scanning_manager.h | 4 | ||||
-rw-r--r-- | system/stack/acl/btm_acl.cc | 11 | ||||
-rw-r--r-- | system/stack/btm/btm_sco.cc | 20 | ||||
-rw-r--r-- | system/stack/include/acl_api.h | 1 | ||||
-rw-r--r-- | system/test/mock/mock_main_shim_le_scanning_manager.cc | 2 |
14 files changed, 669 insertions, 470 deletions
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt index 9b3d7a873b..43e1792c26 100644 --- a/framework/api/system-current.txt +++ b/framework/api/system-current.txt @@ -365,8 +365,10 @@ package android.bluetooth { field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED = "android.bluetooth.action.LE_AUDIO_ACTIVE_DEVICE_CHANGED"; field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_LE_AUDIO_GROUP_NODE_STATUS_CHANGED = "android.bluetooth.action.LE_AUDIO_GROUP_NODE_STATUS_CHANGED"; field @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static final String ACTION_LE_AUDIO_GROUP_STATUS_CHANGED = "android.bluetooth.action.LE_AUDIO_GROUP_STATUS_CHANGED"; + field public static final int AUDIO_LOCATION_INVALID = -1; // 0xffffffff field public static final String EXTRA_LE_AUDIO_GROUP_ID = "android.bluetooth.extra.LE_AUDIO_GROUP_ID"; field public static final String EXTRA_LE_AUDIO_GROUP_NODE_STATUS = "android.bluetooth.extra.LE_AUDIO_GROUP_NODE_STATUS"; + field public static final String EXTRA_LE_AUDIO_GROUP_STATUS = "android.bluetooth.extra.LE_AUDIO_GROUP_STATUS"; field public static final int GROUP_NODE_ADDED = 1; // 0x1 field public static final int GROUP_NODE_REMOVED = 2; // 0x2 } diff --git a/framework/java/android/bluetooth/BluetoothLeAudio.java b/framework/java/android/bluetooth/BluetoothLeAudio.java index 3d611efa78..42e9ff75b9 100644 --- a/framework/java/android/bluetooth/BluetoothLeAudio.java +++ b/framework/java/android/bluetooth/BluetoothLeAudio.java @@ -272,6 +272,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { * * @hide */ + @SystemApi public static final int AUDIO_LOCATION_INVALID = -1; /** @@ -307,6 +308,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { * <p> * @hide */ + @SystemApi public static final String EXTRA_LE_AUDIO_GROUP_STATUS = "android.bluetooth.extra.LE_AUDIO_GROUP_STATUS"; diff --git a/system/blueberry/tests/gd/cert/gd_device.py b/system/blueberry/tests/gd/cert/gd_device.py index 297cf52d67..4042e536e8 100644 --- a/system/blueberry/tests/gd/cert/gd_device.py +++ b/system/blueberry/tests/gd/cert/gd_device.py @@ -214,21 +214,25 @@ class GdDeviceBase(ABC): tag=self.label, color=self.terminal_color) - # Setup gRPC management channels - self.grpc_root_server_channel = grpc.insecure_channel("localhost:%d" % self.grpc_root_server_port) + # If gRPC root server port is not specified, we can skip settings up the root server + if self.grpc_root_server_port != -1: + # Setup gRPC management channels + self.grpc_root_server_channel = grpc.insecure_channel("localhost:%d" % self.grpc_root_server_port) - self.grpc_root_server_ready = False - try: - logging.info("[%s] Waiting to connect to gRPC root server for %s, timeout is %d seconds" % - (self.type_identifier, self.label, GRPC_START_TIMEOUT_SEC)) - grpc.channel_ready_future(self.grpc_root_server_channel).result(timeout=GRPC_START_TIMEOUT_SEC) - logging.info("[%s] Successfully connected to gRPC root server for %s" % (self.type_identifier, self.label)) - self.grpc_root_server_ready = True - except grpc.FutureTimeoutError: - logging.error("[%s] Failed to connect to gRPC root server for %s" % (self.type_identifier, self.label)) + self.grpc_root_server_ready = False - asserts.assert_true( - self.grpc_root_server_ready, msg="gRPC root server did not start after running " + " ".join(self.cmd)) + try: + logging.info("[%s] Waiting to connect to gRPC root server for %s, timeout is %d seconds" % + (self.type_identifier, self.label, GRPC_START_TIMEOUT_SEC)) + grpc.channel_ready_future(self.grpc_root_server_channel).result(timeout=GRPC_START_TIMEOUT_SEC) + logging.info( + "[%s] Successfully connected to gRPC root server for %s" % (self.type_identifier, self.label)) + self.grpc_root_server_ready = True + except grpc.FutureTimeoutError: + logging.error("[%s] Failed to connect to gRPC root server for %s" % (self.type_identifier, self.label)) + + asserts.assert_true( + self.grpc_root_server_ready, msg="gRPC root server did not start after running " + " ".join(self.cmd)) self.grpc_channel = grpc.insecure_channel("localhost:%d" % self.grpc_port) @@ -236,7 +240,9 @@ class GdDeviceBase(ABC): self.grpc_channel = grpc.intercept_channel(self.grpc_channel, LoggingClientInterceptor(self.label)) # Establish services from facades - self.rootservice = facade_rootservice_pb2_grpc.RootFacadeStub(self.grpc_root_server_channel) + if self.grpc_root_server_port != -1: + self.rootservice = facade_rootservice_pb2_grpc.RootFacadeStub(self.grpc_root_server_channel) + self.hal = hal_facade_pb2_grpc.HciHalFacadeStub(self.grpc_channel) self.controller_read_only_property = facade_rootservice_pb2_grpc.ReadOnlyPropertyStub(self.grpc_channel) self.hci = hci_facade_pb2_grpc.HciFacadeStub(self.grpc_channel) @@ -271,7 +277,8 @@ class GdDeviceBase(ABC): :return: """ self.grpc_channel.close() - self.grpc_root_server_channel.close() + if self.grpc_root_server_port != -1: + self.grpc_root_server_channel.close() stop_signal = signal.SIGINT self.backing_process.send_signal(stop_signal) try: @@ -325,9 +332,10 @@ class GdHostOnlyDevice(GdDeviceBase): # Only check on host only test, for Android devices, these ports will # be opened on Android device and host machine ports will be occupied # by sshd or adb forwarding + ports_needed = [self.grpc_port, + self.grpc_root_server_port] if self.grpc_root_server_port != -1 else [self.grpc_port] asserts.assert_true( - make_ports_available((self.grpc_port, self.grpc_root_server_port)), - "[%s] Failed to make backing process ports available" % self.label) + make_ports_available(ports_needed), "[%s] Failed to make backing process ports available" % self.label) super().setup() def teardown(self): @@ -462,7 +470,8 @@ class GdAndroidDevice(GdDeviceBase): # Set up port forwarding or reverse or die self.tcp_forward_or_die(self.grpc_port, self.grpc_port) - self.tcp_forward_or_die(self.grpc_root_server_port, self.grpc_root_server_port) + if self.grpc_root_server_port != -1: + self.tcp_forward_or_die(self.grpc_root_server_port, self.grpc_root_server_port) self.tcp_reverse_or_die(self.signal_port, self.signal_port) logging.info("Port forwarding done on device %s %s" % (self.label, self.serial_number)) @@ -587,7 +596,8 @@ class GdAndroidDevice(GdDeviceBase): logging.error(msg) try: - self.adb.remove_tcp_forward(self.grpc_root_server_port) + if self.grpc_root_server_port != -1: + self.adb.remove_tcp_forward(self.grpc_root_server_port) except AdbError as error: msg = PORT_FORWARDING_ERROR_MSG_PREFIX + str(error) if "not found" in msg: diff --git a/system/blueberry/tests/gd/rust/topshim/facade/topshim_device.py b/system/blueberry/tests/gd/rust/topshim/facade/topshim_device.py index 850b6dad14..1e853d118e 100644 --- a/system/blueberry/tests/gd/rust/topshim/facade/topshim_device.py +++ b/system/blueberry/tests/gd/rust/topshim/facade/topshim_device.py @@ -57,9 +57,8 @@ def get_instances_with_configs(configs): logging.debug(arg) resolved_cmd.append(replace_vars_for_topshim(arg, config)) verbose_mode = bool(config.get('verbose_mode', False)) - device = GdHostOnlyDevice(config["grpc_port"], config["grpc_root_server_port"], config["signal_port"], - resolved_cmd, config["label"], MOBLY_CONTROLLER_CONFIG_NAME, config["name"], - verbose_mode) + device = GdHostOnlyDevice(config["grpc_port"], "-1", config["signal_port"], resolved_cmd, config["label"], + MOBLY_CONTROLLER_CONFIG_NAME, config["name"], verbose_mode) device.setup() devices.append(device) return devices diff --git a/system/gd/cert/run_topshim b/system/gd/cert/run_topshim index 6ac78b23a3..50a01343df 100755 --- a/system/gd/cert/run_topshim +++ b/system/gd/cert/run_topshim @@ -20,7 +20,7 @@ import os import argparse TEST_SUITES = [ - "blueberry.tests.gd.rust.topshim.facade.adapter_test_blueberry" + "blueberry.tests.gd.rust.topshim.facade.adapter_test" ] SOONG_UI_BASH = 'build/soong/soong_ui.bash' diff --git a/system/gd/hci/le_scanning_callback.h b/system/gd/hci/le_scanning_callback.h index bbe5137741..d0ef782a7c 100644 --- a/system/gd/hci/le_scanning_callback.h +++ b/system/gd/hci/le_scanning_callback.h @@ -21,7 +21,6 @@ #include "hci/address_with_type.h" #include "hci/hci_packets.h" #include "hci/uuid.h" -#include "module.h" namespace bluetooth { namespace hci { diff --git a/system/gd/rust/common/src/sys_prop.rs b/system/gd/rust/common/src/sys_prop.rs index 188669e2fb..c63cd48efd 100644 --- a/system/gd/rust/common/src/sys_prop.rs +++ b/system/gd/rust/common/src/sys_prop.rs @@ -3,7 +3,7 @@ /// Gets the value of a system property on Android #[cfg(target_os = "android")] pub fn get(name: &str) -> Option<String> { - rustutils::system_properties::read(name).ok() + rustutils::system_properties::read(name).unwrap_or(None) } /// Fake getter for non-Android, which will always return nothing. diff --git a/system/main/shim/ble_scanner_interface_impl.h b/system/main/shim/ble_scanner_interface_impl.h new file mode 100644 index 0000000000..a9545b6791 --- /dev/null +++ b/system/main/shim/ble_scanner_interface_impl.h @@ -0,0 +1,129 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Gd shim layer to legacy le scanner + */ +#pragma once + +#include <queue> +#include <set> + +#include "hci/le_scanning_callback.h" +#include "include/hardware/ble_scanner.h" +#include "types/ble_address_with_type.h" +#include "types/bluetooth/uuid.h" +#include "types/raw_address.h" + +namespace bluetooth { +namespace shim { + +extern ::ScanningCallbacks* default_scanning_callback; + +class BleScannerInterfaceImpl : public ::BleScannerInterface, + public bluetooth::hci::ScanningCallback { + public: + ~BleScannerInterfaceImpl() override{}; + + void Init(); + + // ::BleScannerInterface + void RegisterScanner(const bluetooth::Uuid& uuid, RegisterCallback) override; + void Unregister(int scanner_id) override; + void Scan(bool start) override; + void ScanFilterParamSetup( + uint8_t client_if, uint8_t action, uint8_t filter_index, + std::unique_ptr<btgatt_filt_param_setup_t> filt_param, + FilterParamSetupCallback cb) override; + void ScanFilterAdd(int filter_index, std::vector<ApcfCommand> filters, + FilterConfigCallback cb) override; + void ScanFilterClear(int filter_index, FilterConfigCallback cb) override; + void ScanFilterEnable(bool enable, EnableCallback cb) override; + void SetScanParameters(int scanner_id, int scan_interval, int scan_window, + Callback cb) override; + void BatchscanConfigStorage(int client_if, int batch_scan_full_max, + int batch_scan_trunc_max, + int batch_scan_notify_threshold, + Callback cb) override; + void BatchscanEnable(int scan_mode, int scan_interval, int scan_window, + int addr_type, int discard_rule, Callback cb) override; + void BatchscanDisable(Callback cb) override; + void BatchscanReadReports(int client_if, int scan_mode) override; + void StartSync(uint8_t sid, RawAddress address, uint16_t skip, + uint16_t timeout, StartSyncCb start_cb, SyncReportCb report_cb, + SyncLostCb lost_cb) override; + void StopSync(uint16_t handle) override; + void CancelCreateSync(uint8_t sid, RawAddress address) override; + void TransferSync(RawAddress address, uint16_t service_data, + uint16_t sync_handle, SyncTransferCb cb) override; + void TransferSetInfo(RawAddress address, uint16_t service_data, + uint8_t adv_handle, SyncTransferCb cb) override; + void SyncTxParameters(RawAddress addr, uint8_t mode, uint16_t skip, + uint16_t timeout, StartSyncCb start_cb) override; + + // bluetooth::hci::ScanningCallback + void RegisterCallbacks(ScanningCallbacks* callbacks); + void OnScannerRegistered(const bluetooth::hci::Uuid app_uuid, + bluetooth::hci::ScannerId scanner_id, + ScanningStatus status) override; + void OnSetScannerParameterComplete(bluetooth::hci::ScannerId scanner_id, + ScanningStatus status) override; + void OnScanResult(uint16_t event_type, uint8_t address_type, + bluetooth::hci::Address address, uint8_t primary_phy, + uint8_t secondary_phy, uint8_t advertising_sid, + int8_t tx_power, int8_t rssi, + uint16_t periodic_advertising_interval, + std::vector<uint8_t> advertising_data) override; + void OnTrackAdvFoundLost(bluetooth::hci::AdvertisingFilterOnFoundOnLostInfo + on_found_on_lost_info) override; + void OnBatchScanReports(int client_if, int status, int report_format, + int num_records, std::vector<uint8_t> data) override; + void OnBatchScanThresholdCrossed(int client_if) override; + void OnTimeout() override; + void OnFilterEnable(bluetooth::hci::Enable enable, uint8_t status) override; + void OnFilterParamSetup(uint8_t available_spaces, + bluetooth::hci::ApcfAction action, + uint8_t status) override; + void OnFilterConfigCallback(bluetooth::hci::ApcfFilterType filter_type, + uint8_t available_spaces, + bluetooth::hci::ApcfAction action, + uint8_t status) override; + ::ScanningCallbacks* scanning_callbacks_ = default_scanning_callback; + + private: + bool parse_filter_command( + bluetooth::hci::AdvertisingPacketContentFilterCommand& + advertising_packet_content_filter_command, + ApcfCommand apcf_command); + void handle_remote_properties(RawAddress bd_addr, tBLE_ADDR_TYPE addr_type, + std::vector<uint8_t> advertising_data); + + class AddressCache { + public: + void init(void); + void add(const RawAddress& p_bda); + bool find(const RawAddress& p_bda); + + private: + // all access to this variable should be done on the jni thread + std::set<RawAddress> remote_bdaddr_cache_; + std::queue<RawAddress> remote_bdaddr_cache_ordered_; + const size_t remote_bdaddr_cache_max_size_ = 1024; + } address_cache_; +}; + +} // namespace shim +} // namespace bluetooth diff --git a/system/main/shim/le_scanning_manager.cc b/system/main/shim/le_scanning_manager.cc index 667480ee70..8ed2d156ba 100644 --- a/system/main/shim/le_scanning_manager.cc +++ b/system/main/shim/le_scanning_manager.cc @@ -28,22 +28,25 @@ #include "advertise_data_parser.h" #include "btif/include/btif_common.h" -#include "gd/hci/address.h" -#include "gd/hci/le_scanning_manager.h" -#include "gd/storage/device.h" -#include "gd/storage/le_device.h" -#include "gd/storage/storage_module.h" +#include "hci/address.h" +#include "hci/le_scanning_manager.h" +#include "include/hardware/ble_scanner.h" +#include "main/shim/ble_scanner_interface_impl.h" #include "main/shim/dumpsys.h" #include "main/shim/entry.h" #include "main/shim/helpers.h" +#include "main/shim/le_scanning_manager.h" #include "main/shim/shim.h" #include "stack/btm/btm_int_types.h" #include "stack/include/btm_log_history.h" +#include "storage/device.h" +#include "storage/le_device.h" +#include "storage/storage_module.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" -using bluetooth::ToRawAddress; using bluetooth::ToGdAddress; +using bluetooth::ToRawAddress; namespace { constexpr char kBtmLogTag[] = "SCAN"; @@ -51,7 +54,42 @@ constexpr uint16_t kAllowAllFilter = 0x00; constexpr uint16_t kListLogicOr = 0x01; constexpr uint8_t kFilterLogicOr = 0x00; constexpr uint8_t kLowestRssiValue = 129; -} + +class DefaultScanningCallback : public ::ScanningCallbacks { + void OnScannerRegistered(const bluetooth::Uuid app_uuid, uint8_t scanner_id, + uint8_t status) { + LogUnused(); + } + void OnSetScannerParameterComplete(uint8_t scanner_id, uint8_t status) { + LogUnused(); + } + void OnScanResult(uint16_t event_type, uint8_t address_type, RawAddress bda, + uint8_t primary_phy, uint8_t secondary_phy, + uint8_t advertising_sid, int8_t tx_power, int8_t rssi, + uint16_t periodic_advertising_interval, + std::vector<uint8_t> advertising_data) { + LogUnused(); + } + void OnTrackAdvFoundLost(AdvertisingTrackInfo advertising_track_info) { + LogUnused(); + } + void OnBatchScanReports(int client_if, int status, int report_format, + int num_records, std::vector<uint8_t> data) { + LogUnused(); + } + void OnBatchScanThresholdCrossed(int client_if) { LogUnused(); } + + private: + void LogUnused() const { + LOG_WARN("BLE Scanning callbacks have not been registered"); + } +} default_scanning_callback_; + +} // namespace + +::ScanningCallbacks* bluetooth::shim::default_scanning_callback = + static_cast<::ScanningCallbacks*>(&default_scanning_callback_); +extern ::ScanningCallbacks* bluetooth::shim::default_scanning_callback; extern void btm_ble_process_adv_pkt_cont_for_inquiry( uint16_t event_type, uint8_t address_type, const RawAddress& raw_address, @@ -66,493 +104,485 @@ extern void btif_dm_update_ble_remote_properties(const RawAddress& bd_addr, extern void btm_ble_process_adv_addr(RawAddress& raw_address, tBLE_ADDR_TYPE* address_type); -class BleScannerInterfaceImpl : public BleScannerInterface, - public bluetooth::hci::ScanningCallback { - public: - ~BleScannerInterfaceImpl() override{}; +using bluetooth::shim::BleScannerInterfaceImpl; - void Init() { - LOG_INFO("init BleScannerInterfaceImpl"); - bluetooth::shim::GetScanning()->RegisterScanningCallback(this); - } +void BleScannerInterfaceImpl::Init() { + LOG_INFO("init BleScannerInterfaceImpl"); + bluetooth::shim::GetScanning()->RegisterScanningCallback(this); +} - /** Registers a scanner with the stack */ - void RegisterScanner(const bluetooth::Uuid& uuid, RegisterCallback) { - LOG(INFO) << __func__ << " in shim layer"; - auto app_uuid = bluetooth::hci::Uuid::From128BitBE(uuid.To128BitBE()); - bluetooth::shim::GetScanning()->RegisterScanner(app_uuid); - } +/** Registers a scanner with the stack */ +void BleScannerInterfaceImpl::RegisterScanner(const bluetooth::Uuid& uuid, + RegisterCallback) { + LOG(INFO) << __func__ << " in shim layer"; + auto app_uuid = bluetooth::hci::Uuid::From128BitBE(uuid.To128BitBE()); + bluetooth::shim::GetScanning()->RegisterScanner(app_uuid); +} - /** Unregister a scanner from the stack */ - void Unregister(int scanner_id) { - LOG(INFO) << __func__ << " in shim layer, scanner_id:" << scanner_id; - bluetooth::shim::GetScanning()->Unregister(scanner_id); - } +/** Unregister a scanner from the stack */ +void BleScannerInterfaceImpl::Unregister(int scanner_id) { + LOG(INFO) << __func__ << " in shim layer, scanner_id:" << scanner_id; + bluetooth::shim::GetScanning()->Unregister(scanner_id); +} /** Start or stop LE device scanning */ - void Scan(bool start) { - LOG(INFO) << __func__ << " in shim layer"; - bluetooth::shim::GetScanning()->Scan(start); - BTM_LogHistory( - kBtmLogTag, RawAddress::kEmpty, - base::StringPrintf("Le scan %s", (start) ? "started" : "stopped")); - init_address_cache(); - } +void BleScannerInterfaceImpl::Scan(bool start) { + LOG(INFO) << __func__ << " in shim layer"; + bluetooth::shim::GetScanning()->Scan(start); + BTM_LogHistory( + kBtmLogTag, RawAddress::kEmpty, + base::StringPrintf("Le scan %s", (start) ? "started" : "stopped")); + address_cache_.init(); +} /** Setup scan filter params */ - void ScanFilterParamSetup( - uint8_t client_if, uint8_t action, uint8_t filter_index, - std::unique_ptr<btgatt_filt_param_setup_t> filt_param, - FilterParamSetupCallback cb) { - LOG(INFO) << __func__ << " in shim layer"; - - auto apcf_action = static_cast<bluetooth::hci::ApcfAction>(action); - bluetooth::hci::AdvertisingFilterParameter advertising_filter_parameter; - - if (filt_param != nullptr) { - if (filt_param && filt_param->dely_mode == 1) { - bluetooth::shim::GetScanning()->TrackAdvertiser(client_if); - } - advertising_filter_parameter.feature_selection = filt_param->feat_seln; - advertising_filter_parameter.list_logic_type = - filt_param->list_logic_type; - advertising_filter_parameter.filter_logic_type = - filt_param->filt_logic_type; - advertising_filter_parameter.rssi_high_thresh = - filt_param->rssi_high_thres; - advertising_filter_parameter.delivery_mode = - static_cast<bluetooth::hci::DeliveryMode>(filt_param->dely_mode); - if (filt_param && filt_param->dely_mode == 1) { - advertising_filter_parameter.onfound_timeout = - filt_param->found_timeout; - advertising_filter_parameter.onfound_timeout_cnt = - filt_param->found_timeout_cnt; - advertising_filter_parameter.rssi_low_thresh = - filt_param->rssi_low_thres; - advertising_filter_parameter.onlost_timeout = filt_param->lost_timeout; - advertising_filter_parameter.num_of_tracking_entries = - filt_param->num_of_tracking_entries; - } - } +void BleScannerInterfaceImpl::ScanFilterParamSetup( + uint8_t client_if, uint8_t action, uint8_t filter_index, + std::unique_ptr<btgatt_filt_param_setup_t> filt_param, + FilterParamSetupCallback cb) { + LOG(INFO) << __func__ << " in shim layer"; - bluetooth::shim::GetScanning()->ScanFilterParameterSetup( - apcf_action, filter_index, advertising_filter_parameter); - // TODO refactor callback mechanism - do_in_jni_thread(FROM_HERE, - base::Bind(cb, 0, 0, btm_status_value(BTM_SUCCESS))); - } + auto apcf_action = static_cast<bluetooth::hci::ApcfAction>(action); + bluetooth::hci::AdvertisingFilterParameter advertising_filter_parameter; - /** Configure a scan filter condition */ - void ScanFilterAdd(int filter_index, std::vector<ApcfCommand> filters, - FilterConfigCallback cb) { - LOG(INFO) << __func__ << " in shim layer"; - std::vector<bluetooth::hci::AdvertisingPacketContentFilterCommand> - new_filters = {}; - for (size_t i = 0; i < filters.size(); i++) { - bluetooth::hci::AdvertisingPacketContentFilterCommand command{}; - if (!parse_filter_command(command, filters[i])) { - LOG_ERROR("invalid apcf command"); - return; - } - new_filters.push_back(command); + if (filt_param != nullptr) { + if (filt_param && filt_param->dely_mode == 1) { + bluetooth::shim::GetScanning()->TrackAdvertiser(client_if); + } + advertising_filter_parameter.feature_selection = filt_param->feat_seln; + advertising_filter_parameter.list_logic_type = filt_param->list_logic_type; + advertising_filter_parameter.filter_logic_type = + filt_param->filt_logic_type; + advertising_filter_parameter.rssi_high_thresh = filt_param->rssi_high_thres; + advertising_filter_parameter.delivery_mode = + static_cast<bluetooth::hci::DeliveryMode>(filt_param->dely_mode); + if (filt_param && filt_param->dely_mode == 1) { + advertising_filter_parameter.onfound_timeout = filt_param->found_timeout; + advertising_filter_parameter.onfound_timeout_cnt = + filt_param->found_timeout_cnt; + advertising_filter_parameter.rssi_low_thresh = filt_param->rssi_low_thres; + advertising_filter_parameter.onlost_timeout = filt_param->lost_timeout; + advertising_filter_parameter.num_of_tracking_entries = + filt_param->num_of_tracking_entries; } - bluetooth::shim::GetScanning()->ScanFilterAdd(filter_index, new_filters); - do_in_jni_thread(FROM_HERE, - base::Bind(cb, 0, 0, 0, btm_status_value(BTM_SUCCESS))); } - /** Clear all scan filter conditions for specific filter index*/ - void ScanFilterClear(int filter_index, FilterConfigCallback cb) { - LOG(INFO) << __func__ << " in shim layer"; - // This function doesn't used in java layer + bluetooth::shim::GetScanning()->ScanFilterParameterSetup( + apcf_action, filter_index, advertising_filter_parameter); + // TODO refactor callback mechanism + do_in_jni_thread(FROM_HERE, + base::Bind(cb, 0, 0, btm_status_value(BTM_SUCCESS))); +} + +/** Configure a scan filter condition */ +void BleScannerInterfaceImpl::ScanFilterAdd(int filter_index, + std::vector<ApcfCommand> filters, + FilterConfigCallback cb) { + LOG(INFO) << __func__ << " in shim layer"; + std::vector<bluetooth::hci::AdvertisingPacketContentFilterCommand> + new_filters = {}; + for (size_t i = 0; i < filters.size(); i++) { + bluetooth::hci::AdvertisingPacketContentFilterCommand command{}; + if (!parse_filter_command(command, filters[i])) { + LOG_ERROR("invalid apcf command"); + return; + } + new_filters.push_back(command); } + bluetooth::shim::GetScanning()->ScanFilterAdd(filter_index, new_filters); + do_in_jni_thread(FROM_HERE, + base::Bind(cb, 0, 0, 0, btm_status_value(BTM_SUCCESS))); +} - /** Enable / disable scan filter feature*/ - void ScanFilterEnable(bool enable, EnableCallback cb) { - LOG(INFO) << __func__ << " in shim layer"; - bluetooth::shim::GetScanning()->ScanFilterEnable(enable); +/** Clear all scan filter conditions for specific filter index*/ +void BleScannerInterfaceImpl::ScanFilterClear(int filter_index, + FilterConfigCallback cb) { + LOG(INFO) << __func__ << " in shim layer"; + // This function doesn't used in java layer +} - uint8_t action = enable ? 1 : 0; - do_in_jni_thread(FROM_HERE, - base::Bind(cb, action, btm_status_value(BTM_SUCCESS))); - } +/** Enable / disable scan filter feature*/ +void BleScannerInterfaceImpl::ScanFilterEnable(bool enable, EnableCallback cb) { + LOG(INFO) << __func__ << " in shim layer"; + bluetooth::shim::GetScanning()->ScanFilterEnable(enable); + + uint8_t action = enable ? 1 : 0; + do_in_jni_thread(FROM_HERE, + base::Bind(cb, action, btm_status_value(BTM_SUCCESS))); +} /** Sets the LE scan interval and window in units of N*0.625 msec */ - void SetScanParameters(int scanner_id, int scan_interval, int scan_window, - Callback cb) { - LOG(INFO) << __func__ << " in shim layer"; - // use active scan - auto scan_type = static_cast<bluetooth::hci::LeScanType>(0x01); - bluetooth::shim::GetScanning()->SetScanParameters( - scanner_id, scan_type, scan_interval, scan_window); - } +void BleScannerInterfaceImpl::SetScanParameters(int scanner_id, + int scan_interval, + int scan_window, Callback cb) { + LOG(INFO) << __func__ << " in shim layer"; + // use active scan + auto scan_type = static_cast<bluetooth::hci::LeScanType>(0x01); + bluetooth::shim::GetScanning()->SetScanParameters(scanner_id, scan_type, + scan_interval, scan_window); +} - /* Configure the batchscan storage */ - void BatchscanConfigStorage(int client_if, int batch_scan_full_max, - int batch_scan_trunc_max, - int batch_scan_notify_threshold, Callback cb) { - LOG(INFO) << __func__ << " in shim layer"; - bluetooth::shim::GetScanning()->BatchScanConifgStorage( - batch_scan_full_max, batch_scan_trunc_max, batch_scan_notify_threshold, - client_if); - do_in_jni_thread(FROM_HERE, base::Bind(cb, btm_status_value(BTM_SUCCESS))); - } +/* Configure the batchscan storage */ +void BleScannerInterfaceImpl::BatchscanConfigStorage( + int client_if, int batch_scan_full_max, int batch_scan_trunc_max, + int batch_scan_notify_threshold, Callback cb) { + LOG(INFO) << __func__ << " in shim layer"; + bluetooth::shim::GetScanning()->BatchScanConifgStorage( + batch_scan_full_max, batch_scan_trunc_max, batch_scan_notify_threshold, + client_if); + do_in_jni_thread(FROM_HERE, base::Bind(cb, btm_status_value(BTM_SUCCESS))); +} - /* Enable batchscan */ - virtual void BatchscanEnable(int scan_mode, int scan_interval, - int scan_window, int addr_type, int discard_rule, - Callback cb) { - LOG(INFO) << __func__ << " in shim layer"; - auto batch_scan_mode = - static_cast<bluetooth::hci::BatchScanMode>(scan_mode); - auto batch_scan_discard_rule = - static_cast<bluetooth::hci::BatchScanDiscardRule>(discard_rule); - bluetooth::shim::GetScanning()->BatchScanEnable( - batch_scan_mode, scan_window, scan_interval, batch_scan_discard_rule); - do_in_jni_thread(FROM_HERE, base::Bind(cb, btm_status_value(BTM_SUCCESS))); - } +/* Enable batchscan */ +void BleScannerInterfaceImpl::BatchscanEnable(int scan_mode, int scan_interval, + int scan_window, int addr_type, + int discard_rule, Callback cb) { + LOG(INFO) << __func__ << " in shim layer"; + auto batch_scan_mode = static_cast<bluetooth::hci::BatchScanMode>(scan_mode); + auto batch_scan_discard_rule = + static_cast<bluetooth::hci::BatchScanDiscardRule>(discard_rule); + bluetooth::shim::GetScanning()->BatchScanEnable( + batch_scan_mode, scan_window, scan_interval, batch_scan_discard_rule); + do_in_jni_thread(FROM_HERE, base::Bind(cb, btm_status_value(BTM_SUCCESS))); +} - /* Disable batchscan */ - virtual void BatchscanDisable(Callback cb) { - LOG(INFO) << __func__ << " in shim layer"; - bluetooth::shim::GetScanning()->BatchScanDisable(); - do_in_jni_thread(FROM_HERE, base::Bind(cb, btm_status_value(BTM_SUCCESS))); - } +/* Disable batchscan */ +void BleScannerInterfaceImpl::BatchscanDisable(Callback cb) { + LOG(INFO) << __func__ << " in shim layer"; + bluetooth::shim::GetScanning()->BatchScanDisable(); + do_in_jni_thread(FROM_HERE, base::Bind(cb, btm_status_value(BTM_SUCCESS))); +} - /* Read out batchscan reports */ - void BatchscanReadReports(int client_if, int scan_mode) { - LOG(INFO) << __func__ << " in shim layer"; - auto batch_scan_mode = - static_cast<bluetooth::hci::BatchScanMode>(scan_mode); - auto scanner_id = static_cast<bluetooth::hci::ScannerId>(client_if); - bluetooth::shim::GetScanning()->BatchScanReadReport(scanner_id, - batch_scan_mode); - } +/* Read out batchscan reports */ +void BleScannerInterfaceImpl::BatchscanReadReports(int client_if, + int scan_mode) { + LOG(INFO) << __func__ << " in shim layer"; + auto batch_scan_mode = static_cast<bluetooth::hci::BatchScanMode>(scan_mode); + auto scanner_id = static_cast<bluetooth::hci::ScannerId>(client_if); + bluetooth::shim::GetScanning()->BatchScanReadReport(scanner_id, + batch_scan_mode); +} - void StartSync(uint8_t sid, RawAddress address, uint16_t skip, - uint16_t timeout, StartSyncCb start_cb, SyncReportCb report_cb, - SyncLostCb lost_cb) { - LOG(INFO) << __func__ << " in shim layer"; - // This function doesn't implement in the old stack - } +void BleScannerInterfaceImpl::StartSync(uint8_t sid, RawAddress address, + uint16_t skip, uint16_t timeout, + StartSyncCb start_cb, + SyncReportCb report_cb, + SyncLostCb lost_cb) { + LOG(INFO) << __func__ << " in shim layer"; + // This function doesn't implement in the old stack +} - void StopSync(uint16_t handle) { - LOG(INFO) << __func__ << " in shim layer"; - // This function doesn't implement in the old stack - } +void BleScannerInterfaceImpl::StopSync(uint16_t handle) { + LOG(INFO) << __func__ << " in shim layer"; + // This function doesn't implement in the old stack +} - void CancelCreateSync(uint8_t sid, RawAddress address) { - LOG(INFO) << __func__ << " in shim layer"; - // This function doesn't implement in the old stack - } +void BleScannerInterfaceImpl::CancelCreateSync(uint8_t sid, + RawAddress address) { + LOG(INFO) << __func__ << " in shim layer"; + // This function doesn't implement in the old stack +} - void TransferSync(RawAddress address, uint16_t service_data, - uint16_t sync_handle, SyncTransferCb cb) { - LOG(INFO) << __func__ << " in shim layer"; - // This function doesn't implement in the old stack - } +void BleScannerInterfaceImpl::TransferSync(RawAddress address, + uint16_t service_data, + uint16_t sync_handle, + SyncTransferCb cb) { + LOG(INFO) << __func__ << " in shim layer"; + // This function doesn't implement in the old stack +} - void TransferSetInfo(RawAddress address, uint16_t service_data, - uint8_t adv_handle, SyncTransferCb cb) { - LOG(INFO) << __func__ << " in shim layer"; - // This function doesn't implement in the old stack - } +void BleScannerInterfaceImpl::TransferSetInfo(RawAddress address, + uint16_t service_data, + uint8_t adv_handle, + SyncTransferCb cb) { + LOG(INFO) << __func__ << " in shim layer"; + // This function doesn't implement in the old stack +} - void SyncTxParameters(RawAddress addr, uint8_t mode, uint16_t skip, - uint16_t timeout, StartSyncCb start_cb) { - LOG(INFO) << __func__ << " in shim layer"; - // This function doesn't implement in the old stack - } +void BleScannerInterfaceImpl::SyncTxParameters(RawAddress addr, uint8_t mode, + uint16_t skip, uint16_t timeout, + StartSyncCb start_cb) { + LOG(INFO) << __func__ << " in shim layer"; + // This function doesn't implement in the old stack +} - void RegisterCallbacks(ScanningCallbacks* callbacks) { - LOG(INFO) << __func__ << " in shim layer"; - scanning_callbacks_ = callbacks; - } +void BleScannerInterfaceImpl::RegisterCallbacks(ScanningCallbacks* callbacks) { + LOG(INFO) << __func__ << " in shim layer"; + scanning_callbacks_ = callbacks; +} - void OnScannerRegistered(const bluetooth::hci::Uuid app_uuid, - bluetooth::hci::ScannerId scanner_id, - ScanningStatus status) { - auto uuid = bluetooth::Uuid::From128BitBE(app_uuid.To128BitBE()); - do_in_jni_thread(FROM_HERE, - base::Bind(&ScanningCallbacks::OnScannerRegistered, - base::Unretained(scanning_callbacks_), uuid, - scanner_id, status)); - } +void BleScannerInterfaceImpl::OnScannerRegistered( + const bluetooth::hci::Uuid app_uuid, bluetooth::hci::ScannerId scanner_id, + ScanningStatus status) { + auto uuid = bluetooth::Uuid::From128BitBE(app_uuid.To128BitBE()); + do_in_jni_thread(FROM_HERE, + base::Bind(&ScanningCallbacks::OnScannerRegistered, + base::Unretained(scanning_callbacks_), uuid, + scanner_id, status)); +} - void OnSetScannerParameterComplete(bluetooth::hci::ScannerId scanner_id, - ScanningStatus status) { - do_in_jni_thread( - FROM_HERE, - base::Bind(&ScanningCallbacks::OnSetScannerParameterComplete, - base::Unretained(scanning_callbacks_), scanner_id, status)); - } +void BleScannerInterfaceImpl::OnSetScannerParameterComplete( + bluetooth::hci::ScannerId scanner_id, ScanningStatus status) { + do_in_jni_thread( + FROM_HERE, + base::Bind(&ScanningCallbacks::OnSetScannerParameterComplete, + base::Unretained(scanning_callbacks_), scanner_id, status)); +} - void OnScanResult(uint16_t event_type, uint8_t address_type, - bluetooth::hci::Address address, uint8_t primary_phy, - uint8_t secondary_phy, uint8_t advertising_sid, - int8_t tx_power, int8_t rssi, - uint16_t periodic_advertising_interval, - std::vector<uint8_t> advertising_data) { - RawAddress raw_address = ToRawAddress(address); +void BleScannerInterfaceImpl::OnScanResult( + uint16_t event_type, uint8_t address_type, bluetooth::hci::Address address, + uint8_t primary_phy, uint8_t secondary_phy, uint8_t advertising_sid, + int8_t tx_power, int8_t rssi, uint16_t periodic_advertising_interval, + std::vector<uint8_t> advertising_data) { + RawAddress raw_address = ToRawAddress(address); + + if (address_type != BLE_ADDR_ANONYMOUS) { + btm_ble_process_adv_addr(raw_address, &address_type); + } + + do_in_jni_thread( + FROM_HERE, + base::BindOnce(&BleScannerInterfaceImpl::handle_remote_properties, + base::Unretained(this), raw_address, address_type, + advertising_data)); + + do_in_jni_thread( + FROM_HERE, + base::BindOnce(&ScanningCallbacks::OnScanResult, + base::Unretained(scanning_callbacks_), event_type, + address_type, raw_address, primary_phy, secondary_phy, + advertising_sid, tx_power, rssi, + periodic_advertising_interval, advertising_data)); + + // TODO: Remove when StartInquiry in GD part implemented + btm_ble_process_adv_pkt_cont_for_inquiry( + event_type, address_type, raw_address, primary_phy, secondary_phy, + advertising_sid, tx_power, rssi, periodic_advertising_interval, + advertising_data); +} - if (address_type != BLE_ADDR_ANONYMOUS) { - btm_ble_process_adv_addr(raw_address, &address_type); - } +void BleScannerInterfaceImpl::OnTrackAdvFoundLost( + bluetooth::hci::AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info) { + AdvertisingTrackInfo track_info = {}; + RawAddress raw_address = + ToRawAddress(on_found_on_lost_info.advertiser_address); + track_info.advertiser_address = raw_address; + track_info.advertiser_address_type = + on_found_on_lost_info.advertiser_address_type; + track_info.scanner_id = on_found_on_lost_info.scanner_id; + track_info.filter_index = on_found_on_lost_info.filter_index; + track_info.advertiser_state = on_found_on_lost_info.advertiser_state; + track_info.advertiser_info_present = + static_cast<uint8_t>(on_found_on_lost_info.advertiser_info_present); + if (on_found_on_lost_info.advertiser_info_present == + bluetooth::hci::AdvtInfoPresent::ADVT_INFO_PRESENT) { + track_info.tx_power = on_found_on_lost_info.tx_power; + track_info.rssi = on_found_on_lost_info.rssi; + track_info.time_stamp = on_found_on_lost_info.time_stamp; + auto adv_data = on_found_on_lost_info.adv_packet; + track_info.adv_packet_len = (uint8_t)adv_data.size(); + track_info.adv_packet.reserve(adv_data.size()); + track_info.adv_packet.insert(track_info.adv_packet.end(), adv_data.begin(), + adv_data.end()); + auto scan_rsp_data = on_found_on_lost_info.scan_response; + track_info.scan_response_len = (uint8_t)scan_rsp_data.size(); + track_info.scan_response.reserve(adv_data.size()); + track_info.scan_response.insert(track_info.scan_response.end(), + scan_rsp_data.begin(), scan_rsp_data.end()); + } + do_in_jni_thread( + FROM_HERE, + base::BindOnce(&ScanningCallbacks::OnTrackAdvFoundLost, + base::Unretained(scanning_callbacks_), track_info)); +} - do_in_jni_thread( - FROM_HERE, - base::BindOnce(&BleScannerInterfaceImpl::handle_remote_properties, - base::Unretained(this), raw_address, address_type, - advertising_data)); - - do_in_jni_thread( - FROM_HERE, - base::BindOnce(&ScanningCallbacks::OnScanResult, - base::Unretained(scanning_callbacks_), event_type, - address_type, raw_address, primary_phy, secondary_phy, - advertising_sid, tx_power, rssi, - periodic_advertising_interval, advertising_data)); - - // TODO: Remove when StartInquiry in GD part implemented - btm_ble_process_adv_pkt_cont_for_inquiry( - event_type, address_type, raw_address, primary_phy, secondary_phy, - advertising_sid, tx_power, rssi, periodic_advertising_interval, - advertising_data); - } +void BleScannerInterfaceImpl::OnBatchScanReports(int client_if, int status, + int report_format, + int num_records, + std::vector<uint8_t> data) { + do_in_jni_thread( + FROM_HERE, + base::BindOnce(&ScanningCallbacks::OnBatchScanReports, + base::Unretained(scanning_callbacks_), client_if, status, + report_format, num_records, data)); +} - void OnTrackAdvFoundLost(bluetooth::hci::AdvertisingFilterOnFoundOnLostInfo - on_found_on_lost_info) { - AdvertisingTrackInfo track_info = {}; - RawAddress raw_address = - ToRawAddress(on_found_on_lost_info.advertiser_address); - track_info.advertiser_address = raw_address; - track_info.advertiser_address_type = - on_found_on_lost_info.advertiser_address_type; - track_info.scanner_id = on_found_on_lost_info.scanner_id; - track_info.filter_index = on_found_on_lost_info.filter_index; - track_info.advertiser_state = on_found_on_lost_info.advertiser_state; - track_info.advertiser_info_present = - static_cast<uint8_t>(on_found_on_lost_info.advertiser_info_present); - if (on_found_on_lost_info.advertiser_info_present == - bluetooth::hci::AdvtInfoPresent::ADVT_INFO_PRESENT) { - track_info.tx_power = on_found_on_lost_info.tx_power; - track_info.rssi = on_found_on_lost_info.rssi; - track_info.time_stamp = on_found_on_lost_info.time_stamp; - auto adv_data = on_found_on_lost_info.adv_packet; - track_info.adv_packet_len = (uint8_t)adv_data.size(); - track_info.adv_packet.reserve(adv_data.size()); - track_info.adv_packet.insert(track_info.adv_packet.end(), - adv_data.begin(), adv_data.end()); - auto scan_rsp_data = on_found_on_lost_info.scan_response; - track_info.scan_response_len = (uint8_t)scan_rsp_data.size(); - track_info.scan_response.reserve(adv_data.size()); - track_info.scan_response.insert(track_info.scan_response.end(), - scan_rsp_data.begin(), - scan_rsp_data.end()); - } - do_in_jni_thread( - FROM_HERE, - base::BindOnce(&ScanningCallbacks::OnTrackAdvFoundLost, - base::Unretained(scanning_callbacks_), track_info)); - } +void BleScannerInterfaceImpl::OnBatchScanThresholdCrossed(int client_if) { + do_in_jni_thread( + FROM_HERE, + base::BindOnce(&ScanningCallbacks::OnBatchScanThresholdCrossed, + base::Unretained(scanning_callbacks_), client_if)); +} - void OnBatchScanReports(int client_if, int status, int report_format, - int num_records, std::vector<uint8_t> data) { - do_in_jni_thread( - FROM_HERE, - base::BindOnce(&ScanningCallbacks::OnBatchScanReports, - base::Unretained(scanning_callbacks_), client_if, status, - report_format, num_records, data)); +void BleScannerInterfaceImpl::OnTimeout() {} +void BleScannerInterfaceImpl::OnFilterEnable(bluetooth::hci::Enable enable, + uint8_t status) {} +void BleScannerInterfaceImpl::OnFilterParamSetup( + uint8_t available_spaces, bluetooth::hci::ApcfAction action, + uint8_t status) {} +void BleScannerInterfaceImpl::OnFilterConfigCallback( + bluetooth::hci::ApcfFilterType filter_type, uint8_t available_spaces, + bluetooth::hci::ApcfAction action, uint8_t status) {} + +bool BleScannerInterfaceImpl::parse_filter_command( + bluetooth::hci::AdvertisingPacketContentFilterCommand& + advertising_packet_content_filter_command, + ApcfCommand apcf_command) { + advertising_packet_content_filter_command.filter_type = + static_cast<bluetooth::hci::ApcfFilterType>(apcf_command.type); + bluetooth::hci::Address address = ToGdAddress(apcf_command.address); + advertising_packet_content_filter_command.address = address; + advertising_packet_content_filter_command.application_address_type = + static_cast<bluetooth::hci::ApcfApplicationAddressType>( + apcf_command.addr_type); + + if (!apcf_command.uuid.IsEmpty()) { + uint8_t uuid_len = apcf_command.uuid.GetShortestRepresentationSize(); + switch (uuid_len) { + case bluetooth::Uuid::kNumBytes16: { + advertising_packet_content_filter_command.uuid = + bluetooth::hci::Uuid::From16Bit(apcf_command.uuid.As16Bit()); + } break; + case bluetooth::Uuid::kNumBytes32: { + advertising_packet_content_filter_command.uuid = + bluetooth::hci::Uuid::From32Bit(apcf_command.uuid.As32Bit()); + } break; + case bluetooth::Uuid::kNumBytes128: { + advertising_packet_content_filter_command.uuid = + bluetooth::hci::Uuid::From128BitBE(apcf_command.uuid.To128BitBE()); + } break; + default: + LOG_WARN("illegal UUID length %d", (uint16_t)uuid_len); + return false; + } } - void OnBatchScanThresholdCrossed(int client_if) { - do_in_jni_thread( - FROM_HERE, - base::BindOnce(&ScanningCallbacks::OnBatchScanThresholdCrossed, - base::Unretained(scanning_callbacks_), client_if)); + if (!apcf_command.uuid_mask.IsEmpty()) { + uint8_t uuid_len = apcf_command.uuid.GetShortestRepresentationSize(); + switch (uuid_len) { + case bluetooth::Uuid::kNumBytes16: { + advertising_packet_content_filter_command.uuid_mask = + bluetooth::hci::Uuid::From16Bit(apcf_command.uuid_mask.As16Bit()); + } break; + case bluetooth::Uuid::kNumBytes32: { + advertising_packet_content_filter_command.uuid_mask = + bluetooth::hci::Uuid::From32Bit(apcf_command.uuid_mask.As32Bit()); + } break; + case bluetooth::Uuid::kNumBytes128: { + advertising_packet_content_filter_command.uuid_mask = + bluetooth::hci::Uuid::From128BitBE( + apcf_command.uuid_mask.To128BitBE()); + } break; + default: + LOG_WARN("illegal UUID length %d", (uint16_t)uuid_len); + return false; + } } - void OnTimeout() {} - - void OnFilterEnable(bluetooth::hci::Enable enable, uint8_t status){}; - - void OnFilterParamSetup(uint8_t available_spaces, - bluetooth::hci::ApcfAction action, uint8_t status){}; - - void OnFilterConfigCallback(bluetooth::hci::ApcfFilterType filter_type, - uint8_t available_spaces, - bluetooth::hci::ApcfAction action, - uint8_t status){}; - - ScanningCallbacks* scanning_callbacks_; + advertising_packet_content_filter_command.name.assign( + apcf_command.name.begin(), apcf_command.name.end()); + advertising_packet_content_filter_command.company = apcf_command.company; + advertising_packet_content_filter_command.company_mask = + apcf_command.company_mask; + advertising_packet_content_filter_command.data.assign( + apcf_command.data.begin(), apcf_command.data.end()); + advertising_packet_content_filter_command.data_mask.assign( + apcf_command.data_mask.begin(), apcf_command.data_mask.end()); + return true; +} - private: - bool parse_filter_command( - bluetooth::hci::AdvertisingPacketContentFilterCommand& - advertising_packet_content_filter_command, - ApcfCommand apcf_command) { - advertising_packet_content_filter_command.filter_type = - static_cast<bluetooth::hci::ApcfFilterType>(apcf_command.type); - bluetooth::hci::Address address = ToGdAddress(apcf_command.address); - advertising_packet_content_filter_command.address = address; - advertising_packet_content_filter_command.application_address_type = - static_cast<bluetooth::hci::ApcfApplicationAddressType>( - apcf_command.addr_type); - - if (!apcf_command.uuid.IsEmpty()) { - uint8_t uuid_len = apcf_command.uuid.GetShortestRepresentationSize(); - switch (uuid_len) { - case bluetooth::Uuid::kNumBytes16: { - advertising_packet_content_filter_command.uuid = - bluetooth::hci::Uuid::From16Bit(apcf_command.uuid.As16Bit()); - } break; - case bluetooth::Uuid::kNumBytes32: { - advertising_packet_content_filter_command.uuid = - bluetooth::hci::Uuid::From32Bit(apcf_command.uuid.As32Bit()); - } break; - case bluetooth::Uuid::kNumBytes128: { - advertising_packet_content_filter_command.uuid = - bluetooth::hci::Uuid::From128BitBE( - apcf_command.uuid.To128BitBE()); - } break; - default: - LOG_WARN("illegal UUID length %d", (uint16_t)uuid_len); - return false; - } +void BleScannerInterfaceImpl::handle_remote_properties( + RawAddress bd_addr, tBLE_ADDR_TYPE addr_type, + std::vector<uint8_t> advertising_data) { + // skip anonymous advertisment + if (addr_type == BLE_ADDR_ANONYMOUS) { + return; + } + + auto device_type = bluetooth::hci::DeviceType::LE; + uint8_t flag_len; + const uint8_t* p_flag = AdvertiseDataParser::GetFieldByType( + advertising_data, BTM_BLE_AD_TYPE_FLAG, &flag_len); + if (p_flag != NULL && flag_len != 0) { + if ((BTM_BLE_BREDR_NOT_SPT & *p_flag) == 0) { + device_type = bluetooth::hci::DeviceType::DUAL; } + } - if (!apcf_command.uuid_mask.IsEmpty()) { - uint8_t uuid_len = apcf_command.uuid.GetShortestRepresentationSize(); - switch (uuid_len) { - case bluetooth::Uuid::kNumBytes16: { - advertising_packet_content_filter_command.uuid_mask = - bluetooth::hci::Uuid::From16Bit(apcf_command.uuid_mask.As16Bit()); - } break; - case bluetooth::Uuid::kNumBytes32: { - advertising_packet_content_filter_command.uuid_mask = - bluetooth::hci::Uuid::From32Bit(apcf_command.uuid_mask.As32Bit()); - } break; - case bluetooth::Uuid::kNumBytes128: { - advertising_packet_content_filter_command.uuid_mask = - bluetooth::hci::Uuid::From128BitBE( - apcf_command.uuid_mask.To128BitBE()); - } break; - default: - LOG_WARN("illegal UUID length %d", (uint16_t)uuid_len); - return false; - } - } + uint8_t remote_name_len; + const uint8_t* p_eir_remote_name = AdvertiseDataParser::GetFieldByType( + advertising_data, HCI_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len); - advertising_packet_content_filter_command.name.assign( - apcf_command.name.begin(), apcf_command.name.end()); - advertising_packet_content_filter_command.company = apcf_command.company; - advertising_packet_content_filter_command.company_mask = - apcf_command.company_mask; - advertising_packet_content_filter_command.data.assign( - apcf_command.data.begin(), apcf_command.data.end()); - advertising_packet_content_filter_command.data_mask.assign( - apcf_command.data_mask.begin(), apcf_command.data_mask.end()); - return true; + if (p_eir_remote_name == NULL) { + p_eir_remote_name = AdvertiseDataParser::GetFieldByType( + advertising_data, HCI_EIR_SHORTENED_LOCAL_NAME_TYPE, &remote_name_len); } - void handle_remote_properties(RawAddress bd_addr, tBLE_ADDR_TYPE addr_type, - std::vector<uint8_t> advertising_data) { - // skip anonymous advertisment - if (addr_type == BLE_ADDR_ANONYMOUS) { - return; - } + // update device name + if ((addr_type != BLE_ADDR_RANDOM) || (p_eir_remote_name)) { + if (!address_cache_.find(bd_addr)) { + address_cache_.add(bd_addr); - auto device_type = bluetooth::hci::DeviceType::LE; - uint8_t flag_len; - const uint8_t* p_flag = AdvertiseDataParser::GetFieldByType( - advertising_data, BTM_BLE_AD_TYPE_FLAG, &flag_len); - if (p_flag != NULL && flag_len != 0) { - if ((BTM_BLE_BREDR_NOT_SPT & *p_flag) == 0) { - device_type = bluetooth::hci::DeviceType::DUAL; - } - } + if (p_eir_remote_name) { + if (remote_name_len > BD_NAME_LEN + 1 || + (remote_name_len == BD_NAME_LEN + 1 && + p_eir_remote_name[BD_NAME_LEN] != '\0')) { + LOG_INFO("%s dropping invalid packet - device name too long: %d", + __func__, remote_name_len); + return; + } - uint8_t remote_name_len; - const uint8_t* p_eir_remote_name = AdvertiseDataParser::GetFieldByType( - advertising_data, HCI_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len); + bt_bdname_t bdname; + memcpy(bdname.name, p_eir_remote_name, remote_name_len); + if (remote_name_len < BD_NAME_LEN + 1) + bdname.name[remote_name_len] = '\0'; - if (p_eir_remote_name == NULL) { - p_eir_remote_name = AdvertiseDataParser::GetFieldByType( - advertising_data, HCI_EIR_SHORTENED_LOCAL_NAME_TYPE, - &remote_name_len); - } - - // update device name - if ((addr_type != BLE_ADDR_RANDOM) || (p_eir_remote_name)) { - if (!find_address_cache(bd_addr)) { - add_address_cache(bd_addr); - - if (p_eir_remote_name) { - if (remote_name_len > BD_NAME_LEN + 1 || - (remote_name_len == BD_NAME_LEN + 1 && - p_eir_remote_name[BD_NAME_LEN] != '\0')) { - LOG_INFO("%s dropping invalid packet - device name too long: %d", - __func__, remote_name_len); - return; - } - - bt_bdname_t bdname; - memcpy(bdname.name, p_eir_remote_name, remote_name_len); - if (remote_name_len < BD_NAME_LEN + 1) - bdname.name[remote_name_len] = '\0'; - - btif_dm_update_ble_remote_properties(bd_addr, bdname.name, - device_type); - } + btif_dm_update_ble_remote_properties(bd_addr, bdname.name, device_type); } } - if (!bluetooth::shim::is_gd_stack_started_up()) { - LOG_WARN("Gd stack is stopped, return"); - return; - } - auto* storage_module = bluetooth::shim::GetStorage(); - bluetooth::hci::Address address = ToGdAddress(bd_addr); - - // update device type - auto mutation = storage_module->Modify(); - bluetooth::storage::Device device = - storage_module->GetDeviceByLegacyKey(address); - mutation.Add(device.SetDeviceType(device_type)); - mutation.Commit(); - - // update address type - auto mutation2 = storage_module->Modify(); - bluetooth::storage::LeDevice le_device = device.Le(); - mutation2.Add( - le_device.SetAddressType((bluetooth::hci::AddressType)addr_type)); - mutation2.Commit(); } - - void add_address_cache(const RawAddress& p_bda) { - // Remove the oldest entries - while (remote_bdaddr_cache_.size() >= remote_bdaddr_cache_max_size_) { - const RawAddress& raw_address = remote_bdaddr_cache_ordered_.front(); - remote_bdaddr_cache_.erase(raw_address); - remote_bdaddr_cache_ordered_.pop(); - } - remote_bdaddr_cache_.insert(p_bda); - remote_bdaddr_cache_ordered_.push(p_bda); + if (!bluetooth::shim::is_gd_stack_started_up()) { + LOG_WARN("Gd stack is stopped, return"); + return; } - bool find_address_cache(const RawAddress& p_bda) { - return (remote_bdaddr_cache_.find(p_bda) != remote_bdaddr_cache_.end()); - } + auto* storage_module = bluetooth::shim::GetStorage(); + bluetooth::hci::Address address = ToGdAddress(bd_addr); - void init_address_cache(void) { - remote_bdaddr_cache_.clear(); - remote_bdaddr_cache_ordered_ = {}; + // update device type + auto mutation = storage_module->Modify(); + bluetooth::storage::Device device = + storage_module->GetDeviceByLegacyKey(address); + mutation.Add(device.SetDeviceType(device_type)); + mutation.Commit(); + + // update address type + auto mutation2 = storage_module->Modify(); + bluetooth::storage::LeDevice le_device = device.Le(); + mutation2.Add( + le_device.SetAddressType((bluetooth::hci::AddressType)addr_type)); + mutation2.Commit(); +} + +void BleScannerInterfaceImpl::AddressCache::add(const RawAddress& p_bda) { + // Remove the oldest entries + while (remote_bdaddr_cache_.size() >= remote_bdaddr_cache_max_size_) { + const RawAddress& raw_address = remote_bdaddr_cache_ordered_.front(); + remote_bdaddr_cache_.erase(raw_address); + remote_bdaddr_cache_ordered_.pop(); } + remote_bdaddr_cache_.insert(p_bda); + remote_bdaddr_cache_ordered_.push(p_bda); +} - // all access to this variable should be done on the jni thread - std::set<RawAddress> remote_bdaddr_cache_; - std::queue<RawAddress> remote_bdaddr_cache_ordered_; - const size_t remote_bdaddr_cache_max_size_ = 1024; -}; +bool BleScannerInterfaceImpl::AddressCache::find(const RawAddress& p_bda) { + return (remote_bdaddr_cache_.find(p_bda) != remote_bdaddr_cache_.end()); +} + +void BleScannerInterfaceImpl::AddressCache::init(void) { + remote_bdaddr_cache_.clear(); + remote_bdaddr_cache_ordered_ = {}; +} BleScannerInterfaceImpl* bt_le_scanner_instance = nullptr; @@ -564,7 +594,9 @@ BleScannerInterface* bluetooth::shim::get_ble_scanner_instance() { } void bluetooth::shim::init_scanning_manager() { - bt_le_scanner_instance->Init(); + static_cast<BleScannerInterfaceImpl*>( + bluetooth::shim::get_ble_scanner_instance()) + ->Init(); } void bluetooth::shim::set_empty_filter(bool enable) { diff --git a/system/main/shim/le_scanning_manager.h b/system/main/shim/le_scanning_manager.h index b828a6119b..abc72ee538 100644 --- a/system/main/shim/le_scanning_manager.h +++ b/system/main/shim/le_scanning_manager.h @@ -24,9 +24,9 @@ namespace bluetooth { namespace shim { -BleScannerInterface* get_ble_scanner_instance(); +::BleScannerInterface* get_ble_scanner_instance(); void init_scanning_manager(); void set_empty_filter(bool enable); } // namespace shim -} // namespace bluetooth
\ No newline at end of file +} // namespace bluetooth diff --git a/system/stack/acl/btm_acl.cc b/system/stack/acl/btm_acl.cc index 90e0ee26f9..23353d5084 100644 --- a/system/stack/acl/btm_acl.cc +++ b/system/stack/acl/btm_acl.cc @@ -2449,6 +2449,17 @@ bool sco_peer_supports_esco_3m_phy(const RawAddress& remote_bda) { return HCI_EDR_ESCO_3MPS_SUPPORTED(features); } +bool sco_peer_supports_esco_ev3(const RawAddress& remote_bda) { + uint8_t* features = BTM_ReadRemoteFeatures(remote_bda); + if (features == nullptr) { + LOG_WARN( + "Checking remote features but remote feature read is " + "incomplete"); + return false; + } + return HCI_ESCO_EV3_SUPPORTED(features); +} + bool acl_is_switch_role_idle(const RawAddress& bd_addr, tBT_TRANSPORT transport) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(bd_addr, transport); diff --git a/system/stack/btm/btm_sco.cc b/system/stack/btm/btm_sco.cc index 2d1e1eae7f..c1d96dec86 100644 --- a/system/stack/btm/btm_sco.cc +++ b/system/stack/btm/btm_sco.cc @@ -131,11 +131,13 @@ static void btm_esco_conn_rsp(uint16_t sco_inx, uint8_t hci_status, /* If parameters not specified use the default */ if (p_parms) { *p_setup = *p_parms; + } else if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO || + !sco_peer_supports_esco_ev3(bda)) { + *p_setup = esco_parameters_for_codec(SCO_CODEC_CVSD_D1); } else { /* Use the last setup passed thru BTM_SetEscoMode (or defaults) */ *p_setup = btm_cb.sco_cb.def_esco_parms; } - /* Use Enhanced Synchronous commands if supported */ if (controller_get_interface() ->supports_enhanced_setup_synchronous_connection()) { @@ -256,6 +258,11 @@ static tBTM_STATUS btm_send_connect_request(uint16_t acl_handle, << unsigned(acl_handle); btsnd_hcic_add_SCO_conn(acl_handle, BTM_ESCO_2_SCO(p_setup->packet_types)); } else { + /* Save the previous values in case command fails */ + uint16_t saved_packet_types = p_setup->packet_types; + uint8_t saved_retransmission_effort = p_setup->retransmission_effort; + uint16_t saved_max_latency_ms = p_setup->max_latency_ms; + uint16_t temp_packet_types = (p_setup->packet_types & static_cast<uint16_t>(BTM_SCO_SUPPORTED_PKTS_MASK) & @@ -280,6 +287,13 @@ static tBTM_STATUS btm_send_connect_request(uint16_t acl_handle, temp_packet_types |= (ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV5); } + if (!sco_peer_supports_esco_ev3(bd_addr)) { + BTM_TRACE_DEBUG("BTM Remote does not support EV3 eSCO"); + // If EV3 is not supported, EV4 and EV% are not supported, either. + temp_packet_types &= ~BTM_ESCO_LINK_ONLY_MASK; + p_setup->retransmission_effort = ESCO_RETRANSMISSION_OFF; + p_setup->max_latency_ms = 10; + } /* Check to see if BR/EDR Secure Connections is being used ** If so, we cannot use SCO-only packet types (HFP 1.7) @@ -324,8 +338,6 @@ static tBTM_STATUS btm_send_connect_request(uint16_t acl_handle, PRIVATE_ADDRESS(bd_addr)); } - /* Save the previous types in case command fails */ - uint16_t saved_packet_types = p_setup->packet_types; p_setup->packet_types = temp_packet_types; /* Use Enhanced Synchronous commands if supported */ @@ -345,6 +357,8 @@ static tBTM_STATUS btm_send_connect_request(uint16_t acl_handle, << unsigned(p_setup->input_data_path); btsnd_hcic_enhanced_set_up_synchronous_connection(acl_handle, p_setup); p_setup->packet_types = saved_packet_types; + p_setup->retransmission_effort = saved_retransmission_effort; + p_setup->max_latency_ms = saved_max_latency_ms; } else { /* Use older command */ LOG_INFO("Sending eSCO connect request over handle:0x%04x", acl_handle); uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup); diff --git a/system/stack/include/acl_api.h b/system/stack/include/acl_api.h index 559e1cde12..d86127c499 100644 --- a/system/stack/include/acl_api.h +++ b/system/stack/include/acl_api.h @@ -203,6 +203,7 @@ bool acl_peer_supports_ble_connection_parameters_request( bool sco_peer_supports_esco_2m_phy(const RawAddress& remote_bda); bool sco_peer_supports_esco_3m_phy(const RawAddress& remote_bda); +bool sco_peer_supports_esco_ev3(const RawAddress& remote_bda); bool acl_peer_supports_ble_packet_extension(uint16_t hci_handle); bool acl_peer_supports_ble_2m_phy(uint16_t hci_handle); diff --git a/system/test/mock/mock_main_shim_le_scanning_manager.cc b/system/test/mock/mock_main_shim_le_scanning_manager.cc index 0ba29dc83b..a3573357b9 100644 --- a/system/test/mock/mock_main_shim_le_scanning_manager.cc +++ b/system/test/mock/mock_main_shim_le_scanning_manager.cc @@ -31,7 +31,7 @@ extern std::map<std::string, int> mock_function_count_map; #define UNUSED_ATTR #endif -BleScannerInterface* bluetooth::shim::get_ble_scanner_instance() { +::BleScannerInterface* bluetooth::shim::get_ble_scanner_instance() { mock_function_count_map[__func__]++; return nullptr; } |