diff options
author | 2022-10-13 15:30:16 -0700 | |
---|---|---|
committer | 2022-10-17 16:14:26 +0000 | |
commit | 86ee3105f7f66c7b43cf3834d268bc50206aed6a (patch) | |
tree | 6dee9616c60be7aceb845e214d9f37c83d4b2602 | |
parent | cd129a99ad439b31b8078f3f288b1c5321b8e4f2 (diff) |
Add gd controller data to dumpsys
Bug: 253533304
Test: gd/cert/run
Tag: #refactor
BYPASS_LONG_LINES_REASON: Bluetooth likes 120 lines
Change-Id: Icc74895d7e4baeb034bc04f47dd2dd7c93c66c34
-rw-r--r-- | system/gd/Android.bp | 4 | ||||
-rw-r--r-- | system/gd/BUILD.gn | 2 | ||||
-rw-r--r-- | system/gd/dumpsys_data.fbs | 2 | ||||
-rw-r--r-- | system/gd/hci/Android.bp | 2 | ||||
-rw-r--r-- | system/gd/hci/controller.cc | 103 | ||||
-rw-r--r-- | system/gd/hci/controller.h | 3 | ||||
-rw-r--r-- | system/gd/hci/controller_test.cc | 101 | ||||
-rw-r--r-- | system/gd/hci/hci_controller.fbs | 69 |
8 files changed, 251 insertions, 35 deletions
diff --git a/system/gd/Android.bp b/system/gd/Android.bp index 0cd9f56c61..6daf791ea9 100644 --- a/system/gd/Android.bp +++ b/system/gd/Android.bp @@ -719,6 +719,7 @@ genrule { "common/init_flags.fbs", "dumpsys_data.fbs", "hci/hci_acl_manager.fbs", + "hci/hci_controller.fbs", "l2cap/classic/l2cap_classic_module.fbs", "shim/dumpsys.fbs", "os/wakelock_manager.fbs", @@ -729,6 +730,7 @@ genrule { "dumpsys.bfbs", "dumpsys_data.bfbs", "hci_acl_manager.bfbs", + "hci_controller.bfbs", "l2cap_classic_module.bfbs", "wakelock_manager.bfbs", ], @@ -745,6 +747,7 @@ genrule { "common/init_flags.fbs", "dumpsys_data.fbs", "hci/hci_acl_manager.fbs", + "hci/hci_controller.fbs", "l2cap/classic/l2cap_classic_module.fbs", "shim/dumpsys.fbs", "os/wakelock_manager.fbs", @@ -754,6 +757,7 @@ genrule { "dumpsys_data_generated.h", "dumpsys_generated.h", "hci_acl_manager_generated.h", + "hci_controller_generated.h", "init_flags_generated.h", "l2cap_classic_module_generated.h", "wakelock_manager_generated.h", diff --git a/system/gd/BUILD.gn b/system/gd/BUILD.gn index 33a35e1181..d035b8f91a 100644 --- a/system/gd/BUILD.gn +++ b/system/gd/BUILD.gn @@ -90,6 +90,7 @@ flatbuffer("BluetoothGeneratedDumpsysDataSchema_h") { "common/init_flags.fbs", "dumpsys_data.fbs", "hci/hci_acl_manager.fbs", + "hci/hci_controller.fbs", "l2cap/classic/l2cap_classic_module.fbs", "os/wakelock_manager.fbs", "shim/dumpsys.fbs", @@ -102,6 +103,7 @@ bt_flatc_binary_schema("BluetoothGeneratedDumpsysBinarySchema_bfbs") { "common/init_flags.fbs", "dumpsys_data.fbs", "hci/hci_acl_manager.fbs", + "hci/hci_controller.fbs", "l2cap/classic/l2cap_classic_module.fbs", "os/wakelock_manager.fbs", "shim/dumpsys.fbs", diff --git a/system/gd/dumpsys_data.fbs b/system/gd/dumpsys_data.fbs index 85992b18f9..326d211357 100644 --- a/system/gd/dumpsys_data.fbs +++ b/system/gd/dumpsys_data.fbs @@ -12,6 +12,7 @@ include "btaa/activity_attribution.fbs"; include "common/init_flags.fbs"; include "hci/hci_acl_manager.fbs"; +include "hci/hci_controller.fbs"; include "l2cap/classic/l2cap_classic_module.fbs"; include "module_unittest.fbs"; include "os/wakelock_manager.fbs"; @@ -28,6 +29,7 @@ table DumpsysData { shim_dumpsys_data:bluetooth.shim.DumpsysModuleData (privacy:"Any"); l2cap_classic_dumpsys_data:bluetooth.l2cap.classic.L2capClassicModuleData (privacy:"Any"); hci_acl_manager_dumpsys_data:bluetooth.hci.AclManagerData (privacy:"Any"); + hci_controller_dumpsys_data:bluetooth.hci.ControllerData (privacy:"Any"); module_unittest_data:bluetooth.ModuleUnitTestData; // private activity_attribution_dumpsys_data:bluetooth.activity_attribution.ActivityAttributionData (privacy:"Any"); } diff --git a/system/gd/hci/Android.bp b/system/gd/hci/Android.bp index acc7be6e56..cc25bf2816 100644 --- a/system/gd/hci/Android.bp +++ b/system/gd/hci/Android.bp @@ -42,6 +42,7 @@ filegroup { "address_unittest.cc", "address_with_type_test.cc", "class_of_device_unittest.cc", + "controller_test.cc", "controller_unittest.cc", "hci_layer_unittest.cc", "hci_packets_test.cc", @@ -57,7 +58,6 @@ filegroup { srcs: [ "acl_manager/round_robin_scheduler_test.cc", "acl_manager_test.cc", - "controller_test.cc", "hci_layer_test.cc", "le_address_manager_test.cc", "le_advertising_manager_test.cc", diff --git a/system/gd/hci/controller.cc b/system/gd/hci/controller.cc index ec7c4e193b..0d32915e2e 100644 --- a/system/gd/hci/controller.cc +++ b/system/gd/hci/controller.cc @@ -23,6 +23,7 @@ #include "common/init_flags.h" #include "hci/hci_layer.h" +#include "hci_controller_generated.h" namespace bluetooth { namespace hci { @@ -591,6 +592,9 @@ struct Controller::impl { return supported; \ } + void Dump( + std::promise<flatbuffers::Offset<ControllerData>> promise, flatbuffers::FlatBufferBuilder* fb_builder) const; + bool is_supported(OpCode op_code) { switch (op_code) { OP_CODE_MAPPING(INQUIRY) @@ -1202,5 +1206,104 @@ void Controller::Stop() { std::string Controller::ToString() const { return "Controller"; } + +void Controller::impl::Dump( + std::promise<flatbuffers::Offset<ControllerData>> promise, flatbuffers::FlatBufferBuilder* fb_builder) const { + ASSERT(fb_builder != nullptr); + auto title = fb_builder->CreateString("----- Hci Controller Dumpsys -----"); + + auto local_version_information_data = CreateLocalVersionInformationData( + *fb_builder, + fb_builder->CreateString(HciVersionText(local_version_information_.hci_version_)), + local_version_information_.hci_revision_, + fb_builder->CreateString(LmpVersionText(local_version_information_.lmp_version_)), + local_version_information_.manufacturer_name_, + local_version_information_.lmp_subversion_); + + auto acl_buffer_size_data = BufferSizeData(acl_buffer_length_, acl_buffers_); + + auto sco_buffer_size_data = BufferSizeData(sco_buffer_length_, sco_buffers_); + + auto le_buffer_size_data = + BufferSizeData(le_buffer_size_.le_data_packet_length_, le_buffer_size_.total_num_le_packets_); + + auto iso_buffer_size_data = + BufferSizeData(iso_buffer_size_.le_data_packet_length_, iso_buffer_size_.total_num_le_packets_); + + auto le_maximum_data_length_data = LeMaximumDataLengthData( + le_maximum_data_length_.supported_max_tx_octets_, + le_maximum_data_length_.supported_max_tx_time_, + le_maximum_data_length_.supported_max_rx_octets_, + le_maximum_data_length_.supported_max_rx_time_); + + std::vector<LocalSupportedCommandsData> local_supported_commands_vector; + for (uint8_t index = 0; index < local_supported_commands_.size(); index++) { + local_supported_commands_vector.push_back(LocalSupportedCommandsData(index, local_supported_commands_[index])); + } + auto local_supported_commands_data = fb_builder->CreateVectorOfStructs(local_supported_commands_vector); + + auto vendor_capabilities_data = VendorCapabilitiesData( + vendor_capabilities_.is_supported_, + vendor_capabilities_.max_advt_instances_, + vendor_capabilities_.offloaded_resolution_of_private_address_, + vendor_capabilities_.total_scan_results_storage_, + vendor_capabilities_.max_irk_list_sz_, + vendor_capabilities_.filtering_support_, + vendor_capabilities_.max_filter_, + vendor_capabilities_.activity_energy_info_support_, + vendor_capabilities_.version_supported_, + vendor_capabilities_.total_num_of_advt_tracked_, + vendor_capabilities_.extended_scan_support_, + vendor_capabilities_.debug_logging_supported_, + vendor_capabilities_.le_address_generation_offloading_support_, + vendor_capabilities_.a2dp_source_offload_capability_mask_, + vendor_capabilities_.bluetooth_quality_report_support_); + + auto extended_lmp_features_vector = fb_builder->CreateVector(extended_lmp_features_array_); + + // Create the root table + ControllerDataBuilder builder(*fb_builder); + + builder.add_title(title); + builder.add_local_version_information(local_version_information_data); + + builder.add_acl_buffer_size(&acl_buffer_size_data); + builder.add_sco_buffer_size(&sco_buffer_size_data); + builder.add_iso_buffer_size(&iso_buffer_size_data); + builder.add_le_buffer_size(&le_buffer_size_data); + + builder.add_le_connect_list_size(le_connect_list_size_); + builder.add_le_resolving_list_size(le_resolving_list_size_); + + builder.add_le_maximum_data_length(&le_maximum_data_length_data); + builder.add_le_maximum_advertising_data_length(le_maximum_advertising_data_length_); + builder.add_le_suggested_default_data_length(le_suggested_default_data_length_); + builder.add_le_number_supported_advertising_sets(le_number_supported_advertising_sets_); + builder.add_le_periodic_advertiser_list_size(le_periodic_advertiser_list_size_); + + builder.add_local_supported_commands(local_supported_commands_data); + builder.add_extended_lmp_features_array(extended_lmp_features_vector); + builder.add_le_local_supported_features(le_local_supported_features_); + builder.add_le_supported_states(le_supported_states_); + builder.add_vendor_capabilities(&vendor_capabilities_data); + + flatbuffers::Offset<ControllerData> dumpsys_data = builder.Finish(); + promise.set_value(dumpsys_data); +} + +DumpsysDataFinisher Controller::GetDumpsysData(flatbuffers::FlatBufferBuilder* fb_builder) const { + ASSERT(fb_builder != nullptr); + + std::promise<flatbuffers::Offset<ControllerData>> promise; + auto future = promise.get_future(); + impl_->Dump(std::move(promise), fb_builder); + + auto dumpsys_data = future.get(); + + return [dumpsys_data](DumpsysDataBuilder* dumpsys_builder) { + dumpsys_builder->add_hci_controller_dumpsys_data(dumpsys_data); + }; +} + } // namespace hci } // namespace bluetooth diff --git a/system/gd/hci/controller.h b/system/gd/hci/controller.h index d67a24abcb..69ba43a275 100644 --- a/system/gd/hci/controller.h +++ b/system/gd/hci/controller.h @@ -19,6 +19,7 @@ #include "hci/address.h" #include "hci/hci_packets.h" #include "hci/le_rand_callback.h" +#include "hci_controller_generated.h" #include "module.h" #include "os/handler.h" @@ -228,6 +229,8 @@ class Controller : public Module { std::string ToString() const override; + DumpsysDataFinisher GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const override; // Module + private: virtual uint64_t GetLocalFeatures(uint8_t page_number) const; virtual uint64_t GetLocalLeFeatures() const; diff --git a/system/gd/hci/controller_test.cc b/system/gd/hci/controller_test.cc index 908c872002..c5641b2bb3 100644 --- a/system/gd/hci/controller_test.cc +++ b/system/gd/hci/controller_test.cc @@ -16,12 +16,13 @@ #include "hci/controller.h" +#include <gtest/gtest.h> + #include <algorithm> #include <chrono> #include <future> #include <map> - -#include <gtest/gtest.h> +#include <memory> #include "common/bind.h" #include "common/callback.h" @@ -31,9 +32,8 @@ #include "os/thread.h" #include "packet/raw_builder.h" -namespace bluetooth { -namespace hci { -namespace { +using namespace bluetooth; +using namespace std::chrono_literals; using common::BidiQueue; using common::BidiQueueEnd; @@ -41,11 +41,20 @@ using packet::kLittleEndian; using packet::PacketView; using packet::RawBuilder; +namespace bluetooth { +namespace hci { + +namespace { + constexpr uint16_t kHandle1 = 0x123; constexpr uint16_t kCredits1 = 0x78; constexpr uint16_t kHandle2 = 0x456; constexpr uint16_t kCredits2 = 0x9a; +constexpr uint64_t kRandomNumber = 0x123456789abcdef0; uint16_t feature_spec_version = 55; +constexpr char title[] = "hci_controller_test"; + +} // namespace PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) { auto bytes = std::make_shared<std::vector<uint8_t>>(); @@ -67,7 +76,7 @@ class TestHciLayer : public HciLayer { void EnqueueCommand( std::unique_ptr<CommandBuilder> command, common::ContextualOnceCallback<void(CommandStatusView)> on_status) override { - EXPECT_TRUE(false) << "Controller properties should not generate Command Status"; + FAIL() << "Controller properties should not generate Command Status"; } void HandleCommand( @@ -185,6 +194,12 @@ class TestHciLayer : public HciLayer { event_builder = LeSetEventMaskCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS); } break; + case (OpCode::LE_RAND): { + auto view = LeRandView::Create(LeSecurityCommandView::Create(command)); + ASSERT_TRUE(view.IsValid()); + event_builder = LeRandCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, kRandomNumber); + } break; + case (OpCode::RESET): case (OpCode::SET_EVENT_FILTER): case (OpCode::HOST_BUFFER_SIZE): @@ -204,12 +219,12 @@ class TestHciLayer : public HciLayer { } void RegisterEventHandler(EventCode event_code, common::ContextualCallback<void(EventView)> event_handler) override { - EXPECT_EQ(event_code, EventCode::NUMBER_OF_COMPLETED_PACKETS) << "Only NUMBER_OF_COMPLETED_PACKETS is needed"; + ASSERT_EQ(event_code, EventCode::NUMBER_OF_COMPLETED_PACKETS) << "Only NUMBER_OF_COMPLETED_PACKETS is needed"; number_of_completed_packets_callback_ = event_handler; } void UnregisterEventHandler(EventCode event_code) override { - EXPECT_EQ(event_code, EventCode::NUMBER_OF_COMPLETED_PACKETS) << "Only NUMBER_OF_COMPLETED_PACKETS is needed"; + ASSERT_EQ(event_code, EventCode::NUMBER_OF_COMPLETED_PACKETS) << "Only NUMBER_OF_COMPLETED_PACKETS is needed"; number_of_completed_packets_callback_ = {}; } @@ -234,17 +249,15 @@ class TestHciLayer : public HciLayer { std::chrono::milliseconds time = std::chrono::milliseconds(3000); // wait for command - while (command_queue_.size() == 0) { + while (command_queue_.size() == 0UL) { if (not_empty_.wait_for(lock, time) == std::cv_status::timeout) { break; } } - EXPECT_TRUE(command_queue_.size() > 0); if (command_queue_.empty()) { return CommandView::Create(PacketView<kLittleEndian>(std::make_shared<std::vector<uint8_t>>())); } CommandView command = command_queue_.front(); - EXPECT_EQ(command.GetOpCode(), op_code); command_queue_.pop(); return command; } @@ -305,7 +318,7 @@ TEST_F(ControllerTest, read_controller_info) { ASSERT_EQ(local_version_information.lmp_subversion_, 0x5678); ASSERT_EQ(controller_->GetLeBufferSize().le_data_packet_length_, 0x16); ASSERT_EQ(controller_->GetLeBufferSize().total_num_le_packets_, 0x08); - ASSERT_EQ(controller_->GetLeSupportedStates(), 0x001f123456789abe); + ASSERT_EQ(controller_->GetLeSupportedStates(), 0x001f123456789abeUL); ASSERT_EQ(controller_->GetLeMaximumDataLength().supported_max_tx_octets_, 0x12); ASSERT_EQ(controller_->GetLeMaximumDataLength().supported_max_tx_time_, 0x34); ASSERT_EQ(controller_->GetLeMaximumDataLength().supported_max_rx_octets_, 0x56); @@ -394,34 +407,35 @@ TEST_F(ControllerTest, is_supported_test) { } TEST_F(ControllerTest, feature_spec_version_055_test) { - EXPECT_EQ(controller_->GetVendorCapabilities().version_supported_, 55); - EXPECT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT)); - EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO)); - EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE)); + ASSERT_EQ(controller_->GetVendorCapabilities().version_supported_, 55); + ASSERT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT)); + ASSERT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO)); + ASSERT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE)); feature_spec_version = 95; } TEST_F(ControllerTest, feature_spec_version_095_test) { - EXPECT_EQ(controller_->GetVendorCapabilities().version_supported_, 95); - EXPECT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT)); - EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO)); - EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE)); + ASSERT_EQ(controller_->GetVendorCapabilities().version_supported_, 95); + ASSERT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT)); + ASSERT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO)); + ASSERT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE)); feature_spec_version = 96; } TEST_F(ControllerTest, feature_spec_version_096_test) { - EXPECT_EQ(controller_->GetVendorCapabilities().version_supported_, 96); - EXPECT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT)); - EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO)); - EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE)); + ASSERT_EQ(controller_->GetVendorCapabilities().version_supported_, 96); + ASSERT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT)); + ASSERT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO)); + ASSERT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE)); feature_spec_version = 98; } TEST_F(ControllerTest, feature_spec_version_098_test) { - EXPECT_EQ(controller_->GetVendorCapabilities().version_supported_, 98); - EXPECT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT)); - EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO)); - EXPECT_TRUE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE)); + ASSERT_EQ(controller_->GetVendorCapabilities().version_supported_, 98); + ASSERT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT)); + ASSERT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO)); + ASSERT_TRUE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE)); + feature_spec_version = 55; } std::promise<void> credits1_set; @@ -443,12 +457,18 @@ void CheckReceivedCredits(uint16_t handle, uint16_t credits) { } TEST_F(ControllerTest, aclCreditCallbacksTest) { + credits1_set = std::promise<void>(); + credits2_set = std::promise<void>(); + + auto credits1_set_future = credits1_set.get_future(); + auto credits2_set_future = credits2_set.get_future(); + controller_->RegisterCompletedAclPacketsCallback(client_handler_->Bind(&CheckReceivedCredits)); test_hci_layer_->IncomingCredit(); - credits1_set.get_future().wait(); - credits2_set.get_future().wait(); + ASSERT_EQ(std::future_status::ready, credits1_set_future.wait_for(2s)); + ASSERT_EQ(std::future_status::ready, credits2_set_future.wait_for(2s)); } TEST_F(ControllerTest, aclCreditCallbackListenerUnregistered) { @@ -470,14 +490,27 @@ void le_rand_callback(uint64_t random) { } TEST_F(ControllerTest, leRandTest) { - controller_->LeRand(client_handler_->Bind(&le_rand_callback)); - le_rand_set.get_future().wait(); + le_rand_set = std::promise<uint64_t>(); + auto le_rand_set_future = le_rand_set.get_future(); + + controller_->LeRand(common::Bind(le_rand_callback)); + + ASSERT_EQ(std::future_status::ready, le_rand_set_future.wait_for(2s)); + ASSERT_EQ(kRandomNumber, le_rand_set_future.get()); } TEST_F(ControllerTest, AllowWakeByHidTest) { - controller->AllowWakeByHid(); + controller_->AllowWakeByHid(); +} + +TEST_F(ControllerTest, Dumpsys) { + ModuleDumper dumper(fake_registry_, title); + + std::string output; + dumper.DumpState(&output); + + ASSERT_TRUE(output.find("Hci Controller Dumpsys") != std::string::npos); } -} // namespace } // namespace hci } // namespace bluetooth diff --git a/system/gd/hci/hci_controller.fbs b/system/gd/hci/hci_controller.fbs new file mode 100644 index 0000000000..ce142b6687 --- /dev/null +++ b/system/gd/hci/hci_controller.fbs @@ -0,0 +1,69 @@ +namespace bluetooth.hci; + +attribute "privacy"; + +table LocalVersionInformationData { + hci_version : string (privacy:"Any"); + hci_revision : ushort (privacy:"Any"); + lmp_version : string (privacy:"Any"); + manufacturer_name : ushort (privacy:"Any"); + lmp_subversion : ushort (privacy:"Any"); +} + +struct BufferSizeData { + data_packet_length : ushort (privacy:"Any"); + total_num_packets : ubyte (privacy:"Any"); +} + +struct LeMaximumDataLengthData { + supported_max_tx_octets : ushort (privacy:"Any"); + supported_max_tx_time : ushort (privacy:"Any"); + supported_max_rx_octets : ushort (privacy:"Any"); + supported_max_rx_time : ushort (privacy:"Any"); +} + +struct VendorCapabilitiesData { + is_supported : ubyte (privacy:"Any"); + max_advt_instances : ubyte (privacy:"Any"); + offloaded_resolution_of_private_address : ubyte (privacy:"Any"); + total_scan_results_storage : ushort (privacy:"Any"); + max_irk_list_sz : ubyte (privacy:"Any"); + filtering_support : ubyte (privacy:"Any"); + max_filter : ubyte (privacy:"Any"); + activity_energy_info_support : ubyte (privacy:"Any"); + version_supported : ushort (privacy:"Any"); + total_num_of_advt_tracked : ushort (privacy:"Any"); + extended_scan_support : ubyte (privacy:"Any"); + debug_logging_supported : ubyte (privacy:"Any"); + le_address_generation_offloading_support : ubyte (privacy:"Any"); + a2dp_source_offload_capability_mask : uint (privacy:"Any"); + bluetooth_quality_report_support : ubyte (privacy:"Any"); +} + +struct LocalSupportedCommandsData { + index : ubyte (privacy:"Any"); + value: ubyte (privacy:"Any"); +} + +table ControllerData { + title : string (privacy:"Any"); + local_version_information : LocalVersionInformationData (privacy:"Any"); + acl_buffer_size : BufferSizeData (privacy:"Any"); + sco_buffer_size : BufferSizeData (privacy:"Any"); + iso_buffer_size : BufferSizeData (privacy:"Any"); + le_buffer_size : BufferSizeData (privacy:"Any"); + le_connect_list_size : uint64 (privacy:"Any"); + le_resolving_list_size : uint64 (privacy:"Any"); + le_maximum_data_length : LeMaximumDataLengthData (privacy:"Any"); + le_maximum_advertising_data_length : ushort (privacy:"Any"); + le_suggested_default_data_length : ushort (privacy:"Any"); + le_number_supported_advertising_sets : ubyte (privacy:"Any"); + le_periodic_advertiser_list_size : ubyte (privacy:"Any"); + local_supported_commands : [LocalSupportedCommandsData] (privacy:"Any"); + extended_lmp_features_array : [uint64] (privacy:"Any"); + le_local_supported_features : int64 (privacy:"Any"); + le_supported_states : uint64 (privacy:"Any"); + vendor_capabilities : VendorCapabilitiesData (privacy:"Any"); +} + +root_type ControllerData; |