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

Commit 17ae9d4e authored by Jack He's avatar Jack He Committed by Gerrit Code Review
Browse files

Merge changes I6b35e11d,Iacec1d37

* changes:
  HCI: Send Debug packet when HCI timeout
  HCI: Add support for Debug packet
parents 4d50cf28 0b096160
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -49,8 +49,8 @@ static void fail_if_reset_complete_not_success(CommandCompleteView complete) {
  ASSERT(reset_complete.GetStatus() == ErrorCode::SUCCESS);
}

static void on_hci_timeout(OpCode op_code) {
  ASSERT_LOG(false, "Timed out waiting for 0x%02hx (%s)", op_code, OpCodeText(op_code).c_str());
static void abort_after_time_out(OpCode op_code) {
  ASSERT_LOG(false, "Done waiting for debug information after HCI timeout (%s)", OpCodeText(op_code).c_str());
}

class CommandQueueEntry {
@@ -87,12 +87,14 @@ class CommandQueueEntry {
struct HciLayer::impl {
  impl(hal::HciHal* hal, HciLayer& module) : hal_(hal), module_(module) {
    hci_timeout_alarm_ = new Alarm(module.GetHandler());
    hci_abort_alarm_ = new Alarm(module.GetHandler());
  }

  ~impl() {
    incoming_acl_buffer_.Clear();
    incoming_iso_buffer_.Clear();
    delete hci_timeout_alarm_;
    delete hci_abort_alarm_;
    command_queue_.clear();
  }

@@ -167,6 +169,21 @@ struct HciLayer::impl {
    send_next_command();
  }

  void on_hci_timeout(OpCode op_code) {
    LOG_ERROR("Timed out waiting for 0x%02hx (%s)", op_code, OpCodeText(op_code).c_str());

    LOG_ERROR("Flushing %zd waiting commands", command_queue_.size());
    // Clear any waiting commands (there is an abort coming anyway)
    command_queue_.clear();
    command_credits_ = 1;
    waiting_command_ = OpCode::NONE;
    enqueue_command(
        ControllerDebugInfoBuilder::Create(), module_.GetHandler()->BindOnce(&fail_if_reset_complete_not_success));
    // Don't time out for this one;
    hci_timeout_alarm_->Cancel();
    hci_abort_alarm_->Schedule(BindOnce(&abort_after_time_out, op_code), kHciTimeoutRestartMs);
  }

  void send_next_command() {
    if (command_credits_ == 0) {
      return;
@@ -187,7 +204,7 @@ struct HciLayer::impl {
    OpCode op_code = cmd_view.GetOpCode();
    waiting_command_ = op_code;
    command_credits_ = 0;  // Only allow one outstanding command
    hci_timeout_alarm_->Schedule(BindOnce(&on_hci_timeout, op_code), kHciTimeoutMs);
    hci_timeout_alarm_->Schedule(BindOnce(&impl::on_hci_timeout, common::Unretained(this), op_code), kHciTimeoutMs);
  }

  void register_event(EventCode event, ContextualCallback<void(EventView)> handler) {
@@ -291,6 +308,7 @@ struct HciLayer::impl {
  OpCode waiting_command_{OpCode::NONE};
  uint8_t command_credits_{1};  // Send reset first
  Alarm* hci_timeout_alarm_{nullptr};
  Alarm* hci_abort_alarm_{nullptr};

  // Acl packets
  BidiQueue<AclView, AclBuilder> acl_queue_{3 /* TODO: Set queue depth */};
+1 −0
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@ class HciLayer : public Module, public CommandInterface<CommandBuilder> {
  }

  static constexpr std::chrono::milliseconds kHciTimeoutMs = std::chrono::milliseconds(2000);
  static constexpr std::chrono::milliseconds kHciTimeoutRestartMs = std::chrono::milliseconds(5000);

  static const ModuleFactory Factory;

+20 −0
Original line number Diff line number Diff line
@@ -545,6 +545,26 @@ TEST_F(HciTest, vendorSpecificEventUnknown) {
  ASSERT_NE(event_status, std::future_status::ready);
}

TEST_F(HciTest, hciTimeOut) {
  auto event_future = upper->GetReceivedEventFuture();
  auto reset_command_future = hal->GetSentCommandFuture();
  upper->SendHciCommandExpectingComplete(ResetBuilder::Create());
  auto reset_command_sent_status = reset_command_future.wait_for(kTimeout);
  ASSERT_EQ(reset_command_sent_status, std::future_status::ready);
  auto reset = hal->GetSentCommand();
  ASSERT_TRUE(reset.IsValid());
  ASSERT_EQ(reset.GetOpCode(), OpCode::RESET);

  auto debug_command_future = hal->GetSentCommandFuture();
  auto event_status = event_future.wait_for(HciLayer::kHciTimeoutMs);
  ASSERT_NE(event_status, std::future_status::ready);
  auto debug_command_sent_status = debug_command_future.wait_for(kTimeout);
  ASSERT_EQ(debug_command_sent_status, std::future_status::ready);
  auto debug = hal->GetSentCommand();
  ASSERT_TRUE(debug.IsValid());
  ASSERT_EQ(debug.GetOpCode(), OpCode::CONTROLLER_DEBUG_INFO);
}

TEST_F(HciTest, noOpCredits) {
  ASSERT_EQ(0, hal->GetNumSentCommands());

+1 −2
Original line number Diff line number Diff line
@@ -4772,11 +4772,10 @@ packet LeExtendedScanParamsComplete : CommandComplete (command_op_code = LE_EXTE
}

packet ControllerDebugInfo : VendorCommand (op_code = CONTROLLER_DEBUG_INFO) {
  _payload_,  // placeholder (unimplemented)
}

packet ControllerDebugInfoComplete : CommandComplete (command_op_code = CONTROLLER_DEBUG_INFO) {
  _payload_,  // placeholder (unimplemented)
  status : ErrorCode,
}

packet ControllerA2DPOpcode : VendorCommand (op_code = CONTROLLER_A2DP_OPCODE) {