summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--system/gd/Android.bp4
-rw-r--r--system/gd/BUILD.gn2
-rw-r--r--system/gd/dumpsys_data.fbs2
-rw-r--r--system/gd/hci/Android.bp2
-rw-r--r--system/gd/hci/controller.cc103
-rw-r--r--system/gd/hci/controller.h3
-rw-r--r--system/gd/hci/controller_test.cc101
-rw-r--r--system/gd/hci/hci_controller.fbs69
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;