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

Commit 55c60321 authored by Henri Chataing's avatar Henri Chataing
Browse files

RootCanal: Implement extended advertising PDUs

Refactor LE extended advertising to implement HCI parameter
validation as required by the specification.

Add a new link layer packet type LE_EXTENDED_ADVERTISING_PDU
corresponding to ADV_EXT_IND, AUX_ADV_IND, AUX_CHAIN_IND PDUs,
and implement proper handling for extended scanning and legacy
initiator states

Test: atest --host rootcanal_hci_test
Test: gd/cert
Test: pts-bot
Change-Id: I6696ccc47de7b72715e6f6eeda3ab4c5511e11af
parent f850ed63
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -137,6 +137,10 @@ cc_test_host {
        "test/controller/le/le_set_scan_enable_test.cc",
        "test/controller/le/le_set_extended_scan_parameters_test.cc",
        "test/controller/le/le_set_extended_scan_enable_test.cc",
        "test/controller/le/le_set_extended_advertising_parameters_test.cc",
        "test/controller/le/le_set_extended_advertising_data_test.cc",
        "test/controller/le/le_set_extended_scan_response_data_test.cc",
        "test/controller/le/le_set_extended_advertising_enable_test.cc",
    ],
    header_libs: [
        "libbluetooth_headers",
+5 −0
Original line number Diff line number Diff line
@@ -320,6 +320,11 @@ ControllerProperties::ControllerProperties(const std::string& file_name)
  ParseUint(root, "le_resolving_list_size", le_resolving_list_size);
  ParseUint(root, "le_supported_states", le_supported_states);

  ParseUint(root, "le_max_advertising_data_length",
            le_max_advertising_data_length);
  ParseUint(root, "le_num_supported_advertising_sets",
            le_num_supported_advertising_sets);

  ParseUintVector(root, "le_vendor_capabilities", le_vendor_capabilities);

  this->hci_version = static_cast<HciVersion>(hci_version);
+9 −0
Original line number Diff line number Diff line
@@ -96,6 +96,15 @@ struct ControllerProperties {
  // LE Supported States (Vol 4, Part E § 7.8.27).
  uint64_t le_supported_states{0x3ffffffffff};

  // LE Maximum Advertising Data Length (Vol 4, Part E § 7.8.57).
  // Note: valid range 0x001F to 0x0672.
  uint16_t le_max_advertising_data_length{512};

  // LE Number of Supported Advertising Sets (Vol 4, Part E § 7.8.58)
  // Note: the controller can change the number of advertising sets
  // at any time. This behaviour is not emulated here.
  uint8_t le_num_supported_advertising_sets{8};

  // Vendor Information.
  // Provide parameters returned by vendor specific commands.
  std::vector<uint8_t> le_vendor_capabilities{};
+35 −31
Original line number Diff line number Diff line
@@ -1992,7 +1992,8 @@ void DualModeController::RemoteNameRequest(CommandView command) {
  Address remote_addr = command_view.GetBdAddr();

  auto status = link_layer_controller_.SendCommandToRemoteByAddress(
      OpCode::REMOTE_NAME_REQUEST, command_view.GetPayload(), remote_addr);
      OpCode::REMOTE_NAME_REQUEST, command_view.GetPayload(), GetAddress(),
      remote_addr);

  send_event_(bluetooth::hci::RemoteNameRequestStatusBuilder::Create(
      status, kNumCommandPackets));
@@ -2206,7 +2207,8 @@ void DualModeController::LeCreateConnection(CommandView command) {
    link_layer_controller_.SetLePeerAddress(AddressWithType{
        command_view.GetPeerAddress(), command_view.GetPeerAddressType()});
  }
  link_layer_controller_.SetLeAddressType(command_view.GetOwnAddressType());
  link_layer_controller_.SetLeConnectionOwnAddressType(
      command_view.GetOwnAddressType());
  link_layer_controller_.SetLeConnectionIntervalMin(
      command_view.GetConnIntervalMin());
  link_layer_controller_.SetLeConnectionIntervalMax(
@@ -2487,7 +2489,8 @@ void DualModeController::LeExtendedCreateConnection(CommandView command) {
        command_view.GetPeerAddressType(),
    });
  }
  link_layer_controller_.SetLeAddressType(command_view.GetOwnAddressType());
  link_layer_controller_.SetLeConnectionOwnAddressType(
      command_view.GetOwnAddressType());
  link_layer_controller_.SetLeConnectionIntervalMin(
      params[0].conn_interval_min_);
  link_layer_controller_.SetLeConnectionIntervalMax(
@@ -2799,32 +2802,37 @@ void DualModeController::LeSetAdvertisingSetRandomAddress(CommandView command) {
  auto command_view = gd_hci::LeSetAdvertisingSetRandomAddressView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  link_layer_controller_.SetLeExtendedAddress(
  ErrorCode status = link_layer_controller_.LeSetAdvertisingSetRandomAddress(
      command_view.GetAdvertisingHandle(), command_view.GetRandomAddress());
  send_event_(
      bluetooth::hci::LeSetAdvertisingSetRandomAddressCompleteBuilder::Create(
          kNumCommandPackets, ErrorCode::SUCCESS));
          kNumCommandPackets, status));
}

void DualModeController::LeSetExtendedAdvertisingParameters(
    CommandView command) {
  auto command_view =
      gd_hci::LeSetExtendedAdvertisingParametersLegacyView::Create(
  auto command_view = gd_hci::LeSetExtendedAdvertisingParametersView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  // TODO: Support non-legacy parameters
  ASSERT(command_view.IsValid());
  link_layer_controller_.SetLeExtendedAdvertisingParameters(
  ErrorCode status = link_layer_controller_.LeSetExtendedAdvertisingParameters(
      command_view.GetAdvertisingHandle(),
      command_view.GetAdvertisingEventProperties(),
      command_view.GetPrimaryAdvertisingIntervalMin(),
      command_view.GetPrimaryAdvertisingIntervalMax(),
      command_view.GetLegacyAdvertisingEventProperties(),
      command_view.GetPrimaryAdvertisingChannelMap(),
      command_view.GetOwnAddressType(), command_view.GetPeerAddressType(),
      command_view.GetPeerAddress(), command_view.GetAdvertisingFilterPolicy(),
      command_view.GetAdvertisingTxPower());

      command_view.GetAdvertisingTxPower(),
      command_view.GetPrimaryAdvertisingPhy(),
      command_view.GetSecondaryAdvertisingMaxSkip(),
      command_view.GetSecondaryAdvertisingPhy(),
      command_view.GetAdvertisingSid(),
      command_view.GetScanRequestNotificationEnable() == Enable::ENABLED);
  // The selected TX power is always the requested TX power
  // at the moment.
  send_event_(
      bluetooth::hci::LeSetExtendedAdvertisingParametersCompleteBuilder::Create(
          kNumCommandPackets, ErrorCode::SUCCESS, 0xa5));
          kNumCommandPackets, status, command_view.GetAdvertisingTxPower()));
}

