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

Commit 6d6cb816 authored by Chienyuan's avatar Chienyuan Committed by android-build-merger
Browse files

GD: Implement internal HCI commands am: c6fda887

am: 6f172f85

Change-Id: Ia1b75da4e16a4e41c8b00d54e5955287b927d8b6
parents 5d2e168b 6f172f85
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -336,3 +336,9 @@ class SimpleHciTest(GdBaseTestClass):

        self.dut_command_complete_stream.unsubscribe()
        self._disconnect_from_dut()

    def test_interal_hci_command(self):
        self._connect_from_dut()
        self.device_under_test.hci.TestInternalHciCommands(empty_pb2.Empty())
        self.device_under_test.hci.TestInternalHciLeCommands(empty_pb2.Empty())
        self._disconnect_from_dut()
 No newline at end of file
+593 −1

File changed.

Preview size limit exceeded, changes collapsed.

+56 −0
Original line number Diff line number Diff line
@@ -34,6 +34,18 @@ class Controller : public Module {
  virtual void RegisterCompletedAclPacketsCallback(
      common::Callback<void(uint16_t /* handle */, uint16_t /* num_packets */)> cb, os::Handler* handler);

  virtual std::string GetControllerLocalName();

  virtual LocalVersionInformation GetControllerLocalVersionInformation();

  virtual std::array<uint8_t, 64> GetControllerLocalSupportedCommands();

  virtual uint64_t GetControllerLocalSupportedFeatures();

  virtual uint8_t GetControllerLocalExtendedFeaturesMaxPageNumber();

  virtual uint64_t GetControllerLocalExtendedFeatures(uint8_t page_number);

  virtual uint16_t GetControllerAclPacketLength();

  virtual uint16_t GetControllerNumAclPacketBuffers();
@@ -44,6 +56,50 @@ class Controller : public Module {

  virtual Address GetControllerMacAddress();

  virtual void SetEventMask(uint64_t event_mask);

  virtual void Reset();

  virtual void SetEventFilterClearAll();

  virtual void SetEventFilterInquiryResultAllDevices();

  virtual void SetEventFilterInquiryResultClassOfDevice(ClassOfDevice class_of_device,
                                                        ClassOfDevice class_of_device_mask);

  virtual void SetEventFilterInquiryResultAddress(Address address);

  virtual void SetEventFilterConnectionSetupAllDevices(AutoAcceptFlag auto_accept_flag);

  virtual void SetEventFilterConnectionSetupClassOfDevice(ClassOfDevice class_of_device,
                                                          ClassOfDevice class_of_device_mask,
                                                          AutoAcceptFlag auto_accept_flag);

  virtual void SetEventFilterConnectionSetupAddress(Address address, AutoAcceptFlag auto_accept_flag);

  virtual void WriteLocalName(std::string local_name);

  virtual void HostBufferSize(uint16_t host_acl_data_packet_length, uint8_t host_synchronous_data_packet_length,
                              uint16_t host_total_num_acl_data_packets,
                              uint16_t host_total_num_synchronous_data_packets);

  // LE controller commands
  virtual void LeSetEventMask(uint64_t le_event_mask);

  LeBufferSize GetControllerLeBufferSize();

  uint64_t GetControllerLeLocalSupportedFeatures();

  uint64_t GetControllerLeSupportedStates();

  LeMaximumDataLength GetControllerLeMaximumDataLength();

  uint16_t GetControllerLeMaximumAdvertisingDataLength();

  uint16_t GetControllerLeNumberOfSupportedAdverisingSets();

  bool IsSupport(OpCode op_code);

  static const ModuleFactory Factory;

 protected:
+203 −0
Original line number Diff line number Diff line
@@ -75,6 +75,45 @@ class TestHciLayer : public HciLayer {
    uint8_t num_packets = 1;
    std::unique_ptr<packet::BasePacketBuilder> event_builder;
    switch (command.GetOpCode()) {
      case (OpCode::READ_LOCAL_NAME): {
        std::array<uint8_t, 248> local_name = {'D', 'U', 'T', '\0'};
        event_builder = ReadLocalNameCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, local_name);
      } break;
      case (OpCode::READ_LOCAL_VERSION_INFORMATION): {
        LocalVersionInformation local_version_information;
        local_version_information.hci_version_ = HciVersion::V_5_0;
        local_version_information.hci_revision_ = 0x1234;
        local_version_information.lmp_version_ = LmpVersion::V_4_2;
        local_version_information.manufacturer_name_ = 0xBAD;
        local_version_information.lmp_subversion_ = 0x5678;
        event_builder = ReadLocalVersionInformationCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS,
                                                                           local_version_information);
      } break;
      case (OpCode::READ_LOCAL_SUPPORTED_COMMANDS): {
        std::array<uint8_t, 64> supported_commands;
        for (int i = 0; i < 37; i++) {
          supported_commands[i] = 0xff;
        }
        for (int i = 37; i < 64; i++) {
          supported_commands[i] = 0x00;
        }
        event_builder =
            ReadLocalSupportedCommandsCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, supported_commands);
      } break;
      case (OpCode::READ_LOCAL_SUPPORTED_FEATURES): {
        uint64_t lmp_features = 0x012345678abcdef;
        event_builder =
            ReadLocalSupportedFeaturesCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, lmp_features);
      } break;
      case (OpCode::READ_LOCAL_EXTENDED_FEATURES): {
        ReadLocalExtendedFeaturesView read_command = ReadLocalExtendedFeaturesView::Create(command);
        ASSERT(read_command.IsValid());
        uint8_t page_bumber = read_command.GetPageNumber();
        uint64_t lmp_features = 0x012345678abcdef;
        lmp_features += page_bumber;
        event_builder = ReadLocalExtendedFeaturesCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, page_bumber,
                                                                         0x02, lmp_features);
      } break;
      case (OpCode::READ_BUFFER_SIZE): {
        event_builder = ReadBufferSizeCompleteBuilder::Create(
            num_packets, ErrorCode::SUCCESS, acl_data_packet_length, synchronous_data_packet_length,
@@ -83,6 +122,45 @@ class TestHciLayer : public HciLayer {
      case (OpCode::READ_BD_ADDR): {
        event_builder = ReadBdAddrCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, Address::kAny);
      } break;
      case (OpCode::LE_READ_BUFFER_SIZE): {
        LeBufferSize le_buffer_size;
        le_buffer_size.le_data_packet_length_ = 0x16;
        le_buffer_size.total_num_le_packets_ = 0x08;
        event_builder = LeReadBufferSizeCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, le_buffer_size);
      } break;
      case (OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES): {
        event_builder =
            LeReadLocalSupportedFeaturesCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0x001f123456789abc);
      } break;
      case (OpCode::LE_READ_SUPPORTED_STATES): {
        event_builder =
            LeReadSupportedStatesCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0x001f123456789abe);
      } break;
      case (OpCode::LE_READ_MAXIMUM_DATA_LENGTH): {
        LeMaximumDataLength le_maximum_data_length;
        le_maximum_data_length.supported_max_tx_octets_ = 0x12;
        le_maximum_data_length.supported_max_tx_time_ = 0x34;
        le_maximum_data_length.supported_max_rx_octets_ = 0x56;
        le_maximum_data_length.supported_max_rx_time_ = 0x78;
        event_builder =
            LeReadMaximumDataLengthCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, le_maximum_data_length);
      } break;
      case (OpCode::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH): {
        event_builder =
            LeReadMaximumAdvertisingDataLengthCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0x0672);
      } break;
      case (OpCode::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS): {
        event_builder =
            LeReadNumberOfSupportedAdvertisingSetsCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0xF0);
      } break;
      case (OpCode::SET_EVENT_MASK):
      case (OpCode::RESET):
      case (OpCode::SET_EVENT_FILTER):
      case (OpCode::HOST_BUFFER_SIZE):
      case (OpCode::LE_SET_EVENT_MASK):
        command_queue_.push(command);
        not_empty_.notify_all();
        return;
      default:
        LOG_INFO("Dropping unhandled packet");
        return;
