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

Commit e41c9449 authored by Myles Watson's avatar Myles Watson
Browse files

Check RemoteNameRequestCancel status

Bug: 329259336
Test: atest bluetooth_test_gd_unit
Flag: EXEMPT, simple bug fix with test
Change-Id: Icb7a8255115ffdb8999eff5502006bfd9b9335ff
parent f4f42a30
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();