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

Commit df775263 authored by Chris Manton's avatar Chris Manton
Browse files

Add inquiry module unit tests

Test: bluetooth_test_gd
Bug: 142061208

Change-Id: I0d18af5592d09d1a63f3c37f10838fd95269dac8
parent 350b8fa9
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.