void DualModeController::LeSetExtendedAdvertisingData(CommandView command) {
@@ -2834,12 +2842,13 @@ void DualModeController::LeSetExtendedAdvertisingData(CommandView command) {
  auto raw_command_view = gd_hci::LeSetExtendedAdvertisingDataRawView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(raw_command_view.IsValid());
  link_layer_controller_.SetLeExtendedAdvertisingData(
      command_view.GetAdvertisingHandle(),
  ErrorCode status = link_layer_controller_.LeSetExtendedAdvertisingData(
      command_view.GetAdvertisingHandle(), command_view.GetOperation(),
      command_view.GetFragmentPreference(),
      raw_command_view.GetAdvertisingData());
  send_event_(
      bluetooth::hci::LeSetExtendedAdvertisingDataCompleteBuilder::Create(
          kNumCommandPackets, ErrorCode::SUCCESS));
          kNumCommandPackets, status));
}

void DualModeController::LeSetExtendedScanResponseData(CommandView command) {
@@ -2849,26 +2858,22 @@ void DualModeController::LeSetExtendedScanResponseData(CommandView command) {
  auto raw_command_view = gd_hci::LeSetExtendedScanResponseDataRawView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(raw_command_view.IsValid());
  link_layer_controller_.SetLeExtendedScanResponseData(
      command_view.GetAdvertisingHandle(),
  ErrorCode status = link_layer_controller_.LeSetExtendedScanResponseData(
      command_view.GetAdvertisingHandle(), command_view.GetOperation(),
      command_view.GetFragmentPreference(),
      raw_command_view.GetScanResponseData());
  send_event_(
      bluetooth::hci::LeSetExtendedScanResponseDataCompleteBuilder::Create(
          kNumCommandPackets, ErrorCode::SUCCESS));
          kNumCommandPackets, status));
}

void DualModeController::LeSetExtendedAdvertisingEnable(CommandView command) {
  auto command_view = gd_hci::LeSetExtendedAdvertisingEnableView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  auto enabled_sets = command_view.GetEnabledSets();
  ErrorCode status = ErrorCode::SUCCESS;
  if (enabled_sets.size() == 0) {
    link_layer_controller_.LeDisableAdvertisingSets();
  } else {
    status = link_layer_controller_.SetLeExtendedAdvertisingEnable(
        command_view.GetEnable(), command_view.GetEnabledSets());
  }
  ErrorCode status = link_layer_controller_.LeSetExtendedAdvertisingEnable(
      command_view.GetEnable() == bluetooth::hci::Enable::ENABLED,
      command_view.GetEnabledSets());
  send_event_(
      bluetooth::hci::LeSetExtendedAdvertisingEnableCompleteBuilder::Create(
          kNumCommandPackets, status));
@@ -2893,9 +2898,8 @@ void DualModeController::LeReadNumberOfSupportedAdvertisingSets(
  ASSERT(command_view.IsValid());
  send_event_(
      bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsCompleteBuilder::
          Create(
              kNumCommandPackets, ErrorCode::SUCCESS,
              link_layer_controller_.LeReadNumberOfSupportedAdvertisingSets()));
          Create(kNumCommandPackets, ErrorCode::SUCCESS,
                 properties_.le_num_supported_advertising_sets));
}

void DualModeController::LeRemoveAdvertisingSet(CommandView command) {
+1085 −200

File changed.

Preview size limit exceeded, changes collapsed.

Loading