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

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

Merge "GD: implement GetVendorCapabilities command" am: 5e98e7ed am: 23d02987

am: a0f11da2

Change-Id: Ieb078eeeddf22fc45ca89fb9fc77d63cbf0c962a
parents b37c03fe a0f11da2
Loading
Loading
Loading
Loading
+126 −17
Original line number Diff line number Diff line
@@ -86,24 +86,28 @@ struct Controller::impl {
                         BindOnce(&Controller::impl::le_read_supported_states_handler, common::Unretained(this)),
                         module_.GetHandler());

    if (is_support(OpCode::LE_READ_MAXIMUM_DATA_LENGTH)) {
    if (is_supported(OpCode::LE_READ_MAXIMUM_DATA_LENGTH)) {
      hci_->EnqueueCommand(LeReadMaximumDataLengthBuilder::Create(),
                           BindOnce(&Controller::impl::le_read_maximum_data_length_handler, common::Unretained(this)),
                           module_.GetHandler());
    }
    if (is_support(OpCode::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH)) {
    if (is_supported(OpCode::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH)) {
      hci_->EnqueueCommand(
          LeReadMaximumAdvertisingDataLengthBuilder::Create(),
          BindOnce(&Controller::impl::le_read_maximum_advertising_data_length_handler, common::Unretained(this)),
          module_.GetHandler());
    }
    if (is_support(OpCode::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS)) {
    if (is_supported(OpCode::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS)) {
      hci_->EnqueueCommand(
          LeReadNumberOfSupportedAdvertisingSetsBuilder::Create(),
          BindOnce(&Controller::impl::le_read_number_of_supported_advertising_sets_handler, common::Unretained(this)),
          module_.GetHandler());
    }

    hci_->EnqueueCommand(LeGetVendorCapabilitiesBuilder::Create(),
                         BindOnce(&Controller::impl::le_get_vendor_capabilities_handler, common::Unretained(this)),
                         module_.GetHandler());

    // We only need to synchronize the last read. Make BD_ADDR to be the last one.
    std::promise<void> promise;
    auto future = promise.get_future();
@@ -264,20 +268,98 @@ struct Controller::impl {
    le_number_supported_advertising_sets_ = complete_view.GetNumberSupportedAdvertisingSets();
  }

  void le_get_vendor_capabilities_handler(CommandCompleteView view) {
    auto complete_view = LeGetVendorCapabilitiesCompleteView::Create(view);

    vendor_capabilities_.is_supported_ = 0x00;
    vendor_capabilities_.max_advt_instances_ = 0x00;
    vendor_capabilities_.offloaded_resolution_of_private_address_ = 0x00;
    vendor_capabilities_.total_scan_results_storage_ = 0x00;
    vendor_capabilities_.max_irk_list_sz_ = 0x00;
    vendor_capabilities_.filtering_support_ = 0x00;
    vendor_capabilities_.max_filter_ = 0x00;
    vendor_capabilities_.activity_energy_info_support_ = 0x00;
    vendor_capabilities_.version_supported_ = 0x00;
    vendor_capabilities_.version_supported_ = 0x00;
    vendor_capabilities_.total_num_of_advt_tracked_ = 0x00;
    vendor_capabilities_.extended_scan_support_ = 0x00;
    vendor_capabilities_.debug_logging_supported_ = 0x00;
    vendor_capabilities_.le_address_generation_offloading_support_ = 0x00;
    vendor_capabilities_.a2dp_source_offload_capability_mask_ = 0x00;
    vendor_capabilities_.bluetooth_quality_report_support_ = 0x00;

    if (complete_view.IsValid()) {
      vendor_capabilities_.is_supported_ = 0x01;

      // v0.55
      BaseVendorCapabilities base_vendor_capabilities = complete_view.GetBaseVendorCapabilities();
      vendor_capabilities_.max_advt_instances_ = base_vendor_capabilities.max_advt_instances_;
      vendor_capabilities_.offloaded_resolution_of_private_address_ =
          base_vendor_capabilities.offloaded_resolution_of_private_address_;
      vendor_capabilities_.total_scan_results_storage_ = base_vendor_capabilities.total_scan_results_storage_;
      vendor_capabilities_.max_irk_list_sz_ = base_vendor_capabilities.max_irk_list_sz_;
      vendor_capabilities_.filtering_support_ = base_vendor_capabilities.filtering_support_;
      vendor_capabilities_.max_filter_ = base_vendor_capabilities.max_filter_;
      vendor_capabilities_.activity_energy_info_support_ = base_vendor_capabilities.activity_energy_info_support_;
      if (complete_view.GetPayload().size() == 0) {
        vendor_capabilities_.version_supported_ = 55;
        return;
      }

      // v0.95
      auto v95 = LeGetVendorCapabilitiesComplete095View::Create(complete_view);
      if (!v95.IsValid()) {
        LOG_ERROR("invalid data for hci requirements v0.95");
        return;
      }
      vendor_capabilities_.version_supported_ = v95.GetVersionSupported();
      vendor_capabilities_.total_num_of_advt_tracked_ = v95.GetTotalNumOfAdvtTracked();
      vendor_capabilities_.extended_scan_support_ = v95.GetExtendedScanSupport();
      vendor_capabilities_.debug_logging_supported_ = v95.GetDebugLoggingSupported();
      if (vendor_capabilities_.version_supported_ <= 95 || complete_view.GetPayload().size() == 0) {
        return;
      }

      // v0.96
      auto v96 = LeGetVendorCapabilitiesComplete096View::Create(v95);
      if (!v96.IsValid()) {
        LOG_ERROR("invalid data for hci requirements v0.96");
        return;
      }
      vendor_capabilities_.le_address_generation_offloading_support_ = v96.GetLeAddressGenerationOffloadingSupport();
      if (vendor_capabilities_.version_supported_ <= 96 || complete_view.GetPayload().size() == 0) {
        return;
      }

      // v0.98
      auto v98 = LeGetVendorCapabilitiesComplete098View::Create(v96);
      if (!v98.IsValid()) {
        LOG_ERROR("invalid data for hci requirements v0.98");
        return;
      }
      vendor_capabilities_.a2dp_source_offload_capability_mask_ = v98.GetA2dpSourceOffloadCapabilityMask();
      vendor_capabilities_.bluetooth_quality_report_support_ = v98.GetBluetoothQualityReportSupport();
    }
  }

  void set_event_mask(uint64_t event_mask) {
    std::unique_ptr<SetEventMaskBuilder> packet = SetEventMaskBuilder::Create(event_mask);
    hci_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandCompleteView complete) { /* TODO */ }),
    hci_->EnqueueCommand(std::move(packet),
                         BindOnce(&Controller::impl::check_status<SetEventMaskCompleteView>, common::Unretained(this)),
                         module_.GetHandler());
  }

  void reset() {
    std::unique_ptr<ResetBuilder> packet = ResetBuilder::Create();
    hci_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandCompleteView complete) { /* TODO */ }),
    hci_->EnqueueCommand(std::move(packet),
                         BindOnce(&Controller::impl::check_status<ResetCompleteView>, common::Unretained(this)),
                         module_.GetHandler());
  }

  void set_event_filter(std::unique_ptr<SetEventFilterBuilder> packet) {
    hci_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandCompleteView complete) { /* TODO */ }),
    hci_->EnqueueCommand(
        std::move(packet),
        BindOnce(&Controller::impl::check_status<SetEventFilterCompleteView>, common::Unretained(this)),
        module_.GetHandler());
  }

