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

Commit 046dd002 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Add inquiry module unit tests"

parents 0cd968b5 df775263
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ filegroup {
filegroup {
    name: "BluetoothNeighborTestSources",
    srcs: [
            "inquiry_test.cc",
    ],
}
+79 −62
Original line number Diff line number Diff line
@@ -88,10 +88,18 @@ struct InquiryModule::impl {
  hci::InquiryScanType inquiry_scan_type_;
  int8_t inquiry_response_tx_power_;

  void EnqueueCommandComplete(std::unique_ptr<hci::CommandPacketBuilder> command);
  void EnqueueCommandStatus(std::unique_ptr<hci::CommandPacketBuilder> command);
  void OnCommandComplete(hci::CommandCompleteView view);
  void OnCommandStatus(hci::CommandStatusView status);

  void EnqueueCommandCompleteSync(std::unique_ptr<hci::CommandPacketBuilder> command);
  void OnCommandCompleteSync(hci::CommandCompleteView view);

  void OnEvent(hci::EventPacketView view);

  std::promise<void>* command_sync_{nullptr};

  hci::HciLayer* hci_layer_;
  os::Handler* handler_;
};
@@ -103,33 +111,34 @@ neighbor::InquiryModule::impl::impl(neighbor::InquiryModule& module) : module_(m
  limited_lap_.lap_ = kLimitedInquiryAccessCode;
}

void neighbor::InquiryModule::impl::OnCommandCompleteSync(hci::CommandCompleteView view) {
  OnCommandComplete(view);
  ASSERT(command_sync_ != nullptr);
  command_sync_->set_value();
}

void neighbor::InquiryModule::impl::OnCommandComplete(hci::CommandCompleteView view) {
  switch (view.GetCommandOpCode()) {
    case hci::OpCode::INQUIRY_CANCEL: {
      auto packet = hci::InquiryCancelCompleteView::Create(view);
      ASSERT(packet.IsValid());
      ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
      if (active_one_shot_ == nullptr) {
        LOG_WARN("Received inquiry cancel without a one shot inquiry in progress");
      }
      active_one_shot_ = nullptr;
    } break;

    case hci::OpCode::PERIODIC_INQUIRY_MODE: {
      auto packet = hci::PeriodicInquiryModeCompleteView::Create(view);
      ASSERT(packet.IsValid());
      ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
      if (active_periodic_ != nullptr) {
        LOG_DEBUG("Periodic inquiry started lap:%s", LapText(active_periodic_->lap_).c_str());
      }
    } break;

    case hci::OpCode::EXIT_PERIODIC_INQUIRY_MODE: {
      auto packet = hci::ExitPeriodicInquiryModeCompleteView::Create(view);
      ASSERT(packet.IsValid());
      ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
      if (active_periodic_ == nullptr) {
        LOG_WARN("Received exit periodic inquiry without a periodic inquiry in progress");
      }
      active_periodic_ = nullptr;
    }
    } break;

    case hci::OpCode::WRITE_INQUIRY_MODE: {
      auto packet = hci::WriteInquiryModeCompleteView::Create(view);
@@ -186,14 +195,14 @@ void neighbor::InquiryModule::impl::OnCommandComplete(hci::CommandCompleteView v

void neighbor::InquiryModule::impl::OnCommandStatus(hci::CommandStatusView status) {
  ASSERT(status.GetStatus() == hci::ErrorCode::SUCCESS);
  ASSERT(status.GetNumHciCommandPackets() == 1);

  switch (status.GetCommandOpCode()) {
    case hci::OpCode::INQUIRY: {
      auto packet = hci::InquiryStatusView::Create(status);
      ASSERT(packet.IsValid());
      ASSERT(active_one_shot_ != nullptr);
      if (active_one_shot_ != nullptr) {
        LOG_DEBUG("Inquiry started lap:%s", LapText(active_one_shot_->lap_).c_str());
      }
    } break;

    default:
@@ -207,6 +216,7 @@ void neighbor::InquiryModule::impl::OnEvent(hci::EventPacketView view) {
    case hci::EventCode::INQUIRY_COMPLETE: {
      auto packet = hci::InquiryCompleteView::Create(view);
      ASSERT(packet.IsValid());
      LOG_DEBUG("inquiry complete");
      active_one_shot_ = nullptr;
      inquiry_callbacks_.complete(packet.GetStatus());
    } break;
@@ -214,8 +224,8 @@ void neighbor::InquiryModule::impl::OnEvent(hci::EventPacketView view) {
    case hci::EventCode::INQUIRY_RESULT: {
      auto packet = hci::InquiryResultView::Create(view);
      ASSERT(packet.IsValid());
      LOG_DEBUG("Inquiry result num_responses:%d addr:%s repetition_mode:%s cod:%s clock_offset:%d",
                packet.GetNumResponses(), packet.GetBdAddr().ToString().c_str(),
      LOG_DEBUG("Inquiry result size:%zd num_responses:%d addr:%s repetition_mode:%s cod:%s clock_offset:%d",
                packet.size(), packet.GetNumResponses(), packet.GetBdAddr().ToString().c_str(),
                hci::PageScanRepetitionModeText(packet.GetPageScanRepetitionMode()).c_str(),
                packet.GetClassOfDevice().ToString().c_str(), packet.GetClockOffset());
      inquiry_callbacks_.result(packet);
@@ -252,27 +262,59 @@ void neighbor::InquiryModule::impl::OnEvent(hci::EventPacketView view) {
 */
void neighbor::InquiryModule::impl::RegisterCallbacks(InquiryCallbacks callbacks) {
  inquiry_callbacks_ = callbacks;

  hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT,
                                   common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_);
  hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI,
                                   common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_);
  hci_layer_->RegisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT,
                                   common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_);
  hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_COMPLETE,
                                   common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_);
}

void neighbor::InquiryModule::impl::UnregisterCallbacks() {
  hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_COMPLETE);
  hci_layer_->UnregisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT);
  hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI);
  hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT);

  inquiry_callbacks_ = {nullptr, nullptr, nullptr, nullptr};
}

void neighbor::InquiryModule::impl::EnqueueCommandComplete(std::unique_ptr<hci::CommandPacketBuilder> command) {
  hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)),
                             handler_);
}

