Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 52a366a0 authored by Chienyuan's avatar Chienyuan
Browse files

Read APCF extended features

Bug: 247032118
Test: gd/cert/run
Test: ./bluetooth_test_gd_unit64 --gtest_filter=*ScanningManagerTest* --gtest_repeat=1000
Tag: #refactor
BYPASS_LONG_LINES_REASON: Bluetooth likes 120 lines

Change-Id: Id956c8e0d37fad934033dc462f393b050d19d9fb
Merged-In: Id956c8e0d37fad934033dc462f393b050d19d9fb
parent 46fbeecd
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -1169,9 +1169,16 @@ class CsisClientImpl : public CsisClient {
  }

  void CsisActiveObserverSet(bool enable) {
    LOG(INFO) << __func__ << " CSIS Discovery SET: " << enable;

    bool is_ad_type_filter_supported =
        bluetooth::shim::is_ad_type_filter_supported();
    LOG_INFO("CSIS Discovery SET: %d, is_ad_type_filter_supported: %d", enable,
             is_ad_type_filter_supported);
    if (is_ad_type_filter_supported) {
      bluetooth::shim::set_ad_type_rsi_filter(enable);
    } else {
      bluetooth::shim::set_empty_filter(enable);
    }

    BTA_DmBleCsisObserve(
        enable, [](tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data) {
          /* If there's no instance we are most likely shutting
+17 −0
Original line number Diff line number Diff line
@@ -4840,6 +4840,7 @@ enum ApcfOpcode : 8 {
  MANUFACTURER_DATA = 0x06,
  SERVICE_DATA = 0x07,
  AD_TYPE = 0x08,
  READ_EXTENDED_FEATURES = 0xFF,
}

// https://source.android.com/devices/bluetooth/hci_requirements#advertising-packet-content-filter
@@ -5007,6 +5008,22 @@ packet LeAdvFilterADTypeComplete : LeAdvFilterComplete (apcf_opcode = AD_TYPE) {
  apcf_available_spaces : 8,
}

packet LeAdvFilterReadExtendedFeatures : LeAdvFilter (apcf_opcode = READ_EXTENDED_FEATURES) {
}

test LeAdvFilterReadExtendedFeatures {
  "\x57\xfd\x01\xff",
}

packet LeAdvFilterReadExtendedFeaturesComplete : LeAdvFilterComplete (apcf_opcode = READ_EXTENDED_FEATURES) {
  ad_type_filter : 1,
  _reserved_ : 15,
}

test LeAdvFilterReadExtendedFeaturesComplete {
  "\x0e\x07\x01\x57\xfd\x00\xff\x01\x00",
}

packet LeEnergyInfo : VendorCommand (op_code = LE_ENERGY_INFO) {
}

+102 −62
Original line number Diff line number Diff line
@@ -136,7 +136,7 @@ class AdvertisingCache {
};

class NullScanningCallback : public ScanningCallback {
  void OnScannerRegistered(const bluetooth::hci::Uuid app_uuid, ScannerId scanner_id, ScanningStatus status) override {
  void OnScannerRegistered(const Uuid app_uuid, ScannerId scanner_id, ScanningStatus status) override {
    LOG_INFO("OnScannerRegistered in NullScanningCallback");
  }
  void OnSetScannerParameterComplete(ScannerId scanner_id, ScanningStatus status) override {
@@ -222,7 +222,7 @@ struct BatchScanConfig {
  ScannerId ref_value;
};

struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback {
struct LeScanningManager::impl : public LeAddressManagerCallback {
  impl(Module* module) : module_(module), le_scanning_interface_(nullptr) {}

  ~impl() {
@@ -233,10 +233,10 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback

  void start(
      os::Handler* handler,
      hci::HciLayer* hci_layer,
      hci::Controller* controller,
      hci::AclManager* acl_manager,
      hci::VendorSpecificEventManager* vendor_specific_event_manager,
      HciLayer* hci_layer,
      Controller* controller,
      AclManager* acl_manager,
      VendorSpecificEventManager* vendor_specific_event_manager,
      storage::StorageModule* storage_module) {
    module_handler_ = handler;
    hci_layer_ = hci_layer;
@@ -259,12 +259,17 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
    } else {
      api_type_ = ScanApiType::LEGACY;
    }
    is_filter_support_ = controller_->IsSupported(OpCode::LE_ADV_FILTER);
    is_batch_scan_support_ = controller->IsSupported(OpCode::LE_BATCH_SCAN);
    is_periodic_advertising_sync_transfer_sender_support_ =
    is_filter_supported_ = controller_->IsSupported(OpCode::LE_ADV_FILTER);
    if (is_filter_supported_) {
      le_scanning_interface_->EnqueueCommand(
          LeAdvFilterReadExtendedFeaturesBuilder::Create(),
          module_handler_->BindOnceOn(this, &impl::on_apcf_read_extended_features_complete));
    }
    is_batch_scan_supported_ = controller->IsSupported(OpCode::LE_BATCH_SCAN);
    is_periodic_advertising_sync_transfer_sender_supported_ =
        controller_->SupportsBlePeriodicAdvertisingSyncTransferSender();
    total_num_of_advt_tracked_ = controller->GetVendorCapabilities().total_num_of_advt_tracked_;
    if (is_batch_scan_support_) {
    if (is_batch_scan_supported_) {
      vendor_specific_event_manager_->RegisterEventHandler(
          VseSubeventCode::BLE_THRESHOLD, handler->BindOn(this, &LeScanningManager::impl::on_storage_threshold_breach));
      vendor_specific_event_manager_->RegisterEventHandler(
@@ -284,7 +289,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
    for (auto subevent_code : LeScanningEvents) {
      hci_layer_->UnregisterLeEventHandler(subevent_code);
    }
    if (is_batch_scan_support_) {
    if (is_batch_scan_supported_) {
      // TODO implete vse module
      // hci_layer_->UnregisterVesEventHandler(VseSubeventCode::BLE_THRESHOLD);
      // hci_layer_->UnregisterVesEventHandler(VseSubeventCode::BLE_TRACKING);
@@ -297,35 +302,35 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback

  void handle_scan_results(LeMetaEventView event) {
    switch (event.GetSubeventCode()) {
      case hci::SubeventCode::ADVERTISING_REPORT:
      case SubeventCode::ADVERTISING_REPORT:
        handle_advertising_report(LeAdvertisingReportView::Create(event));
        break;
      case hci::SubeventCode::DIRECTED_ADVERTISING_REPORT:
      case SubeventCode::DIRECTED_ADVERTISING_REPORT:
        handle_directed_advertising_report(LeDirectedAdvertisingReportView::Create(event));
        break;
      case hci::SubeventCode::EXTENDED_ADVERTISING_REPORT:
      case SubeventCode::EXTENDED_ADVERTISING_REPORT:
        handle_extended_advertising_report(LeExtendedAdvertisingReportView::Create(event));
        break;
      case hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_ESTABLISHED:
      case SubeventCode::PERIODIC_ADVERTISING_SYNC_ESTABLISHED:
        LePeriodicAdvertisingSyncEstablishedView::Create(event);
        periodic_sync_manager_.HandleLePeriodicAdvertisingSyncEstablished(
            LePeriodicAdvertisingSyncEstablishedView::Create(event));
        break;
      case hci::SubeventCode::PERIODIC_ADVERTISING_REPORT:
      case SubeventCode::PERIODIC_ADVERTISING_REPORT:
        periodic_sync_manager_.HandleLePeriodicAdvertisingReport(LePeriodicAdvertisingReportView::Create(event));
        break;
      case hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_LOST:
      case SubeventCode::PERIODIC_ADVERTISING_SYNC_LOST:
        periodic_sync_manager_.HandleLePeriodicAdvertisingSyncLost(LePeriodicAdvertisingSyncLostView::Create(event));
        break;
      case hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED:
      case SubeventCode::PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED:
        periodic_sync_manager_.HandleLePeriodicAdvertisingSyncTransferReceived(
            LePeriodicAdvertisingSyncTransferReceivedView::Create(event));
        break;
      case hci::SubeventCode::SCAN_TIMEOUT:
      case SubeventCode::SCAN_TIMEOUT:
        scanning_callbacks_->OnTimeout();
        break;
      default:
        LOG_ALWAYS_FATAL("Unknown advertising subevent %s", hci::SubeventCodeText(event.GetSubeventCode()).c_str());
        LOG_ALWAYS_FATAL("Unknown advertising subevent %s", SubeventCodeText(event.GetSubeventCode()).c_str());
    }
  }

@@ -361,21 +366,21 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
    for (LeAdvertisingResponse report : reports) {
      uint16_t extended_event_type = 0;
      switch (report.event_type_) {
        case hci::AdvertisingEventType::ADV_IND:
        case AdvertisingEventType::ADV_IND:
          transform_to_extended_event_type(
              &extended_event_type, {.connectable = true, .scannable = true, .legacy = true});
          break;
        case hci::AdvertisingEventType::ADV_DIRECT_IND:
        case AdvertisingEventType::ADV_DIRECT_IND:
          transform_to_extended_event_type(
              &extended_event_type, {.connectable = true, .directed = true, .legacy = true});
          break;
        case hci::AdvertisingEventType::ADV_SCAN_IND:
        case AdvertisingEventType::ADV_SCAN_IND:
          transform_to_extended_event_type(&extended_event_type, {.scannable = true, .legacy = true});
          break;
        case hci::AdvertisingEventType::ADV_NONCONN_IND:
        case AdvertisingEventType::ADV_NONCONN_IND:
          transform_to_extended_event_type(&extended_event_type, {.legacy = true});
          break;
        case hci::AdvertisingEventType::SCAN_RESPONSE:
        case AdvertisingEventType::SCAN_RESPONSE:
          transform_to_extended_event_type(
              &extended_event_type, {.connectable = true, .scannable = true, .scan_response = true, .legacy = true});
          break;
@@ -452,7 +457,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
      int8_t tx_power,
      int8_t rssi,
      uint16_t periodic_advertising_interval,
      std::vector<bluetooth::hci::LengthAndData> advertising_data) {
      std::vector<LengthAndData> advertising_data) {
    bool is_scannable = event_type & (1 << kScannableBit);
    bool is_scan_response = event_type & (1 << kScanResponseBit);
    bool is_legacy = event_type & (1 << kLegacyBit);
@@ -549,20 +554,21 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
    switch (api_type_) {
      case ScanApiType::EXTENDED:
        le_scanning_interface_->EnqueueCommand(
            hci::LeSetExtendedScanParametersBuilder::Create(
            LeSetExtendedScanParametersBuilder::Create(
                own_address_type_, filter_policy_, phys_in_use, parameter_vector),
            module_handler_->BindOnceOn(this, &impl::on_set_scan_parameter_complete));
        break;
      case ScanApiType::ANDROID_HCI:
        le_scanning_interface_->EnqueueCommand(
            hci::LeExtendedScanParamsBuilder::Create(
            LeExtendedScanParamsBuilder::Create(
                le_scan_type_, interval_ms_, window_ms_, own_address_type_, filter_policy_),
            module_handler_->BindOnceOn(this, &impl::on_set_scan_parameter_complete));

        break;
      case ScanApiType::LEGACY:
        le_scanning_interface_->EnqueueCommand(
            hci::LeSetScanParametersBuilder::Create(

            LeSetScanParametersBuilder::Create(
                le_scan_type_, interval_ms_, window_ms_, own_address_type_, filter_policy_),
            module_handler_->BindOnceOn(this, &impl::on_set_scan_parameter_complete));
        break;
@@ -635,14 +641,14 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
    switch (api_type_) {
      case ScanApiType::EXTENDED:
        le_scanning_interface_->EnqueueCommand(
            hci::LeSetExtendedScanEnableBuilder::Create(
            LeSetExtendedScanEnableBuilder::Create(
                Enable::ENABLED, FilterDuplicates::DISABLED /* filter duplicates */, 0, 0),
            module_handler_->BindOnce(impl::check_status));
        break;
      case ScanApiType::ANDROID_HCI:
      case ScanApiType::LEGACY:
        le_scanning_interface_->EnqueueCommand(
            hci::LeSetScanEnableBuilder::Create(Enable::ENABLED, Enable::DISABLED /* filter duplicates */),
            LeSetScanEnableBuilder::Create(Enable::ENABLED, Enable::DISABLED /* filter duplicates */),
            module_handler_->BindOnce(impl::check_status));
        break;
    }