@@ -289,7 +371,9 @@ struct Controller::impl {
    std::copy(std::begin(local_name), std::end(local_name), std::begin(local_name_array));

    std::unique_ptr<WriteLocalNameBuilder> packet = WriteLocalNameBuilder::Create(local_name_array);
    hci_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandCompleteView complete) { /* TODO */ }),
    hci_->EnqueueCommand(
        std::move(packet),
        BindOnce(&Controller::impl::check_status<WriteLocalNameCompleteView>, common::Unretained(this)),
        module_.GetHandler());
  }

@@ -298,16 +382,28 @@ struct Controller::impl {
    std::unique_ptr<HostBufferSizeBuilder> packet =
        HostBufferSizeBuilder::Create(host_acl_data_packet_length, host_synchronous_data_packet_length,
                                      host_total_num_acl_data_packets, host_total_num_synchronous_data_packets);
    hci_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandCompleteView complete) { /* TODO */ }),
    hci_->EnqueueCommand(
        std::move(packet),
        BindOnce(&Controller::impl::check_status<HostBufferSizeCompleteView>, common::Unretained(this)),
        module_.GetHandler());
  }

  void le_set_event_mask(uint64_t le_event_mask) {
    std::unique_ptr<LeSetEventMaskBuilder> packet = LeSetEventMaskBuilder::Create(le_event_mask);
    hci_->EnqueueCommand(std::move(packet), common::BindOnce([](CommandCompleteView complete) { /* TODO */ }),
    hci_->EnqueueCommand(
        std::move(packet),
        BindOnce(&Controller::impl::check_status<LeSetEventMaskCompleteView>, common::Unretained(this)),
        module_.GetHandler());
  }

  template <class T>
  void check_status(CommandCompleteView view) {
    ASSERT(view.IsValid());
    auto status_view = T::Create(view);
    ASSERT(status_view.IsValid());
    ASSERT(status_view.GetStatus() == ErrorCode::SUCCESS);
  }

#define OP_CODE_MAPPING(name)                                                  \
  case OpCode::name: {                                                         \
    uint16_t index = (uint16_t)OpCodeIndex::name;                              \
@@ -320,7 +416,7 @@ struct Controller::impl {
    return supported;                                                          \
  }

  bool is_support(OpCode op_code) {
  bool is_supported(OpCode op_code) {
    switch (op_code) {
      OP_CODE_MAPPING(INQUIRY)
      OP_CODE_MAPPING(INQUIRY_CANCEL)
@@ -537,15 +633,23 @@ struct Controller::impl {
      OP_CODE_MAPPING(LE_SET_PRIVACY_MODE)
      // vendor specific
      case OpCode::LE_GET_VENDOR_CAPABILITIES:
        return vendor_capabilities_.is_supported_ == 0x01;
      case OpCode::LE_MULTI_ADVT:
        return vendor_capabilities_.max_advt_instances_ != 0x00;
      case OpCode::LE_BATCH_SCAN:
        return vendor_capabilities_.total_scan_results_storage_ != 0x00;
      case OpCode::LE_ADV_FILTER:
        return vendor_capabilities_.filtering_support_ == 0x01;
      case OpCode::LE_TRACK_ADV:
        return vendor_capabilities_.total_num_of_advt_tracked_ > 0;
      case OpCode::LE_ENERGY_INFO:
        return vendor_capabilities_.activity_energy_info_support_ == 0x01;
      case OpCode::LE_EXTENDED_SCAN_PARAMS:
        return vendor_capabilities_.extended_scan_support_ == 0x01;
      case OpCode::CONTROLLER_DEBUG_INFO:
        return vendor_capabilities_.debug_logging_supported_ == 0x01;
      case OpCode::CONTROLLER_A2DP_OPCODE:
        return true;
        return vendor_capabilities_.a2dp_source_offload_capability_mask_ != 0x00;
      // undefined in local_supported_commands_
      case OpCode::CREATE_NEW_UNIT_KEY:
      case OpCode::READ_LOCAL_SUPPORTED_COMMANDS:
@@ -580,6 +684,7 @@ struct Controller::impl {
  LeMaximumDataLength le_maximum_data_length_;
  uint16_t le_maximum_advertising_data_length_;
  uint16_t le_number_supported_advertising_sets_;
  VendorCapabilities vendor_capabilities_;
};  // namespace hci

Controller::Controller() : impl_(std::make_unique<impl>(*this)) {}
@@ -732,8 +837,12 @@ uint16_t Controller::GetControllerLeNumberOfSupportedAdverisingSets() {
  return impl_->le_number_supported_advertising_sets_;
}

bool Controller::IsSupport(bluetooth::hci::OpCode op_code) {
  return impl_->is_support(op_code);
VendorCapabilities Controller::GetControllerVendorCapabilities() {
  return impl_->vendor_capabilities_;
}

bool Controller::IsSupported(bluetooth::hci::OpCode op_code) {
  return impl_->is_supported(op_code);
}

const ModuleFactory Controller::Factory = ModuleFactory([]() { return new Controller(); });
+3 −1
Original line number Diff line number Diff line
@@ -98,7 +98,9 @@ class Controller : public Module {

  uint16_t GetControllerLeNumberOfSupportedAdverisingSets();

  bool IsSupport(OpCode op_code);
  VendorCapabilities GetControllerVendorCapabilities();

  bool IsSupported(OpCode op_code);

  static const ModuleFactory Factory;

+61 −6
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ constexpr uint16_t kHandle1 = 0x123;
constexpr uint16_t kCredits1 = 0x78;
constexpr uint16_t kHandle2 = 0x456;
constexpr uint16_t kCredits2 = 0x9a;
uint16_t feature_spec_version = 55;

PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
  auto bytes = std::make_shared<std::vector<uint8_t>>();
@@ -153,6 +154,25 @@ class TestHciLayer : public HciLayer {
        event_builder =
            LeReadNumberOfSupportedAdvertisingSetsCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0xF0);
      } break;
      case (OpCode::LE_GET_VENDOR_CAPABILITIES): {
        BaseVendorCapabilities base_vendor_capabilities;
        base_vendor_capabilities.max_advt_instances_ = 0x10;
        base_vendor_capabilities.offloaded_resolution_of_private_address_ = 0x01;
        base_vendor_capabilities.total_scan_results_storage_ = 0x2800;
        base_vendor_capabilities.max_irk_list_sz_ = 0x20;
        base_vendor_capabilities.filtering_support_ = 0x01;
        base_vendor_capabilities.max_filter_ = 0x10;
        base_vendor_capabilities.activity_energy_info_support_ = 0x01;

        auto payload = std::make_unique<RawBuilder>();
        if (feature_spec_version > 55) {
          std::vector<uint8_t> payload_bytes = {0x20, 0x00, 0x01, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00};
          payload->AddOctets2(feature_spec_version);
          payload->AddOctets(payload_bytes);
        }
        event_builder = LeGetVendorCapabilitiesCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS,
                                                                       base_vendor_capabilities, std::move(payload));
      } break;
      case (OpCode::SET_EVENT_MASK):
      case (OpCode::RESET):
      case (OpCode::SET_EVENT_FILTER):
@@ -365,12 +385,47 @@ TEST_F(ControllerTest, send_le_set_event_mask_command) {
}

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));
  ASSERT_TRUE(controller_->IsSupported(OpCode::INQUIRY));
  ASSERT_TRUE(controller_->IsSupported(OpCode::REJECT_CONNECTION_REQUEST));
  ASSERT_TRUE(controller_->IsSupported(OpCode::ACCEPT_CONNECTION_REQUEST));
  ASSERT_FALSE(controller_->IsSupported(OpCode::LE_REMOVE_ADVERTISING_SET));
  ASSERT_FALSE(controller_->IsSupported(OpCode::LE_CLEAR_ADVERTISING_SETS));
  ASSERT_FALSE(controller_->IsSupported(OpCode::LE_SET_PERIODIC_ADVERTISING_PARAM));
}

TEST_F(ControllerTest, feature_spec_version_055_test) {
  EXPECT_EQ(controller_->GetControllerVendorCapabilities().version_supported_, 55);
  EXPECT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT));
  EXPECT_FALSE(controller_->IsSupported(OpCode::LE_TRACK_ADV));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE));
  feature_spec_version = 95;
}