void neighbor::InquiryModule::impl::EnqueueCommandStatus(std::unique_ptr<hci::CommandPacketBuilder> command) {
  hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandStatus, common::Unretained(this)),
                             handler_);
}

void neighbor::InquiryModule::impl::EnqueueCommandCompleteSync(std::unique_ptr<hci::CommandPacketBuilder> command) {
  ASSERT(command_sync_ == nullptr);
  command_sync_ = new std::promise<void>();
  auto command_received = command_sync_->get_future();
  hci_layer_->EnqueueCommand(std::move(command),
                             common::BindOnce(&impl::OnCommandCompleteSync, common::Unretained(this)), handler_);
  command_received.wait();
  delete command_sync_;
  command_sync_ = nullptr;
}

void neighbor::InquiryModule::impl::StartOneShotInquiry(hci::Lap& lap, InquiryLength inquiry_length,
                                                        NumResponses num_responses) {
  ASSERT(active_one_shot_ == nullptr);
  ASSERT(HasCallbacks());
  hci_layer_->EnqueueCommand(hci::InquiryBuilder::Create(lap, inquiry_length, num_responses),
                             common::BindOnce(&impl::OnCommandStatus, common::Unretained(this)), handler_);
  ASSERT(active_one_shot_ == nullptr);
  active_one_shot_ = &lap;
  EnqueueCommandStatus(hci::InquiryBuilder::Create(lap, inquiry_length, num_responses));
}

void neighbor::InquiryModule::impl::StopOneShotInquiry() {
  ASSERT(HasCallbacks());
  hci_layer_->EnqueueCommand(hci::InquiryCancelBuilder::Create(),
                             common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_);
  ASSERT(active_one_shot_ != nullptr);
  active_one_shot_ = nullptr;
  EnqueueCommandComplete(hci::InquiryCancelBuilder::Create());
}

bool neighbor::InquiryModule::impl::IsOneShotInquiryActive(hci::Lap& lap) const {
@@ -282,20 +324,17 @@ bool neighbor::InquiryModule::impl::IsOneShotInquiryActive(hci::Lap& lap) const
void neighbor::InquiryModule::impl::StartPeriodicInquiry(hci::Lap& lap, InquiryLength inquiry_length,
                                                         NumResponses num_responses, PeriodLength max_delay,
                                                         PeriodLength min_delay) {
  ASSERT(active_periodic_ == nullptr);
  ASSERT(HasCallbacks());
  hci_layer_->EnqueueCommand(
      hci::PeriodicInquiryModeBuilder::Create(inquiry_length, num_responses, lap, max_delay, min_delay),
      common::BindOnce(&impl::OnCommandStatus, common::Unretained(this)), handler_);
  ASSERT(active_periodic_ == nullptr);
  active_periodic_ = &lap;
  EnqueueCommandComplete(
      hci::PeriodicInquiryModeBuilder::Create(inquiry_length, num_responses, lap, max_delay, min_delay));
}

void neighbor::InquiryModule::impl::StopPeriodicInquiry() {
  ASSERT(active_periodic_ != nullptr);
  ASSERT(HasCallbacks());
  hci_layer_->EnqueueCommand(hci::ExitPeriodicInquiryModeBuilder::Create(),
                             common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_);
  active_periodic_ = nullptr;
  EnqueueCommandComplete(hci::ExitPeriodicInquiryModeBuilder::Create());
}

bool neighbor::InquiryModule::impl::IsPeriodicInquiryActive(hci::Lap& lap) const {
@@ -310,31 +349,16 @@ void neighbor::InquiryModule::impl::Start() {
  hci_layer_ = module_.GetDependency<hci::HciLayer>();
  handler_ = module_.GetHandler();

  hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT,
                                   common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_);
  hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI,
                                   common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_);
  hci_layer_->RegisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT,
                                   common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_);
  hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_COMPLETE,
                                   common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_);
  EnqueueCommandComplete(hci::ReadInquiryResponseTransmitPowerLevelBuilder::Create());
  EnqueueCommandComplete(hci::ReadInquiryScanActivityBuilder::Create());
  EnqueueCommandComplete(hci::ReadInquiryScanTypeBuilder::Create());
  EnqueueCommandCompleteSync(hci::ReadInquiryModeBuilder::Create());

  hci_layer_->EnqueueCommand(hci::ReadInquiryResponseTransmitPowerLevelBuilder::Create(),
                             common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_);
  hci_layer_->EnqueueCommand(hci::ReadInquiryScanActivityBuilder::Create(),
                             common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_);
  hci_layer_->EnqueueCommand(hci::ReadInquiryScanTypeBuilder::Create(),
                             common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_);
  LOG_DEBUG("Started inquiry module");
}