@@ -658,14 +664,14 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
    switch (api_type_) {
      case ScanApiType::EXTENDED:
        le_scanning_interface_->EnqueueCommand(
            hci::LeSetExtendedScanEnableBuilder::Create(
            LeSetExtendedScanEnableBuilder::Create(
                Enable::DISABLED, FilterDuplicates::DISABLED /* filter duplicates */, 0, 0),
            module_handler_->BindOnce(impl::check_status));
        break;
      case ScanApiType::ANDROID_HCI:
      case ScanApiType::LEGACY:
        le_scanning_interface_->EnqueueCommand(
            hci::LeSetScanEnableBuilder::Create(Enable::DISABLED, Enable::DISABLED /* filter duplicates */),
            LeSetScanEnableBuilder::Create(Enable::DISABLED, Enable::DISABLED /* filter duplicates */),
            module_handler_->BindOnce(impl::check_status));
        break;
    }
@@ -704,7 +710,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
  }

  void scan_filter_enable(bool enable) {
    if (!is_filter_support_) {
    if (!is_filter_supported_) {
      LOG_WARN("Advertising filter is not supported");
      return;
    }
@@ -728,7 +734,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback

  void scan_filter_parameter_setup(
      ApcfAction action, uint8_t filter_index, AdvertisingFilterParameter advertising_filter_parameter) {
    if (!is_filter_support_) {
    if (!is_filter_supported_) {
      LOG_WARN("Advertising filter is not supported");
      return;
    }
@@ -791,7 +797,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
  }

  void scan_filter_add(uint8_t filter_index, std::vector<AdvertisingPacketContentFilterCommand> filters) {
    if (!is_filter_support_) {
    if (!is_filter_supported_) {
      LOG_WARN("Advertising filter is not supported");
      return;
    }
@@ -1027,6 +1033,11 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
      uint8_t ad_type,
      std::vector<uint8_t> data,
      std::vector<uint8_t> data_mask) {
    if (!is_ad_type_filter_supported_) {
      LOG_ERROR("AD type filter isn't supported");
      return;
    }

    if (data.size() != data_mask.size()) {
      LOG_ERROR("ad type mask should have the same length as ad type data");
      return;
@@ -1051,7 +1062,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
      uint8_t batch_scan_truncated_max,
      uint8_t batch_scan_notify_threshold,
      ScannerId scanner_id) {
    if (!is_batch_scan_support_) {
    if (!is_batch_scan_supported_) {
      LOG_WARN("Batch scan is not supported");
      return;
    }
@@ -1078,7 +1089,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
      uint32_t duty_cycle_scan_window_slots,
      uint32_t duty_cycle_scan_interval_slots,
      BatchScanDiscardRule batch_scan_discard_rule) {
    if (!is_batch_scan_support_) {
    if (!is_batch_scan_supported_) {
      LOG_WARN("Batch scan is not supported");
      return;
    }
@@ -1102,7 +1113,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
  }

  void batch_scan_disable() {
    if (!is_batch_scan_support_) {
    if (!is_batch_scan_supported_) {
      LOG_WARN("Batch scan is not supported");
      return;
    }
@@ -1119,7 +1130,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
      uint32_t duty_cycle_scan_window_slots,
      uint32_t duty_cycle_scan_interval_slots,
      BatchScanDiscardRule batch_scan_discard_rule) {
    if (!is_batch_scan_support_) {
    if (!is_batch_scan_supported_) {
      LOG_WARN("Batch scan is not supported");
      return;
    }
@@ -1161,7 +1172,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
  }

  void batch_scan_read_results(ScannerId scanner_id, uint16_t total_num_of_records, BatchScanMode scan_mode) {
    if (!is_batch_scan_support_) {
    if (!is_batch_scan_supported_) {
      LOG_WARN("Batch scan is not supported");
      int status = static_cast<int>(ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
      scanning_callbacks_->OnBatchScanReports(scanner_id, status, 0, 0, {});
@@ -1187,7 +1198,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback

  void start_sync(
      uint8_t sid, const AddressWithType& address_with_type, uint16_t skip, uint16_t timeout, int request_id) {
    if (!is_periodic_advertising_sync_transfer_sender_support_) {
    if (!is_periodic_advertising_sync_transfer_sender_supported_) {
      LOG_WARN("PAST sender not supported on this device");
      int status = static_cast<int>(ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
      scanning_callbacks_->OnPeriodicSyncStarted(request_id, status, -1, sid, address_with_type, 0, 0);
@@ -1204,7 +1215,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
  }

  void stop_sync(uint16_t handle) {
    if (!is_periodic_advertising_sync_transfer_sender_support_) {
    if (!is_periodic_advertising_sync_transfer_sender_supported_) {
      LOG_WARN("PAST sender not supported on this device");
      return;
    }
@@ -1212,7 +1223,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
  }

  void cancel_create_sync(uint8_t sid, const Address& address) {
    if (!is_periodic_advertising_sync_transfer_sender_support_) {
    if (!is_periodic_advertising_sync_transfer_sender_supported_) {
      LOG_WARN("PAST sender not supported on this device");
      return;
    }
@@ -1220,7 +1231,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
  }

  void transfer_sync(const Address& address, uint16_t service_data, uint16_t sync_handle, int pa_source) {
    if (!is_periodic_advertising_sync_transfer_sender_support_) {
    if (!is_periodic_advertising_sync_transfer_sender_supported_) {
      LOG_WARN("PAST sender not supported on this device");
      int status = static_cast<int>(ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
      scanning_callbacks_->OnPeriodicSyncTransferred(pa_source, status, address);
@@ -1237,7 +1248,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
  }

  void transfer_set_info(const Address& address, uint16_t service_data, uint8_t adv_handle, int pa_source) {
    if (!is_periodic_advertising_sync_transfer_sender_support_) {
    if (!is_periodic_advertising_sync_transfer_sender_supported_) {
      LOG_WARN("PAST sender not supported on this device");
      int status = static_cast<int>(ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
      scanning_callbacks_->OnPeriodicSyncTransferred(pa_source, status, address);
@@ -1254,7 +1265,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
  }

  void sync_tx_parameters(const Address& address, uint8_t mode, uint16_t skip, uint16_t timeout, int reg_id) {
    if (!is_periodic_advertising_sync_transfer_sender_support_) {
    if (!is_periodic_advertising_sync_transfer_sender_supported_) {
      LOG_WARN("PAST sender not supported on this device");
      int status = static_cast<int>(ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
      AddressWithType address_with_type(address, AddressType::RANDOM_DEVICE_ADDRESS);
@@ -1288,6 +1299,10 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
    periodic_sync_manager_.SetScanningCallback(scanning_callbacks_);
  }

  bool is_ad_type_filter_supported() {
    return is_ad_type_filter_supported_;
  }

  void on_set_scan_parameter_complete(CommandCompleteView view) {
    switch (view.GetCommandOpCode()) {
      case (OpCode::LE_SET_SCAN_PARAMETERS): {
@@ -1413,6 +1428,26 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
    }
  }

  void on_apcf_read_extended_features_complete(CommandCompleteView view) {
    ASSERT(view.IsValid());
    auto status_view = LeAdvFilterCompleteView::Create(view);
    if (!status_view.IsValid()) {
      LOG_WARN("Can not get valid LeAdvFilterCompleteView, return");
      return;
    }
    if (status_view.GetStatus() != ErrorCode::SUCCESS) {
      LOG_WARN(
          "Got a Command complete %s, status %s",
          OpCodeText(view.GetCommandOpCode()).c_str(),
          ErrorCodeText(status_view.GetStatus()).c_str());
      return;
    }
    auto complete_view = LeAdvFilterReadExtendedFeaturesCompleteView::Create(status_view);
    ASSERT(complete_view.IsValid());
    is_ad_type_filter_supported_ = complete_view.GetAdTypeFilter() == 1;
    LOG_INFO("set is_ad_type_filter_supported_ to %d", is_ad_type_filter_supported_);
  }

  void on_batch_scan_complete(CommandCompleteView view) {
    ASSERT(view.IsValid());
    auto status_view = LeBatchScanCompleteView::Create(view);
@@ -1539,13 +1574,13 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback

  Module* module_;
  os::Handler* module_handler_;
  hci::HciLayer* hci_layer_;
  hci::Controller* controller_;
  hci::AclManager* acl_manager_;
  hci::VendorSpecificEventManager* vendor_specific_event_manager_;
  HciLayer* hci_layer_;
  Controller* controller_;
  AclManager* acl_manager_;
  VendorSpecificEventManager* vendor_specific_event_manager_;
  storage::StorageModule* storage_module_;
  hci::LeScanningInterface* le_scanning_interface_;
  hci::LeAddressManager* le_address_manager_;
  LeScanningInterface* le_scanning_interface_;
  LeAddressManager* le_address_manager_;
  bool address_manager_registered_ = false;
  NullScanningCallback null_scanning_callback_;
  ScanningCallback* scanning_callbacks_ = &null_scanning_callback_;
@@ -1555,9 +1590,10 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
  bool scan_on_resume_ = false;
  bool paused_ = false;
  AdvertisingCache advertising_cache_;
  bool is_filter_support_ = false;
  bool is_batch_scan_support_ = false;
  bool is_periodic_advertising_sync_transfer_sender_support_ = false;
  bool is_filter_supported_ = false;
  bool is_ad_type_filter_supported_ = false;
  bool is_batch_scan_supported_ = false;
  bool is_periodic_advertising_sync_transfer_sender_supported_ = false;

  LeScanType le_scan_type_ = LeScanType::ACTIVE;
  uint32_t interval_ms_{1000};
@@ -1598,18 +1634,18 @@ LeScanningManager::LeScanningManager() {
}

void LeScanningManager::ListDependencies(ModuleList* list) const {
  list->add<hci::HciLayer>();
  list->add<hci::VendorSpecificEventManager>();
  list->add<hci::Controller>();
  list->add<hci::AclManager>();
  list->add<HciLayer>();
  list->add<VendorSpecificEventManager>();
  list->add<Controller>();
  list->add<AclManager>();
  list->add<storage::StorageModule>();
}

void LeScanningManager::Start() {
  pimpl_->start(
      GetHandler(),
      GetDependency<hci::HciLayer>(),
      GetDependency<hci::Controller>(),
      GetDependency<HciLayer>(),
      GetDependency<Controller>(),
      GetDependency<AclManager>(),
      GetDependency<VendorSpecificEventManager>(),
      GetDependency<storage::StorageModule>());
@@ -1727,5 +1763,9 @@ void LeScanningManager::RegisterScanningCallback(ScanningCallback* scanning_call
  CallOn(pimpl_.get(), &impl::register_scanning_callback, scanning_callback);
}

bool LeScanningManager::IsAdTypeFilterSupported() const {
  return pimpl_->is_ad_type_filter_supported();
}

}  // namespace hci
}  // namespace bluetooth
+2 −0
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@ class LeScanningManager : public bluetooth::Module {

  virtual void RegisterScanningCallback(ScanningCallback* scanning_callback);

  virtual bool IsAdTypeFilterSupported() const;

  static const ModuleFactory Factory;

 protected:
+40 −18
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ class TestHciLayer : public HciLayer {
  void EnqueueCommand(
      std::unique_ptr<CommandBuilder> command,
      common::ContextualOnceCallback<void(CommandStatusView)> on_status) override {
    std::lock_guard<std::mutex> lock(mutex_);
    command_queue_.push(std::move(command));
    command_status_callbacks.push_back(std::move(on_status));
    command_count_--;
@@ -86,6 +87,7 @@ class TestHciLayer : public HciLayer {
  void EnqueueCommand(
      std::unique_ptr<CommandBuilder> command,
      common::ContextualOnceCallback<void(CommandCompleteView)> on_complete) override {
    std::lock_guard<std::mutex> lock(mutex_);
    command_queue_.push(std::move(command));
    command_complete_callbacks.push_back(std::move(on_complete));
    command_count_--;
@@ -103,31 +105,21 @@ class TestHciLayer : public HciLayer {
    command_future_ = std::make_unique<std::future<void>>(command_promise_->get_future());
  }

  CommandView GetLastCommand() {
    if (command_queue_.size() == 0) {
      return empty_command_view_;
    }
    auto last = std::move(command_queue_.front());
    command_queue_.pop();
    return CommandView::Create(GetPacketView(std::move(last)));
  }

  CommandView GetCommand() {
    if (!command_queue_.empty()) {
      std::lock_guard<std::mutex> lock(mutex_);
      if (command_future_ != nullptr) {
        command_future_.reset();
        command_promise_.reset();
      }
    } else if (command_future_ != nullptr) {
    // Wait for EnqueueCommand if command_queue_ is empty
    if (command_queue_.empty() && command_future_ != nullptr) {
      command_future_->wait_for(std::chrono::milliseconds(1000));
    }

    std::lock_guard<std::mutex> lock(mutex_);
    if (command_queue_.empty()) {
      LOG_ERROR("Command queue is empty");
      return empty_command_view_;
    }
    CommandView command_packet_view = GetLastCommand();

    auto last = std::move(command_queue_.front());
    command_queue_.pop();
    CommandView command_packet_view = CommandView::Create(GetPacketView(std::move(last)));
    if (!command_packet_view.IsValid()) {
      LOG_ERROR("Got invalid command");
      return empty_command_view_;
@@ -283,7 +275,12 @@ class LeScanningManagerTest : public ::testing::Test {
    fake_registry_.InjectTestModule(&AclManager::Factory, test_acl_manager_);
    client_handler_ = fake_registry_.GetTestModuleHandler(&HciLayer::Factory);
    ASSERT_NE(client_handler_, nullptr);
    if (is_filter_support_) {
      // Will send APCF read extended features command if APCF supported
      test_hci_layer_->SetCommandFuture(2);
    } else {
      test_hci_layer_->SetCommandFuture(1);
    }
    // configure_scan will be trigger by impl.start() and enqueue set scan parameter command
    fake_registry_.Start<LeScanningManager>(&thread_);
    le_scanning_manager =
@@ -293,6 +290,7 @@ class LeScanningManagerTest : public ::testing::Test {
  }

  void TearDown() override {
    sync_client_handler();
    fake_registry_.SynchronizeModuleHandler(&LeScanningManager::Factory, std::chrono::milliseconds(20));
    fake_registry_.StopAll();
  }
@@ -378,9 +376,13 @@ class LeAndroidHciScanningManagerTest : public LeScanningManagerTest {
    is_filter_support_ = true;
    is_batch_scan_support_ = true;
    LeScanningManagerTest::SetUp();
    sync_client_handler();
  }

  void HandleConfiguration() override {
    ASSERT_EQ(OpCode::LE_ADV_FILTER, test_hci_layer_->GetCommand().GetOpCode());
    test_hci_layer_->IncomingEvent(LeAdvFilterReadExtendedFeaturesCompleteBuilder::Create(1, ErrorCode::SUCCESS, 0x01));
    sync_client_handler();
    ASSERT_EQ(param_opcode_, test_hci_layer_->GetCommand().GetOpCode());
    test_hci_layer_->IncomingEvent(LeExtendedScanParamsCompleteBuilder::Create(1, ErrorCode::SUCCESS));
  }
@@ -432,6 +434,22 @@ TEST_F(LeScanningManagerTest, start_scan_test) {
  test_hci_layer_->IncomingLeMetaEvent(LeAdvertisingReportBuilder::Create({report}));
}

TEST_F(LeScanningManagerTest, is_ad_type_filter_supported_false_test) {
  ASSERT_FALSE(le_scanning_manager->IsAdTypeFilterSupported());
}

TEST_F(LeScanningManagerTest, scan_filter_add_ad_type_not_supported_test) {
  test_hci_layer_->SetCommandFuture(1);
  std::vector<AdvertisingPacketContentFilterCommand> filters = {};
  AdvertisingPacketContentFilterCommand filter{};
  filter.filter_type = ApcfFilterType::AD_TYPE;
  filter.ad_type = 0x09;
  filter.data = {0x12, 0x34, 0x56, 0x78};
  filter.data_mask = {0xff, 0xff, 0xff, 0xff};
  filters.push_back(filter);
  le_scanning_manager->ScanFilterAdd(0x01, filters);
}

TEST_F(LeAndroidHciScanningManagerTest, startup_teardown) {}

TEST_F(LeAndroidHciScanningManagerTest, start_scan_test) {
@@ -464,6 +482,10 @@ TEST_F(LeAndroidHciScanningManagerTest, start_scan_test) {
  test_hci_layer_->IncomingLeMetaEvent(LeAdvertisingReportBuilder::Create({report}));
}

TEST_F(LeAndroidHciScanningManagerTest, is_ad_type_filter_supported_true_test) {
  ASSERT_TRUE(le_scanning_manager->IsAdTypeFilterSupported());
}

TEST_F(LeAndroidHciScanningManagerTest, scan_filter_enable_test) {
  test_hci_layer_->SetCommandFuture(1);
  le_scanning_manager->ScanFilterEnable(true);
Loading