TEST_F(ControllerTest, feature_spec_version_095_test) {
  EXPECT_EQ(controller_->GetControllerVendorCapabilities().version_supported_, 95);
  EXPECT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT));
  EXPECT_TRUE(controller_->IsSupported(OpCode::LE_TRACK_ADV));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE));
  feature_spec_version = 96;
}

TEST_F(ControllerTest, feature_spec_version_096_test) {
  EXPECT_EQ(controller_->GetControllerVendorCapabilities().version_supported_, 96);
  EXPECT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT));
  EXPECT_TRUE(controller_->IsSupported(OpCode::LE_TRACK_ADV));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE));
  feature_spec_version = 98;
}

TEST_F(ControllerTest, feature_spec_version_098_test) {
  EXPECT_EQ(controller_->GetControllerVendorCapabilities().version_supported_, 98);
  EXPECT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT));
  EXPECT_TRUE(controller_->IsSupported(OpCode::LE_TRACK_ADV));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO));
  EXPECT_TRUE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE));
}

std::promise<void> credits1_set;
+50 −1
Original line number Diff line number Diff line
@@ -2420,7 +2420,56 @@ packet LeSetPrivacyMode : LeSecurityCommand (op_code = LE_SET_PRIVACY_MODE) {

  // VENDOR_SPECIFIC
packet LeGetVendorCapabilities : VendorCommand (op_code = LE_GET_VENDOR_CAPABILITIES) {
  _payload_,  // placeholder (unimplemented)
}

struct VendorCapabilities {
  is_supported : 8,
  max_advt_instances: 8,
  offloaded_resolution_of_private_address : 8,
  total_scan_results_storage: 16,
  max_irk_list_sz: 8,
  filtering_support: 8,
  max_filter: 8,
  activity_energy_info_support: 8,
  version_supported: 16,
  total_num_of_advt_tracked: 16,
  extended_scan_support: 8,
  debug_logging_supported: 8,
  le_address_generation_offloading_support: 8,
  a2dp_source_offload_capability_mask: 32,
  bluetooth_quality_report_support: 8
}

struct BaseVendorCapabilities {
  max_advt_instances: 8,
  offloaded_resolution_of_private_address : 8,
  total_scan_results_storage: 16,
  max_irk_list_sz: 8,
  filtering_support: 8,
  max_filter: 8,
  activity_energy_info_support: 8,
}

packet LeGetVendorCapabilitiesComplete : CommandComplete (command_op_code = LE_GET_VENDOR_CAPABILITIES) {
  status : ErrorCode,
  base_vendor_capabilities : BaseVendorCapabilities,
  _payload_,
}
packet LeGetVendorCapabilitiesComplete095 : LeGetVendorCapabilitiesComplete {
  version_supported: 16,
  total_num_of_advt_tracked: 16,
  extended_scan_support: 8,
  debug_logging_supported: 8,
  _payload_,
}
packet LeGetVendorCapabilitiesComplete096 : LeGetVendorCapabilitiesComplete095 {
  le_address_generation_offloading_support: 8,
  _payload_,
}

packet LeGetVendorCapabilitiesComplete098 : LeGetVendorCapabilitiesComplete096 {
  a2dp_source_offload_capability_mask: 32,
  bluetooth_quality_report_support: 8
}

packet LeMultiAdvt : VendorCommand (op_code = LE_MULTI_ADVT) {