From 51b8baeb00d28939e99bb6577ff1d13ae13a7956 Mon Sep 17 00:00:00 2001 From: Myles Watson Date: Fri, 27 Jan 2023 14:22:24 -0800 Subject: [PATCH 1/3] VtsHalBluetooth: Use PDL to generate packets Bug: 266221125 Test: atest VtsHalBluetoothTargetTest Change-Id: If3180282249027ffab45b7e84138a660266ce2b8 --- bluetooth/aidl/vts/Android.bp | 16 +- .../aidl/vts/VtsHalBluetoothTargetTest.cpp | 460 ++++++++---------- 2 files changed, 219 insertions(+), 257 deletions(-) diff --git a/bluetooth/aidl/vts/Android.bp b/bluetooth/aidl/vts/Android.bp index 414f707dfd..5fc0b2eef7 100644 --- a/bluetooth/aidl/vts/Android.bp +++ b/bluetooth/aidl/vts/Android.bp @@ -13,7 +13,17 @@ cc_test { "VtsHalTargetTestDefaults", "use_libaidlvintf_gtest_helper_static", ], - srcs: ["VtsHalBluetoothTargetTest.cpp"], + srcs: [ + "VtsHalBluetoothTargetTest.cpp", + ":BluetoothPacketSources", + ":BluetoothHciPacketSources", + ], + generated_headers: [ + "BluetoothGeneratedPackets_h", + ], + include_dirs: [ + "packages/modules/Bluetooth/system/gd", + ], shared_libs: [ "libbase", "libbinder_ndk", @@ -45,4 +55,8 @@ cc_test { tidy_flags: [ "--header-filter=^.*tools\\/rootcanal\\/(model|include|net|desktop)\\/(.(?!\\.pb\\.h))*$", ], + tidy_disabled_srcs: [ + ":BluetoothPacketSources", + ":BluetoothHciPacketSources", + ], } diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp index 3704c3dcda..43cb914d80 100644 --- a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp +++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp @@ -35,17 +35,20 @@ #include #include +// TODO: Remove custom logging defines from PDL packets. +#undef LOG_INFO +#undef LOG_DEBUG +#undef LOG_TAG +#define LOG_TAG "VtsHalBluetooth" +#include "hci/hci_packets.h" +#include "packet/raw_builder.h" + using aidl::android::hardware::bluetooth::IBluetoothHci; using aidl::android::hardware::bluetooth::IBluetoothHciCallbacks; using aidl::android::hardware::bluetooth::Status; using ndk::ScopedAStatus; using ndk::SpAIBinder; -// Bluetooth Core Specification 3.0 + HS -static constexpr uint8_t kHciMinimumHciVersion = 5; -// Bluetooth Core Specification 3.0 + HS -static constexpr uint8_t kHciMinimumLmpVersion = 5; - static constexpr size_t kNumHciCommandsBandwidth = 100; static constexpr size_t kNumScoPacketsBandwidth = 100; static constexpr size_t kNumAclPacketsBandwidth = 100; @@ -55,57 +58,6 @@ static constexpr std::chrono::milliseconds kWaitForScoDataTimeout(1000); static constexpr std::chrono::milliseconds kWaitForAclDataTimeout(1000); static constexpr std::chrono::milliseconds kInterfaceCloseDelayMs(200); -static constexpr uint8_t kCommandHciShouldBeUnknown[] = { - 0xff, 0x3B, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; -static constexpr uint8_t kCommandHciReadLocalVersionInformation[] = {0x01, 0x10, - 0x00}; -static constexpr uint8_t kCommandHciReadBufferSize[] = {0x05, 0x10, 0x00}; -static constexpr uint8_t kCommandHciWriteLoopbackModeLocal[] = {0x02, 0x18, - 0x01, 0x01}; -static constexpr uint8_t kCommandHciReset[] = {0x03, 0x0c, 0x00}; -static constexpr uint8_t kCommandHciSynchronousFlowControlEnable[] = { - 0x2f, 0x0c, 0x01, 0x01}; -static constexpr uint8_t kCommandHciWriteLocalName[] = {0x13, 0x0c, 0xf8}; -static constexpr uint8_t kHciStatusSuccess = 0x00; -static constexpr uint8_t kHciStatusUnknownHciCommand = 0x01; - -static constexpr uint8_t kEventConnectionComplete = 0x03; -static constexpr uint8_t kEventCommandComplete = 0x0e; -static constexpr uint8_t kEventCommandStatus = 0x0f; -static constexpr uint8_t kEventNumberOfCompletedPackets = 0x13; -static constexpr uint8_t kEventLoopbackCommand = 0x19; - -static constexpr size_t kEventCodeByte = 0; -static constexpr size_t kEventLengthByte = 1; -static constexpr size_t kEventFirstPayloadByte = 2; -static constexpr size_t kEventCommandStatusStatusByte = 2; -static constexpr size_t kEventCommandStatusOpcodeLsByte = 4; // Bytes 4 and 5 -static constexpr size_t kEventCommandCompleteOpcodeLsByte = 3; // Bytes 3 and 4 -static constexpr size_t kEventCommandCompleteStatusByte = 5; -static constexpr size_t kEventCommandCompleteFirstParamByte = 6; -static constexpr size_t kEventLocalHciVersionByte = - kEventCommandCompleteFirstParamByte; -static constexpr size_t kEventLocalLmpVersionByte = - kEventLocalHciVersionByte + 3; - -static constexpr size_t kEventConnectionCompleteParamLength = 11; -static constexpr size_t kEventConnectionCompleteType = 11; -static constexpr size_t kEventConnectionCompleteTypeSco = 0; -static constexpr size_t kEventConnectionCompleteTypeAcl = 1; -static constexpr size_t kEventConnectionCompleteHandleLsByte = 3; - -static constexpr size_t kEventNumberOfCompletedPacketsNumHandles = 2; - -static constexpr size_t kAclBroadcastFlagOffset = 6; -static constexpr uint8_t kAclBroadcastFlagPointToPoint = 0x0; -static constexpr uint8_t kAclBroadcastPointToPoint = - (kAclBroadcastFlagPointToPoint << kAclBroadcastFlagOffset); - -static constexpr uint8_t kAclPacketBoundaryFlagOffset = 4; -static constexpr uint8_t kAclPacketBoundaryFlagFirstAutoFlushable = 0x2; -static constexpr uint8_t kAclPacketBoundaryFirstAutoFlushable = - kAclPacketBoundaryFlagFirstAutoFlushable << kAclPacketBoundaryFlagOffset; - // To discard Qualcomm ACL debugging static constexpr uint16_t kAclHandleQcaDebugMessage = 0xedc; @@ -205,7 +157,7 @@ class BluetoothAidlTest : public ::testing::TestWithParam { void handle_no_ops(); void discard_qca_debugging(); void wait_for_event(bool timeout_is_error); - void wait_for_command_complete_event(std::vector cmd); + void wait_for_command_complete_event(::bluetooth::hci::OpCode opCode); int wait_for_completed_packets_event(uint16_t handle); // A simple test implementation of BluetoothHciCallbacks. @@ -283,6 +235,14 @@ class BluetoothAidlTest : public ::testing::TestWithParam { return true; }; + void pop() { + std::lock_guard lock(m_); + if (q_.empty()) { + return; + } + q_.pop(); + }; + bool front(T& v) { std::lock_guard lock(m_); if (q_.empty()) { @@ -355,17 +315,20 @@ void BluetoothAidlTest::handle_no_ops() { while (!event_queue.empty()) { std::vector event; event_queue.front(event); - ASSERT_GE(event.size(), - static_cast(kEventCommandCompleteStatusByte)); - bool event_is_no_op = - (event[kEventCodeByte] == kEventCommandComplete) && - (event[kEventCommandCompleteOpcodeLsByte] == 0x00) && - (event[kEventCommandCompleteOpcodeLsByte + 1] == 0x00); - event_is_no_op |= (event[kEventCodeByte] == kEventCommandStatus) && - (event[kEventCommandStatusOpcodeLsByte] == 0x00) && - (event[kEventCommandStatusOpcodeLsByte + 1] == 0x00); - if (event_is_no_op) { - event_queue.pop(event); + auto complete_view = ::bluetooth::hci::CommandCompleteView::Create( + ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView( + std::make_shared>(event)))); + auto status_view = ::bluetooth::hci::CommandCompleteView::Create( + ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView( + std::make_shared>(event)))); + bool is_complete_no_op = + complete_view.IsValid() && + complete_view.GetCommandOpCode() == ::bluetooth::hci::OpCode::NONE; + bool is_status_no_op = + status_view.IsValid() && + status_view.GetCommandOpCode() == ::bluetooth::hci::OpCode::NONE; + if (is_complete_no_op || is_status_no_op) { + event_queue.pop(); } else { break; } @@ -377,12 +340,12 @@ void BluetoothAidlTest::discard_qca_debugging() { while (!acl_queue.empty()) { std::vector acl_packet; acl_queue.front(acl_packet); - uint16_t connection_handle = acl_packet[1] & 0xF; - connection_handle <<= 8; - connection_handle |= acl_packet[0]; - bool packet_is_no_op = connection_handle == kAclHandleQcaDebugMessage; - if (packet_is_no_op) { - acl_queue.pop(acl_packet); + auto acl_view = + ::bluetooth::hci::AclView::Create(::bluetooth::hci::PacketView( + std::make_shared>(acl_packet))); + EXPECT_TRUE(acl_view.IsValid()); + if (acl_view.GetHandle() == kAclHandleQcaDebugMessage) { + acl_queue.pop(); } else { break; } @@ -409,46 +372,42 @@ void BluetoothAidlTest::wait_for_event(bool timeout_is_error = true) { // Wait until a command complete is received. void BluetoothAidlTest::wait_for_command_complete_event( - std::vector cmd) { + ::bluetooth::hci::OpCode opCode) { ASSERT_NO_FATAL_FAILURE(wait_for_event()); std::vector event; ASSERT_FALSE(event_queue.empty()); ASSERT_TRUE(event_queue.pop(event)); - - ASSERT_GT(event.size(), static_cast(kEventCommandCompleteStatusByte)); - ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]); - ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]); - ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]); - ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]); + auto complete_view = ::bluetooth::hci::CommandCompleteView::Create( + ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView( + std::make_shared>(event)))); + ASSERT_TRUE(complete_view.IsValid()); + ASSERT_EQ(complete_view.GetCommandOpCode(), opCode); + ASSERT_EQ(complete_view.GetPayload()[0], + static_cast(::bluetooth::hci::ErrorCode::SUCCESS)); } // Send the command to read the controller's buffer sizes. void BluetoothAidlTest::setBufferSizes() { - std::vector cmd{ - kCommandHciReadBufferSize, - kCommandHciReadBufferSize + sizeof(kCommandHciReadBufferSize)}; + std::vector cmd; + ::bluetooth::packet::BitInserter bi{cmd}; + ::bluetooth::hci::ReadBufferSizeBuilder::Create()->Serialize(bi); hci->sendHciCommand(cmd); ASSERT_NO_FATAL_FAILURE(wait_for_event()); - if (event_queue.empty()) { - return; - } std::vector event; ASSERT_TRUE(event_queue.pop(event)); + auto complete_view = ::bluetooth::hci::ReadBufferSizeCompleteView::Create( + ::bluetooth::hci::CommandCompleteView::Create( + ::bluetooth::hci::EventView::Create( + ::bluetooth::hci::PacketView( + std::make_shared>(event))))); - ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]); - ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]); - ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]); - ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]); - - max_acl_data_packet_length = - event[kEventCommandCompleteStatusByte + 1] + - (event[kEventCommandCompleteStatusByte + 2] << 8); - max_sco_data_packet_length = event[kEventCommandCompleteStatusByte + 3]; - max_acl_data_packets = event[kEventCommandCompleteStatusByte + 4] + - (event[kEventCommandCompleteStatusByte + 5] << 8); - max_sco_data_packets = event[kEventCommandCompleteStatusByte + 6] + - (event[kEventCommandCompleteStatusByte + 7] << 8); + ASSERT_TRUE(complete_view.IsValid()); + ASSERT_EQ(complete_view.GetStatus(), ::bluetooth::hci::ErrorCode::SUCCESS); + max_acl_data_packet_length = complete_view.GetAclDataPacketLength(); + max_sco_data_packet_length = complete_view.GetSynchronousDataPacketLength(); + max_acl_data_packets = complete_view.GetTotalNumAclDataPackets(); + max_sco_data_packets = complete_view.GetTotalNumSynchronousDataPackets(); ALOGD("%s: ACL max %d num %d SCO max %d num %d", __func__, static_cast(max_acl_data_packet_length), @@ -459,39 +418,39 @@ void BluetoothAidlTest::setBufferSizes() { // Enable flow control packets for SCO void BluetoothAidlTest::setSynchronousFlowControlEnable() { - std::vector cmd{kCommandHciSynchronousFlowControlEnable, - kCommandHciSynchronousFlowControlEnable + - sizeof(kCommandHciSynchronousFlowControlEnable)}; + std::vector cmd; + ::bluetooth::packet::BitInserter bi{cmd}; + ::bluetooth::hci::WriteSynchronousFlowControlEnableBuilder::Create( + ::bluetooth::hci::Enable::ENABLED) + ->Serialize(bi); hci->sendHciCommand(cmd); - wait_for_command_complete_event(cmd); + wait_for_command_complete_event( + ::bluetooth::hci::OpCode::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE); } // Send an HCI command (in Loopback mode) and check the response. void BluetoothAidlTest::sendAndCheckHci(int num_packets) { ThroughputLogger logger = {__func__}; int command_size = 0; + char new_name[] = "John Jacob Jingleheimer Schmidt ___________________"; + size_t new_name_length = strlen(new_name); for (int n = 0; n < num_packets; n++) { - // Send an HCI packet - std::vector write_name{ - kCommandHciWriteLocalName, - kCommandHciWriteLocalName + sizeof(kCommandHciWriteLocalName)}; - // With a name - char new_name[] = "John Jacob Jingleheimer Schmidt ___________________0"; - size_t new_name_length = strlen(new_name); + // The name to set is new_name + std::array name_array; for (size_t i = 0; i < new_name_length; i++) { - write_name.push_back(static_cast(new_name[i])); + name_array[i] = new_name[i]; } // And the packet number - size_t i = new_name_length - 1; - for (int digits = n; digits > 0; digits = digits / 10, i--) { - write_name[i] = static_cast('0' + digits % 10); + char number[11] = "0000000000"; + snprintf(number, sizeof(number), "%010d", static_cast(n)); + for (size_t i = new_name_length; i < new_name_length + sizeof(number) - 1; + i++) { + name_array[new_name_length + i] = number[i]; } - // And padding - for (size_t i = 0; i < 248 - new_name_length; i++) { - write_name.push_back(static_cast(0)); - } - + std::vector write_name; + ::bluetooth::packet::BitInserter bi{write_name}; + ::bluetooth::hci::WriteLocalNameBuilder::Create(name_array)->Serialize(bi); hci->sendHciCommand(write_name); // Check the loopback of the HCI packet @@ -499,28 +458,17 @@ void BluetoothAidlTest::sendAndCheckHci(int num_packets) { std::vector event; ASSERT_TRUE(event_queue.pop(event)); - - size_t compare_length = (write_name.size() > static_cast(0xff) - ? static_cast(0xff) - : write_name.size()); - ASSERT_GT(event.size(), compare_length + kEventFirstPayloadByte - 1); - - ASSERT_EQ(kEventLoopbackCommand, event[kEventCodeByte]); - ASSERT_EQ(compare_length, event[kEventLengthByte]); - - // Don't compare past the end of the event. - if (compare_length + kEventFirstPayloadByte > event.size()) { - compare_length = event.size() - kEventFirstPayloadByte; - ALOGE("Only comparing %d bytes", static_cast(compare_length)); - } + auto event_view = ::bluetooth::hci::LoopbackCommandView::Create( + ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView( + std::make_shared>(event)))); + ASSERT_TRUE(event_view.IsValid()); + std::vector looped_back_command{event_view.GetPayload().begin(), + event_view.GetPayload().end()}; + ASSERT_EQ(looped_back_command, write_name); if (n == num_packets - 1) { command_size = write_name.size(); } - - for (size_t i = 0; i < compare_length; i++) { - ASSERT_EQ(write_name[i], event[kEventFirstPayloadByte + i]); - } } logger.setTotalBytes(command_size * num_packets * 2); } @@ -532,12 +480,14 @@ void BluetoothAidlTest::sendAndCheckSco(int num_packets, size_t size, for (int n = 0; n < num_packets; n++) { // Send a SCO packet std::vector sco_packet; - sco_packet.push_back(static_cast(handle & 0xff)); - sco_packet.push_back(static_cast((handle & 0x0f00) >> 8)); - sco_packet.push_back(static_cast(size & 0xff)); + std::vector payload; for (size_t i = 0; i < size; i++) { - sco_packet.push_back(static_cast(i + n)); + payload.push_back(static_cast(i + n)); } + ::bluetooth::packet::BitInserter bi{sco_packet}; + ::bluetooth::hci::ScoBuilder::Create( + handle, ::bluetooth::hci::PacketStatusFlag::CORRECTLY_RECEIVED, payload) + ->Serialize(bi); hci->sendScoData(sco_packet); // Check the loopback of the SCO packet @@ -545,21 +495,7 @@ void BluetoothAidlTest::sendAndCheckSco(int num_packets, size_t size, ASSERT_TRUE( sco_queue.tryPopWithTimeout(sco_loopback, kWaitForScoDataTimeout)); - ASSERT_EQ(sco_packet.size(), sco_loopback.size()); - size_t successful_bytes = 0; - - for (size_t i = 0; i < sco_packet.size(); i++) { - if (sco_packet[i] == sco_loopback[i]) { - successful_bytes = i; - } else { - ALOGE("Miscompare at %d (expected %x, got %x)", static_cast(i), - sco_packet[i], sco_loopback[i]); - ALOGE("At %d (expected %x, got %x)", static_cast(i + 1), - sco_packet[i + 1], sco_loopback[i + 1]); - break; - } - } - ASSERT_EQ(sco_packet.size(), successful_bytes + 1); + ASSERT_EQ(sco_packet, sco_loopback); } logger.setTotalBytes(num_packets * size * 2); } @@ -569,17 +505,18 @@ void BluetoothAidlTest::sendAndCheckAcl(int num_packets, size_t size, uint16_t handle) { ThroughputLogger logger = {__func__}; for (int n = 0; n < num_packets; n++) { - // Send an ACL packet - std::vector acl_packet; - acl_packet.push_back(static_cast(handle & 0xff)); - acl_packet.push_back(static_cast((handle & 0x0f00) >> 8) | - kAclBroadcastPointToPoint | - kAclPacketBoundaryFirstAutoFlushable); - acl_packet.push_back(static_cast(size & 0xff)); - acl_packet.push_back(static_cast((size & 0xff00) >> 8)); + // Send an ACL packet with counting data + auto payload = std::make_unique<::bluetooth::packet::RawBuilder>(); for (size_t i = 0; i < size; i++) { - acl_packet.push_back(static_cast(i + n)); + payload->AddOctets1(static_cast(i + n)); } + std::vector acl_packet; + ::bluetooth::packet::BitInserter bi{acl_packet}; + ::bluetooth::hci::AclBuilder::Create( + handle, + ::bluetooth::hci::PacketBoundaryFlag::FIRST_AUTOMATICALLY_FLUSHABLE, + ::bluetooth::hci::BroadcastFlag::POINT_TO_POINT, std::move(payload)) + ->Serialize(bi); hci->sendAclData(acl_packet); std::vector acl_loopback; @@ -587,21 +524,7 @@ void BluetoothAidlTest::sendAndCheckAcl(int num_packets, size_t size, ASSERT_TRUE( acl_queue.tryPopWithTimeout(acl_loopback, kWaitForAclDataTimeout)); - ASSERT_EQ(acl_packet.size(), acl_loopback.size()); - size_t successful_bytes = 0; - - for (size_t i = 0; i < acl_packet.size(); i++) { - if (acl_packet[i] == acl_loopback[i]) { - successful_bytes = i; - } else { - ALOGE("Miscompare at %d (expected %x, got %x)", static_cast(i), - acl_packet[i], acl_loopback[i]); - ALOGE("At %d (expected %x, got %x)", static_cast(i + 1), - acl_packet[i + 1], acl_loopback[i + 1]); - break; - } - } - ASSERT_EQ(acl_packet.size(), successful_bytes + 1); + ASSERT_EQ(acl_packet, acl_loopback); } logger.setTotalBytes(num_packets * size * 2); } @@ -620,23 +543,29 @@ int BluetoothAidlTest::wait_for_completed_packets_event(uint16_t handle) { } std::vector event; EXPECT_TRUE(event_queue.pop(event)); - - EXPECT_EQ(kEventNumberOfCompletedPackets, event[kEventCodeByte]); - EXPECT_EQ(1, event[kEventNumberOfCompletedPacketsNumHandles]); - - uint16_t event_handle = event[3] + (event[4] << 8); - EXPECT_EQ(handle, event_handle); - - packets_processed += event[5] + (event[6] << 8); + auto event_view = ::bluetooth::hci::NumberOfCompletedPacketsView::Create( + ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView( + std::make_shared>(event)))); + if (!event_view.IsValid()) { + ADD_FAILURE(); + return packets_processed; + } + auto completed_packets = event_view.GetCompletedPackets(); + for (const auto entry : completed_packets) { + EXPECT_EQ(handle, entry.connection_handle_); + packets_processed += entry.host_num_of_completed_packets_; + } } return packets_processed; } // Send local loopback command and initialize SCO and ACL handles. void BluetoothAidlTest::enterLoopbackMode() { - std::vector cmd{kCommandHciWriteLoopbackModeLocal, - kCommandHciWriteLoopbackModeLocal + - sizeof(kCommandHciWriteLoopbackModeLocal)}; + std::vector cmd; + ::bluetooth::packet::BitInserter bi{cmd}; + ::bluetooth::hci::WriteLoopbackModeBuilder::Create( + bluetooth::hci::LoopbackMode::ENABLE_LOCAL) + ->Serialize(bi); hci->sendHciCommand(cmd); // Receive connection complete events with data channels @@ -652,34 +581,35 @@ void BluetoothAidlTest::enterLoopbackMode() { } std::vector event; ASSERT_TRUE(event_queue.pop(event)); - ASSERT_GT(event.size(), - static_cast(kEventCommandCompleteStatusByte)); - if (event[kEventCodeByte] == kEventConnectionComplete) { - ASSERT_GT(event.size(), - static_cast(kEventConnectionCompleteType)); - ASSERT_EQ(event[kEventLengthByte], kEventConnectionCompleteParamLength); - uint8_t connection_type = event[kEventConnectionCompleteType]; + auto event_view = + ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView( + std::make_shared>(event))); + ASSERT_TRUE(event_view.IsValid()); - ASSERT_TRUE(connection_type == kEventConnectionCompleteTypeSco || - connection_type == kEventConnectionCompleteTypeAcl); - - // Save handles - uint16_t handle = event[kEventConnectionCompleteHandleLsByte] | - event[kEventConnectionCompleteHandleLsByte + 1] << 8; - if (connection_type == kEventConnectionCompleteTypeSco) { - sco_connection_handles.push_back(handle); - } else { - acl_connection_handles.push_back(handle); + if (event_view.GetEventCode() == + ::bluetooth::hci::EventCode::CONNECTION_COMPLETE) { + auto complete_view = + ::bluetooth::hci::ConnectionCompleteView::Create(event_view); + ASSERT_TRUE(complete_view.IsValid()); + switch (complete_view.GetLinkType()) { + case ::bluetooth::hci::LinkType::ACL: + acl_connection_handles.push_back(complete_view.GetConnectionHandle()); + break; + case ::bluetooth::hci::LinkType::SCO: + sco_connection_handles.push_back(complete_view.GetConnectionHandle()); + break; + default: + ASSERT_EQ(complete_view.GetLinkType(), + ::bluetooth::hci::LinkType::ACL); } - - ALOGD("Connect complete type = %d handle = %d", - event[kEventConnectionCompleteType], handle); connection_event_count++; } else { - ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]); - ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]); - ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]); - ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]); + auto command_complete_view = + ::bluetooth::hci::WriteLoopbackModeCompleteView::Create( + ::bluetooth::hci::CommandCompleteView::Create(event_view)); + ASSERT_TRUE(command_complete_view.IsValid()); + ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, + command_complete_view.GetStatus()); command_complete_received = true; } } @@ -690,59 +620,75 @@ TEST_P(BluetoothAidlTest, InitializeAndClose) {} // Send an HCI Reset with sendHciCommand and wait for a command complete event. TEST_P(BluetoothAidlTest, HciReset) { - std::vector reset{kCommandHciReset, - kCommandHciReset + sizeof(kCommandHciReset)}; + std::vector reset; + ::bluetooth::packet::BitInserter bi{reset}; + ::bluetooth::hci::ResetBuilder::Create()->Serialize(bi); hci->sendHciCommand(reset); - wait_for_command_complete_event(reset); + wait_for_command_complete_event(::bluetooth::hci::OpCode::RESET); } // Read and check the HCI version of the controller. TEST_P(BluetoothAidlTest, HciVersionTest) { - std::vector cmd{kCommandHciReadLocalVersionInformation, - kCommandHciReadLocalVersionInformation + - sizeof(kCommandHciReadLocalVersionInformation)}; + std::vector cmd; + ::bluetooth::packet::BitInserter bi{cmd}; + ::bluetooth::hci::ReadLocalVersionInformationBuilder::Create()->Serialize(bi); hci->sendHciCommand(cmd); ASSERT_NO_FATAL_FAILURE(wait_for_event()); std::vector event; ASSERT_TRUE(event_queue.pop(event)); - ASSERT_GT(event.size(), static_cast(kEventLocalLmpVersionByte)); - - ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]); - ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]); - ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]); - ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]); - - ASSERT_LE(kHciMinimumHciVersion, event[kEventLocalHciVersionByte]); - ASSERT_LE(kHciMinimumLmpVersion, event[kEventLocalLmpVersionByte]); + auto complete_view = + ::bluetooth::hci::ReadLocalVersionInformationCompleteView::Create( + ::bluetooth::hci::CommandCompleteView::Create( + ::bluetooth::hci::EventView::Create( + ::bluetooth::hci::PacketView( + std::make_shared>(event))))); + ASSERT_TRUE(complete_view.IsValid()); + ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, complete_view.GetStatus()); + auto version = complete_view.GetLocalVersionInformation(); + ASSERT_LE(::bluetooth::hci::HciVersion::V_3_0, version.hci_version_); + ASSERT_LE(::bluetooth::hci::LmpVersion::V_3_0, version.lmp_version_); } // Send an unknown HCI command and wait for the error message. TEST_P(BluetoothAidlTest, HciUnknownCommand) { - std::vector cmd{ - kCommandHciShouldBeUnknown, - kCommandHciShouldBeUnknown + sizeof(kCommandHciShouldBeUnknown)}; + std::vector cmd; + ::bluetooth::packet::BitInserter bi{cmd}; + ::bluetooth::hci::CommandBuilder::Create( + static_cast<::bluetooth::hci::OpCode>(0x3cff), + std::make_unique<::bluetooth::packet::RawBuilder>()) + ->Serialize(bi); hci->sendHciCommand(cmd); ASSERT_NO_FATAL_FAILURE(wait_for_event()); std::vector event; ASSERT_TRUE(event_queue.pop(event)); + auto event_view = + ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView( + std::make_shared>(event))); + ASSERT_TRUE(event_view.IsValid()); - ASSERT_GT(event.size(), static_cast(kEventCommandCompleteStatusByte)); - if (event[kEventCodeByte] == kEventCommandComplete) { - ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]); - ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]); - ASSERT_EQ(kHciStatusUnknownHciCommand, - event[kEventCommandCompleteStatusByte]); - } else { - ASSERT_EQ(kEventCommandStatus, event[kEventCodeByte]); - ASSERT_EQ(cmd[0], event[kEventCommandStatusOpcodeLsByte]); - ASSERT_EQ(cmd[1], event[kEventCommandStatusOpcodeLsByte + 1]); - ASSERT_EQ(kHciStatusUnknownHciCommand, - event[kEventCommandStatusStatusByte]); + switch (event_view.GetEventCode()) { + case ::bluetooth::hci::EventCode::COMMAND_COMPLETE: { + auto command_complete = + ::bluetooth::hci::CommandCompleteView::Create(event_view); + ASSERT_TRUE(command_complete.IsValid()); + ASSERT_EQ(command_complete.GetPayload()[0], + static_cast( + ::bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND)); + } break; + case ::bluetooth::hci::EventCode::COMMAND_STATUS: { + auto command_status = + ::bluetooth::hci::CommandStatusView::Create(event_view); + ASSERT_TRUE(command_status.IsValid()); + ASSERT_EQ(command_status.GetStatus(), + ::bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND); + } break; + default: + ADD_FAILURE(); } } @@ -851,20 +797,22 @@ TEST_P(BluetoothAidlTest, LoopbackModeAclBandwidth) { // Set all bits in the event mask TEST_P(BluetoothAidlTest, SetEventMask) { - std::vector set_event_mask{ - 0x01, 0x0c, 0x08 /*parameter bytes*/, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff}; - hci->sendHciCommand({set_event_mask}); - wait_for_command_complete_event(set_event_mask); + std::vector cmd; + ::bluetooth::packet::BitInserter bi{cmd}; + uint64_t full_mask = UINT64_MAX; + ::bluetooth::hci::SetEventMaskBuilder::Create(full_mask)->Serialize(bi); + hci->sendHciCommand(cmd); + wait_for_command_complete_event(::bluetooth::hci::OpCode::SET_EVENT_MASK); } // Set all bits in the LE event mask TEST_P(BluetoothAidlTest, SetLeEventMask) { - std::vector set_event_mask{ - 0x20, 0x0c, 0x08 /*parameter bytes*/, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff}; - hci->sendHciCommand({set_event_mask}); - wait_for_command_complete_event(set_event_mask); + std::vector cmd; + ::bluetooth::packet::BitInserter bi{cmd}; + uint64_t full_mask = UINT64_MAX; + ::bluetooth::hci::LeSetEventMaskBuilder::Create(full_mask)->Serialize(bi); + hci->sendHciCommand(cmd); + wait_for_command_complete_event(::bluetooth::hci::OpCode::LE_SET_EVENT_MASK); } // Call initialize twice, second one should fail. From dbceaca8e1335ff1c549d5f53ac0eec5ab2be331 Mon Sep 17 00:00:00 2001 From: Jack He Date: Mon, 27 Mar 2023 18:06:38 -0700 Subject: [PATCH 2/3] Fix clang-tidy errors Bug: 263257831 Test: vts Change-Id: I235ca85f9c1c84ab0a929572221020bfd568a2b0 --- .../aidl/vts/VtsHalBluetoothTargetTest.cpp | 79 +++++++++++-------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp index 43cb914d80..7f89853b44 100644 --- a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp +++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp @@ -24,15 +24,14 @@ #include #include #include -#include #include #include #include #include -#include #include #include +#include #include // TODO: Remove custom logging defines from PDL packets. @@ -63,9 +62,9 @@ static constexpr uint16_t kAclHandleQcaDebugMessage = 0xedc; class ThroughputLogger { public: - ThroughputLogger(std::string task) + explicit ThroughputLogger(std::string task) : total_bytes_(0), - task_(task), + task_(std::move(task)), start_time_(std::chrono::steady_clock::now()) {} ~ThroughputLogger() { @@ -94,7 +93,7 @@ class ThroughputLogger { // The main test class for Bluetooth HAL. class BluetoothAidlTest : public ::testing::TestWithParam { public: - virtual void SetUp() override { + void SetUp() override { // currently test passthrough mode only hci = IBluetoothHci::fromBinder( SpAIBinder(AServiceManager_waitForService(GetParam().c_str()))); @@ -110,7 +109,7 @@ class BluetoothAidlTest : public ::testing::TestWithParam { ASSERT_NE(bluetooth_hci_death_recipient, nullptr); ASSERT_EQ(STATUS_OK, AIBinder_linkToDeath(hci->asBinder().get(), - bluetooth_hci_death_recipient, 0)); + bluetooth_hci_death_recipient, nullptr)); hci_cb = ndk::SharedRefBase::make(*this); ASSERT_NE(hci_cb, nullptr); @@ -131,7 +130,7 @@ class BluetoothAidlTest : public ::testing::TestWithParam { ASSERT_TRUE(future.get()); } - virtual void TearDown() override { + void TearDown() override { ALOGI("TearDown"); // Should not be checked in production code ASSERT_TRUE(hci->close().isOk()); @@ -166,36 +165,41 @@ class BluetoothAidlTest : public ::testing::TestWithParam { BluetoothAidlTest& parent_; public: - BluetoothHciCallbacks(BluetoothAidlTest& parent) : parent_(parent){}; + explicit BluetoothHciCallbacks(BluetoothAidlTest& parent) + : parent_(parent){}; - virtual ~BluetoothHciCallbacks() = default; + ~BluetoothHciCallbacks() override = default; - ndk::ScopedAStatus initializationComplete(Status status) { + ndk::ScopedAStatus initializationComplete(Status status) override { parent_.initialized_promise.set_value(status == Status::SUCCESS); ALOGV("%s (status = %d)", __func__, static_cast(status)); return ScopedAStatus::ok(); }; - ndk::ScopedAStatus hciEventReceived(const std::vector& event) { + ndk::ScopedAStatus hciEventReceived( + const std::vector& event) override { parent_.event_cb_count++; parent_.event_queue.push(event); ALOGV("Event received (length = %d)", static_cast(event.size())); return ScopedAStatus::ok(); }; - ndk::ScopedAStatus aclDataReceived(const std::vector& data) { + ndk::ScopedAStatus aclDataReceived( + const std::vector& data) override { parent_.acl_cb_count++; parent_.acl_queue.push(data); return ScopedAStatus::ok(); }; - ndk::ScopedAStatus scoDataReceived(const std::vector& data) { + ndk::ScopedAStatus scoDataReceived( + const std::vector& data) override { parent_.sco_cb_count++; parent_.sco_queue.push(data); return ScopedAStatus::ok(); }; - ndk::ScopedAStatus isoDataReceived(const std::vector& data) { + ndk::ScopedAStatus isoDataReceived( + const std::vector& data) override { parent_.iso_cb_count++; parent_.iso_queue.push(data); return ScopedAStatus::ok(); @@ -205,7 +209,8 @@ class BluetoothAidlTest : public ::testing::TestWithParam { template class WaitQueue { public: - WaitQueue(){}; + WaitQueue() = default; + ; virtual ~WaitQueue() = default; @@ -289,22 +294,22 @@ class BluetoothAidlTest : public ::testing::TestWithParam { std::shared_ptr hci; std::shared_ptr hci_cb; - AIBinder_DeathRecipient* bluetooth_hci_death_recipient; + AIBinder_DeathRecipient* bluetooth_hci_death_recipient{}; WaitQueue> event_queue; WaitQueue> acl_queue; WaitQueue> sco_queue; WaitQueue> iso_queue; std::promise initialized_promise; - int event_cb_count; - int sco_cb_count; - int acl_cb_count; - int iso_cb_count; + int event_cb_count{}; + int sco_cb_count{}; + int acl_cb_count{}; + int iso_cb_count{}; - int max_acl_data_packet_length; - int max_sco_data_packet_length; - int max_acl_data_packets; - int max_sco_data_packets; + int max_acl_data_packet_length{}; + int max_sco_data_packet_length{}; + int max_acl_data_packets{}; + int max_sco_data_packets{}; std::vector sco_connection_handles; std::vector acl_connection_handles; @@ -431,13 +436,13 @@ void BluetoothAidlTest::setSynchronousFlowControlEnable() { // Send an HCI command (in Loopback mode) and check the response. void BluetoothAidlTest::sendAndCheckHci(int num_packets) { - ThroughputLogger logger = {__func__}; - int command_size = 0; + ThroughputLogger logger{__func__}; + size_t command_size = 0; char new_name[] = "John Jacob Jingleheimer Schmidt ___________________"; size_t new_name_length = strlen(new_name); for (int n = 0; n < num_packets; n++) { // The name to set is new_name - std::array name_array; + std::array name_array{}; for (size_t i = 0; i < new_name_length; i++) { name_array[i] = new_name[i]; } @@ -476,7 +481,7 @@ void BluetoothAidlTest::sendAndCheckHci(int num_packets) { // Send a SCO data packet (in Loopback mode) and check the response. void BluetoothAidlTest::sendAndCheckSco(int num_packets, size_t size, uint16_t handle) { - ThroughputLogger logger = {__func__}; + ThroughputLogger logger{__func__}; for (int n = 0; n < num_packets; n++) { // Send a SCO packet std::vector sco_packet; @@ -503,7 +508,7 @@ void BluetoothAidlTest::sendAndCheckSco(int num_packets, size_t size, // Send an ACL data packet (in Loopback mode) and check the response. void BluetoothAidlTest::sendAndCheckAcl(int num_packets, size_t size, uint16_t handle) { - ThroughputLogger logger = {__func__}; + ThroughputLogger logger{__func__}; for (int n = 0; n < num_packets; n++) { // Send an ACL packet with counting data auto payload = std::make_unique<::bluetooth::packet::RawBuilder>(); @@ -551,7 +556,7 @@ int BluetoothAidlTest::wait_for_completed_packets_event(uint16_t handle) { return packets_processed; } auto completed_packets = event_view.GetCompletedPackets(); - for (const auto entry : completed_packets) { + for (const auto& entry : completed_packets) { EXPECT_EQ(handle, entry.connection_handle_); packets_processed += entry.host_num_of_completed_packets_; } @@ -820,28 +825,32 @@ TEST_P(BluetoothAidlTest, CallInitializeTwice) { class SecondCb : public aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks { public: - ndk::ScopedAStatus initializationComplete(Status status) { + ndk::ScopedAStatus initializationComplete(Status status) override { EXPECT_EQ(status, Status::ALREADY_INITIALIZED); init_promise.set_value(); return ScopedAStatus::ok(); }; - ndk::ScopedAStatus hciEventReceived(const std::vector& /*event*/) { + ndk::ScopedAStatus hciEventReceived( + const std::vector& /*event*/) override { ADD_FAILURE(); return ScopedAStatus::ok(); }; - ndk::ScopedAStatus aclDataReceived(const std::vector& /*data*/) { + ndk::ScopedAStatus aclDataReceived( + const std::vector& /*data*/) override { ADD_FAILURE(); return ScopedAStatus::ok(); }; - ndk::ScopedAStatus scoDataReceived(const std::vector& /*data*/) { + ndk::ScopedAStatus scoDataReceived( + const std::vector& /*data*/) override { ADD_FAILURE(); return ScopedAStatus::ok(); }; - ndk::ScopedAStatus isoDataReceived(const std::vector& /*data*/) { + ndk::ScopedAStatus isoDataReceived( + const std::vector& /*data*/) override { ADD_FAILURE(); return ScopedAStatus::ok(); }; From 2d2f3c272d8962bfcc97b874d9403ee5f15dd908 Mon Sep 17 00:00:00 2001 From: Jack He Date: Mon, 27 Mar 2023 03:04:52 -0700 Subject: [PATCH 3/3] VTS: Add VSR requirement tests to VTS * Enforce that LMP version must be greater than or equal to HCI version * Enforce that minimum advertising set is 16 when HCI version is 5.0 and above * Enforce Link Layer Security, 2M Phy, Coded PHY requirements at BT 5 * Enforce minimum 8 resolving list entries at BT 5 Bug: 263257831 Test: vts Change-Id: I53a6713563c0b9a5ba27eecf2a69caff0a57f30b --- bluetooth/aidl/TEST_MAPPING | 8 +- .../aidl/vts/VtsHalBluetoothTargetTest.cpp | 130 ++++++++++++++++-- 2 files changed, 126 insertions(+), 12 deletions(-) diff --git a/bluetooth/aidl/TEST_MAPPING b/bluetooth/aidl/TEST_MAPPING index 342a1e45ad..f059c04ed2 100644 --- a/bluetooth/aidl/TEST_MAPPING +++ b/bluetooth/aidl/TEST_MAPPING @@ -1,7 +1,13 @@ { "presubmit" : [ { - "name" : "VtsHalBluetoothTargetTest" + "name" : "VtsHalBluetoothTargetTest", + "options": [ + { + // TODO(b/275847929) + "exclude-filter": "VtsHalBluetoothTargetTest.PerInstance/BluetoothAidlTest#Cdd_C_12_1_Bluetooth5Requirements/0_android_hardware_bluetooth_IBluetoothHci_default" + } + ] } ] } diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp index 7f89853b44..529e092dc7 100644 --- a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp +++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp @@ -48,6 +48,27 @@ using aidl::android::hardware::bluetooth::Status; using ndk::ScopedAStatus; using ndk::SpAIBinder; +using ::bluetooth::hci::CommandBuilder; +using ::bluetooth::hci::CommandCompleteView; +using ::bluetooth::hci::CommandView; +using ::bluetooth::hci::ErrorCode; +using ::bluetooth::hci::EventView; +using ::bluetooth::hci::LeReadLocalSupportedFeaturesBuilder; +using ::bluetooth::hci::LeReadLocalSupportedFeaturesCompleteView; +using ::bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsBuilder; +using ::bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsCompleteView; +using ::bluetooth::hci::LeReadResolvingListSizeBuilder; +using ::bluetooth::hci::LeReadResolvingListSizeCompleteView; +using ::bluetooth::hci::LLFeaturesBits; +using ::bluetooth::hci::OpCode; +using ::bluetooth::hci::OpCodeText; +using ::bluetooth::hci::PacketView; +using ::bluetooth::hci::ReadLocalVersionInformationBuilder; +using ::bluetooth::hci::ReadLocalVersionInformationCompleteView; + +static constexpr uint8_t kMinLeAdvSetForBt5 = 16; +static constexpr uint8_t kMinLeResolvingListForBt5 = 8; + static constexpr size_t kNumHciCommandsBandwidth = 100; static constexpr size_t kNumScoPacketsBandwidth = 100; static constexpr size_t kNumAclPacketsBandwidth = 100; @@ -156,8 +177,14 @@ class BluetoothAidlTest : public ::testing::TestWithParam { void handle_no_ops(); void discard_qca_debugging(); void wait_for_event(bool timeout_is_error); - void wait_for_command_complete_event(::bluetooth::hci::OpCode opCode); + void wait_for_command_complete_event(OpCode opCode, + std::vector& complete_event); + // Wait until a command complete is received. + // Command complete will be consumed after this method + void wait_and_validate_command_complete_event(OpCode opCode); int wait_for_completed_packets_event(uint16_t handle); + void send_and_wait_for_cmd_complete(std::unique_ptr cmd, + std::vector& cmd_complete); // A simple test implementation of BluetoothHciCallbacks. class BluetoothHciCallbacks @@ -180,7 +207,7 @@ class BluetoothAidlTest : public ::testing::TestWithParam { const std::vector& event) override { parent_.event_cb_count++; parent_.event_queue.push(event); - ALOGV("Event received (length = %d)", static_cast(event.size())); + ALOGI("Event received (length = %d)", static_cast(event.size())); return ScopedAStatus::ok(); }; @@ -375,22 +402,27 @@ void BluetoothAidlTest::wait_for_event(bool timeout_is_error = true) { } } -// Wait until a command complete is received. void BluetoothAidlTest::wait_for_command_complete_event( - ::bluetooth::hci::OpCode opCode) { + OpCode opCode, std::vector& complete_event) { ASSERT_NO_FATAL_FAILURE(wait_for_event()); - std::vector event; ASSERT_FALSE(event_queue.empty()); - ASSERT_TRUE(event_queue.pop(event)); + ASSERT_TRUE(event_queue.pop(complete_event)); auto complete_view = ::bluetooth::hci::CommandCompleteView::Create( ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView( - std::make_shared>(event)))); + std::make_shared>(complete_event)))); ASSERT_TRUE(complete_view.IsValid()); ASSERT_EQ(complete_view.GetCommandOpCode(), opCode); ASSERT_EQ(complete_view.GetPayload()[0], static_cast(::bluetooth::hci::ErrorCode::SUCCESS)); } +void BluetoothAidlTest::wait_and_validate_command_complete_event( + ::bluetooth::hci::OpCode opCode) { + std::vector complete_event; + ASSERT_NO_FATAL_FAILURE( + wait_for_command_complete_event(opCode, complete_event)); +} + // Send the command to read the controller's buffer sizes. void BluetoothAidlTest::setBufferSizes() { std::vector cmd; @@ -430,7 +462,7 @@ void BluetoothAidlTest::setSynchronousFlowControlEnable() { ->Serialize(bi); hci->sendHciCommand(cmd); - wait_for_command_complete_event( + wait_and_validate_command_complete_event( ::bluetooth::hci::OpCode::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE); } @@ -620,6 +652,20 @@ void BluetoothAidlTest::enterLoopbackMode() { } } +void BluetoothAidlTest::send_and_wait_for_cmd_complete( + std::unique_ptr cmd, std::vector& cmd_complete) { + std::vector cmd_bytes = cmd->SerializeToBytes(); + hci->sendHciCommand(cmd_bytes); + + auto view = CommandView::Create( + PacketView(std::make_shared>(cmd_bytes))); + ASSERT_TRUE(view.IsValid()); + ALOGI("Waiting for %s[0x%x]", OpCodeText(view.GetOpCode()).c_str(), + static_cast(view.GetOpCode())); + ASSERT_NO_FATAL_FAILURE( + wait_for_command_complete_event(view.GetOpCode(), cmd_complete)); +} + // Empty test: Initialize()/Close() are called in SetUp()/TearDown(). TEST_P(BluetoothAidlTest, InitializeAndClose) {} @@ -630,7 +676,7 @@ TEST_P(BluetoothAidlTest, HciReset) { ::bluetooth::hci::ResetBuilder::Create()->Serialize(bi); hci->sendHciCommand(reset); - wait_for_command_complete_event(::bluetooth::hci::OpCode::RESET); + wait_and_validate_command_complete_event(::bluetooth::hci::OpCode::RESET); } // Read and check the HCI version of the controller. @@ -807,7 +853,8 @@ TEST_P(BluetoothAidlTest, SetEventMask) { uint64_t full_mask = UINT64_MAX; ::bluetooth::hci::SetEventMaskBuilder::Create(full_mask)->Serialize(bi); hci->sendHciCommand(cmd); - wait_for_command_complete_event(::bluetooth::hci::OpCode::SET_EVENT_MASK); + wait_and_validate_command_complete_event( + ::bluetooth::hci::OpCode::SET_EVENT_MASK); } // Set all bits in the LE event mask @@ -817,7 +864,8 @@ TEST_P(BluetoothAidlTest, SetLeEventMask) { uint64_t full_mask = UINT64_MAX; ::bluetooth::hci::LeSetEventMaskBuilder::Create(full_mask)->Serialize(bi); hci->sendHciCommand(cmd); - wait_for_command_complete_event(::bluetooth::hci::OpCode::LE_SET_EVENT_MASK); + wait_and_validate_command_complete_event( + ::bluetooth::hci::OpCode::LE_SET_EVENT_MASK); } // Call initialize twice, second one should fail. @@ -866,6 +914,66 @@ TEST_P(BluetoothAidlTest, CallInitializeTwice) { ASSERT_EQ(status, std::future_status::ready); } +TEST_P(BluetoothAidlTest, Cdd_C_12_1_Bluetooth5Requirements) { + std::vector version_event; + send_and_wait_for_cmd_complete(ReadLocalVersionInformationBuilder::Create(), + version_event); + auto version_view = ReadLocalVersionInformationCompleteView::Create( + CommandCompleteView::Create(EventView::Create(PacketView( + std::make_shared>(version_event))))); + ASSERT_TRUE(version_view.IsValid()); + ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, version_view.GetStatus()); + auto version = version_view.GetLocalVersionInformation(); + if (version.hci_version_ < ::bluetooth::hci::HciVersion::V_5_0) { + // This test does not apply to controllers below 5.0 + return; + }; + // When HCI version is 5.0, LMP version must also be at least 5.0 + ASSERT_GE(static_cast(version.lmp_version_), + static_cast(version.hci_version_)); + + std::vector le_features_event; + send_and_wait_for_cmd_complete(LeReadLocalSupportedFeaturesBuilder::Create(), + le_features_event); + auto le_features_view = LeReadLocalSupportedFeaturesCompleteView::Create( + CommandCompleteView::Create(EventView::Create(PacketView( + std::make_shared>(le_features_event))))); + ASSERT_TRUE(le_features_view.IsValid()); + ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, le_features_view.GetStatus()); + auto le_features = le_features_view.GetLeFeatures(); + ASSERT_TRUE(le_features & static_cast(LLFeaturesBits::LL_PRIVACY)); + ASSERT_TRUE(le_features & static_cast(LLFeaturesBits::LE_2M_PHY)); + ASSERT_TRUE(le_features & + static_cast(LLFeaturesBits::LE_CODED_PHY)); + ASSERT_TRUE(le_features & + static_cast(LLFeaturesBits::LE_EXTENDED_ADVERTISING)); + + std::vector num_adv_set_event; + send_and_wait_for_cmd_complete( + LeReadNumberOfSupportedAdvertisingSetsBuilder::Create(), + num_adv_set_event); + auto num_adv_set_view = + LeReadNumberOfSupportedAdvertisingSetsCompleteView::Create( + CommandCompleteView::Create(EventView::Create(PacketView( + std::make_shared>(num_adv_set_event))))); + ASSERT_TRUE(num_adv_set_view.IsValid()); + ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, num_adv_set_view.GetStatus()); + auto num_adv_set = num_adv_set_view.GetNumberSupportedAdvertisingSets(); + ASSERT_GE(num_adv_set, kMinLeAdvSetForBt5); + + std::vector num_resolving_list_event; + send_and_wait_for_cmd_complete(LeReadResolvingListSizeBuilder::Create(), + num_resolving_list_event); + auto num_resolving_list_view = LeReadResolvingListSizeCompleteView::Create( + CommandCompleteView::Create(EventView::Create(PacketView( + std::make_shared>(num_resolving_list_event))))); + ASSERT_TRUE(num_resolving_list_view.IsValid()); + ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, + num_resolving_list_view.GetStatus()); + auto num_resolving_list = num_resolving_list_view.GetResolvingListSize(); + ASSERT_GE(num_resolving_list, kMinLeResolvingListForBt5); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAidlTest); INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(