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

Commit a66b9c4f authored by Myles Watson's avatar Myles Watson
Browse files

HCI: Le extended advertising packets

LeSetExtendedAdvertisingRandomAddress
LeSetExtendedAdvertisingLegacyParameters
LeSetExtendedAdvertisingParameters
LeSetExtendedAdvertisingData
LeSetExtendedAdvertisingScanResponse
LeSetExtendedAdvertisingEnable
LeRemoveAdvertisingSet
LeSetPeriodicAdvertisingParam
LeSetPeriodicAdvertisingData
LeSetPeriodicAdvertisingEnable

Bug: 143568835
Test: bluetooth_test_gd
Change-Id: Ica9669db0fb541e0a5b3a33d6e973ee162a65819
parent b00f40e4
Loading
Loading
Loading
Loading
+193 −23
Original line number Diff line number Diff line
@@ -2600,23 +2600,177 @@ packet LeEnhancedTransmitterTest : CommandPacket (op_code = LE_ENHANCED_TRANSMIT
}

packet LeSetExtendedAdvertisingRandomAddress : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_RANDOM_ADDRESS) {
  _payload_,  // placeholder (unimplemented)
  advertising_handle : 8,
  advertising_random_address : Address,
}

packet LeSetExtendedAdvertisingRandomAddressComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_RANDOM_ADDRESS) {
  status : ErrorCode,
}

// The lower 4 bits of the advertising event properties
enum LegacyAdvertisingProperties : 4 {
  ADV_IND = 0x3,
  ADV_DIRECT_IND_LOW = 0x5,
  ADV_DIRECT_IND_HIGH = 0xD,
  ADV_SCAN_IND = 0x2,
  ADV_NONCONN_IND = 0,
}

enum PrimaryPhyType : 8 {
  LE_1M = 0x01,
  LE_CODED = 0x03,
}

enum SecondaryPhyType : 8 {
  NO_PACKETS = 0x00,
  LE_1M = 0x01,
  LE_2M = 0x02,
  LE_CODED = 0x03,
}

packet LeSetExtendedAdvertisingLegacyParameters : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_PARAMETERS) {
  advertising_handle : 8,
  advertising_event_legacy_properties : LegacyAdvertisingProperties,
  _fixed_ = 0x1 : 1, // legacy bit set
  _reserved_ : 11, // advertising_event_properties
  primary_advertising_interval_min : 24, // 0x20 - 0xFFFFFF N * 0.625 ms
  primary_advertising_interval_max : 24, // 0x20 - 0xFFFFFF N * 0.625 ms
  primary_advertising_channel_map : 3,  // bit 0 - Channel 37, bit 1 - 38, bit 2 - 39
  _reserved_ : 5,
  own_address_type : OwnAddressType,
  peer_address_type : PeerAddressType,
  peer_address : Address,
  advertising_filter_policy : AdvertisingFilterPolicy,
  _reserved_ : 6,
  advertising_tx_power : 8, // -127 to +20, 0x7F - no preference
  primary_advertising_phy : PrimaryPhyType,
  _reserved_ : 8, // secondary_advertising_max_skip
  _reserved_ : 8, // secondary_advertising_phy
  advertising_sid : 8, // SID subfield from the ADI field of the PDU
  scan_request_notification_enable : Enable,
}

packet LeSetExtendedAdvertisingParameters : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_PARAMETERS) {
  _payload_,  // placeholder (unimplemented)
  advertising_handle : 8,
  advertising_event_legacy_properties : 4,
  _fixed_ = 0 : 1, // legacy bit cleared
  advertising_event_properties : 3,
  _reserved_ : 8,
  primary_advertising_interval_min : 24, // 0x20 - 0xFFFFFF N * 0.625 ms
  primary_advertising_interval_max : 24, // 0x20 - 0xFFFFFF N * 0.625 ms
  primary_advertising_channel_map : 3,  // bit 0 - Channel 37, bit 1 - 38, bit 2 - 39
  _reserved_ : 5,
  own_address_type : OwnAddressType,
  peer_address_type : PeerAddressType,
  peer_address : Address,
  advertising_filter_policy : AdvertisingFilterPolicy,
  _reserved_ : 6,
  advertising_tx_power : 8, // -127 to +20, 0x7F - no preference
  primary_advertising_phy : PrimaryPhyType,
  secondary_advertising_max_skip : 8, // 1 to 255, 0x00 - AUX_ADV_IND sent before next advertising event
  secondary_advertising_phy : SecondaryPhyType,
  advertising_sid : 8, // SID subfield from the ADI field of the PDU
  scan_request_notification_enable : Enable,
}

packet LeSetExtendedAdvertisingParametersComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_PARAMETERS) {
  status : ErrorCode,
  selected_tx_power : 8, // -127 to +20
}

enum Operation : 3 {
  INTERMEDIATE_FRAGMENT = 0,
  FIRST_FRAGMENT = 1,
  LAST_FRAGMENT = 2,
  COMPLETE_ADVERTISMENT = 3,
  UNCHANGED_DATA = 4,
}

enum FragmentPreference : 1 {
  CONTROLLER_MAY_FRAGMENT = 0,
  CONTROLLER_SHOULD_NOT = 1,
}

packet LeSetExtendedAdvertisingData : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_DATA) {
  _payload_,  // placeholder (unimplemented)
  advertising_handle : 8,
  operation : Operation,
  _reserved_ : 5,
  fragment_preference : FragmentPreference,
  _reserved_ : 7,
  _size_(advertising_data) : 8,
  advertising_data : GapData[],
}

packet LeSetExtendedAdvertisingDataRaw : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_DATA) {
  advertising_handle : 8,
  operation : Operation,
  _reserved_ : 5,
  fragment_preference : FragmentPreference,
  _reserved_ : 7,
  _size_(advertising_data) : 8,
  advertising_data : 8[],
}

packet LeSetExtendedAdvertisingDataComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_DATA) {
  status : ErrorCode,
}

packet LeSetExtendedAdvertisingScanResponse : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE) {
  _payload_,  // placeholder (unimplemented)
  advertising_handle : 8,
  operation : Operation,
  _reserved_ : 5,
  fragment_preference : FragmentPreference,
  _reserved_ : 7,
  _size_(scan_response_data) : 8,
  scan_response_data : GapData[],
}

packet LeSetExtendedAdvertisingScanResponseRaw : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE) {
  advertising_handle : 8,
  operation : Operation,
  _reserved_ : 5,
  fragment_preference : FragmentPreference,
  _reserved_ : 7,
  _size_(scan_response_data) : 8,
  scan_response_data : 8[],
}

packet LeSetExtendedAdvertisingScanResponseComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE) {
  status : ErrorCode,
}

packet LeSetExtendedAdvertisingEnableDisableAll : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
  _fixed_ = 0x00 : 8, // Enable::DISABLED
  _fixed_ = 0x00 : 8, // Disable all sets
}

struct EnabledSet {
  advertising_handle : 8,
  duration : 16,
  max_extended_advertising_events : 8,
}

struct DisabledSet {
  advertising_handle : 8,
  _fixed_ = 0x00 : 16, // duration
  _fixed_ = 0x00 : 8, // max_extended_advertising_events
}

packet LeSetExtendedAdvertisingDisable : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
  _fixed_ = 0x00 : 8, // Enable::DISABLED
  _count_(disabled_sets) : 8,
  disabled_sets : DisabledSet[],
}

packet LeSetExtendedAdvertisingEnable : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
  _payload_,  // placeholder (unimplemented)
  enable : Enable,
  _count_(enabled_sets) : 8,
  enabled_sets : EnabledSet[],
}

packet LeSetExtendedAdvertisingEnableComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
  status : ErrorCode,
}

