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

Commit 89384290 authored by Henri Chataing's avatar Henri Chataing Committed by Automerger Merge Worker
Browse files

Merge "Revert "RootCanal: Refactor implementation of Inquiry and...

Merge "Revert "RootCanal: Refactor implementation of Inquiry and InquiryCancel"" into main am: f0369fac

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/2919308



Change-Id: Idfed3461a3a55ab0e0b2a34858af48f4050fb939
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 66e97bd3 f0369fac
Loading
Loading
Loading
Loading
+17 −12
Original line number Diff line number Diff line
@@ -1717,19 +1717,24 @@ void DualModeController::SetEventFilter(CommandView command) {
void DualModeController::Inquiry(CommandView command) {
  auto command_view = bluetooth::hci::InquiryView::Create(command);
  ASSERT(command_view.IsValid());
  auto lap = command_view.GetLap().lap_;
  auto inquiry_length = command_view.GetInquiryLength();
  auto num_responses = command_view.GetNumResponses();
  auto max_responses = command_view.GetNumResponses();
  auto length = command_view.GetInquiryLength();

  DEBUG(id_, "<< Inquiry");
  DEBUG(id_, "   lap={}", lap);
  DEBUG(id_, "   inquiry_length={}", inquiry_length);
  DEBUG(id_, "   num_responses={}", num_responses);
  DEBUG(id_, "   num_responses={}", max_responses);
  DEBUG(id_, "   inquiry_length={}", length);

  auto status =
      link_layer_controller_.Inquiry(lap, inquiry_length, num_responses);
  send_event_(
      bluetooth::hci::InquiryStatusBuilder::Create(status, kNumCommandPackets));
  if (max_responses > 0xff || length < 1 || length > 0x30) {
    send_event_(bluetooth::hci::InquiryStatusBuilder::Create(
        ErrorCode::INVALID_HCI_COMMAND_PARAMETERS, kNumCommandPackets));
    return;
  }
  link_layer_controller_.SetInquiryLAP(command_view.GetLap().lap_);
  link_layer_controller_.SetInquiryMaxResponses(max_responses);
  link_layer_controller_.StartInquiry(std::chrono::milliseconds(length * 1280));

  send_event_(bluetooth::hci::InquiryStatusBuilder::Create(ErrorCode::SUCCESS,
                                                           kNumCommandPackets));
}

void DualModeController::InquiryCancel(CommandView command) {
@@ -1738,9 +1743,9 @@ void DualModeController::InquiryCancel(CommandView command) {

  DEBUG(id_, "<< Inquiry Cancel");

  auto status = link_layer_controller_.InquiryCancel();
  link_layer_controller_.InquiryCancel();
  send_event_(bluetooth::hci::InquiryCancelCompleteBuilder::Create(
      kNumCommandPackets, status));
      kNumCommandPackets, ErrorCode::SUCCESS));
}

