| /* |
| * Copyright 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "hal/snoop_logger.h" |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| #include <netinet/in.h> |
| #include <sys/socket.h> |
| |
| #include <future> |
| #include <unordered_map> |
| |
| #include "common/init_flags.h" |
| #include "hal/snoop_logger_common.h" |
| #include "hal/syscall_wrapper_impl.h" |
| #include "os/fake_timer/fake_timerfd.h" |
| #include "os/system_properties.h" |
| #include "os/utils.h" |
| |
| namespace testing { |
| |
| using bluetooth::hal::SnoopLoggerCommon; |
| using bluetooth::hal::SnoopLoggerSocket; |
| using bluetooth::hal::SnoopLoggerSocketInterface; |
| using bluetooth::hal::SnoopLoggerSocketThread; |
| using bluetooth::hal::SyscallWrapperImpl; |
| using bluetooth::os::fake_timer::fake_timerfd_advance; |
| using bluetooth::os::fake_timer::fake_timerfd_reset; |
| |
| namespace { |
| std::vector<uint8_t> kInformationRequest = { |
| 0xfe, |
| 0x2e, |
| 0x0a, |
| 0x00, |
| 0x06, |
| 0x00, |
| 0x01, |
| 0x00, |
| 0x0a, |
| 0x02, |
| 0x02, |
| 0x00, |
| 0x02, |
| 0x00, |
| }; |
| |
| std::vector<uint8_t> kSdpConnectionRequest = { |
| 0x08, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x01, 0x00, 0x02, 0x0c, 0x04, 0x00, 0x01, 0x00, 0x44, 0x00}; |
| |
| std::vector<uint8_t> kAvdtpSuspend = {0x02, 0x02, 0x00, 0x07, 0x00, 0x03, 0x00, 0x8d, 0x00, 0x90, 0x09, 0x04}; |
| |
| std::vector<uint8_t> kHfpAtNrec0 = {0x02, 0x02, 0x20, 0x13, 0x00, 0x0f, 0x00, 0x41, 0x00, 0x09, 0xff, 0x15, |
| 0x01, 0x41, 0x54, 0x2b, 0x4e, 0x52, 0x45, 0x43, 0x3d, 0x30, 0x0d, 0x5c}; |
| |
| std::vector<uint8_t> kQualcommConnectionRequest = {0xdc, 0x2e, 0x54, 0x00, 0x50, 0x00, 0xff, 0x00, 0x00, 0x0a, |
| 0x0f, 0x09, 0x01, 0x00, 0x5c, 0x93, 0x01, 0x00, 0x42, 0x00}; |
| |
| std::vector<uint8_t> kA2dpMediaPacket = { |
| 0x0b, 0x20, 0x3a, 0x00, 0x36, 0x00, 0x40, 0xa0, 0x80, 0xe0, 0x07, 0x7f, 0x00, 0x1e, 0x08, 0x00, |
| 0x00, 0x00, 0x00, 0x02, 0x47, 0xfc, 0x00, 0x00, 0xb0, 0x90, 0x80, 0x03, 0x00, 0x20, 0x21, 0x11, |
| 0x45, 0x00, 0x14, 0x50, 0x01, 0x46, 0xf0, 0x81, 0x0a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, |
| 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e, |
| }; |
| |
| std::vector<bluetooth::hal::HciPacket> kTestData = { |
| {0x02, 0x20, 0x11, 0x00, 0x0d, 0x00, 0x41, 0x00, 0x9d, 0xef, 0x35, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| {0x02, 0x00, 0x12, 0x00, 0x0e, 0x00, 0x40, 0x00, 0x9f, 0xff, 0x3f, |
| 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| {0x02, 0x20, 0x11, 0x00, 0x0d, 0x00, 0x41, 0x00, 0x9d, 0xef, 0x85, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| {0x02, 0x00, 0x12, 0x00, 0x0e, 0x00, 0x40, 0x00, 0x9f, 0xff, 0x1f, |
| 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| {0x02, 0x20, 0x11, 0x00, 0x0d, 0x00, 0x41, 0x00, 0x9d, 0xef, 0x99, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| {0x02, 0x00, 0x13, 0x00, 0x0f, 0x00, 0x40, 0x00, 0x9f, 0xff, 0xc6, 0x01, |
| 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| {0x02, 0x20, 0x11, 0x00, 0x0d, 0x00, 0x41, 0x00, 0x9d, 0xef, 0x99, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| {0x02, 0x00, 0x12, 0x00, 0x0e, 0x00, 0x40, 0x00, 0x9f, 0xff, 0x1f, |
| 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| {0x02, 0x20, 0x12, 0x00, 0x0e, 0x00, 0x41, 0x00, 0x9d, 0xff, 0x01, |
| 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| {0x02, 0x00, 0x12, 0x00, 0x0e, 0x00, 0x40, 0x00, 0x9f, 0xff, 0x8f, |
| 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| {0x02, 0x20, 0x11, 0x00, 0x0d, 0x00, 0x41, 0x00, 0x9d, 0xef, 0x89, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| {0x02, 0x00, 0x12, 0x00, 0x0e, 0x00, 0x40, 0x00, 0x9f, 0xff, 0x1f, |
| 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| {0x02, 0x20, 0x11, 0x00, 0x0d, 0x00, 0x41, 0x00, 0x9d, 0xef, 0x43, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, |
| {0x02, 0x00, 0x12, 0x00, 0x0e, 0x00, 0x40, 0x00, 0x9f, 0xff, 0x11, |
| 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; |
| |
| } // namespace |
| |
| using bluetooth::TestModuleRegistry; |
| using bluetooth::hal::SnoopLogger; |
| using namespace std::chrono_literals; |
| |
| const char* test_flags[] = { |
| "INIT_logging_debug_enabled_for_all=true", |
| "INIT_gd_hal_snoop_logger_socket=true", |
| "INIT_gd_hal_snoop_logger_filtering=true", |
| nullptr, |
| }; |
| |
| // Expose protected constructor for test |
| class TestSnoopLoggerModule : public SnoopLogger { |
| public: |
| TestSnoopLoggerModule( |
| std::string snoop_log_path, |
| std::string snooz_log_path, |
| size_t max_packets_per_file, |
| const std::string& btsnoop_mode, |
| bool qualcomm_debug_log_enabled, |
| bool snoop_log_persists) |
| : SnoopLogger( |
| std::move(snoop_log_path), |
| std::move(snooz_log_path), |
| max_packets_per_file, |
| SnoopLogger::GetMaxPacketsPerBuffer(), |
| btsnoop_mode, |
| qualcomm_debug_log_enabled, |
| 20ms, |
| 5ms, |
| snoop_log_persists) {} |
| |
| std::string ToString() const override { |
| return std::string("TestSnoopLoggerModule"); |
| } |
| |
| void CallGetDumpsysData(flatbuffers::FlatBufferBuilder* builder) { |
| GetDumpsysData(builder); |
| } |
| |
| SnoopLoggerSocketThread* GetSocketThread() { |
| return snoop_logger_socket_thread_.get(); |
| } |
| |
| uint32_t GetL2capHeaderSize() { |
| return L2CAP_HEADER_SIZE; |
| } |
| |
| size_t GetMaxFilteredSize() { |
| return MAX_HCI_ACL_LEN - PACKET_TYPE_LENGTH; |
| } |
| }; |
| |
| class SnoopLoggerModuleTest : public Test { |
| public: |
| flatbuffers::FlatBufferBuilder* builder_; |
| TestModuleRegistry* test_registry; |
| |
| protected: |
| void SetUp() override { |
| temp_dir_ = std::filesystem::temp_directory_path(); |
| temp_snoop_log_ = temp_dir_ / "btsnoop_hci.log"; |
| temp_snoop_log_last_ = temp_dir_ / "btsnoop_hci.log.last"; |
| temp_snooz_log_ = temp_dir_ / "btsnooz_hci.log"; |
| temp_snooz_log_last_ = temp_dir_ / "btsnooz_hci.log.last"; |
| temp_snoop_log_filtered = temp_dir_ / "btsnoop_hci.log.filtered"; |
| temp_snoop_log_filtered_last = temp_dir_ / "btsnoop_hci.log.filtered.last"; |
| builder_ = new flatbuffers::FlatBufferBuilder(); |
| |
| DeleteSnoopLogFiles(); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_filtered)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_filtered_last)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_last_)); |
| |
| test_registry = new TestModuleRegistry(); |
| |
| bluetooth::common::InitFlags::Load(test_flags); |
| } |
| |
| void TearDown() override { |
| DeleteSnoopLogFiles(); |
| delete builder_; |
| fake_timerfd_reset(); |
| test_registry->StopAll(); |
| delete test_registry; |
| } |
| |
| void DeleteSnoopLogFiles() { |
| if (std::filesystem::exists(temp_snoop_log_)) { |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_)); |
| } |
| if (std::filesystem::exists(temp_snoop_log_last_)) { |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_last_)); |
| } |
| if (std::filesystem::exists(temp_snoop_log_filtered)) { |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered)); |
| } |
| if (std::filesystem::exists(temp_snoop_log_filtered_last)) { |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered_last)); |
| } |
| if (std::filesystem::exists(temp_snooz_log_)) { |
| ASSERT_TRUE(std::filesystem::remove(temp_snooz_log_)); |
| } |
| if (std::filesystem::exists(temp_snooz_log_last_)) { |
| ASSERT_TRUE(std::filesystem::remove(temp_snooz_log_last_)); |
| } |
| } |
| |
| std::filesystem::path temp_dir_; |
| std::filesystem::path temp_snoop_log_; |
| std::filesystem::path temp_snoop_log_last_; |
| std::filesystem::path temp_snooz_log_; |
| std::filesystem::path temp_snooz_log_last_; |
| std::filesystem::path temp_snoop_log_filtered; |
| std::filesystem::path temp_snoop_log_filtered_last; |
| }; |
| |
| TEST_F(SnoopLoggerModuleTest, empty_snoop_log_test) { |
| // Actual test |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFull, |
| false, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| test_registry->StopAll(); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_), sizeof(SnoopLoggerCommon::FileHeaderType)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, disable_snoop_log_test) { |
| // Actual test |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeDisabled, |
| false, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| test_registry->StopAll(); |
| |
| // Verify states after test |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, capture_one_packet_test) { |
| // Actual test |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFull, |
| false, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| snoop_logger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD); |
| |
| test_registry->StopAll(); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size()); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, capture_hci_cmd_btsnooz_test) { |
| // Actual test |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeDisabled, |
| false, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| snoop_logger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD); |
| snoop_logger->CallGetDumpsysData(builder_); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snooz_log_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size()); |
| |
| test_registry->StopAll(); |
| |
| // Verify states after test |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, capture_l2cap_signal_packet_btsnooz_test) { |
| // Actual test |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeDisabled, |
| false, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| snoop_logger->Capture(kSdpConnectionRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| snoop_logger->CallGetDumpsysData(builder_); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snooz_log_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kSdpConnectionRequest.size()); |
| |
| test_registry->StopAll(); |
| |
| // Verify states after test |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, capture_l2cap_short_data_packet_btsnooz_test) { |
| // Actual test |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeDisabled, |
| false, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| snoop_logger->Capture(kAvdtpSuspend, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| snoop_logger->CallGetDumpsysData(builder_); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snooz_log_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kAvdtpSuspend.size()); |
| |
| test_registry->StopAll(); |
| |
| // Verify states after test |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, capture_l2cap_long_data_packet_btsnooz_test) { |
| // Actual test |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeDisabled, |
| false, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| snoop_logger->Capture(kHfpAtNrec0, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| snoop_logger->CallGetDumpsysData(builder_); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snooz_log_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + 14); |
| |
| test_registry->StopAll(); |
| |
| // Verify states after test |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, snoop_log_persists) { |
| // Actual test |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeDisabled, |
| false, |
| true); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| snoop_logger->Capture( |
| kHfpAtNrec0, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| snoop_logger->CallGetDumpsysData(builder_); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snooz_log_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + 14); |
| |
| test_registry->StopAll(); |
| ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, delete_old_snooz_log_files) { |
| // Actual test |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeDisabled, |
| false, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| std::filesystem::create_directories(temp_snooz_log_); |
| |
| auto* handler = test_registry->GetTestModuleHandler(&SnoopLogger::Factory); |
| ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); |
| handler->Post(bluetooth::common::BindOnce(fake_timerfd_advance, 10)); |
| ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); |
| handler->Post(bluetooth::common::BindOnce(fake_timerfd_advance, 15)); |
| handler->Post(bluetooth::common::BindOnce( |
| [](std::filesystem::path path) { ASSERT_FALSE(std::filesystem::exists(path)); }, temp_snooz_log_)); |
| test_registry->StopAll(); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, rotate_file_at_new_session_test) { |
| // Start once |
| { |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFull, |
| false, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| snoop_logger->Capture( |
| kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD); |
| test_registry->StopAll(); |
| } |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size()); |
| |
| // Start again |
| { |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFull, |
| false, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| snoop_logger->Capture( |
| kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD); |
| snoop_logger->Capture( |
| kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD); |
| test_registry->StopAll(); |
| } |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + |
| (sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size()) * 2); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_last_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size()); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, rotate_file_after_full_test) { |
| // Actual test |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFull, |
| false, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| for (int i = 0; i < 11; i++) { |
| snoop_logger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD); |
| } |
| |
| test_registry->StopAll(); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + |
| (sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size()) * 1); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_last_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + |
| (sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size()) * 10); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, qualcomm_debug_log_test) { |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeDisabled, |
| true, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| snoop_logger->Capture( |
| kQualcommConnectionRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| snoop_logger->CallGetDumpsysData(builder_); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snooz_log_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + |
| kQualcommConnectionRequest.size()); |
| |
| test_registry->StopAll(); |
| |
| // Verify states after test |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, qualcomm_debug_log_regression_test) { |
| { |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeDisabled, |
| true, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| snoop_logger->Capture( |
| kHfpAtNrec0, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| snoop_logger->CallGetDumpsysData(builder_); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snooz_log_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + 14); |
| test_registry->StopAll(); |
| } |
| |
| // Verify states after test |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); |
| |
| { |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeDisabled, |
| false, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| snoop_logger->Capture( |
| kQualcommConnectionRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| snoop_logger->CallGetDumpsysData(builder_); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snooz_log_), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + 14); |
| test_registry->StopAll(); |
| } |
| |
| // Verify states after test |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); |
| ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, filter_tracker_test) { |
| std::unordered_map<uint16_t, bluetooth::hal::FilterTracker> filter_list; |
| uint16_t handle = 1; |
| uint16_t local_cid = 0x40; |
| uint16_t remote_cid = 0x41; |
| uint8_t dlci = 0x02; |
| |
| filter_list[handle].AddL2capCid(local_cid, remote_cid); |
| ASSERT_TRUE(filter_list[handle].IsAcceptlistedL2cap(true, local_cid)); |
| ASSERT_TRUE(filter_list[handle].IsAcceptlistedL2cap(false, remote_cid)); |
| |
| filter_list[handle].RemoveL2capCid(local_cid, remote_cid); |
| ASSERT_FALSE(filter_list[handle].IsAcceptlistedL2cap(true, local_cid)); |
| ASSERT_FALSE(filter_list[handle].IsAcceptlistedL2cap(false, remote_cid)); |
| |
| filter_list[handle].AddRfcommDlci(dlci); |
| ASSERT_TRUE(filter_list[handle].IsAcceptlistedDlci(dlci)); |
| |
| filter_list[handle].SetRfcommCid(local_cid, remote_cid); |
| ASSERT_TRUE(filter_list[handle].IsRfcommChannel(true, local_cid)); |
| ASSERT_TRUE(filter_list[handle].IsRfcommChannel(false, remote_cid)); |
| |
| filter_list[handle].RemoveL2capCid(local_cid, remote_cid); |
| ASSERT_FALSE(filter_list[handle].IsAcceptlistedL2cap(true, local_cid)); |
| ASSERT_FALSE(filter_list[handle].IsAcceptlistedL2cap(false, remote_cid)); |
| ASSERT_FALSE(filter_list[handle].IsAcceptlistedDlci(dlci)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, a2dp_packets_filtered_test) { |
| // Actual test |
| uint16_t conn_handle = 0x000b; |
| uint16_t local_cid = 0x0001; |
| uint16_t remote_cid = 0xa040; |
| |
| ASSERT_TRUE( |
| bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileA2dpProperty, "true")); |
| auto filter_a2dp_property = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileA2dpProperty); |
| ASSERT_TRUE(filter_a2dp_property && filter_a2dp_property.value() == "true"); |
| |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFiltered, |
| false, |
| false); |
| |
| TestModuleRegistry test_registry; |
| test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| // Simulate A2dp Media channel setup |
| snoop_logger->AddA2dpMediaChannel(conn_handle, local_cid, remote_cid); |
| |
| snoop_logger->Capture( |
| kA2dpMediaPacket, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| test_registry.StopAll(); |
| |
| ASSERT_TRUE( |
| bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileA2dpProperty, "false")); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| // Should filter packet |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_filtered), |
| sizeof(SnoopLoggerCommon::FileHeaderType)); |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, a2dp_packets_filtered_negative_test) { |
| // Actual test |
| uint16_t conn_handle = 0x000b; |
| uint16_t local_cid = 0x0001; |
| uint16_t remote_cid = 0xa040; |
| |
| ASSERT_TRUE( |
| bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileA2dpProperty, "true")); |
| auto filter_a2dp_property = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileA2dpProperty); |
| ASSERT_TRUE(filter_a2dp_property && filter_a2dp_property.value() == "true"); |
| |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFiltered, |
| false, |
| false); |
| |
| TestModuleRegistry test_registry; |
| test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| // Simulate A2dp Media channel setup |
| snoop_logger->AddA2dpMediaChannel(conn_handle, local_cid, remote_cid); |
| snoop_logger->RemoveA2dpMediaChannel(conn_handle, local_cid); |
| |
| snoop_logger->Capture( |
| kA2dpMediaPacket, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| test_registry.StopAll(); |
| |
| ASSERT_TRUE( |
| bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileA2dpProperty, "false")); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| // Should not filter |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_filtered), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + |
| kA2dpMediaPacket.size()); |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, headers_filtered_test) { |
| ASSERT_TRUE( |
| bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterHeadersProperty, "true")); |
| auto filter_headers_property = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterHeadersProperty); |
| ASSERT_TRUE(filter_headers_property && filter_headers_property.value() == "true"); |
| |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFiltered, |
| false, |
| false); |
| |
| TestModuleRegistry test_registry; |
| test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| std::vector<uint8_t> kAclPacket = { |
| 0x0b, 0x20, 0x18, 0x00, 0x14, 0x00, 0x44, 0x00, 0x1b, 0x2f, 0x21, 0x41, 0x54, 0x2b, |
| 0x43, 0x4d, 0x45, 0x52, 0x3d, 0x33, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x31, 0x0d, 0x8f, |
| }; |
| |
| snoop_logger->Capture(kAclPacket, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| test_registry.StopAll(); |
| |
| ASSERT_TRUE( |
| bluetooth::os::SetSystemProperty(SnoopLogger::kBtSnoopLogFilterHeadersProperty, "false")); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| LOG_INFO( |
| "const size: %d", |
| (int)(sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType))); |
| |
| // Packet should be filtered |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_filtered), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + |
| snoop_logger->GetMaxFilteredSize()); |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_sabme_ua_test) { |
| // Actual test |
| uint16_t conn_handle = 0x000b; |
| uint16_t local_cid = 0x0044; |
| uint16_t remote_cid = 0x3040; |
| |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty, "true")); |
| auto filter_rfcomm_property = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty); |
| ASSERT_TRUE(filter_rfcomm_property); |
| ASSERT_TRUE(filter_rfcomm_property.value() == "true"); |
| |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFiltered, |
| false, |
| false); |
| |
| TestModuleRegistry test_registry; |
| test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| // Simulate Rfcomm channel |
| snoop_logger->AddRfcommL2capChannel(conn_handle, local_cid, remote_cid); |
| std::vector<uint8_t> kRfcommSabme = { |
| 0x0b, 0x20, 0x18, 0x00, 0x14, 0x00, 0x44, 0x00, 0x1b, 0x2f, 0x21, 0x41, 0x54, 0x2b, |
| 0x43, 0x4d, 0x45, 0x52, 0x3d, 0x33, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x31, 0x0d, 0x8f, |
| }; |
| std::vector<uint8_t> kRfcommUa = { |
| 0x0b, 0x20, 0x18, 0x00, 0x14, 0x00, 0x44, 0x00, 0x1b, 0x63, 0x21, 0x41, 0x54, 0x2b, |
| 0x43, 0x4d, 0x45, 0x52, 0x3d, 0x33, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x31, 0x0d, 0x8f, |
| }; |
| |
| snoop_logger->Capture( |
| kRfcommSabme, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL); |
| snoop_logger->Capture(kRfcommUa, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL); |
| snoop_logger->ClearL2capAcceptlist(conn_handle, local_cid, remote_cid); |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| test_registry.StopAll(); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| // Packets should not be filtered because because they are SAMBE and UA events. |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_filtered), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + 2 * sizeof(SnoopLogger::PacketHeaderType) + |
| kRfcommSabme.size() + kRfcommUa.size()); |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_acceptlisted_dlci_test) { |
| // Actual test |
| uint16_t conn_handle = 0x000b; |
| uint16_t local_cid = 0x0041; |
| uint16_t remote_cid = 0x3040; |
| uint8_t dlci = 0x04; |
| uint8_t dlci_byte = dlci << 2; |
| |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty, "true")); |
| auto filter_rfcomm_property = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty); |
| ASSERT_TRUE(filter_rfcomm_property); |
| ASSERT_TRUE(filter_rfcomm_property.value() == "true"); |
| |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFiltered, |
| false, |
| false); |
| |
| TestModuleRegistry test_registry; |
| test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| // Simulate Rfcomm channel |
| snoop_logger->AddRfcommL2capChannel(conn_handle, local_cid, remote_cid); |
| snoop_logger->AcceptlistRfcommDlci(conn_handle, local_cid, dlci); |
| |
| std::vector<uint8_t> kRfcommDlci = { |
| 0x0b, 0x20, 0x12, 0x00, 0x0e, 0x00, 0x41, 0x00, dlci_byte, 0xef, 0x15, |
| 0x83, 0x11, 0x06, 0xf0, 0x07, 0x00, 0x9d, 0x02, 0x00, 0x07, 0x70, |
| }; |
| |
| snoop_logger->Capture( |
| kRfcommDlci, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL); |
| snoop_logger->ClearL2capAcceptlist(conn_handle, local_cid, remote_cid); |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| test_registry.StopAll(); |
| |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty, "false")); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| // Packet should not be filtered because DLCI acceptlisted |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_filtered), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + |
| kRfcommDlci.size()); |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_not_acceptlisted_dlci_test) { |
| // Actual test |
| uint16_t conn_handle = 0x000b; |
| uint16_t local_cid = 0x0041; |
| uint16_t remote_cid = 0x3040; |
| uint8_t dlci = 0x04; |
| uint8_t dlci_byte = dlci << 2; |
| |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty, "true")); |
| auto filter_rfcomm_property = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty); |
| ASSERT_TRUE(filter_rfcomm_property); |
| ASSERT_TRUE(filter_rfcomm_property.value() == "true"); |
| |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFiltered, |
| false, |
| false); |
| |
| TestModuleRegistry test_registry; |
| test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| // Simulate Rfcomm channel |
| snoop_logger->AddRfcommL2capChannel(conn_handle, local_cid, remote_cid); |
| |
| std::vector<uint8_t> kRfcommDlci = { |
| 0x0b, 0x20, 0x12, 0x00, 0x0e, 0x00, 0x41, 0x00, dlci_byte, 0xef, 0x15, |
| 0x83, 0x11, 0x06, 0xf0, 0x07, 0x00, 0x9d, 0x02, 0x00, 0x07, 0x70, |
| }; |
| |
| snoop_logger->Capture( |
| kRfcommDlci, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL); |
| snoop_logger->ClearL2capAcceptlist(conn_handle, local_cid, remote_cid); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| test_registry.StopAll(); |
| |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty, "false")); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| // Packet should be filtered because DLCI not acceptlisted |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_filtered), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + |
| snoop_logger->GetL2capHeaderSize()); |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_not_acceptlisted_l2cap_channel_test) { |
| // Actual test |
| uint16_t conn_handle = 0x000b; |
| uint16_t local_cid = 0x0041; |
| uint16_t remote_cid = 0x3040; |
| |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty, "true")); |
| auto filter_rfcomm_property = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty); |
| ASSERT_TRUE(filter_rfcomm_property); |
| ASSERT_TRUE(filter_rfcomm_property.value() == "true"); |
| |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFiltered, |
| false, |
| false); |
| |
| TestModuleRegistry test_registry; |
| test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| std::vector<uint8_t> kRfcommL2capChannel = { |
| 0x0b, 0x20, 0x12, 0x00, 0x0e, 0x00, 0x41, 0x00, 0x00, 0xef, 0x15, |
| 0x83, 0x11, 0x06, 0xf0, 0x07, 0x00, 0x9d, 0x02, 0x00, 0x07, 0x70, |
| }; |
| |
| snoop_logger->Capture( |
| kRfcommL2capChannel, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL); |
| snoop_logger->ClearL2capAcceptlist(conn_handle, local_cid, remote_cid); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| test_registry.StopAll(); |
| |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty, "false")); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| // Packet should be filtered because L2CAP channel not acceptlisted |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_filtered), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + |
| snoop_logger->GetL2capHeaderSize()); |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, rfcomm_channel_filtered_acceptlisted_l2cap_channel_test) { |
| // Actual test |
| uint16_t conn_handle = 0x000b; |
| uint16_t local_cid = 0x0041; |
| uint16_t remote_cid = 0x3040; |
| |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty, "true")); |
| auto filter_rfcomm_property = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty); |
| ASSERT_TRUE(filter_rfcomm_property); |
| ASSERT_TRUE(filter_rfcomm_property.value() == "true"); |
| |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFiltered, |
| false, |
| false); |
| |
| TestModuleRegistry test_registry; |
| test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| snoop_logger->AcceptlistL2capChannel(conn_handle, local_cid, remote_cid); |
| |
| std::vector<uint8_t> kRfcommL2capChannel = { |
| 0x0b, 0x20, 0x12, 0x00, 0x0e, 0x00, 0x41, 0x00, 0x00, 0xef, 0x15, |
| 0x83, 0x11, 0x06, 0xf0, 0x07, 0x00, 0x9d, 0x02, 0x00, 0x07, 0x70, |
| }; |
| |
| snoop_logger->Capture( |
| kRfcommL2capChannel, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL); |
| snoop_logger->ClearL2capAcceptlist(conn_handle, local_cid, remote_cid); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| test_registry.StopAll(); |
| |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty, "false")); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| // Packet should not be filtered because L2CAP channel acceptlisted |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_filtered), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + |
| kRfcommL2capChannel.size()); |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, profiles_filtered_hfp_hf_test) { |
| // Actual test |
| uint16_t conn_handle = 0x000b; |
| uint16_t local_cid = 0x0043; |
| uint16_t remote_cid = 0x3040; |
| uint8_t dlci = 0x06; |
| uint16_t psm = 0x0003; |
| uint16_t profile_uuid_hfp_hf = 0x111f; |
| bool flow = true; |
| |
| const std::string clcc_pattern = "\x0d\x0a+CLCC:"; |
| const uint16_t HEADER_SIZE = 12; |
| |
| // Set pbap and map filtering modes |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeMagic)); |
| auto filterPbapModeProperty = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty); |
| ASSERT_TRUE( |
| filterPbapModeProperty && |
| (filterPbapModeProperty->find(SnoopLogger::kBtSnoopLogFilterProfileModeMagic) != |
| std::string::npos)); |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeMagic)); |
| auto filterMapModeProperty = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty); |
| ASSERT_TRUE( |
| filterMapModeProperty && |
| (filterMapModeProperty->find(SnoopLogger::kBtSnoopLogFilterProfileModeMagic) != |
| std::string::npos)); |
| |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFiltered, |
| false, |
| false); |
| |
| TestModuleRegistry test_registry; |
| test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| snoop_logger->SetL2capChannelOpen(conn_handle, local_cid, remote_cid, psm, false); |
| snoop_logger->SetRfcommPortOpen(conn_handle, local_cid, dlci, profile_uuid_hfp_hf, flow); |
| |
| std::vector<uint8_t> kPhoneNumber = { |
| 0x0b, 0x00, 0x30, 0x00, 0x2c, 0x00, 0x40, 0x30, 0x19, 0xff, 0x4f, 0x01, 0x0d, |
| 0x0a, 0x2b, 0x43, 0x4c, 0x43, 0x43, 0x3a, 0x20, 0x31, 0x2c, 0x31, 0x2c, 0x34, |
| 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x22, 0x2b, 0x39, 0x39, 0x31, 0x32, 0x33, 0x34, |
| 0x35, 0x36, 0x37, 0x38, 0x39, 0x22, 0x2c, 0x31, 0x34, 0x35, 0x0d, 0x0a, 0x49, |
| }; |
| |
| snoop_logger->Capture( |
| kPhoneNumber, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| snoop_logger->SetL2capChannelClose(conn_handle, local_cid, remote_cid); |
| snoop_logger->SetRfcommPortClose(conn_handle, local_cid, dlci, profile_uuid_hfp_hf); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| test_registry.StopAll(); |
| |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeDisabled)); |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeDisabled)); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| // Packet should be filtered |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_filtered), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + |
| HEADER_SIZE + strlen(clcc_pattern.c_str())); |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_magic_test) { |
| // Actual test |
| constexpr uint16_t PROFILE_PSM_PBAP = 0x1025; |
| constexpr uint16_t PROFILE_UUID_PBAP = 0x112f; |
| uint16_t conn_handle = 0x0002; |
| uint16_t local_cid = 0x0041; |
| uint16_t remote_cid = 0x0040; |
| uint8_t dlci = 0x27; |
| uint16_t psm = PROFILE_PSM_PBAP; |
| uint16_t profile_uuid_pbap = PROFILE_UUID_PBAP; |
| bool flow = true; |
| const std::string magic_string = "PROHIBITED"; |
| const uint16_t HEADER_SIZE = 8; |
| |
| // Set pbap and map filtering modes |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeMagic)); |
| auto filterPbapModeProperty = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty); |
| ASSERT_TRUE( |
| filterPbapModeProperty && |
| (filterPbapModeProperty->find(SnoopLogger::kBtSnoopLogFilterProfileModeMagic) != |
| std::string::npos)); |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeMagic)); |
| auto filterMapModeProperty = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty); |
| ASSERT_TRUE( |
| filterMapModeProperty && |
| (filterMapModeProperty->find(SnoopLogger::kBtSnoopLogFilterProfileModeMagic) != |
| std::string::npos)); |
| |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 15, |
| SnoopLogger::kBtSnoopLogModeFiltered, |
| false, |
| false); |
| |
| TestModuleRegistry test_registry; |
| test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| snoop_logger->SetL2capChannelOpen(conn_handle, local_cid, remote_cid, psm, false); |
| snoop_logger->SetRfcommPortOpen(conn_handle, local_cid, dlci, profile_uuid_pbap, flow); |
| |
| for (int i = 0; i < (int)kTestData.size(); i++) { |
| snoop_logger->Capture( |
| kTestData[i], (SnoopLogger::Direction)(i % 2), SnoopLogger::PacketType::ACL); |
| } |
| |
| snoop_logger->SetL2capChannelClose(conn_handle, local_cid, remote_cid); |
| snoop_logger->SetRfcommPortClose(conn_handle, local_cid, dlci, profile_uuid_pbap); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| test_registry.StopAll(); |
| |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeDisabled)); |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeDisabled)); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| // Packets should be filtered |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_filtered), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + |
| (int)kTestData.size() * |
| (sizeof(SnoopLogger::PacketHeaderType) + HEADER_SIZE + strlen(magic_string.c_str()))); |
| |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_header_test) { |
| // Actual test |
| constexpr uint16_t PROFILE_PSM_PBAP = 0x1025; |
| constexpr uint16_t PROFILE_UUID_PBAP = 0x112f; |
| uint16_t conn_handle = 0x0002; |
| uint16_t local_cid = 0x0041; |
| uint16_t remote_cid = 0x0040; |
| uint8_t dlci = 0x27; |
| uint16_t psm = PROFILE_PSM_PBAP; |
| uint16_t profile_uuid_pbap = PROFILE_UUID_PBAP; |
| bool flow = true; |
| const uint16_t HEADER_SIZE = 8; |
| |
| // Set pbap and map filtering modes |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeHeader)); |
| auto filterPbapModeProperty = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty); |
| ASSERT_TRUE( |
| filterPbapModeProperty && |
| (filterPbapModeProperty->find(SnoopLogger::kBtSnoopLogFilterProfileModeHeader) != |
| std::string::npos)); |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeHeader)); |
| auto filterMapModeProperty = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty); |
| ASSERT_TRUE( |
| filterMapModeProperty && |
| (filterMapModeProperty->find(SnoopLogger::kBtSnoopLogFilterProfileModeHeader) != |
| std::string::npos)); |
| |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 15, |
| SnoopLogger::kBtSnoopLogModeFiltered, |
| false, |
| false); |
| |
| TestModuleRegistry test_registry; |
| test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| snoop_logger->SetL2capChannelOpen(conn_handle, local_cid, remote_cid, psm, false); |
| snoop_logger->SetRfcommPortOpen(conn_handle, local_cid, dlci, profile_uuid_pbap, flow); |
| |
| for (int i = 0; i < (int)kTestData.size(); i++) { |
| snoop_logger->Capture( |
| kTestData[i], (SnoopLogger::Direction)(i % 2), SnoopLogger::PacketType::ACL); |
| } |
| |
| snoop_logger->SetL2capChannelClose(conn_handle, local_cid, remote_cid); |
| snoop_logger->SetRfcommPortClose(conn_handle, local_cid, dlci, profile_uuid_pbap); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| test_registry.StopAll(); |
| |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeDisabled)); |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeDisabled)); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| // Packets should be filtered |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_filtered), |
| sizeof(SnoopLoggerCommon::FileHeaderType) + |
| (int)kTestData.size() * (sizeof(SnoopLogger::PacketHeaderType) + HEADER_SIZE)); |
| |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered)); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, profiles_filtered_pbap_fullfilter_test) { |
| // Actual test |
| constexpr uint16_t PROFILE_PSM_PBAP = 0x1025; |
| constexpr uint16_t PROFILE_UUID_PBAP = 0x112f; |
| uint16_t conn_handle = 0x0002; |
| uint16_t local_cid = 0x0041; |
| uint16_t remote_cid = 0x0040; |
| uint8_t dlci = 0x27; |
| uint16_t psm = PROFILE_PSM_PBAP; |
| uint16_t profile_uuid_pbap = PROFILE_UUID_PBAP; |
| bool flow = true; |
| |
| // Set pbap and map filtering modes |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeFullfillter)); |
| auto filterPbapModeProperty = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty); |
| ASSERT_TRUE( |
| filterPbapModeProperty && |
| (filterPbapModeProperty->find(SnoopLogger::kBtSnoopLogFilterProfileModeFullfillter) != |
| std::string::npos)); |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeFullfillter)); |
| auto filterMapModeProperty = |
| bluetooth::os::GetSystemProperty(SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty); |
| ASSERT_TRUE( |
| filterMapModeProperty && |
| (filterMapModeProperty->find(SnoopLogger::kBtSnoopLogFilterProfileModeFullfillter) != |
| std::string::npos)); |
| |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 15, |
| SnoopLogger::kBtSnoopLogModeFiltered, |
| false, |
| false); |
| |
| TestModuleRegistry test_registry; |
| test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| snoop_logger->SetL2capChannelOpen(conn_handle, local_cid, remote_cid, psm, false); |
| snoop_logger->SetRfcommPortOpen(conn_handle, local_cid, dlci, profile_uuid_pbap, flow); |
| |
| for (int i = 0; i < (int)kTestData.size(); i++) { |
| snoop_logger->Capture( |
| kTestData[i], (SnoopLogger::Direction)(i % 2), SnoopLogger::PacketType::ACL); |
| } |
| |
| snoop_logger->SetL2capChannelClose(conn_handle, local_cid, remote_cid); |
| snoop_logger->SetRfcommPortClose(conn_handle, local_cid, dlci, profile_uuid_pbap); |
| |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| test_registry.StopAll(); |
| |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeDisabled)); |
| ASSERT_TRUE(bluetooth::os::SetSystemProperty( |
| SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty, |
| SnoopLogger::kBtSnoopLogFilterProfileModeDisabled)); |
| |
| // Verify states after test |
| ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_filtered)); |
| |
| // Packets should be filtered |
| ASSERT_EQ( |
| std::filesystem::file_size(temp_snoop_log_filtered), |
| sizeof(SnoopLoggerCommon::FileHeaderType)); |
| |
| ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_filtered)); |
| } |
| |
| static constexpr int INVALID_FD = -1; |
| |
| TEST_F(SnoopLoggerModuleTest, socket_disabled_connect_fail_test) { |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeDisabled, |
| true, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| // // Create a TCP socket file descriptor |
| int socket_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP); |
| ASSERT_TRUE(socket_fd != INVALID_FD); |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| addr.sin_addr.s_addr = htonl(SnoopLoggerSocket::DEFAULT_LOCALHOST_); |
| addr.sin_port = htons(SnoopLoggerSocket::DEFAULT_LISTEN_PORT_); |
| |
| int ret; |
| |
| // Connect to snoop logger socket |
| RUN_NO_INTR(ret = connect(socket_fd, (struct sockaddr*)&addr, sizeof(addr))); |
| ASSERT_TRUE(ret != 0); |
| |
| test_registry->StopAll(); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, default_socket_enabled_capture_recv_test) { |
| int ret; |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFull, |
| true, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| // // Create a TCP socket file descriptor |
| int socket_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP); |
| ASSERT_TRUE(socket_fd != INVALID_FD); |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| addr.sin_addr.s_addr = htonl(SnoopLoggerSocket::DEFAULT_LOCALHOST_); |
| addr.sin_port = htons(SnoopLoggerSocket::DEFAULT_LISTEN_PORT_); |
| |
| // Connect to snoop logger socket |
| RUN_NO_INTR(ret = connect(socket_fd, (struct sockaddr*)&addr, sizeof(addr))); |
| ASSERT_TRUE(ret == 0); |
| |
| char recv_buf1[sizeof(SnoopLoggerCommon::FileHeaderType)]; |
| char recv_buf2[sizeof(SnoopLogger::PacketHeaderType)]; |
| char recv_buf3[99]; |
| int bytes_read = -1; |
| |
| auto a = std::async(std::launch::async, [&] { |
| recv(socket_fd, recv_buf1, sizeof(recv_buf1), 0); |
| recv(socket_fd, recv_buf2, sizeof(recv_buf2), 0); |
| return recv(socket_fd, recv_buf3, sizeof(recv_buf3), 0); |
| }); |
| |
| snoop_logger->GetSocketThread()->GetSocket()->WaitForClientSocketConnected(); |
| |
| snoop_logger->Capture(kHfpAtNrec0, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| |
| a.wait(); |
| bytes_read = a.get(); |
| |
| ASSERT_TRUE(std::memcmp(recv_buf1, &SnoopLoggerCommon::kBtSnoopFileHeader, sizeof(recv_buf1)) == 0); |
| ASSERT_EQ(bytes_read, static_cast<int>(kHfpAtNrec0.size())); |
| ASSERT_TRUE(std::memcmp(recv_buf3, kHfpAtNrec0.data(), kHfpAtNrec0.size()) == 0); |
| |
| test_registry->StopAll(); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, custom_socket_register_enabled_capture_recv_test) { |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFull, |
| true, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| int new_port = 8873; |
| SyscallWrapperImpl syscall_if; |
| auto sls = std::make_unique<SnoopLoggerSocket>(&syscall_if, SnoopLoggerSocket::DEFAULT_LOCALHOST_, new_port); |
| SnoopLoggerSocketThread slsThread(std::move(sls)); |
| auto thread_start_future = slsThread.Start(); |
| thread_start_future.wait(); |
| ASSERT_TRUE(thread_start_future.get()); |
| |
| snoop_logger->RegisterSocket(&slsThread); |
| |
| // // Create a TCP socket file descriptor |
| int socket_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP); |
| ASSERT_TRUE(socket_fd != INVALID_FD); |
| |
| struct sockaddr_in addr; |
| addr.sin_family = AF_INET; |
| addr.sin_addr.s_addr = htonl(SnoopLoggerSocket::DEFAULT_LOCALHOST_); |
| addr.sin_port = htons(new_port); |
| |
| int ret = 0; |
| // Connect to snoop logger socket |
| RUN_NO_INTR(ret = connect(socket_fd, (struct sockaddr*)&addr, sizeof(addr))); |
| ASSERT_TRUE(ret == 0); |
| |
| char recv_buf1[sizeof(SnoopLoggerCommon::FileHeaderType)]; |
| char recv_buf2[sizeof(SnoopLogger::PacketHeaderType)]; |
| char recv_buf3[99]; |
| int bytes_read = -1; |
| |
| auto a = std::async(std::launch::async, [socket_fd, &recv_buf1, &recv_buf2, &recv_buf3] { |
| recv(socket_fd, recv_buf1, sizeof(recv_buf1), 0); |
| recv(socket_fd, recv_buf2, sizeof(recv_buf2), 0); |
| return recv(socket_fd, recv_buf3, sizeof(recv_buf3), 0); |
| }); |
| |
| slsThread.GetSocket()->WaitForClientSocketConnected(); |
| |
| snoop_logger->Capture(kHfpAtNrec0, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| |
| a.wait(); |
| bytes_read = a.get(); |
| |
| ASSERT_TRUE(std::memcmp(recv_buf1, &SnoopLoggerCommon::kBtSnoopFileHeader, sizeof(recv_buf1)) == 0); |
| ASSERT_EQ(bytes_read, static_cast<int>(kHfpAtNrec0.size())); |
| ASSERT_TRUE(std::memcmp(recv_buf3, kHfpAtNrec0.data(), kHfpAtNrec0.size()) == 0); |
| |
| test_registry->StopAll(); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, custom_socket_interface_register_logging_disabled_test) { |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeDisabled, |
| true, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| class SnoopLoggerSocketMock : public SnoopLoggerSocketInterface { |
| public: |
| bool write_called; |
| SnoopLoggerSocketMock() { |
| write_called = false; |
| } |
| virtual void Write(const void* data, size_t length) { |
| write_called = true; |
| } |
| }; |
| |
| SnoopLoggerSocketMock mock; |
| |
| snoop_logger->RegisterSocket(&mock); |
| snoop_logger->Capture(kQualcommConnectionRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| |
| ASSERT_FALSE(mock.write_called); |
| |
| test_registry->StopAll(); |
| } |
| |
| TEST_F(SnoopLoggerModuleTest, custom_socket_interface_register_logging_enabled_test) { |
| auto* snoop_logger = new TestSnoopLoggerModule( |
| temp_snoop_log_.string(), |
| temp_snooz_log_.string(), |
| 10, |
| SnoopLogger::kBtSnoopLogModeFull, |
| true, |
| false); |
| test_registry->InjectTestModule(&SnoopLogger::Factory, snoop_logger); |
| |
| class SnoopLoggerSocketMock : public SnoopLoggerSocketInterface { |
| public: |
| bool write_called; |
| SnoopLoggerSocketMock() { |
| write_called = false; |
| } |
| virtual void Write(const void* data, size_t length) { |
| write_called = true; |
| } |
| }; |
| |
| SnoopLoggerSocketMock mock; |
| |
| snoop_logger->RegisterSocket(&mock); |
| snoop_logger->Capture(kQualcommConnectionRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); |
| |
| ASSERT_TRUE(mock.write_called); |
| |
| test_registry->StopAll(); |
| } |
| } // namespace testing |