@@ -124,6 +202,23 @@ class TestHciLayer : public HciLayer {
    client_handler_->Post(common::BindOnce(number_of_completed_packets_callback_, event));
  }

  CommandPacketView GetCommand(OpCode op_code) {
    std::unique_lock<std::mutex> lock(mutex_);
    std::chrono::milliseconds time = std::chrono::milliseconds(3000);

    // wait for command
    while (command_queue_.size() == 0) {
      if (not_empty_.wait_for(lock, time) == std::cv_status::timeout) {
        break;
      }
    }
    ASSERT(command_queue_.size() > 0);
    CommandPacketView command = command_queue_.front();
    EXPECT_EQ(command.GetOpCode(), op_code);
    command_queue_.pop();
    return command;
  }

  void ListDependencies(ModuleList* list) override {}
  void Start() override {}
  void Stop() override {}
@@ -136,6 +231,9 @@ class TestHciLayer : public HciLayer {
 private:
  common::Callback<void(EventPacketView)> number_of_completed_packets_callback_;
  os::Handler* client_handler_;
  std::queue<CommandPacketView> command_queue_;
  mutable std::mutex mutex_;
  std::condition_variable not_empty_;
};

class ControllerTest : public ::testing::Test {
@@ -168,6 +266,111 @@ TEST_F(ControllerTest, read_controller_info) {
  ASSERT_EQ(controller_->GetControllerScoPacketLength(), test_hci_layer_->synchronous_data_packet_length);
  ASSERT_EQ(controller_->GetControllerNumScoPacketBuffers(), test_hci_layer_->total_num_synchronous_data_packets);
  ASSERT_EQ(controller_->GetControllerMacAddress(), Address::kAny);
  LocalVersionInformation local_version_information = controller_->GetControllerLocalVersionInformation();
  ASSERT_EQ(local_version_information.hci_version_, HciVersion::V_5_0);
  ASSERT_EQ(local_version_information.hci_revision_, 0x1234);
  ASSERT_EQ(local_version_information.lmp_version_, LmpVersion::V_4_2);
  ASSERT_EQ(local_version_information.manufacturer_name_, 0xBAD);
  ASSERT_EQ(local_version_information.lmp_subversion_, 0x5678);
  std::array<uint8_t, 64> supported_commands;
  for (int i = 0; i < 37; i++) {
    supported_commands[i] = 0xff;
  }
  for (int i = 37; i < 64; i++) {
    supported_commands[i] = 0x00;
  }
  ASSERT_EQ(controller_->GetControllerLocalSupportedCommands(), supported_commands);
  ASSERT_EQ(controller_->GetControllerLocalSupportedFeatures(), 0x012345678abcdef);
  ASSERT_EQ(controller_->GetControllerLocalExtendedFeaturesMaxPageNumber(), 0x02);
  ASSERT_EQ(controller_->GetControllerLocalExtendedFeatures(0), 0x012345678abcdef);
  ASSERT_EQ(controller_->GetControllerLocalExtendedFeatures(1), 0x012345678abcdf0);
  ASSERT_EQ(controller_->GetControllerLocalExtendedFeatures(2), 0x012345678abcdf1);
  ASSERT_EQ(controller_->GetControllerLocalExtendedFeatures(100), 0x00);
  ASSERT_EQ(controller_->GetControllerLeBufferSize().le_data_packet_length_, 0x16);
  ASSERT_EQ(controller_->GetControllerLeBufferSize().total_num_le_packets_, 0x08);
  ASSERT_EQ(controller_->GetControllerLeLocalSupportedFeatures(), 0x001f123456789abc);
  ASSERT_EQ(controller_->GetControllerLeSupportedStates(), 0x001f123456789abe);
  ASSERT_EQ(controller_->GetControllerLeMaximumDataLength().supported_max_tx_octets_, 0x12);
  ASSERT_EQ(controller_->GetControllerLeMaximumDataLength().supported_max_rx_octets_, 0x56);
  ASSERT_EQ(controller_->GetControllerLeMaximumAdvertisingDataLength(), 0x0672);
  ASSERT_EQ(controller_->GetControllerLeNumberOfSupportedAdverisingSets(), 0xF0);
}

TEST_F(ControllerTest, read_write_local_name) {
  ASSERT_EQ(controller_->GetControllerLocalName(), "DUT");
  controller_->WriteLocalName("New name");
  ASSERT_EQ(controller_->GetControllerLocalName(), "New name");
}

TEST_F(ControllerTest, send_set_event_mask_command) {
  controller_->SetEventMask(0x00001FFFFFFFFFFF);
  auto packet = test_hci_layer_->GetCommand(OpCode::SET_EVENT_MASK);
  auto command = SetEventMaskView::Create(packet);
  ASSERT(command.IsValid());
  ASSERT_EQ(command.GetEventMask(), 0x00001FFFFFFFFFFF);
}

TEST_F(ControllerTest, send_reset_command) {
  controller_->Reset();
  auto packet = test_hci_layer_->GetCommand(OpCode::RESET);
  auto command = ResetView::Create(packet);
  ASSERT(command.IsValid());
}

TEST_F(ControllerTest, send_set_event_filter_command) {
  controller_->SetEventFilterInquiryResultAllDevices();
  auto packet = test_hci_layer_->GetCommand(OpCode::SET_EVENT_FILTER);
  auto set_event_filter_view1 = SetEventFilterView::Create(packet);
  auto set_event_filter_inquiry_result_view1 = SetEventFilterInquiryResultView::Create(set_event_filter_view1);
  auto command1 = SetEventFilterInquiryResultAllDevicesView::Create(set_event_filter_inquiry_result_view1);
  ASSERT(command1.IsValid());

  ClassOfDevice class_of_device({0xab, 0xcd, 0xef});
  ClassOfDevice class_of_device_mask({0x12, 0x34, 0x56});
  controller_->SetEventFilterInquiryResultClassOfDevice(class_of_device, class_of_device_mask);
  packet = test_hci_layer_->GetCommand(OpCode::SET_EVENT_FILTER);
  auto set_event_filter_view2 = SetEventFilterView::Create(packet);
  auto set_event_filter_inquiry_result_view2 = SetEventFilterInquiryResultView::Create(set_event_filter_view2);
  auto command2 = SetEventFilterInquiryResultClassOfDeviceView::Create(set_event_filter_inquiry_result_view2);
  ASSERT(command2.IsValid());
  ASSERT_EQ(command2.GetClassOfDevice(), class_of_device);

  Address bdaddr({0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc});
  controller_->SetEventFilterConnectionSetupAddress(bdaddr, AutoAcceptFlag::AUTO_ACCEPT_ON_ROLE_SWITCH_ENABLED);
  packet = test_hci_layer_->GetCommand(OpCode::SET_EVENT_FILTER);
  auto set_event_filter_view3 = SetEventFilterView::Create(packet);
  auto set_event_filter_connection_setup_view = SetEventFilterConnectionSetupView::Create(set_event_filter_view3);
  auto command3 = SetEventFilterConnectionSetupAddressView::Create(set_event_filter_connection_setup_view);
  ASSERT(command3.IsValid());
  ASSERT_EQ(command3.GetAddress(), bdaddr);
}

TEST_F(ControllerTest, send_host_buffer_size_command) {
  controller_->HostBufferSize(0xFF00, 0xF1, 0xFF02, 0xFF03);
  auto packet = test_hci_layer_->GetCommand(OpCode::HOST_BUFFER_SIZE);
  auto command = HostBufferSizeView::Create(packet);
  ASSERT(command.IsValid());
  ASSERT_EQ(command.GetHostAclDataPacketLength(), 0xFF00);
  ASSERT_EQ(command.GetHostSynchronousDataPacketLength(), 0xF1);
  ASSERT_EQ(command.GetHostTotalNumAclDataPackets(), 0xFF02);
  ASSERT_EQ(command.GetHostTotalNumSynchronousDataPackets(), 0xFF03);
}

TEST_F(ControllerTest, send_le_set_event_mask_command) {
  controller_->LeSetEventMask(0x000000000000001F);
  auto packet = test_hci_layer_->GetCommand(OpCode::LE_SET_EVENT_MASK);
  auto command = LeSetEventMaskView::Create(packet);
  ASSERT(command.IsValid());
  ASSERT_EQ(command.GetLeEventMask(), 0x000000000000001F);
}

TEST_F(ControllerTest, is_supported_test) {
  ASSERT_TRUE(controller_->IsSupport(OpCode::INQUIRY));
  ASSERT_TRUE(controller_->IsSupport(OpCode::REJECT_CONNECTION_REQUEST));
  ASSERT_TRUE(controller_->IsSupport(OpCode::ACCEPT_CONNECTION_REQUEST));
  ASSERT_FALSE(controller_->IsSupport(OpCode::LE_REMOVE_ADVERTISING_SET));
  ASSERT_FALSE(controller_->IsSupport(OpCode::LE_CLEAR_ADVERTISING_SETS));
  ASSERT_FALSE(controller_->IsSupport(OpCode::LE_SET_PERIODIC_ADVERTISING_PARAM));
}

std::promise<void> credits1_set;
+52 −0
Original line number Diff line number Diff line
@@ -123,6 +123,58 @@ class AclManagerFacadeService : public AclManagerFacade::Service, public ::bluet
    return acl_stream_.HandleRequest(context, request, writer);
  }

  ::grpc::Status TestInternalHciCommands(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
                                         ::google::protobuf::Empty* response) {
    LocalVersionInformation local_version_information = controller_->GetControllerLocalVersionInformation();
    LOG_DEBUG("local name : %s", controller_->GetControllerLocalName().c_str());
    controller_->WriteLocalName("Device Under Test");
    LOG_DEBUG("new local name : %s", controller_->GetControllerLocalName().c_str());
    LOG_DEBUG("manufacturer name : %d", local_version_information.manufacturer_name_);
    LOG_DEBUG("hci version : %x", (uint16_t)local_version_information.hci_version_);
    LOG_DEBUG("lmp version : %x", (uint16_t)local_version_information.lmp_version_);
    LOG_DEBUG("supported commands : %x", controller_->GetControllerLocalSupportedCommands()[0]);
    LOG_DEBUG("supported features : %lx", controller_->GetControllerLocalSupportedFeatures());
    LOG_DEBUG("local extended features :");
    for (int i = 0; i <= controller_->GetControllerLocalExtendedFeaturesMaxPageNumber() + 1; i++) {
      LOG_DEBUG("page %d, %lx", i, controller_->GetControllerLocalExtendedFeatures(i));
    }

    controller_->SetEventMask(0x00001FFFFFFFFFFF);
    controller_->SetEventFilterInquiryResultAllDevices();
    ClassOfDevice class_of_device({0xab, 0xcd, 0xef});
    ClassOfDevice class_of_device_mask({0x12, 0x34, 0x56});
    controller_->SetEventFilterInquiryResultClassOfDevice(class_of_device, class_of_device_mask);
    Address bdaddr({0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc});
    controller_->SetEventFilterInquiryResultAddress(bdaddr);
    controller_->SetEventFilterConnectionSetupAllDevices(AutoAcceptFlag::AUTO_ACCEPT_OFF);
    controller_->SetEventFilterConnectionSetupClassOfDevice(class_of_device, class_of_device_mask,
                                                            AutoAcceptFlag::AUTO_ACCEPT_ON_ROLE_SWITCH_DISABLED);
    controller_->SetEventFilterConnectionSetupAddress(bdaddr, AutoAcceptFlag::AUTO_ACCEPT_ON_ROLE_SWITCH_ENABLED);
    controller_->SetEventFilterClearAll();
    controller_->HostBufferSize(0xFF00, 0xF1, 0xFF02, 0xFF03);
    return ::grpc::Status::OK;
  }

  ::grpc::Status TestInternalHciLeCommands(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
                                           ::google::protobuf::Empty* response) {
    LOG_DEBUG("le data packet length : %d", controller_->GetControllerLeBufferSize().le_data_packet_length_);
    LOG_DEBUG("total num le packets : %d", controller_->GetControllerLeBufferSize().total_num_le_packets_);
    LOG_DEBUG("le local supported features : %lx", controller_->GetControllerLeLocalSupportedFeatures());
    LOG_DEBUG("le supported states : %lx", controller_->GetControllerLeSupportedStates());
    LOG_DEBUG("le supported max tx octets : %d",
              controller_->GetControllerLeMaximumDataLength().supported_max_tx_octets_);
    LOG_DEBUG("le supported max tx times : %d", controller_->GetControllerLeMaximumDataLength().supported_max_tx_time_);
    LOG_DEBUG("le supported max rx octets : %d",
              controller_->GetControllerLeMaximumDataLength().supported_max_rx_octets_);
    LOG_DEBUG("le supported max rx times : %d", controller_->GetControllerLeMaximumDataLength().supported_max_rx_time_);
    LOG_DEBUG("le maximum advertising data length %d", controller_->GetControllerLeMaximumAdvertisingDataLength());
    LOG_DEBUG("le number of supported advertising sets %d",
              controller_->GetControllerLeNumberOfSupportedAdverisingSets());

    controller_->LeSetEventMask(0x000000000000001F);
    return ::grpc::Status::OK;
  }

  void on_incoming_acl(std::string address) {
    auto connection = acl_connections_.find(address);
    if (connection == acl_connections_.end()) {
Loading