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

Commit 373166f9 authored by Myles Watson's avatar Myles Watson Committed by Gerrit Code Review
Browse files

Merge "Check RemoteNameRequestCancel status" into main

parents 588637ec e41c9449
Loading
Loading
Loading
Loading
+30 −13
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@
#include <bluetooth/log.h>

#include "hci/acl_manager/acl_scheduler.h"
#include "hci/event_checkers.h"
#include "hci/hci_layer.h"
#include "hci/hci_packets.h"

@@ -145,7 +144,7 @@ struct RemoteNameRequestModule::impl {
        "assert failed: status.GetCommandOpCode() == OpCode::REMOTE_NAME_REQUEST");
    log::info(
        "Started remote name request peer:{} status:{}",
        address.ToString(),
        address.ToRedactedStringForLogging(),
        ErrorCodeText(status.GetStatus()));
    on_completion.Invoke(status.GetStatus());
    if (status.GetStatus() != ErrorCode::SUCCESS /* pending */) {
@@ -160,7 +159,7 @@ struct RemoteNameRequestModule::impl {
        log::info("Cancelling remote name request to {}", address.ToRedactedStringForLogging());
        hci_layer_->EnqueueCommand(
            RemoteNameRequestCancelBuilder::Create(address),
            handler_->BindOnce(check_complete<RemoteNameRequestCancelCompleteView>));
            handler_->BindOnceOn(this, &impl::check_cancel_status, address));
      } else {
        log::info(
            "Ignoring cancel RNR as RNR event already received to {}",
@@ -171,7 +170,7 @@ struct RemoteNameRequestModule::impl {
      log::info("Cancelling remote name request to {}", address.ToRedactedStringForLogging());
      hci_layer_->EnqueueCommand(
          RemoteNameRequestCancelBuilder::Create(address),
          handler_->BindOnce(check_complete<RemoteNameRequestCancelCompleteView>));
          handler_->BindOnceOn(this, &impl::check_cancel_status, address));
    }
  }

@@ -196,20 +195,38 @@ struct RemoteNameRequestModule::impl {
    }
  }

  void on_remote_name_request_complete(EventView view) {
    auto packet = RemoteNameRequestCompleteView::Create(view);
    log::assert_that(packet.IsValid(), "assert failed: packet.IsValid()");
  void completed(ErrorCode status, std::array<uint8_t, 248> name, Address address) {
    if (pending_) {
      log::info(
          "Received REMOTE_NAME_REQUEST_COMPLETE from {}",
          packet.GetBdAddr().ToRedactedStringForLogging());
          "Received REMOTE_NAME_REQUEST_COMPLETE from {} with status {}",
          address.ToRedactedStringForLogging(),
          ErrorCodeText(status));
      pending_ = false;
      on_remote_name_complete_.Invoke(packet.GetStatus(), packet.GetRemoteName());
      acl_scheduler_->ReportRemoteNameRequestCompletion(packet.GetBdAddr());
      on_remote_name_complete_.Invoke(status, name);
      acl_scheduler_->ReportRemoteNameRequestCompletion(address);
    } else {
      log::error(
          "Received unexpected REMOTE_NAME_REQUEST_COMPLETE when no Remote Name Request is "
          "outstanding");
          "Received unexpected REMOTE_NAME_REQUEST_COMPLETE from {} with status {}",
          address.ToRedactedStringForLogging(),
          ErrorCodeText(status));
    }
  }

  void on_remote_name_request_complete(EventView view) {
    auto packet = RemoteNameRequestCompleteView::Create(view);
    log::assert_that(packet.IsValid(), "Invalid packet");
    completed(packet.GetStatus(), packet.GetRemoteName(), packet.GetBdAddr());
  }

  void check_cancel_status(Address remote, CommandCompleteView complete) {
    auto packet = RemoteNameRequestCancelCompleteView::Create(complete);
    if (!packet.IsValid()) {
      completed(ErrorCode::UNSPECIFIED_ERROR, std::array<uint8_t, 248>{}, remote);
      return;
    }
    auto status = packet.GetStatus();
    if (status != ErrorCode::SUCCESS) {
      completed(status, std::array<uint8_t, 248>{}, packet.GetBdAddr());
    }
  }

+30 −0
Original line number Diff line number Diff line
@@ -327,6 +327,36 @@ TEST_F(RemoteNameRequestModuleTest, SendCommandThenCancelItCallbackInteropWorkar
          Eq(std::make_tuple(ErrorCode::UNKNOWN_CONNECTION, std::array<uint8_t, 248>{}))));
}

TEST_F(RemoteNameRequestModuleTest, SendCommandThenCancelItCancelFails) {
  auto promise = std::promise<std::tuple<ErrorCode, std::array<uint8_t, 248>>>{};
  auto future = promise.get_future();

  // start a remote name request
  remote_name_request_module_->StartRemoteNameRequest(
      address1,
      RemoteNameRequestBuilder::Create(
          address1, PageScanRepetitionMode::R0, 3, ClockOffsetValid::INVALID),
      emptyCallback<ErrorCode>(),
      impossibleCallback<uint64_t>(),
      capturingPromiseCallback<ErrorCode, std::array<uint8_t, 248>>(std::move(promise)));

  // we successfully start
  test_hci_layer_->GetCommand();
  test_hci_layer_->IncomingEvent(RemoteNameRequestStatusBuilder::Create(ErrorCode::SUCCESS, 1));

  // but then the request is cancelled successfully (the status doesn't matter)
  remote_name_request_module_->CancelRemoteNameRequest(address1);
  test_hci_layer_->GetCommand();
  test_hci_layer_->IncomingEvent(RemoteNameRequestCancelCompleteBuilder::Create(
      1, ErrorCode::INVALID_HCI_COMMAND_PARAMETERS, address1));

  // we expect the name callback to be invoked nonetheless
  EXPECT_THAT(
      future,
      IsSetWithValue(Eq(
          std::make_tuple(ErrorCode::INVALID_HCI_COMMAND_PARAMETERS, std::array<uint8_t, 248>{}))));
}

TEST_F(RemoteNameRequestModuleTest, HostSupportedEvents) {
  auto promise = std::promise<uint64_t>{};
  auto future = promise.get_future();