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

Commit 6788e3ec authored by Henri Chataing's avatar Henri Chataing
Browse files

RootCanal: Refactor LE scanning commands

Implement HCI parameter validation as required by the specification.
Resolve or generate private addresses when required in
6.B.6.3 Privacy in scanning state.

Test: atest --host --no-bazel rootcanal_hci_test
Change-Id: Ice2e2e46b8ca157ca1b4131d0c7a642a2074ddc6
parent c411f010
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -135,6 +135,10 @@ cc_test_host {
        "test/controller/le/le_set_address_resolution_enable_test.cc",
        "test/controller/le/le_set_advertising_parameters_test.cc",
        "test/controller/le/le_set_advertising_enable_test.cc",
        "test/controller/le/le_set_scan_parameters_test.cc",
        "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",
    ],
    header_libs: [
        "libbluetooth_headers",
+29 −53
Original line number Diff line number Diff line
@@ -2129,9 +2129,10 @@ void DualModeController::LeSetAdvertisingData(CommandView command) {
  ASSERT_LOG(command_view.IsValid(), "%s command.size() = %zu",
             gd_hci::OpCodeText(command.GetOpCode()).c_str(), command.size());
  ASSERT(command_view.GetPayload().size() == 32);
  ErrorCode status =
      link_layer_controller_.LeSetAdvertisingData(advertising_data);
  send_event_(bluetooth::hci::LeSetAdvertisingDataCompleteBuilder::Create(
      kNumCommandPackets, ErrorCode::SUCCESS));
      kNumCommandPackets, status));
}

void DualModeController::LeSetScanResponseData(CommandView command) {
@@ -2139,10 +2140,11 @@ void DualModeController::LeSetScanResponseData(CommandView command) {
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  ASSERT(command_view.GetPayload().size() == 32);
  link_layer_controller_.LeSetScanResponseData(std::vector<uint8_t>(
      command_view.GetPayload().begin() + 1, command_view.GetPayload().end()));
  ErrorCode status = link_layer_controller_.LeSetScanResponseData(
      std::vector<uint8_t>(command_view.GetPayload().begin() + 1,
                           command_view.GetPayload().end()));
  send_event_(bluetooth::hci::LeSetScanResponseDataCompleteBuilder::Create(
      kNumCommandPackets, ErrorCode::SUCCESS));
      kNumCommandPackets, status));
}

void DualModeController::LeSetAdvertisingEnable(CommandView command) {
@@ -2163,15 +2165,13 @@ void DualModeController::LeSetScanParameters(CommandView command) {
  auto command_view = gd_hci::LeSetScanParametersView::Create(
      gd_hci::LeScanningCommandView::Create(command));
  ASSERT(command_view.IsValid());
  link_layer_controller_.SetLeScanType(
      static_cast<uint8_t>(command_view.GetLeScanType()));
  link_layer_controller_.SetLeScanInterval(command_view.GetLeScanInterval());
  link_layer_controller_.SetLeScanWindow(command_view.GetLeScanWindow());
  link_layer_controller_.SetLeAddressType(command_view.GetOwnAddressType());
  link_layer_controller_.SetLeScanFilterPolicy(

  ErrorCode status = link_layer_controller_.LeSetScanParameters(
      command_view.GetLeScanType(), command_view.GetLeScanInterval(),
      command_view.GetLeScanWindow(), command_view.GetOwnAddressType(),
      command_view.GetScanningFilterPolicy());
  send_event_(bluetooth::hci::LeSetScanParametersCompleteBuilder::Create(
      kNumCommandPackets, ErrorCode::SUCCESS));
      kNumCommandPackets, status));
}

void DualModeController::LeSetScanEnable(CommandView command) {
@@ -2182,15 +2182,11 @@ void DualModeController::LeSetScanEnable(CommandView command) {
  LOG_INFO("%s | LeSetScanEnable (%d)", GetAddress().ToString().c_str(),
           command_view.GetLeScanEnable() == gd_hci::Enable::ENABLED);

  if (command_view.GetLeScanEnable() == gd_hci::Enable::ENABLED) {
    link_layer_controller_.SetLeScanEnable(gd_hci::OpCode::LE_SET_SCAN_ENABLE);
  } else {
    link_layer_controller_.SetLeScanEnable(gd_hci::OpCode::NONE);
  }
  link_layer_controller_.SetLeFilterDuplicates(
  ErrorCode status = link_layer_controller_.LeSetScanEnable(
      command_view.GetLeScanEnable() == gd_hci::Enable::ENABLED,
      command_view.GetFilterDuplicates() == gd_hci::Enable::ENABLED);
  send_event_(bluetooth::hci::LeSetScanEnableCompleteBuilder::Create(
      kNumCommandPackets, ErrorCode::SUCCESS));
      kNumCommandPackets, status));
}

