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

Commit 9de33747 authored by Myles Watson's avatar Myles Watson Committed by Automerger Merge Worker
Browse files

Merge "HCI: Create a valid command complete for status" into main am: 1f5c1307 am: fd7252d6

parents 5fd19dd2 fd7252d6
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include "os/metrics.h"
#include "os/queue.h"
#include "osi/include/stack_power_telemetry.h"
#include "packet/raw_builder.h"
#include "storage/storage_module.h"

namespace bluetooth {
@@ -218,10 +219,19 @@ struct HciLayer::impl {
      // we can't treat this as hard failure since we have no way of probing this lack of support at
      // earlier time. Instead we let the command complete handler handle a empty Command Complete
      // packet, which will be interpreted as invalid response.
      CommandCompleteView command_complete_view = CommandCompleteView::Create(
          EventView::Create(PacketView<kLittleEndian>(std::make_shared<std::vector<uint8_t>>(std::vector<uint8_t>()))));
      command_queue_.front().GetCallback<CommandCompleteView>()->Invoke(
          std::move(command_complete_view));

      auto payload = std::make_unique<packet::RawBuilder>();
      payload->AddOctets1(static_cast<uint8_t>(status_view.GetStatus()));
      auto complete_event_builder = CommandCompleteBuilder::Create(
          status_view.GetNumHciCommandPackets(),
          status_view.GetCommandOpCode(),
          std::move(payload));
      auto complete =
          std::make_shared<std::vector<std::uint8_t>>(complete_event_builder->SerializeToBytes());
      CommandCompleteView command_complete_view =
          CommandCompleteView::Create(EventView::Create(PacketView<kLittleEndian>(complete)));
      ASSERT(command_complete_view.IsValid());
      command_queue_.front().GetCallback<CommandCompleteView>()->Invoke(command_complete_view);
    } else {
      ASSERT_LOG(
          command_queue_.front().waiting_for_status_ == is_status,
+24 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@

#include <chrono>
#include <future>
#include <memory>

#include "common/bind.h"
#include "common/init_flags.h"
@@ -433,6 +434,29 @@ TEST_F(HciLayerTest, our_command_status_callback_is_invoked) {
  hal_->InjectEvent(ReadClockOffsetStatusBuilder::Create(ErrorCode::SUCCESS, 1));
}

TEST_F(HciLayerTest, vendor_specific_status_instead_of_complete) {
  std::promise<OpCode> callback_promise;
  auto callback_future = callback_promise.get_future();
  FailIfResetNotSent();
  hal_->InjectEvent(ResetCompleteBuilder::Create(1, ErrorCode::SUCCESS));
  hci_->EnqueueCommand(
      LeGetVendorCapabilitiesBuilder::Create(),
      hci_handler_->BindOnce(
          [](std::promise<OpCode> promise, CommandCompleteView view) {
            ASSERT_TRUE(view.IsValid());
            promise.set_value(view.GetCommandOpCode());
          },
          std::move(callback_promise)));
  hal_->InjectEvent(CommandStatusBuilder::Create(
      ErrorCode::UNKNOWN_HCI_COMMAND,
      1,
      OpCode::LE_GET_VENDOR_CAPABILITIES,
      std::make_unique<RawBuilder>()));

  ASSERT_EQ(std::future_status::ready, callback_future.wait_for(std::chrono::seconds(1)));
  ASSERT_EQ(OpCode::LE_GET_VENDOR_CAPABILITIES, callback_future.get());
}

TEST_F(
    HciLayerDeathTest,
    command_complete_callback_is_invoked_with_an_opcode_that_does_not_match_command_queue) {