void DualModeController::AcceptConnectionRequest(CommandView command) {
+48 −59
Original line number Diff line number Diff line
@@ -61,7 +61,6 @@ namespace rootcanal {
constexpr milliseconds kScanRequestTimeout(200);
constexpr milliseconds kNoDelayMs(0);
constexpr milliseconds kPageInterval(1000);
constexpr milliseconds kInquiryInterval(500);

const Address& LinkLayerController::GetAddress() const { return address_; }

@@ -292,43 +291,6 @@ LinkLayerController::GenerateResolvablePrivateAddress(AddressWithType address,
//  BR/EDR Commands
// =============================================================================

// HCI Inquiry command (Vol 4, Part E § 7.1.1).
ErrorCode LinkLayerController::Inquiry(uint8_t lap, uint8_t inquiry_length,
                                       uint8_t num_responses) {
  if (inquiry_.has_value()) {
    INFO(id_, "inquiry is already started");
    return ErrorCode::COMMAND_DISALLOWED;
  }

  if (inquiry_length < 0x1 || inquiry_length > 0x30) {
    INFO(id_, "invalid inquiry length ({})", inquiry_length);
    return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
  }

  // The Inquiry_Length parameter, added to Extended_Inquiry_Length
  // (see Section 6.42), specifies the total duration of the Inquiry Mode and,
  // when this time expires, Inquiry will be halted.
  std::chrono::microseconds inquiry_timeout =
      1280ms * inquiry_length +
      std::chrono::duration_cast<milliseconds>(extended_inquiry_length_);

  auto now = std::chrono::steady_clock::now();
  inquiry_ = InquiryState{
      .lap = lap,
      .num_responses = num_responses,
      .next_inquiry_event = now + kInquiryInterval,
      .inquiry_timeout = now + inquiry_timeout,
  };

  return ErrorCode::SUCCESS;
}

// HCI Inquiry Cancel command (Vol 4, Part E § 7.1.2).
ErrorCode LinkLayerController::InquiryCancel() {
  inquiry_ = {};
  return ErrorCode::SUCCESS;
}

// HCI Read Rssi command (Vol 4, Part E § 7.5.4).
ErrorCode LinkLayerController::ReadRssi(uint16_t connection_handle,
                                        int8_t* rssi) {
@@ -5199,7 +5161,10 @@ void LinkLayerController::IncomingPageResponsePacket(
void LinkLayerController::Tick() {
  RunPendingTasks();
  Paging();
  Inquiring();

  if (inquiry_timer_task_id_ != kInvalidTaskId) {
    Inquiry();
  }
  LeAdvertising();
  LeScanning();
  link_manager_tick(lm_.get());
@@ -5427,7 +5392,7 @@ ErrorCode LinkLayerController::CreateConnection(const Address& bd_addr,
  }

  auto now = std::chrono::steady_clock::now();
  page_ = PageState{
  page_ = Page{
      .bd_addr = bd_addr,
      .allow_role_switch = allow_role_switch,
      .next_page_event = now + kPageInterval,
@@ -6084,7 +6049,10 @@ void LinkLayerController::Reset() {
  initiator_ = Initiator{};
  synchronizing_ = {};
  synchronized_ = {};
  last_inquiry_ = steady_clock::now();
  inquiry_mode_ = InquiryType::STANDARD;
  inquiry_lap_ = 0;
  inquiry_max_responses_ = 0;
  default_tx_phys_ = properties_.LeSupportedPhys();
  default_rx_phys_ = properties_.LeSupportedPhys();

@@ -6094,7 +6062,11 @@ void LinkLayerController::Reset() {
  current_iac_lap_list_.emplace_back(general_iac);

  page_ = {};
  inquiry_ = {};

  if (inquiry_timer_task_id_ != kInvalidTaskId) {
    CancelScheduledTask(inquiry_timer_task_id_);
    inquiry_timer_task_id_ = kInvalidTaskId;
  }

  lm_.reset(link_manager_create(controller_ops_));
  ll_.reset(link_layer_create(controller_ops_));
@@ -6105,7 +6077,7 @@ void LinkLayerController::Paging() {
  auto now = std::chrono::steady_clock::now();

  if (page_.has_value() && now >= page_->page_timeout) {
    INFO(id_, "page timeout triggered for connection with {}",
    INFO("page timeout triggered for connection with {}",
         page_->bd_addr.ToString());

    send_event_(bluetooth::hci::ConnectionCompleteBuilder::Create(
@@ -6128,25 +6100,25 @@ void LinkLayerController::Paging() {
  }
}

/// Drive the logic for the Inquiry controller substate.
void LinkLayerController::Inquiring() {
  auto now = std::chrono::steady_clock::now();
void LinkLayerController::StartInquiry(milliseconds timeout) {
  inquiry_timer_task_id_ = ScheduleTask(milliseconds(timeout), [this]() {
    LinkLayerController::InquiryTimeout();
  });
}

  if (inquiry_.has_value() && now >= inquiry_->inquiry_timeout) {
    INFO(id_, "inquiry timeout triggered");
void LinkLayerController::InquiryCancel() {
  ASSERT(inquiry_timer_task_id_ != kInvalidTaskId);
  CancelScheduledTask(inquiry_timer_task_id_);
  inquiry_timer_task_id_ = kInvalidTaskId;
}

void LinkLayerController::InquiryTimeout() {
  if (inquiry_timer_task_id_ != kInvalidTaskId) {
    inquiry_timer_task_id_ = kInvalidTaskId;
    if (IsEventUnmasked(EventCode::INQUIRY_COMPLETE)) {
      send_event_(
          bluetooth::hci::InquiryCompleteBuilder::Create(ErrorCode::SUCCESS));

    inquiry_ = {};
    return;
    }

  // Send a Inquiry packet when the inquiry interval has passed.
  if (inquiry_.has_value() && now >= inquiry_->next_inquiry_event) {
    SendLinkLayerPacket(model::packets::InquiryBuilder::Create(
        GetAddress(), Address::kEmpty, inquiry_mode_, inquiry_->lap));
    inquiry_->next_inquiry_event = now + kInquiryInterval;
  }
}

@@ -6154,6 +6126,23 @@ void LinkLayerController::SetInquiryMode(uint8_t mode) {
  inquiry_mode_ = static_cast<model::packets::InquiryType>(mode);
}

void LinkLayerController::SetInquiryLAP(uint64_t lap) { inquiry_lap_ = lap; }

void LinkLayerController::SetInquiryMaxResponses(uint8_t max) {
  inquiry_max_responses_ = max;
}

void LinkLayerController::Inquiry() {
  steady_clock::time_point now = steady_clock::now();
  if (duration_cast<milliseconds>(now - last_inquiry_) < milliseconds(2000)) {
    return;
  }

  SendLinkLayerPacket(model::packets::InquiryBuilder::Create(
      GetAddress(), Address::kEmpty, inquiry_mode_, inquiry_lap_));
  last_inquiry_ = now;
}

void LinkLayerController::SetInquiryScanEnable(bool enable) {
  inquiry_scan_enable_ = enable;
}
+13 −21
Original line number Diff line number Diff line
@@ -185,7 +185,6 @@ class LinkLayerController {
  void Reset();

  void Paging();
  void Inquiring();
  void LeAdvertising();
  void LeScanning();
  void LeSynchronization();
@@ -277,7 +276,13 @@ class LinkLayerController {
  uint8_t LeReadNumberOfSupportedAdvertisingSets();

  // Classic
  void StartInquiry(std::chrono::milliseconds timeout);
  void InquiryCancel();
  void InquiryTimeout();
  void SetInquiryMode(uint8_t mode);
  void SetInquiryLAP(uint64_t lap);
  void SetInquiryMaxResponses(uint8_t max);
  void Inquiry();

  bool GetInquiryScanEnable() const { return inquiry_scan_enable_; }
  void SetInquiryScanEnable(bool enable);
@@ -338,12 +343,6 @@ class LinkLayerController {

  // BR/EDR Commands

  // HCI Inquiry command (Vol 4, Part E § 7.1.1).
  ErrorCode Inquiry(uint8_t lap, uint8_t inquiry_length, uint8_t num_responses);

  // HCI Inquiry Cancel command (Vol 4, Part E § 7.1.2).
  ErrorCode InquiryCancel();

  // HCI Read Rssi command (Vol 4, Part E § 7.5.4).
  ErrorCode ReadRssi(uint16_t connection_handle, int8_t* rssi);

@@ -949,9 +948,6 @@ class LinkLayerController {
  // Class of Device (Vol 4, Part E § 6.26).
  uint32_t class_of_device_{0};

  // Extended Inquiry Length (Vol 4, Part E § 6.42).
  slots extended_inquiry_length_{0};

  // Other configuration parameters.

  // Current IAC LAP (Vol 4, Part E § 7.3.44).
@@ -1176,27 +1172,23 @@ class LinkLayerController {
  struct ControllerOps controller_ops_;

  // Classic state.
  struct PageState {
  struct Page {
    Address bd_addr;
    uint8_t allow_role_switch;
    std::chrono::steady_clock::time_point next_page_event{};
    std::chrono::steady_clock::time_point page_timeout{};
  };

  struct InquiryState {
    uint64_t lap;
    uint8_t num_responses;
    std::chrono::steady_clock::time_point next_inquiry_event{};
    std::chrono::steady_clock::time_point inquiry_timeout{};
  };

  // Page and inquiry substates.
  // Page substate.
  // RootCanal will allow only one page request running at the same time.
  std::optional<PageState> page_;
  std::optional<InquiryState> inquiry_;
  std::optional<Page> page_;

  std::chrono::steady_clock::time_point last_inquiry_;
  model::packets::InquiryType inquiry_mode_{
      model::packets::InquiryType::STANDARD};
  TaskId inquiry_timer_task_id_ = kInvalidTaskId;
  uint64_t inquiry_lap_{};
  uint8_t inquiry_max_responses_{};

 public:
  // Type of scheduled tasks.