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

Commit 38537eb7 authored by Henri Chataing's avatar Henri Chataing
Browse files

RootCanal: Provide skeleton implementation for the LE APCF vendor command

- add the android vendor setting to the proto configuration to
  enable android vendor commands
- add the flag supports_le_apcf_vendor_command to controller properties
- match the APCF Opcode and dispatch to subcommand handlers in
  link layer controller

Bug: 296143555
Test: m root-canal
Change-Id: I09206ffd3295f778e433e9678adde5d0ec30a50f
parent 1368c5a5
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ cc_library_static {
        "model/controller/le_advertiser.cc",
        "model/controller/link_layer_controller.cc",
        "model/controller/sco_connection.cc",
        "model/controller/vendor_commands/le_apcf.cc",
        "model/devices/baseband_sniffer.cc",
        "model/devices/beacon.cc",
        "model/devices/beacon_swarm.cc",
@@ -157,6 +158,7 @@ cc_library_host_shared {
        "model/controller/le_advertiser.cc",
        "model/controller/link_layer_controller.cc",
        "model/controller/sco_connection.cc",
        "model/controller/vendor_commands/le_apcf.cc",
        "model/devices/device.cc",
        "model/setup/async_manager.cc",
    ],
+5 −2
Original line number Diff line number Diff line
@@ -1876,7 +1876,7 @@ ControllerProperties::ControllerProperties(

      case ControllerPreset::CSR_RCK_PTS_DONGLE:
        // Configuration extracted with the helper script controller_info.py
        vendor_csr = true;
        supports_csr_vendor_command = true;
        br_supported = true;
        le_supported = true;
        hci_version = bluetooth::hci::HciVersion::V_4_2;
@@ -1970,7 +1970,10 @@ ControllerProperties::ControllerProperties(
  // Apply selected vendor features.
  if (config.has_vendor()) {
    if (config.vendor().has_csr()) {
      vendor_csr = config.vendor().csr();
      supports_csr_vendor_command = config.vendor().csr();
    }
    if (config.vendor().has_android()) {
      supports_le_apcf_vendor_command = config.vendor().android();
    }
  }

+2 −3
Original line number Diff line number Diff line
@@ -101,6 +101,8 @@ struct ControllerProperties {

  // Vendor Supported Commands.
  bool supports_le_get_vendor_capabilities_command{true};
  bool supports_csr_vendor_command{true};
  bool supports_le_apcf_vendor_command{false};

  // Local Supported Features (Vol 4, Part E § 7.4.3) and
  // Local Extended Features (Vol 4, Part E § 7.4.3).
@@ -157,9 +159,6 @@ struct ControllerProperties {
  // Provide parameters returned by vendor specific commands.
  std::vector<uint8_t> le_vendor_capabilities{};

  // Enable the support for the CSR vendor command.
  bool vendor_csr{true};

  bool SupportsLMPFeature(bluetooth::hci::LMPFeaturesPage0Bits bit) const {
    return (lmp_features[0] & static_cast<uint64_t>(bit)) != 0;
  }
+195 −2
Original line number Diff line number Diff line
@@ -49,6 +49,9 @@ constexpr uint16_t kLeMaximumDataLength = 64;
constexpr uint16_t kLeMaximumDataTime = 0x148;
constexpr uint8_t kTransmitPowerLevel = -20;

constexpr bool kLeApcfTransportDiscoveryDataFilterSupported = true;
constexpr bool kLeApcfAdTypeFilterSupported = true;

void DualModeController::SetProperties(ControllerProperties properties) {
  WARNING(id_, "updating the device properties!");
  properties_ = std::move(properties);
@@ -2826,7 +2829,197 @@ void DualModeController::LeBatchScan(CommandView command) {
void DualModeController::LeApcf(CommandView command) {
  auto command_view = bluetooth::hci::LeApcfView::Create(command);
  ASSERT(command_view.IsValid());

  if (!properties_.supports_le_apcf_vendor_command) {
    SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_APCF);
    return;
  }

  switch (command_view.GetApcfOpcode()) {
    case bluetooth::hci::ApcfOpcode::ENABLE: {
      auto subcommand_view =
          bluetooth::hci::LeApcfEnableView::Create(command_view);
      ASSERT(subcommand_view.IsValid());

      DEBUG(id_, "<< LE APCF Enable");
      DEBUG(id_, "   enable={}", subcommand_view.GetApcfEnable());

      ErrorCode status = link_layer_controller_.LeApcfEnable(
          subcommand_view.GetApcfEnable() == bluetooth::hci::Enable::ENABLED);
      send_event_(bluetooth::hci::LeApcfEnableCompleteBuilder::Create(
          kNumCommandPackets, status, subcommand_view.GetApcfEnable()));
      break;
    }
    case bluetooth::hci::ApcfOpcode::SET_FILTERING_PARAMETERS: {
      auto subcommand_view =
          bluetooth::hci::LeApcfSetFilteringParametersView::Create(
              command_view);
      ASSERT(subcommand_view.IsValid());

      DEBUG(id_, "<< LE APCF Set Filtering Parameters");
      DEBUG(id_, "   action={}", subcommand_view.GetApcfAction());

      uint8_t apcf_available_spaces = 0;
      ErrorCode status = link_layer_controller_.LeApcfSetFilteringParameters(
          subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
          subcommand_view.GetApcfFeatureSelection(),
          subcommand_view.GetApcfListLogicType(),
          subcommand_view.GetApcfFilterLogicType(),
          subcommand_view.GetRssiHighThresh(),
          subcommand_view.GetDeliveryMode(),
          subcommand_view.GetOnfoundTimeout(),
          subcommand_view.GetOnfoundTimeoutCnt(),
          subcommand_view.GetRssiLowThresh(),
          subcommand_view.GetOnlostTimeout(),
          subcommand_view.GetNumOfTrackingEntries(), &apcf_available_spaces);
      send_event_(
          bluetooth::hci::LeApcfSetFilteringParametersCompleteBuilder::Create(
              kNumCommandPackets, status, subcommand_view.GetApcfAction(),
              apcf_available_spaces));
      break;
    }
    case bluetooth::hci::ApcfOpcode::BROADCASTER_ADDRESS: {
      auto subcommand_view =
          bluetooth::hci::LeApcfBroadcasterAddressView::Create(command_view);
      ASSERT(subcommand_view.IsValid());

      DEBUG(id_, "<< LE APCF Broadcaster Address");
      DEBUG(id_, "   action={}", subcommand_view.GetApcfAction());

      uint8_t apcf_available_spaces = 0;
      ErrorCode status = link_layer_controller_.LeApcfBroadcasterAddress(
          subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
          subcommand_view.GetApcfBroadcasterAddress(),
          subcommand_view.GetApcfApplicationAddressType(),
          &apcf_available_spaces);
      send_event_(
          bluetooth::hci::LeApcfBroadcasterAddressCompleteBuilder::Create(
              kNumCommandPackets, status, subcommand_view.GetApcfAction(),
              apcf_available_spaces));
      break;
    }
    case bluetooth::hci::ApcfOpcode::SERVICE_UUID: {
      auto subcommand_view =
          bluetooth::hci::LeApcfServiceUuidView::Create(command_view);
      ASSERT(subcommand_view.IsValid());

      DEBUG(id_, "<< LE APCF Service UUID");
      DEBUG(id_, "   action={}", subcommand_view.GetApcfAction());

      uint8_t apcf_available_spaces = 0;
      ErrorCode status = link_layer_controller_.LeApcfServiceUuid(
          subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
          subcommand_view.GetAcpfUuidData(), &apcf_available_spaces);
      send_event_(bluetooth::hci::LeApcfServiceUuidCompleteBuilder::Create(
          kNumCommandPackets, status, subcommand_view.GetApcfAction(),
          apcf_available_spaces));
      break;
    }
    case bluetooth::hci::ApcfOpcode::SERVICE_SOLICITATION_UUID: {
      auto subcommand_view =
          bluetooth::hci::LeApcfServiceSolicitationUuidView::Create(
              command_view);
      ASSERT(subcommand_view.IsValid());

      DEBUG(id_, "<< LE APCF Service Solicitation UUID");
      DEBUG(id_, "   action={}", subcommand_view.GetApcfAction());

      uint8_t apcf_available_spaces = 0;
      ErrorCode status = link_layer_controller_.LeApcfServiceSolicitationUuid(
          subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
          subcommand_view.GetAcpfUuidData(), &apcf_available_spaces);
      send_event_(
          bluetooth::hci::LeApcfServiceSolicitationUuidCompleteBuilder::Create(
              kNumCommandPackets, status, subcommand_view.GetApcfAction(),
              apcf_available_spaces));
      break;
    }
    case bluetooth::hci::ApcfOpcode::LOCAL_NAME: {
      auto subcommand_view =
          bluetooth::hci::LeApcfLocalNameView::Create(command_view);
      ASSERT(subcommand_view.IsValid());

      DEBUG(id_, "<< LE APCF Local Name");
      DEBUG(id_, "   action={}", subcommand_view.GetApcfAction());

      uint8_t apcf_available_spaces = 0;
      ErrorCode status = link_layer_controller_.LeApcfLocalName(
          subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
          subcommand_view.GetApcfLocalName(), &apcf_available_spaces);
      send_event_(bluetooth::hci::LeApcfLocalNameCompleteBuilder::Create(
          kNumCommandPackets, status, subcommand_view.GetApcfAction(),
          apcf_available_spaces));
      break;
    }
    case bluetooth::hci::ApcfOpcode::MANUFACTURER_DATA: {
      auto subcommand_view =
          bluetooth::hci::LeApcfManufacturerDataView::Create(command_view);
      ASSERT(subcommand_view.IsValid());

      DEBUG(id_, "<< LE APCF Manufacturer Data");
      DEBUG(id_, "   action={}", subcommand_view.GetApcfAction());

      uint8_t apcf_available_spaces = 0;
      ErrorCode status = link_layer_controller_.LeApcfManufacturerData(
          subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
          subcommand_view.GetApcfManufacturerData(), &apcf_available_spaces);
      send_event_(bluetooth::hci::LeApcfManufacturerDataCompleteBuilder::Create(
          kNumCommandPackets, status, subcommand_view.GetApcfAction(),
          apcf_available_spaces));
      break;
    }
    case bluetooth::hci::ApcfOpcode::SERVICE_DATA: {
      auto subcommand_view =
          bluetooth::hci::LeApcfServiceDataView::Create(command_view);
      ASSERT(subcommand_view.IsValid());

      DEBUG(id_, "<< LE APCF Service Data");
      DEBUG(id_, "   action={}", subcommand_view.GetApcfAction());

      uint8_t apcf_available_spaces = 0;
      ErrorCode status = link_layer_controller_.LeApcfServiceData(
          subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
          subcommand_view.GetApcfServiceData(), &apcf_available_spaces);
      send_event_(bluetooth::hci::LeApcfServiceDataCompleteBuilder::Create(
          kNumCommandPackets, status, subcommand_view.GetApcfAction(),
          apcf_available_spaces));
      break;
    }
    case bluetooth::hci::ApcfOpcode::AD_TYPE_FILTER: {
      auto subcommand_view =
          bluetooth::hci::LeApcfAdTypeFilterView::Create(command_view);
      ASSERT(subcommand_view.IsValid());

      DEBUG(id_, "<< LE APCF AD Type Filter");
      DEBUG(id_, "   action={}", subcommand_view.GetApcfAction());

      uint8_t apcf_available_spaces = 0;
      ErrorCode status = link_layer_controller_.LeApcfAdTypeFilter(
          subcommand_view.GetApcfAction(), subcommand_view.GetApcfFilterIndex(),
          subcommand_view.GetApcfAdType(), subcommand_view.GetApcfAdData(),
          subcommand_view.GetApcfAdDataMask(), &apcf_available_spaces);
      send_event_(bluetooth::hci::LeApcfAdTypeFilterCompleteBuilder::Create(
          kNumCommandPackets, status, subcommand_view.GetApcfAction(),
          apcf_available_spaces));
      break;
    }
    case bluetooth::hci::ApcfOpcode::READ_EXTENDED_FEATURES: {
      auto subcommand_view =
          bluetooth::hci::LeApcfReadExtendedFeaturesView::Create(command_view);
      ASSERT(subcommand_view.IsValid());

      DEBUG(id_, "<< LE APCF Read Extended Features");

      send_event_(
          bluetooth::hci::LeApcfReadExtendedFeaturesCompleteBuilder::Create(
              kNumCommandPackets, ErrorCode::SUCCESS,
              kLeApcfTransportDiscoveryDataFilterSupported,
              kLeApcfAdTypeFilterSupported));
      break;
    }
    default:
      FATAL(id_, "unknown APCF opcode {}", command_view.GetApcfOpcode());
  }
}

void DualModeController::LeGetControllerActivityEnergyInfo(
@@ -2860,7 +3053,7 @@ void DualModeController::GetControllerDebugInfo(CommandView command) {
// Implement the command specific to the CSR controller
// used specifically by the PTS tool to pass certification tests.
void DualModeController::CsrVendorCommand(CommandView command) {
  if (!properties_.vendor_csr) {
  if (!properties_.supports_csr_vendor_command) {
    SendCommandCompleteUnknownOpCodeEvent(OpCode(CSR_VENDOR));
    return;
  }
+49 −0
Original line number Diff line number Diff line
@@ -579,6 +579,55 @@ class LinkLayerController {
  // HCI LE Clear Periodic Advertiser List command (Vol 4, Part E § 7.8.72).
  ErrorCode LeClearPeriodicAdvertiserList();

  // LE APCF

  ErrorCode LeApcfEnable(bool apcf_enable);

  ErrorCode LeApcfSetFilteringParameters(
      bluetooth::hci::ApcfAction apcf_action, uint8_t apcf_filter_index,
      uint16_t apcf_feature_selection, uint16_t apcf_list_logic_type,
      uint8_t apcf_filter_logic_type, uint8_t rssi_high_thresh,
      bluetooth::hci::DeliveryMode delivery_mode, uint16_t onfound_timeout,
      uint8_t onfound_timeout_cnt, uint8_t rssi_low_thresh,
      uint16_t onlost_timeout, uint16_t num_of_tracking_entries,
      uint8_t* apcf_available_spaces);

  ErrorCode LeApcfBroadcasterAddress(
      bluetooth::hci::ApcfAction apcf_action, uint8_t apcf_filter_index,
      bluetooth::hci::Address apcf_broadcaster_address,
      bluetooth::hci::ApcfApplicationAddressType apcf_application_address_type,
      uint8_t* apcf_available_spaces);

  ErrorCode LeApcfServiceUuid(bluetooth::hci::ApcfAction apcf_action,
                              uint8_t apcf_filter_index,
                              std::vector<uint8_t> acpf_uuid_data,
                              uint8_t* apcf_available_spaces);

  ErrorCode LeApcfServiceSolicitationUuid(
      bluetooth::hci::ApcfAction apcf_action, uint8_t apcf_filter_index,
      std::vector<uint8_t> acpf_uuid_data, uint8_t* apcf_available_spaces);

  ErrorCode LeApcfLocalName(bluetooth::hci::ApcfAction apcf_action,
                            uint8_t apcf_filter_index,
                            std::vector<uint8_t> apcf_local_name,
                            uint8_t* apcf_available_spaces);

  ErrorCode LeApcfManufacturerData(bluetooth::hci::ApcfAction apcf_action,
                                   uint8_t apcf_filter_index,
                                   std::vector<uint8_t> apcf_manufacturer_data,
                                   uint8_t* apcf_available_spaces);

  ErrorCode LeApcfServiceData(bluetooth::hci::ApcfAction apcf_action,
                              uint8_t apcf_filter_index,
                              std::vector<uint8_t> apcf_service_data,
                              uint8_t* apcf_available_spaces);

  ErrorCode LeApcfAdTypeFilter(bluetooth::hci::ApcfAction apcf_action,
                               uint8_t apcf_filter_index, uint8_t ad_type,
                               std::vector<uint8_t> apcf_ad_data,
                               std::vector<uint8_t> apcf_ad_data_mask,
                               uint8_t* apcf_available_spaces);

 protected:
  void SendLinkLayerPacket(
      std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet,
Loading