void DualModeController::LeCreateConnection(CommandView command) {
@@ -2207,11 +2203,8 @@ void DualModeController::LeCreateConnection(CommandView command) {
  if (initiator_filter_policy ==
      bluetooth::hci::InitiatorFilterPolicy::USE_PEER_ADDRESS) {
    // Connect list not used
    uint8_t peer_address_type =
        static_cast<uint8_t>(command_view.GetPeerAddressType());
    Address peer_address = command_view.GetPeerAddress();
    link_layer_controller_.SetLePeerAddressType(peer_address_type);
    link_layer_controller_.SetLePeerAddress(peer_address);
    link_layer_controller_.SetLePeerAddress(AddressWithType{
        command_view.GetPeerAddress(), command_view.GetPeerAddressType()});
  }
  link_layer_controller_.SetLeAddressType(command_view.GetOwnAddressType());
  link_layer_controller_.SetLeConnectionIntervalMin(
@@ -2454,23 +2447,9 @@ void DualModeController::LeSetExtendedScanParameters(CommandView command) {
  auto command_view = gd_hci::LeSetExtendedScanParametersView::Create(
      gd_hci::LeScanningCommandView::Create(command));
  ASSERT(command_view.IsValid());
  auto parameters = command_view.GetParameters();
  // Multiple phys are not supported.
  ASSERT(command_view.GetScanningPhys() == 1);
  ASSERT(parameters.size() == 1);

  auto status = ErrorCode::SUCCESS;
  if (link_layer_controller_.GetLeScanEnable() == OpCode::NONE) {
    link_layer_controller_.SetLeScanType(
        static_cast<uint8_t>(parameters[0].le_scan_type_));
    link_layer_controller_.SetLeScanInterval(parameters[0].le_scan_interval_);
    link_layer_controller_.SetLeScanWindow(parameters[0].le_scan_window_);
    link_layer_controller_.SetLeAddressType(command_view.GetOwnAddressType());
    link_layer_controller_.SetLeScanFilterPolicy(
        command_view.GetScanningFilterPolicy());
  } else {
    status = ErrorCode::COMMAND_DISALLOWED;
  }
  ErrorCode status = link_layer_controller_.LeSetExtendedScanParameters(
      command_view.GetOwnAddressType(), command_view.GetScanningFilterPolicy(),
      command_view.GetScanningPhys(), command_view.GetParameters());
  send_event_(
      bluetooth::hci::LeSetExtendedScanParametersCompleteBuilder::Create(
          kNumCommandPackets, status));
@@ -2480,16 +2459,12 @@ void DualModeController::LeSetExtendedScanEnable(CommandView command) {
  auto command_view = gd_hci::LeSetExtendedScanEnableView::Create(
      gd_hci::LeScanningCommandView::Create(command));
  ASSERT(command_view.IsValid());
  if (command_view.GetEnable() == gd_hci::Enable::ENABLED) {
    link_layer_controller_.SetLeScanEnable(
        gd_hci::OpCode::LE_SET_EXTENDED_SCAN_ENABLE);
  } else {
    link_layer_controller_.SetLeScanEnable(gd_hci::OpCode::NONE);
  }
  link_layer_controller_.SetLeFilterDuplicates(
      command_view.GetFilterDuplicates() == gd_hci::FilterDuplicates::ENABLED);
  ErrorCode status = link_layer_controller_.LeSetExtendedScanEnable(
      command_view.GetEnable() == gd_hci::Enable::ENABLED,
      command_view.GetFilterDuplicates(), command_view.GetDuration(),
      command_view.GetPeriod());
  send_event_(bluetooth::hci::LeSetExtendedScanEnableCompleteBuilder::Create(
      kNumCommandPackets, ErrorCode::SUCCESS));
      kNumCommandPackets, status));
}

void DualModeController::LeExtendedCreateConnection(CommandView command) {
@@ -2507,9 +2482,10 @@ void DualModeController::LeExtendedCreateConnection(CommandView command) {

  if (initiator_filter_policy ==
      gd_hci::InitiatorFilterPolicy::USE_PEER_ADDRESS) {
    link_layer_controller_.SetLePeerAddressType(
        static_cast<uint8_t>(command_view.GetPeerAddressType()));
    link_layer_controller_.SetLePeerAddress(command_view.GetPeerAddress());
    link_layer_controller_.SetLePeerAddress(AddressWithType{
        command_view.GetPeerAddress(),
        command_view.GetPeerAddressType(),
    });
  }
  link_layer_controller_.SetLeAddressType(command_view.GetOwnAddressType());
  link_layer_controller_.SetLeConnectionIntervalMin(
+42 −4
Original line number Diff line number Diff line
@@ -50,6 +50,15 @@ ErrorCode LinkLayerController::LeSetAdvertisingParameters(
    PeerAddressType peer_address_type, Address peer_address,
    uint8_t advertising_channel_map,
    AdvertisingFilterPolicy advertising_filter_policy) {
  // Legacy advertising commands are disallowed when extended advertising
  // commands were used since the last reset.
  if (!SelectLegacyAdvertising()) {
    LOG_INFO(
        "legacy advertising command rejected because extended advertising"
        " is being used");
    return ErrorCode::COMMAND_DISALLOWED;
  }

  // Clear reserved bits.
  advertising_channel_map &= 0x7;

@@ -118,21 +127,47 @@ ErrorCode LinkLayerController::LeSetAdvertisingParameters(
}

// HCI command LE_Set_Advertising_Data (Vol 4, Part E § 7.8.7).
void LinkLayerController::LeSetAdvertisingData(
ErrorCode LinkLayerController::LeSetAdvertisingData(
    const std::vector<uint8_t>& advertising_data) {
  // Legacy advertising commands are disallowed when extended advertising
  // commands were used since the last reset.
  if (!SelectLegacyAdvertising()) {
    LOG_INFO(
        "legacy advertising command rejected because extended advertising"
        " is being used");
    return ErrorCode::COMMAND_DISALLOWED;
  }

  legacy_advertiser_.advertising_data = advertising_data;
  return ErrorCode::SUCCESS;
}

// HCI command LE_Set_Scan_Response_Data (Vol 4, Part E § 7.8.8).
void LinkLayerController::LeSetScanResponseData(
ErrorCode LinkLayerController::LeSetScanResponseData(
    const std::vector<uint8_t>& scan_response_data) {
  // Legacy advertising commands are disallowed when extended advertising
  // commands were used since the last reset.
  if (!SelectLegacyAdvertising()) {
    LOG_INFO(
        "legacy advertising command rejected because extended advertising"
        " is being used");
    return ErrorCode::COMMAND_DISALLOWED;
  }

  legacy_advertiser_.scan_response_data = scan_response_data;
  return ErrorCode::SUCCESS;
}

// HCI command LE_Advertising_Enable (Vol 4, Part E § 7.8.9).
ErrorCode LinkLayerController::LeSetAdvertisingEnable(bool advertising_enable) {
  // Note: additional checks would apply in the case of a LE only Controller
  // with no configured public device address.
  // Legacy advertising commands are disallowed when extended advertising
  // commands were used since the last reset.
  if (!SelectLegacyAdvertising()) {
    LOG_INFO(
        "legacy advertising command rejected because extended advertising"
        " is being used");
    return ErrorCode::COMMAND_DISALLOWED;
  }

  if (!advertising_enable) {
    legacy_advertiser_.advertising_enable = false;
@@ -147,6 +182,9 @@ ErrorCode LinkLayerController::LeSetAdvertisingEnable(bool advertising_enable) {
  std::optional<AddressWithType> resolvable_address =
      GenerateResolvablePrivateAddress(peer_address, IrkSelection::Local);

  // TODO: additional checks would apply in the case of a LE only Controller
  // with no configured public device address.

  switch (legacy_advertiser_.own_address_type) {
    case OwnAddressType::PUBLIC_DEVICE_ADDRESS:
      legacy_advertiser_.advertising_address = public_address;
Loading