packet LeReadMaximumAdvertisingDataLength : CommandPacket (op_code = LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH) {
@@ -2636,23 +2790,52 @@ packet LeReadNumberOfSupportedAdvertisingSetsComplete : CommandComplete (command
}

packet LeRemoveAdvertisingSet : LeAdvertisingCommand (op_code = LE_REMOVE_ADVERTISING_SET) {
  _payload_,  // placeholder (unimplemented)
  advertising_handle : 8,
}

packet LeRemoveAdvertisingSetComplete : CommandComplete (command_op_code = LE_REMOVE_ADVERTISING_SET) {
  status : ErrorCode,
}

packet LeClearAdvertisingSets : LeAdvertisingCommand (op_code = LE_CLEAR_ADVERTISING_SETS) {
  _payload_,  // placeholder (unimplemented)
}

packet LeClearAdvertisingSetsComplete : CommandComplete (command_op_code = LE_CLEAR_ADVERTISING_SETS) {
  status : ErrorCode,
}

packet LeSetPeriodicAdvertisingParam : LeAdvertisingCommand (op_code = LE_SET_PERIODIC_ADVERTISING_PARAM) {
  _payload_,  // placeholder (unimplemented)
  advertising_handle : 8,
  periodic_advertising_interval_min : 16, // 0x006 to 0xFFFF (7.5 ms to 82s)
  periodic_advertising_interval_max : 16, // 0x006 to 0xFFFF (7.5 ms to 82s)
  _reserved_ : 6,
  include_tx_power : 1,
  _reserved_ : 9,
}

packet LeSetPeriodicAdvertisingParamComplete : CommandComplete (command_op_code = LE_SET_PERIODIC_ADVERTISING_PARAM) {
  status : ErrorCode,
}

packet LeSetPeriodicAdvertisingData : LeAdvertisingCommand (op_code = LE_SET_PERIODIC_ADVERTISING_DATA) {
  _payload_,  // placeholder (unimplemented)
  advertising_handle : 8,
  operation : Operation,
  _reserved_ : 5,
  _size_(scan_response_data) : 8,
  scan_response_data : 8[],
}

packet LeSetPeriodicAdvertisingDataComplete : CommandComplete (command_op_code = LE_SET_PERIODIC_ADVERTISING_DATA) {
  status : ErrorCode,
}

packet LeSetPeriodicAdvertisingEnable : LeAdvertisingCommand (op_code = LE_SET_PERIODIC_ADVERTISING_ENABLE) {
  _payload_,  // placeholder (unimplemented)
  advertising_handle : 8,
  enable : Enable,
}

packet LeSetPeriodicAdvertisingEnableComplete : CommandComplete (command_op_code = LE_SET_PERIODIC_ADVERTISING_ENABLE) {
  status : ErrorCode,
}

struct PhyScanParameters {
@@ -3427,19 +3610,6 @@ enum DataStatus : 2 {
  RESERVED = 0x3,
}

enum PrimaryPhyType : 8 {
  LE_1M = 0x01,
  LE_CODED = 0x03,
}

enum SecondaryPhyType : 8 {
  NO_PACKETS = 0x00,
  LE_1M = 0x01,
  LE_2M = 0x02,
  LE_CODED = 0x03,
}


struct LeExtendedAdvertisingReport {
  connectable : 1,
  scannable : 1,
+176 −0
Original line number Diff line number Diff line
@@ -418,5 +418,181 @@ std::vector<uint8_t> le_set_extended_scan_enable_complete{
};
DEFINE_AND_INSTANTIATE_LeSetExtendedScanEnableCompleteReflectionTest(le_set_extended_scan_enable_complete);

std::vector<uint8_t> le_extended_create_connection = {
    0x43, 0x20, 0x2a, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08,
    0x30, 0x00, 0x18, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x08, 0x30, 0x00, 0x18, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00};
DEFINE_AND_INSTANTIATE_LeExtendedCreateConnectionReflectionTest(le_extended_create_connection);

TEST(HciPacketsTest, testLeExtendedCreateConnection) {
  std::shared_ptr<std::vector<uint8_t>> packet_bytes =
      std::make_shared<std::vector<uint8_t>>(le_extended_create_connection);
  PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
  auto view = LeExtendedCreateConnectionView::Create(
      LeConnectionManagementCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
  ASSERT_TRUE(view.IsValid());
}

std::vector<uint8_t> le_set_extended_advertising_random_address = {
    0x35, 0x20, 0x07, 0x00, 0x77, 0x58, 0xeb, 0xd3, 0x1c, 0x6e,
};

TEST(HciPacketsTest, testLeSetExtendedAdvertisingRandomAddress) {
  std::shared_ptr<std::vector<uint8_t>> packet_bytes =
      std::make_shared<std::vector<uint8_t>>(le_set_extended_advertising_random_address);
  PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
  auto view = LeSetExtendedAdvertisingRandomAddressView::Create(
      LeAdvertisingCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
  ASSERT_TRUE(view.IsValid());
  uint8_t random_address_bytes[] = {0x77, 0x58, 0xeb, 0xd3, 0x1c, 0x6e};
  ASSERT_EQ(0, view.GetAdvertisingHandle());
  ASSERT_EQ(Address(random_address_bytes), view.GetAdvertisingRandomAddress());
}
DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingRandomAddressReflectionTest(le_set_extended_advertising_random_address);

std::vector<uint8_t> le_set_extended_advertising_random_address_complete{
    0x0e, 0x04, 0x01, 0x35, 0x20, 0x00,
};
DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingRandomAddressCompleteReflectionTest(
    le_set_extended_advertising_random_address_complete);

std::vector<uint8_t> le_set_extended_advertising_data{
    0x37, 0x20, 0x12, 0x00, 0x03, 0x01, 0x0e, 0x02, 0x01, 0x02, 0x0a,
    0x09, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x33, 0x20, 0x58,
};
TEST(HciPacketsTest, testLeSetExtendedAdvertisingData) {
  std::shared_ptr<std::vector<uint8_t>> packet_bytes =
      std::make_shared<std::vector<uint8_t>>(le_set_extended_advertising_data);
  PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
  auto view = LeSetExtendedAdvertisingDataRawView::Create(
      LeAdvertisingCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
  ASSERT_TRUE(view.IsValid());
  ASSERT_EQ(0, view.GetAdvertisingHandle());
  ASSERT_EQ(Operation::COMPLETE_ADVERTISMENT, view.GetOperation());
  ASSERT_EQ(FragmentPreference::CONTROLLER_SHOULD_NOT, view.GetFragmentPreference());
  std::vector<uint8_t> advertising_data{
      0x02, 0x01, 0x02, 0x0a, 0x09, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x33, 0x20, 0x58,
  };
  ASSERT_EQ(advertising_data, view.GetAdvertisingData());
}

DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingDataRawReflectionTest(le_set_extended_advertising_data);

std::vector<uint8_t> le_set_extended_advertising_data_complete{
    0x0e, 0x04, 0x01, 0x37, 0x20, 0x00,
};
DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingDataCompleteReflectionTest(le_set_extended_advertising_data_complete);

std::vector<uint8_t> le_set_extended_advertising_parameters_set_0{
    0x36, 0x20, 0x19, 0x00, 0x13, 0x00, 0x90, 0x01, 0x00, 0xc2, 0x01, 0x00,          0x07, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x01, 0x00, 0x00 /*0x01*/, 0x01, 0x00,
};
TEST(HciPacketsTest, testLeSetExtendedAdvertisingParametersLegacySet0) {
  std::shared_ptr<std::vector<uint8_t>> packet_bytes =
      std::make_shared<std::vector<uint8_t>>(le_set_extended_advertising_parameters_set_0);
  PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
  auto view = LeSetExtendedAdvertisingLegacyParametersView::Create(
      LeAdvertisingCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
  ASSERT_TRUE(view.IsValid());
  ASSERT_EQ(0, view.GetAdvertisingHandle());
  ASSERT_EQ(400, view.GetPrimaryAdvertisingIntervalMin());
  ASSERT_EQ(450, view.GetPrimaryAdvertisingIntervalMax());
  ASSERT_EQ(0x7, view.GetPrimaryAdvertisingChannelMap());
  ASSERT_EQ(OwnAddressType::RANDOM_DEVICE_ADDRESS, view.GetOwnAddressType());
  ASSERT_EQ(PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, view.GetPeerAddressType());
  ASSERT_EQ(Address::kEmpty, view.GetPeerAddress());
  ASSERT_EQ(AdvertisingFilterPolicy::ALL_DEVICES, view.GetAdvertisingFilterPolicy());
  ASSERT_EQ(PrimaryPhyType::LE_1M, view.GetPrimaryAdvertisingPhy());
  ASSERT_EQ(1, view.GetAdvertisingSid());
  ASSERT_EQ(Enable::DISABLED, view.GetScanRequestNotificationEnable());
}

std::vector<uint8_t> le_set_extended_advertising_parameters_set_1{
    0x36, 0x20, 0x19, 0x01, 0x13, 0x00, 0x90, 0x01, 0x00, 0xc2, 0x01, 0x00,          0x07, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x01, 0x00, 0x00 /*0x01*/, 0x01, 0x00,
};
TEST(HciPacketsTest, testLeSetExtendedAdvertisingParametersSet1) {
  std::shared_ptr<std::vector<uint8_t>> packet_bytes =
      std::make_shared<std::vector<uint8_t>>(le_set_extended_advertising_parameters_set_1);
  PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
  auto view = LeSetExtendedAdvertisingLegacyParametersView::Create(
      LeAdvertisingCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
  ASSERT_TRUE(view.IsValid());
  ASSERT_EQ(1, view.GetAdvertisingHandle());
  ASSERT_EQ(400, view.GetPrimaryAdvertisingIntervalMin());
  ASSERT_EQ(450, view.GetPrimaryAdvertisingIntervalMax());
  ASSERT_EQ(0x7, view.GetPrimaryAdvertisingChannelMap());
  ASSERT_EQ(OwnAddressType::RANDOM_DEVICE_ADDRESS, view.GetOwnAddressType());
  ASSERT_EQ(PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, view.GetPeerAddressType());
  ASSERT_EQ(Address::kEmpty, view.GetPeerAddress());
  ASSERT_EQ(AdvertisingFilterPolicy::ALL_DEVICES, view.GetAdvertisingFilterPolicy());
  ASSERT_EQ(PrimaryPhyType::LE_1M, view.GetPrimaryAdvertisingPhy());
  ASSERT_EQ(1, view.GetAdvertisingSid());
  ASSERT_EQ(Enable::DISABLED, view.GetScanRequestNotificationEnable());
}

DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingLegacyParametersReflectionTest(
    le_set_extended_advertising_parameters_set_0, le_set_extended_advertising_parameters_set_1);

std::vector<uint8_t> le_set_extended_advertising_parameters_complete{0x0e, 0x05, 0x01, 0x36, 0x20, 0x00, 0xf5};
TEST(HciPacketsTest, testLeSetExtendedAdvertisingParametersComplete) {
  std::shared_ptr<std::vector<uint8_t>> packet_bytes =
      std::make_shared<std::vector<uint8_t>>(le_set_extended_advertising_parameters_complete);
  PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
  auto view = LeSetExtendedAdvertisingParametersCompleteView::Create(
      CommandCompleteView::Create(EventPacketView::Create(packet_bytes_view)));
  ASSERT_TRUE(view.IsValid());
  ASSERT_EQ(static_cast<uint8_t>(-11), view.GetSelectedTxPower());
}

DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingParametersCompleteReflectionTest(
    le_set_extended_advertising_parameters_complete);

std::vector<uint8_t> le_remove_advertising_set_1{
    0x3c,
    0x20,
    0x01,
    0x01,
};
TEST(HciPacketsTest, testLeRemoveAdvertisingSet1) {
  std::shared_ptr<std::vector<uint8_t>> packet_bytes =
      std::make_shared<std::vector<uint8_t>>(le_remove_advertising_set_1);
  PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
  auto view = LeRemoveAdvertisingSetView::Create(
      LeAdvertisingCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
  ASSERT_TRUE(view.IsValid());
  ASSERT_EQ(1, view.GetAdvertisingHandle());
}

DEFINE_AND_INSTANTIATE_LeRemoveAdvertisingSetReflectionTest(le_remove_advertising_set_1);

std::vector<uint8_t> le_remove_advertising_set_complete{
    0x0e, 0x04, 0x01, 0x3c, 0x20, 0x00,
};
DEFINE_AND_INSTANTIATE_LeRemoveAdvertisingSetCompleteReflectionTest(le_remove_advertising_set_complete);

std::vector<uint8_t> le_set_extended_advertising_disable_1{
    0x39, 0x20, 0x06, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
};
TEST(HciPacketsTest, testLeSetExtendedAdvertisingDisable1) {
  std::shared_ptr<std::vector<uint8_t>> packet_bytes =
      std::make_shared<std::vector<uint8_t>>(le_set_extended_advertising_disable_1);
  PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
  auto view = LeSetExtendedAdvertisingDisableView::Create(
      LeAdvertisingCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
  ASSERT_TRUE(view.IsValid());
  auto disabled_set = view.GetDisabledSets();
  ASSERT_EQ(1, disabled_set.size());
  ASSERT_EQ(1, disabled_set[0].advertising_handle_);
}

DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingDisableReflectionTest(le_set_extended_advertising_disable_1);

std::vector<uint8_t> le_set_extended_advertising_enable_complete{
    0x0e, 0x04, 0x01, 0x39, 0x20, 0x00,
};
DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingEnableCompleteReflectionTest(
    le_set_extended_advertising_enable_complete);

}  // namespace hci
}  // namespace bluetooth