void neighbor::InquiryModule::impl::Stop() {
  hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_COMPLETE);
  hci_layer_->UnregisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT);
  hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI);
  hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT);

  LOG_INFO("Inquiry scan interval:%hd window:%hd", inquiry_scan_.interval, inquiry_scan_.window);
  LOG_INFO("Inquiry scan interval:%hu window:%hu", inquiry_scan_.interval, inquiry_scan_.window);
  LOG_INFO("Inquiry mode:%s scan_type:%s", hci::InquiryModeText(inquiry_mode_).c_str(),
           hci::InquiryScanTypeText(inquiry_scan_type_).c_str());
  LOG_INFO("Inquiry response tx power:%hhd", inquiry_response_tx_power_);
@@ -342,18 +366,14 @@ void neighbor::InquiryModule::impl::Stop() {
}

void neighbor::InquiryModule::impl::SetInquiryMode(hci::InquiryMode mode) {
  hci_layer_->EnqueueCommand(hci::WriteInquiryModeBuilder::Create(mode),
                             common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_);
  EnqueueCommandComplete(hci::WriteInquiryModeBuilder::Create(mode));
  inquiry_mode_ = mode;
  LOG_DEBUG("Set inquiry mode");
  LOG_DEBUG("Set inquiry mode:%s", hci::InquiryModeText(mode).c_str());
}

void neighbor::InquiryModule::impl::SetScanActivity(ScanParameters params) {
  hci_layer_->EnqueueCommand(hci::WriteInquiryScanActivityBuilder::Create(params.interval, params.window),
                             common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_);

  hci_layer_->EnqueueCommand(hci::ReadInquiryScanActivityBuilder::Create(),
                             common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_);
  EnqueueCommandComplete(hci::WriteInquiryScanActivityBuilder::Create(params.interval, params.window));
  inquiry_scan_ = params;
  LOG_DEBUG("Set scan activity interval:0x%x/%.02fms window:0x%x/%.02fms", params.interval,
            ScanIntervalTimeMs(params.interval), params.window, ScanWindowTimeMs(params.window));
}
@@ -363,10 +383,7 @@ ScanParameters neighbor::InquiryModule::impl::GetScanActivity() const {
}

void neighbor::InquiryModule::impl::SetScanType(hci::InquiryScanType scan_type) {
  hci_layer_->EnqueueCommand(hci::WriteInquiryScanTypeBuilder::Create(scan_type),
                             common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_);
  hci_layer_->EnqueueCommand(hci::ReadInquiryScanTypeBuilder::Create(),
                             common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_);
  EnqueueCommandComplete(hci::WriteInquiryScanTypeBuilder::Create(scan_type));
  LOG_DEBUG("Set scan type:%s", hci::InquiryScanTypeText(scan_type).c_str());
}

@@ -411,7 +428,7 @@ void neighbor::InquiryModule::StartLimitedInquiry(InquiryLength inquiry_length,
}

void neighbor::InquiryModule::StopInquiry() {
  if (pimpl_->IsInquiryActive()) {
  if (!pimpl_->IsInquiryActive()) {
    LOG_WARN("Ignoring stop one shot inquiry as an inquiry is not active");
    return;
  }
@@ -448,7 +465,7 @@ void neighbor::InquiryModule::StartLimitedPeriodicInquiry(InquiryLength inquiry_
}

void neighbor::InquiryModule::StopPeriodicInquiry() {
  if (pimpl_->IsInquiryActive()) {
  if (!pimpl_->IsInquiryActive()) {
    LOG_WARN("Ignoring stop periodic inquiry as an inquiry is not active");
    return;
  }
+488 −0

File added.

Preview size limit exceeded, changes collapsed.