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

Commit 98ab2bf0 authored by Henri Chataing's avatar Henri Chataing
Browse files

Revert "RootCanal: Refactor legacy LE advertising commands"

Revert submission 2234606

Reason for revert: Breaks pts-bot presubmit, resolution takes longer than expected
Reverted Changes:
I83d2bbad3:RootCanal: Refactor legacy LE advertising commands...
Ice2e2e46b:RootCanal: Refactor LE scanning commands

Test: pts-bot presubmits
Change-Id: I3cdee05ee868d38bae411767d898f3f213cf93e0
parent 47229aab
Loading
Loading
Loading
Loading
+0 −3
Original line number Original line Diff line number Diff line
@@ -123,7 +123,6 @@ cc_test_host {
        "rootcanal_defaults",
        "rootcanal_defaults",
    ],
    ],
    srcs: [
    srcs: [
        "test/controller/le/le_set_random_address_test.cc",
        "test/controller/le/le_clear_filter_accept_list_test.cc",
        "test/controller/le/le_clear_filter_accept_list_test.cc",
        "test/controller/le/le_add_device_to_filter_accept_list_test.cc",
        "test/controller/le/le_add_device_to_filter_accept_list_test.cc",
        "test/controller/le/le_remove_device_from_filter_accept_list_test.cc",
        "test/controller/le/le_remove_device_from_filter_accept_list_test.cc",
@@ -131,8 +130,6 @@ cc_test_host {
        "test/controller/le/le_clear_resolving_list_test.cc",
        "test/controller/le/le_clear_resolving_list_test.cc",
        "test/controller/le/le_remove_device_from_resolving_list_test.cc",
        "test/controller/le/le_remove_device_from_resolving_list_test.cc",
        "test/controller/le/le_set_address_resolution_enable_test.cc",
        "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",
    ],
    ],
    header_libs: [
    header_libs: [
        "libbluetooth_headers",
        "libbluetooth_headers",
+0 −2
Original line number Original line Diff line number Diff line
@@ -308,8 +308,6 @@ ControllerProperties::ControllerProperties(const std::string& file_name)
            total_num_le_acl_data_packets);
            total_num_le_acl_data_packets);
  ParseUint(root, "total_num_iso_data_packets ", total_num_iso_data_packets);
  ParseUint(root, "total_num_iso_data_packets ", total_num_iso_data_packets);
  ParseUint(root, "num_supported_iac", num_supported_iac);
  ParseUint(root, "num_supported_iac", num_supported_iac);
  ParseUint(root, "le_advertising_physical_channel_tx_power",
            le_advertising_physical_channel_tx_power);


  ParseUintArray(root, "lmp_features", lmp_features);
  ParseUintArray(root, "lmp_features", lmp_features);
  ParseUintVector(root, "supported_standard_codecs", supported_standard_codecs);
  ParseUintVector(root, "supported_standard_codecs", supported_standard_codecs);
+0 −3
Original line number Original line Diff line number Diff line
@@ -79,9 +79,6 @@ struct ControllerProperties {
  // Number of Supported IAC (Vol 4, Part E § 7.3.43).
  // Number of Supported IAC (Vol 4, Part E § 7.3.43).
  uint8_t num_supported_iac{4};
  uint8_t num_supported_iac{4};


  // LE Advertising Physical Channel TX Power (Vol 4, Part E § 7.8.6).
  uint8_t le_advertising_physical_channel_tx_power{static_cast<uint8_t>(-10)};

  // Supported Codecs (Vol 4, Part E § 7.4.8).
  // Supported Codecs (Vol 4, Part E § 7.4.8).
  // Implements the [v1] version only.
  // Implements the [v1] version only.
  std::vector<uint8_t> supported_standard_codecs{0};
  std::vector<uint8_t> supported_standard_codecs{0};
+61 −19
Original line number Original line Diff line number Diff line
@@ -2096,15 +2096,22 @@ void DualModeController::LeSetAdvertisingParameters(CommandView command) {
  auto command_view = gd_hci::LeSetAdvertisingParametersView::Create(
  auto command_view = gd_hci::LeSetAdvertisingParametersView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  ASSERT(command_view.IsValid());
  ErrorCode status = link_layer_controller_.LeSetAdvertisingParameters(
  auto peer_address = command_view.GetPeerAddress();
  auto type = command_view.GetAdvertisingType();
  if (type != bluetooth::hci::AdvertisingType::ADV_DIRECT_IND_HIGH &&
      type != bluetooth::hci::AdvertisingType::ADV_DIRECT_IND_LOW) {
    peer_address = Address::kEmpty;
  }
  link_layer_controller_.SetLeAdvertisingParameters(
      command_view.GetAdvertisingIntervalMin(),
      command_view.GetAdvertisingIntervalMin(),
      command_view.GetAdvertisingIntervalMax(),
      command_view.GetAdvertisingIntervalMax(), type,
      command_view.GetAdvertisingType(), command_view.GetOwnAddressType(),
      static_cast<uint8_t>(command_view.GetOwnAddressType()),
      command_view.GetPeerAddressType(), command_view.GetPeerAddress(),
      static_cast<uint8_t>(command_view.GetPeerAddressType()), peer_address,
      command_view.GetAdvertisingChannelMap(),
      command_view.GetAdvertisingChannelMap(),
      command_view.GetAdvertisingFilterPolicy());
      command_view.GetAdvertisingFilterPolicy());

  send_event_(bluetooth::hci::LeSetAdvertisingParametersCompleteBuilder::Create(
  send_event_(bluetooth::hci::LeSetAdvertisingParametersCompleteBuilder::Create(
      kNumCommandPackets, status));
      kNumCommandPackets, ErrorCode::SUCCESS));
}
}


void DualModeController::LeReadAdvertisingPhysicalChannelTxPower(
void DualModeController::LeReadAdvertisingPhysicalChannelTxPower(
@@ -2116,7 +2123,7 @@ void DualModeController::LeReadAdvertisingPhysicalChannelTxPower(
  send_event_(
  send_event_(
      bluetooth::hci::LeReadAdvertisingPhysicalChannelTxPowerCompleteBuilder::
      bluetooth::hci::LeReadAdvertisingPhysicalChannelTxPowerCompleteBuilder::
          Create(kNumCommandPackets, ErrorCode::SUCCESS,
          Create(kNumCommandPackets, ErrorCode::SUCCESS,
                 properties_.le_advertising_physical_channel_tx_power));
                 link_layer_controller_.GetLeAdvertisingTxPower()));
}
}


void DualModeController::LeSetAdvertisingData(CommandView command) {
void DualModeController::LeSetAdvertisingData(CommandView command) {
@@ -2125,11 +2132,11 @@ void DualModeController::LeSetAdvertisingData(CommandView command) {
  auto payload = command.GetPayload();
  auto payload = command.GetPayload();
  auto data_size = *payload.begin();
  auto data_size = *payload.begin();
  auto first_data = payload.begin() + 1;
  auto first_data = payload.begin() + 1;
  std::vector<uint8_t> advertising_data{first_data, first_data + data_size};
  std::vector<uint8_t> payload_bytes{first_data, first_data + data_size};
  ASSERT_LOG(command_view.IsValid(), "%s command.size() = %zu",
  ASSERT_LOG(command_view.IsValid(), "%s command.size() = %zu",
             gd_hci::OpCodeText(command.GetOpCode()).c_str(), command.size());
             gd_hci::OpCodeText(command.GetOpCode()).c_str(), command.size());
  ASSERT(command_view.GetPayload().size() == 32);
  ASSERT(command_view.GetPayload().size() == 32);
  link_layer_controller_.LeSetAdvertisingData(advertising_data);
  link_layer_controller_.SetLeAdvertisingData(payload_bytes);
  send_event_(bluetooth::hci::LeSetAdvertisingDataCompleteBuilder::Create(
  send_event_(bluetooth::hci::LeSetAdvertisingDataCompleteBuilder::Create(
      kNumCommandPackets, ErrorCode::SUCCESS));
      kNumCommandPackets, ErrorCode::SUCCESS));
}
}
@@ -2139,7 +2146,7 @@ void DualModeController::LeSetScanResponseData(CommandView command) {
      gd_hci::LeAdvertisingCommandView::Create(command));
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  ASSERT(command_view.IsValid());
  ASSERT(command_view.GetPayload().size() == 32);
  ASSERT(command_view.GetPayload().size() == 32);
  link_layer_controller_.LeSetScanResponseData(std::vector<uint8_t>(
  link_layer_controller_.SetLeScanResponseData(std::vector<uint8_t>(
      command_view.GetPayload().begin() + 1, command_view.GetPayload().end()));
      command_view.GetPayload().begin() + 1, command_view.GetPayload().end()));
  send_event_(bluetooth::hci::LeSetScanResponseDataCompleteBuilder::Create(
  send_event_(bluetooth::hci::LeSetScanResponseDataCompleteBuilder::Create(
      kNumCommandPackets, ErrorCode::SUCCESS));
      kNumCommandPackets, ErrorCode::SUCCESS));
@@ -2153,7 +2160,7 @@ void DualModeController::LeSetAdvertisingEnable(CommandView command) {
  LOG_INFO("%s | LeSetAdvertisingEnable (%d)", GetAddress().ToString().c_str(),
  LOG_INFO("%s | LeSetAdvertisingEnable (%d)", GetAddress().ToString().c_str(),
           command_view.GetAdvertisingEnable() == gd_hci::Enable::ENABLED);
           command_view.GetAdvertisingEnable() == gd_hci::Enable::ENABLED);


  ErrorCode status = link_layer_controller_.LeSetAdvertisingEnable(
  auto status = link_layer_controller_.SetLeAdvertisingEnable(
      command_view.GetAdvertisingEnable() == gd_hci::Enable::ENABLED);
      command_view.GetAdvertisingEnable() == gd_hci::Enable::ENABLED);
  send_event_(bluetooth::hci::LeSetAdvertisingEnableCompleteBuilder::Create(
  send_event_(bluetooth::hci::LeSetAdvertisingEnableCompleteBuilder::Create(
      kNumCommandPackets, status));
      kNumCommandPackets, status));
@@ -2430,10 +2437,18 @@ void DualModeController::LeAddDeviceToResolvingList(CommandView command) {
  auto command_view = gd_hci::LeAddDeviceToResolvingListView::Create(
  auto command_view = gd_hci::LeAddDeviceToResolvingListView::Create(
      gd_hci::LeSecurityCommandView::Create(command));
      gd_hci::LeSecurityCommandView::Create(command));
  ASSERT(command_view.IsValid());
  ASSERT(command_view.IsValid());
  AddressType peer_identity_address_type;
  switch (command_view.GetPeerIdentityAddressType()) {
    case bluetooth::hci::PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS:
      peer_identity_address_type = AddressType::PUBLIC_DEVICE_ADDRESS;
      break;
    case bluetooth::hci::PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS:
      peer_identity_address_type = AddressType::RANDOM_DEVICE_ADDRESS;
      break;
  }
  ErrorCode status = link_layer_controller_.LeAddDeviceToResolvingList(
  ErrorCode status = link_layer_controller_.LeAddDeviceToResolvingList(
      command_view.GetPeerIdentityAddressType(),
      peer_identity_address_type, command_view.GetPeerIdentityAddress(),
      command_view.GetPeerIdentityAddress(), command_view.GetPeerIrk(),
      command_view.GetPeerIrk(), command_view.GetLocalIrk());
      command_view.GetLocalIrk());
  send_event_(bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
  send_event_(bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
      kNumCommandPackets, status));
      kNumCommandPackets, status));
}
}
@@ -2442,9 +2457,18 @@ void DualModeController::LeRemoveDeviceFromResolvingList(CommandView command) {
  auto command_view = gd_hci::LeRemoveDeviceFromResolvingListView::Create(
  auto command_view = gd_hci::LeRemoveDeviceFromResolvingListView::Create(
      gd_hci::LeSecurityCommandView::Create(command));
      gd_hci::LeSecurityCommandView::Create(command));
  ASSERT(command_view.IsValid());
  ASSERT(command_view.IsValid());

  AddressType peer_identity_address_type;
  switch (command_view.GetPeerIdentityAddressType()) {
    case bluetooth::hci::PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS:
      peer_identity_address_type = AddressType::PUBLIC_DEVICE_ADDRESS;
      break;
    case bluetooth::hci::PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS:
      peer_identity_address_type = AddressType::RANDOM_DEVICE_ADDRESS;
      break;
  }
  ErrorCode status = link_layer_controller_.LeRemoveDeviceFromResolvingList(
  ErrorCode status = link_layer_controller_.LeRemoveDeviceFromResolvingList(
      command_view.GetPeerIdentityAddressType(),
      peer_identity_address_type, command_view.GetPeerIdentityAddress());
      command_view.GetPeerIdentityAddress());
  send_event_(
  send_event_(
      bluetooth::hci::LeRemoveDeviceFromResolvingListCompleteBuilder::Create(
      bluetooth::hci::LeRemoveDeviceFromResolvingListCompleteBuilder::Create(
          kNumCommandPackets, status));
          kNumCommandPackets, status));
@@ -2532,11 +2556,27 @@ void DualModeController::LeSetPrivacyMode(CommandView command) {
  auto command_view = gd_hci::LeSetPrivacyModeView::Create(
  auto command_view = gd_hci::LeSetPrivacyModeView::Create(
      gd_hci::LeSecurityCommandView::Create(command));
      gd_hci::LeSecurityCommandView::Create(command));
  ASSERT(command_view.IsValid());
  ASSERT(command_view.IsValid());
  ErrorCode status = link_layer_controller_.LeSetPrivacyMode(

      command_view.GetPeerIdentityAddressType(),
  Address peer_identity_address = command_view.GetPeerIdentityAddress();
      command_view.GetPeerIdentityAddress(), command_view.GetPrivacyMode());
  uint8_t privacy_mode = static_cast<uint8_t>(command_view.GetPrivacyMode());

  AddressType peer_identity_address_type;
  switch (command_view.GetPeerIdentityAddressType()) {
    case bluetooth::hci::PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS:
      peer_identity_address_type = AddressType::PUBLIC_DEVICE_ADDRESS;
      break;
    case bluetooth::hci::PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS:
      peer_identity_address_type = AddressType::RANDOM_DEVICE_ADDRESS;
      break;
  }
  if (link_layer_controller_.LeResolvingListContainsDevice(
          peer_identity_address_type, peer_identity_address)) {
    link_layer_controller_.LeSetPrivacyMode(
        peer_identity_address_type, peer_identity_address, privacy_mode);
  }

  send_event_(bluetooth::hci::LeSetPrivacyModeCompleteBuilder::Create(
  send_event_(bluetooth::hci::LeSetPrivacyModeCompleteBuilder::Create(
      kNumCommandPackets, status));
      kNumCommandPackets, ErrorCode::SUCCESS));
}
}


void DualModeController::LeReadIsoTxSync(CommandView command) {
void DualModeController::LeReadIsoTxSync(CommandView command) {
@@ -2870,6 +2910,8 @@ void DualModeController::LeSetExtendedScanResponseData(CommandView command) {
  auto command_view = gd_hci::LeSetExtendedScanResponseDataView::Create(
  auto command_view = gd_hci::LeSetExtendedScanResponseDataView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  ASSERT(command_view.IsValid());
  link_layer_controller_.SetLeScanResponseData(std::vector<uint8_t>(
      command_view.GetPayload().begin() + 1, command_view.GetPayload().end()));
  auto raw_command_view = gd_hci::LeSetExtendedScanResponseDataRawView::Create(
  auto raw_command_view = gd_hci::LeSetExtendedScanResponseDataRawView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(raw_command_view.IsValid());
  ASSERT(raw_command_view.IsValid());
+36 −308
Original line number Original line Diff line number Diff line
@@ -16,225 +16,31 @@


#include "le_advertiser.h"
#include "le_advertiser.h"


#include "link_layer_controller.h"
#include "os/log.h"

using namespace bluetooth::hci;
using namespace bluetooth::hci;
using namespace std::literals;
using namespace std::literals;


namespace rootcanal {
namespace rootcanal {

void LeAdvertiser::Initialize(OwnAddressType address_type,
namespace chrono {
                              AddressWithType public_address,
using duration = std::chrono::steady_clock::duration;
                              AddressWithType peer_address,
using time_point = std::chrono::steady_clock::time_point;
                              AdvertisingFilterPolicy filter_policy,
};  // namespace chrono
                              AdvertisingType type,

                              const std::vector<uint8_t>& advertisement,
slots operator"" _slots(unsigned long long count) { return slots(count); }
                              const std::vector<uint8_t>& scan_response,

                              std::chrono::steady_clock::duration interval) {
// =============================================================================
  own_address_type_ = address_type;
//  Constants
  public_address_ = public_address;
// =============================================================================
  peer_address_ = peer_address;

  filter_policy_ = filter_policy;
// Vol 6, Part B § 4.4.2.4.3 High duty cycle connectable directed advertising.
  type_ = type;
const chrono::duration adv_direct_ind_high_timeout = 1280ms;
  advertisement_ = advertisement;
const chrono::duration adv_direct_ind_high_interval = 3750us;
  scan_response_ = scan_response;

  interval_ = interval;
// =============================================================================
  tx_power_ = kTxPowerUnavailable;
//  Legacy Advertising Commands
  LOG_INFO("%s -> %s", public_address_.ToString().c_str(),
// =============================================================================
           peer_address.ToString().c_str());

// HCI command LE_Set_Advertising_Parameters (Vol 4, Part E § 7.8.5).
ErrorCode LinkLayerController::LeSetAdvertisingParameters(
    uint16_t advertising_interval_min, uint16_t advertising_interval_max,
    AdvertisingType advertising_type, OwnAddressType own_address_type,
    PeerAddressType peer_address_type, Address peer_address,
    uint8_t advertising_channel_map,
    AdvertisingFilterPolicy advertising_filter_policy) {
  // Clear reserved bits.
  advertising_channel_map &= 0x7;

  // For high duty cycle directed advertising, i.e. when
  // Advertising_Type is 0x01 (ADV_DIRECT_IND, high duty cycle),
  // the Advertising_Interval_Min and Advertising_Interval_Max parameters
  // are not used and shall be ignored.
  if (advertising_type == AdvertisingType::ADV_DIRECT_IND_HIGH) {
    advertising_interval_min = 0x800;  // Default interval value
    advertising_interval_max = 0x800;
  }

  // The Host shall not issue this command when advertising is enabled in the
  // Controller; if it is the Command Disallowed error code shall be used.
  if (legacy_advertiser_.advertising_enable) {
    LOG_INFO("legacy advertising is enabled");
    return ErrorCode::COMMAND_DISALLOWED;
  }

  // At least one channel bit shall be set in the
  // Advertising_Channel_Map parameter.
  if (advertising_channel_map == 0) {
    LOG_INFO(
        "advertising_channel_map (0x%04x) does not enable any"
        " advertising channel",
        advertising_channel_map);
    return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
  }

  // If the advertising interval range provided by the Host
  // (Advertising_Interval_Min, Advertising_Interval_Max) is outside the
  // advertising interval range supported by the Controller, then the
  // Controller shall return the Unsupported Feature or Parameter Value (0x11)
  // error code.
  if (advertising_interval_min < 0x0020 || advertising_interval_min > 0x4000 ||
      advertising_interval_max < 0x0020 || advertising_interval_max > 0x4000) {
    LOG_INFO(
        "advertising_interval_min (0x%04x) and/or"
        " advertising_interval_max (0x%04x) are outside the range"
        " of supported values (0x0020 - 0x4000)",
        advertising_interval_min, advertising_interval_max);
    return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
  }

  // The Advertising_Interval_Min shall be less than or equal to the
  // Advertising_Interval_Max.
  if (advertising_interval_min > advertising_interval_max) {
    LOG_INFO(
        "advertising_interval_min (0x%04x) is larger than"
        " advertising_interval_max (0x%04x)",
        advertising_interval_min, advertising_interval_max);
    return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
  }

  legacy_advertiser_.advertising_interval =
      advertising_type == AdvertisingType::ADV_DIRECT_IND_HIGH
          ? std::chrono::duration_cast<slots>(adv_direct_ind_high_interval)
          : slots(advertising_interval_min);
  legacy_advertiser_.advertising_type = advertising_type;
  legacy_advertiser_.own_address_type = own_address_type;
  legacy_advertiser_.peer_address_type = peer_address_type;
  legacy_advertiser_.peer_address = peer_address;
  legacy_advertiser_.advertising_channel_map = advertising_channel_map;
  legacy_advertiser_.advertising_filter_policy = advertising_filter_policy;
  return ErrorCode::SUCCESS;
}

// HCI command LE_Set_Advertising_Data (Vol 4, Part E § 7.8.7).
void LinkLayerController::LeSetAdvertisingData(
    const std::vector<uint8_t>& advertising_data) {
  legacy_advertiser_.advertising_data = advertising_data;
}

// HCI command LE_Set_Scan_Response_Data (Vol 4, Part E § 7.8.8).
void LinkLayerController::LeSetScanResponseData(
    const std::vector<uint8_t>& scan_response_data) {
  legacy_advertiser_.scan_response_data = scan_response_data;
}

// 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.

  if (!advertising_enable) {
    legacy_advertiser_.advertising_enable = false;
    return ErrorCode::SUCCESS;
  }

  AddressWithType peer_address = PeerDeviceAddress(
      legacy_advertiser_.peer_address, legacy_advertiser_.peer_address_type);
  AddressWithType public_address{address_, AddressType::PUBLIC_DEVICE_ADDRESS};
  AddressWithType random_address{random_address_,
                                 AddressType::RANDOM_DEVICE_ADDRESS};
  std::optional<AddressWithType> resolvable_address =
      GenerateResolvablePrivateAddress(peer_address, IrkSelection::Local);

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

    case OwnAddressType::RANDOM_DEVICE_ADDRESS:
      // If Advertising_Enable is set to 0x01, the advertising parameters'
      // Own_Address_Type parameter is set to 0x01, and the random address for
      // the device has not been initialized using the HCI_LE_Set_Random_Address
      // command, the Controller shall return the error code
      // Invalid HCI Command Parameters (0x12).
      if (random_address.GetAddress() == Address::kEmpty) {
        LOG_INFO(
            "own_address_type is Random_Device_Address but the Random_Address"
            " has not been initialized");
        return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
      }
      legacy_advertiser_.advertising_address = random_address;
      break;

    case OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS:
      legacy_advertiser_.advertising_address =
          resolvable_address.value_or(public_address);
      break;

    case OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS:
      // If Advertising_Enable is set to 0x01, the advertising parameters'
      // Own_Address_Type parameter is set to 0x03, the controller's resolving
      // list did not contain a matching entry, and the random address for the
      // device has not been initialized using the HCI_LE_Set_Random_Address
      // command, the Controller shall return the error code Invalid HCI Command
      // Parameters (0x12).
      if (resolvable_address) {
        legacy_advertiser_.advertising_address = resolvable_address.value();
      } else if (random_address.GetAddress() == Address::kEmpty) {
        LOG_INFO(
            "own_address_type is Resolvable_Or_Random_Address but the"
            " Resolving_List does not contain a matching entry and the"
            " Random_Address is not initialized");
        return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
      } else {
        legacy_advertiser_.advertising_address = random_address;
      }
      break;
  }

  legacy_advertiser_.timeout = {};
  legacy_advertiser_.target_address =
      AddressWithType{Address::kEmpty, AddressType::PUBLIC_DEVICE_ADDRESS};

  switch (legacy_advertiser_.advertising_type) {
    case AdvertisingType::ADV_DIRECT_IND_HIGH:
      // The Link Layer shall exit the Advertising state no later than 1.28 s
      // after the Advertising state was entered.
      legacy_advertiser_.timeout =
          std::chrono::steady_clock::now() + adv_direct_ind_high_timeout;
      [[fallthrough]];

    case AdvertisingType::ADV_DIRECT_IND_LOW: {
      // Note: Vol 6, Part B § 6.2.2 Connectable directed event type
      //
      // If an IRK is available in the Link Layer Resolving
      // List for the peer device, then the target’s device address
      // (TargetA field) shall use a resolvable private address. If an IRK is
      // not available in the Link Layer Resolving List or the IRK is set to
      // zero for the peer device, then the target’s device address
      // (TargetA field) shall use the Identity Address when entering the
      // Advertising State and using connectable directed events.
      std::optional<AddressWithType> peer_resolvable_address =
          GenerateResolvablePrivateAddress(peer_address, IrkSelection::Peer);
      legacy_advertiser_.target_address =
          peer_resolvable_address.value_or(peer_address);
      break;
    }
    default:
      break;
  }

  legacy_advertiser_.advertising_enable = true;
  legacy_advertiser_.next_event = std::chrono::steady_clock::now() +
                                  legacy_advertiser_.advertising_interval;
  return ErrorCode::SUCCESS;
}
}


// =============================================================================
//  Extended Advertising Commands
// =============================================================================

void LeAdvertiser::InitializeExtended(
void LeAdvertiser::InitializeExtended(
    unsigned advertising_handle, OwnAddressType address_type,
    unsigned advertising_handle, OwnAddressType address_type,
    AddressWithType public_address, AddressWithType peer_address,
    AddressWithType public_address, AddressWithType peer_address,
@@ -281,16 +87,24 @@ void LeAdvertiser::SetScanResponse(const std::vector<uint8_t>& data) {
  scan_response_ = data;
  scan_response_ = data;
}
}


void LeAdvertiser::Enable() {
  EnableExtended(0ms);
  extended_ = false;
}

void LeAdvertiser::EnableExtended(std::chrono::milliseconds duration_ms) {
void LeAdvertiser::EnableExtended(std::chrono::milliseconds duration_ms) {
  enabled_ = true;
  enabled_ = true;
  extended_ = true;
  extended_ = true;
  num_events_ = 0;
  num_events_ = 0;


  chrono::duration adv_direct_ind_timeout = 1280ms;        // 1.28s
  using Duration = std::chrono::steady_clock::duration;
  chrono::duration adv_direct_ind_interval_low = 10000us;  // 10ms
  using TimePoint = std::chrono::steady_clock::time_point;
  chrono::duration adv_direct_ind_interval_high = 3750us;  // 3.75ms

  chrono::duration duration = duration_ms;
  Duration adv_direct_ind_timeout = 1280ms;        // 1.28s
  chrono::time_point now = std::chrono::steady_clock::now();
  Duration adv_direct_ind_interval_low = 10000us;  // 10ms
  Duration adv_direct_ind_interval_high = 3750us;  // 3.75ms
  Duration duration = duration_ms;
  TimePoint now = std::chrono::steady_clock::now();


  bluetooth::hci::Address resolvable_address = get_address_();
  bluetooth::hci::Address resolvable_address = get_address_();
  switch (own_address_type_) {
  switch (own_address_type_) {
@@ -334,7 +148,7 @@ void LeAdvertiser::EnableExtended(std::chrono::milliseconds duration_ms) {
      interval_ = adv_direct_ind_interval_low;
      interval_ = adv_direct_ind_interval_low;
      break;
      break;


    // duration set to parameter,
    // Duration set to parameter,
    // interval set by Initialize().
    // interval set by Initialize().
    default:
    default:
      break;
      break;
@@ -441,11 +255,11 @@ LeAdvertiser::GetAdvertisement(std::chrono::steady_clock::time_point now) {
}
}


std::unique_ptr<model::packets::LinkLayerPacketBuilder>
std::unique_ptr<model::packets::LinkLayerPacketBuilder>
LeAdvertiser::GetScanResponse(bluetooth::hci::AddressWithType scanned,
LeAdvertiser::GetScanResponse(bluetooth::hci::Address scanned,
                              bluetooth::hci::AddressWithType scanner,
                              bluetooth::hci::Address scanner,
                              bool scanner_in_filter_accept_list) {
                              bool scanner_in_filter_accept_list) {
  (void)scanner;
  (void)scanner;
  if (scanned != address_ || !enabled_) {
  if (scanned != address_.GetAddress() || !enabled_) {
    return nullptr;
    return nullptr;
  }
  }


@@ -477,90 +291,4 @@ LeAdvertiser::GetScanResponse(bluetooth::hci::AddressWithType scanned,
  }
  }
}
}


// =============================================================================
//  Advertising Routines
// =============================================================================

void LinkLayerController::LeAdvertising() {
  chrono::time_point now = std::chrono::steady_clock::now();

  // Legacy Advertising Timeout

  // Generate HCI Connection Complete or Enhanced HCI Connection Complete
  // events with Advertising Timeout error code when the advertising
  // type is ADV_DIRECT_IND and the connection failed to be established.
  if (legacy_advertiser_.IsEnabled() && legacy_advertiser_.timeout &&
      now >= legacy_advertiser_.timeout.value()) {
    // If the Advertising_Type parameter is 0x01 (ADV_DIRECT_IND, high duty
    // cycle) and the directed advertising fails to create a connection, an
    // HCI_LE_Connection_Complete or HCI_LE_Enhanced_Connection_Complete
    // event shall be generated with the Status code set to
    // Advertising Timeout (0x3C).
    LOG_INFO("Directed Advertising Timeout");
    legacy_advertiser_.Disable();

    // Note: HCI_LE_Connection_Complete is not sent if the
    // HCI_LE_Enhanced_Connection_Complete event (see Section 7.7.65.10)
    // is unmasked.
    if (IsLeEventUnmasked(SubeventCode::ENHANCED_CONNECTION_COMPLETE)) {
      send_event_(bluetooth::hci::LeEnhancedConnectionCompleteBuilder::Create(
          ErrorCode::ADVERTISING_TIMEOUT, 0, Role::PERIPHERAL,
          AddressType::PUBLIC_DEVICE_ADDRESS, Address(), Address(), Address(),
          0, 0, 0, ClockAccuracy::PPM_500));
    } else if (IsLeEventUnmasked(SubeventCode::CONNECTION_COMPLETE)) {
      send_event_(bluetooth::hci::LeConnectionCompleteBuilder::Create(
          ErrorCode::ADVERTISING_TIMEOUT, 0, Role::PERIPHERAL,
          AddressType::PUBLIC_DEVICE_ADDRESS, Address(), 0, 0, 0,
          ClockAccuracy::PPM_500));
    }
  }

  // Legacy Advertising Event

  // Generate Link Layer Advertising events when advertising is enabled
  // and a full interval has passed since the last event.
  if (legacy_advertiser_.IsEnabled() && now >= legacy_advertiser_.next_event) {
    legacy_advertiser_.next_event += legacy_advertiser_.advertising_interval;
    model::packets::LegacyAdvertisingType type;
    switch (legacy_advertiser_.advertising_type) {
      case AdvertisingType::ADV_IND:
        type = model::packets::LegacyAdvertisingType::ADV_IND;
        break;
      case AdvertisingType::ADV_DIRECT_IND_HIGH:
      case AdvertisingType::ADV_DIRECT_IND_LOW:
        type = model::packets::LegacyAdvertisingType::ADV_DIRECT_IND;
        break;
      case AdvertisingType::ADV_SCAN_IND:
        type = model::packets::LegacyAdvertisingType::ADV_SCAN_IND;
        break;
      case AdvertisingType::ADV_NONCONN_IND:
        type = model::packets::LegacyAdvertisingType::ADV_NONCONN_IND;
        break;
    }

    SendLeLinkLayerPacket(model::packets::LeLegacyAdvertisingPduBuilder::Create(
        legacy_advertiser_.advertising_address.GetAddress(),
        legacy_advertiser_.target_address.GetAddress(),
        static_cast<model::packets::AddressType>(
            legacy_advertiser_.advertising_address.GetAddressType()),
        static_cast<model::packets::AddressType>(
            legacy_advertiser_.target_address.GetAddressType()),
        type, legacy_advertiser_.advertising_data));
  }

  // Extended Advertising Timeouts

  for (auto& advertiser : advertisers_) {
    auto event = advertiser.GetEvent(now);
    if (event != nullptr) {
      send_event_(std::move(event));
    }

    auto advertisement = advertiser.GetAdvertisement(now);
    if (advertisement != nullptr) {
      SendLeLinkLayerPacket(std::move(advertisement));
    }
  }
}

}  // namespace rootcanal
}  // namespace rootcanal
Loading