Loading system/gd/hal/snoop_logger.cc +35 −5 Original line number Diff line number Diff line Loading @@ -77,6 +77,10 @@ constexpr size_t kDefaultBtSnoozMaxPayloadBytesPerPacket = constexpr size_t kDefaultBtSnoozMaxPacketsPerBuffer = kDefaultBtsnoozMaxMemoryUsageBytes / kDefaultBtSnoozMaxBytesPerPacket; using namespace std::chrono_literals; constexpr std::chrono::hours kBtSnoozLogLifeTime = 12h; constexpr std::chrono::hours kBtSnoozLogDeleteRepeatingAlarmInterval = 1h; std::string get_btsnoop_log_path(std::string log_dir, bool filtered) { if (filtered) { log_dir.append(".filtered"); Loading Loading @@ -107,6 +111,20 @@ void delete_btsnoop_files(const std::string& log_path) { } } void delete_old_btsnooz_files(const std::string& log_path, const std::chrono::milliseconds log_life_time) { auto opt_created_ts = os::FileCreatedTime(log_path); if (!opt_created_ts) return; using namespace std::chrono; auto created_tp = opt_created_ts.value(); auto current_tp = std::chrono::system_clock::now(); auto diff = duration_cast<milliseconds>(current_tp - created_tp); if (diff >= log_life_time) { delete_btsnoop_files(log_path); } } size_t get_btsnooz_packet_length_to_write(const HciPacket& packet, SnoopLogger::PacketType type) { static const size_t kAclHeaderSize = 4; static const size_t kL2capHeaderSize = 4; Loading Loading @@ -172,11 +190,15 @@ SnoopLogger::SnoopLogger( std::string snoop_log_path, std::string snooz_log_path, size_t max_packets_per_file, const std::string& btsnoop_mode) const std::string& btsnoop_mode, const std::chrono::milliseconds snooz_log_life_time, const std::chrono::milliseconds snooz_log_delete_alarm_interval) : snoop_log_path_(std::move(snoop_log_path)), snooz_log_path_(std::move(snooz_log_path)), max_packets_per_file_(max_packets_per_file), btsnooz_buffer_(kDefaultBtSnoozMaxPacketsPerBuffer) { btsnooz_buffer_(kDefaultBtSnoozMaxPacketsPerBuffer), snooz_log_life_time_(snooz_log_life_time), snooz_log_delete_alarm_interval_(snooz_log_delete_alarm_interval) { if (false && btsnoop_mode == kBtSnoopLogModeFiltered) { // TODO(b/163733538): implement filtered snoop log in GD, currently filtered == disabled LOG_INFO("Filtered Snoop Logs enabled"); Loading Loading @@ -360,14 +382,20 @@ void SnoopLogger::Start() { if (is_enabled_) { OpenNextSnoopLogFile(); } alarm_ = std::make_unique<os::RepeatingAlarm>(GetHandler()); alarm_->Schedule( common::Bind(&delete_old_btsnooz_files, snooz_log_path_, snooz_log_life_time_), snooz_log_delete_alarm_interval_); } void SnoopLogger::Stop() { std::lock_guard<std::recursive_mutex> lock(file_mutex_); LOG_DEBUG("Dumping btsnooz log data to %s", snooz_log_path_.c_str()); DumpSnoozLogToFile(btsnooz_buffer_.Drain()); LOG_DEBUG("Closing btsnoop log data at %s", snoop_log_path_.c_str()); CloseCurrentSnoopLogFile(); // Cancel the alarm alarm_->Cancel(); alarm_.reset(); // delete any existing snooz logs delete_btsnoop_files(snooz_log_path_); } DumpsysDataFinisher SnoopLogger::GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const { Loading Loading @@ -421,7 +449,9 @@ const ModuleFactory SnoopLogger::Factory = ModuleFactory([]() { os::ParameterProvider::SnoopLogFilePath(), os::ParameterProvider::SnoozLogFilePath(), GetMaxPacketsPerFile(), GetBtSnoopMode()); GetBtSnoopMode(), kBtSnoozLogLifeTime, kBtSnoozLogDeleteRepeatingAlarmInterval); }); } // namespace hal Loading system/gd/hal/snoop_logger.h +7 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include "common/circular_buffer.h" #include "hal/hci_hal.h" #include "module.h" #include "os/repeating_alarm.h" namespace bluetooth { namespace hal { Loading Loading @@ -96,7 +97,9 @@ class SnoopLogger : public ::bluetooth::Module { std::string snoop_log_path, std::string snooz_log_path, size_t max_packets_per_file, const std::string& btsnoop_mode); const std::string& btsnoop_mode, const std::chrono::milliseconds snooz_log_life_time, const std::chrono::milliseconds snooz_log_delete_alarm_interval); void CloseCurrentSnoopLogFile(); void OpenNextSnoopLogFile(); void DumpSnoozLogToFile(const std::vector<std::string>& data) const; Loading @@ -111,6 +114,9 @@ class SnoopLogger : public ::bluetooth::Module { common::CircularBuffer<std::string> btsnooz_buffer_; size_t packet_counter_ = 0; mutable std::recursive_mutex file_mutex_; std::unique_ptr<os::RepeatingAlarm> alarm_; std::chrono::milliseconds snooz_log_life_time_; std::chrono::milliseconds snooz_log_delete_alarm_interval_; }; } // namespace hal Loading system/gd/hal/snoop_logger_test.cc +58 −17 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ std::vector<uint8_t> kHfpAtNrec0 = {0x02, 0x02, 0x20, 0x13, 0x00, 0x0f, 0x00, 0x using bluetooth::TestModuleRegistry; using bluetooth::hal::SnoopLogger; using namespace std::chrono_literals; // Expose protected constructor for test class TestSnoopLoggerModule : public SnoopLogger { Loading @@ -60,14 +61,22 @@ class TestSnoopLoggerModule : public SnoopLogger { std::string snooz_log_path, size_t max_packets_per_file, const std::string& btsnoop_mode) : SnoopLogger(std::move(snoop_log_path), std::move(snooz_log_path), max_packets_per_file, btsnoop_mode) {} : SnoopLogger( std::move(snoop_log_path), std::move(snooz_log_path), max_packets_per_file, btsnoop_mode, 20ms, 5ms) {} std::string ToString() const override { return std::string("TestSnoopLoggerModule"); } void CallGetDumpsysData(flatbuffers::FlatBufferBuilder* builder) { GetDumpsysData(builder); } }; class SnoopLoggerModuleTest : public Test { public: flatbuffers::FlatBufferBuilder* builder_; protected: void SetUp() override { temp_dir_ = std::filesystem::temp_directory_path(); Loading @@ -75,6 +84,8 @@ class SnoopLoggerModuleTest : public Test { 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"; builder_ = new flatbuffers::FlatBufferBuilder(); DeleteSnoopLogFiles(); ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_)); ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); Loading @@ -84,6 +95,7 @@ class SnoopLoggerModuleTest : public Test { void TearDown() override { DeleteSnoopLogFiles(); delete builder_; } void DeleteSnoopLogFiles() { Loading Loading @@ -133,7 +145,7 @@ TEST_F(SnoopLoggerModuleTest, disable_snoop_log_test) { // Verify states after test ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_)); ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); } TEST_F(SnoopLoggerModuleTest, capture_one_packet_test) { Loading Loading @@ -163,16 +175,19 @@ TEST_F(SnoopLoggerModuleTest, capture_hci_cmd_btsnooz_test) { test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger); snoop_looger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD); snoop_looger->CallGetDumpsysData(builder_); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::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_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size()); ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); } TEST_F(SnoopLoggerModuleTest, capture_l2cap_signal_packet_btsnooz_test) { Loading @@ -183,16 +198,19 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_signal_packet_btsnooz_test) { test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger); snoop_looger->Capture(kSdpConnectionRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); snoop_looger->CallGetDumpsysData(builder_); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::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_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kSdpConnectionRequest.size()); ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); } TEST_F(SnoopLoggerModuleTest, capture_l2cap_short_data_packet_btsnooz_test) { Loading @@ -203,16 +221,19 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_short_data_packet_btsnooz_test) { test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger); snoop_looger->Capture(kAvdtpSuspend, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); snoop_looger->CallGetDumpsysData(builder_); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::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_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kAvdtpSuspend.size()); ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); } TEST_F(SnoopLoggerModuleTest, capture_l2cap_long_data_packet_btsnooz_test) { Loading @@ -223,16 +244,36 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_long_data_packet_btsnooz_test) { test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger); snoop_looger->Capture(kHfpAtNrec0, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); snoop_looger->CallGetDumpsysData(builder_); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::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, delete_old_snooz_log_files) { // Actual test auto* snoop_looger = new TestSnoopLoggerModule( temp_snoop_log_.string(), temp_snooz_log_.string(), 10, SnoopLogger::kBtSnoopLogModeDisabled); TestModuleRegistry test_registry; test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger); std::filesystem::create_directories(temp_snooz_log_); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + 14); std::this_thread::sleep_for(10ms); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); std::this_thread::sleep_for(15ms); ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); test_registry.StopAll(); } TEST_F(SnoopLoggerModuleTest, rotate_file_at_new_session_test) { Loading system/gd/os/files.h +5 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <chrono> #include <iterator> #include <optional> Loading Loading @@ -45,5 +46,9 @@ bool WriteToFile(const std::string& path, const std::string& data); // Return true on success, false on failure (e.g. file not exist, failed to remove, etc) bool RemoveFile(const std::string& path); // Returns created time_point of given file, return std::nullopt on failure std::optional<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> FileCreatedTime( const std::string& path); } // namespace os } // namespace bluetooth No newline at end of file system/gd/os/linux_generic/files.cc +14 −0 Original line number Diff line number Diff line Loading @@ -195,5 +195,19 @@ bool RemoveFile(const std::string& path) { return true; } std::optional<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> FileCreatedTime( const std::string& path) { struct stat file_info; if (stat(path.c_str(), &file_info) != 0) { LOG_ERROR("unable to read '%s' file metadata, error: %s", path.c_str(), strerror(errno)); return std::nullopt; } using namespace std::chrono; using namespace std::chrono_literals; auto created_ts = file_info.st_ctim; auto d = seconds{created_ts.tv_sec} + nanoseconds{created_ts.tv_nsec}; return time_point<system_clock>(duration_cast<system_clock::duration>(d)); } } // namespace os } // namespace bluetooth No newline at end of file Loading
system/gd/hal/snoop_logger.cc +35 −5 Original line number Diff line number Diff line Loading @@ -77,6 +77,10 @@ constexpr size_t kDefaultBtSnoozMaxPayloadBytesPerPacket = constexpr size_t kDefaultBtSnoozMaxPacketsPerBuffer = kDefaultBtsnoozMaxMemoryUsageBytes / kDefaultBtSnoozMaxBytesPerPacket; using namespace std::chrono_literals; constexpr std::chrono::hours kBtSnoozLogLifeTime = 12h; constexpr std::chrono::hours kBtSnoozLogDeleteRepeatingAlarmInterval = 1h; std::string get_btsnoop_log_path(std::string log_dir, bool filtered) { if (filtered) { log_dir.append(".filtered"); Loading Loading @@ -107,6 +111,20 @@ void delete_btsnoop_files(const std::string& log_path) { } } void delete_old_btsnooz_files(const std::string& log_path, const std::chrono::milliseconds log_life_time) { auto opt_created_ts = os::FileCreatedTime(log_path); if (!opt_created_ts) return; using namespace std::chrono; auto created_tp = opt_created_ts.value(); auto current_tp = std::chrono::system_clock::now(); auto diff = duration_cast<milliseconds>(current_tp - created_tp); if (diff >= log_life_time) { delete_btsnoop_files(log_path); } } size_t get_btsnooz_packet_length_to_write(const HciPacket& packet, SnoopLogger::PacketType type) { static const size_t kAclHeaderSize = 4; static const size_t kL2capHeaderSize = 4; Loading Loading @@ -172,11 +190,15 @@ SnoopLogger::SnoopLogger( std::string snoop_log_path, std::string snooz_log_path, size_t max_packets_per_file, const std::string& btsnoop_mode) const std::string& btsnoop_mode, const std::chrono::milliseconds snooz_log_life_time, const std::chrono::milliseconds snooz_log_delete_alarm_interval) : snoop_log_path_(std::move(snoop_log_path)), snooz_log_path_(std::move(snooz_log_path)), max_packets_per_file_(max_packets_per_file), btsnooz_buffer_(kDefaultBtSnoozMaxPacketsPerBuffer) { btsnooz_buffer_(kDefaultBtSnoozMaxPacketsPerBuffer), snooz_log_life_time_(snooz_log_life_time), snooz_log_delete_alarm_interval_(snooz_log_delete_alarm_interval) { if (false && btsnoop_mode == kBtSnoopLogModeFiltered) { // TODO(b/163733538): implement filtered snoop log in GD, currently filtered == disabled LOG_INFO("Filtered Snoop Logs enabled"); Loading Loading @@ -360,14 +382,20 @@ void SnoopLogger::Start() { if (is_enabled_) { OpenNextSnoopLogFile(); } alarm_ = std::make_unique<os::RepeatingAlarm>(GetHandler()); alarm_->Schedule( common::Bind(&delete_old_btsnooz_files, snooz_log_path_, snooz_log_life_time_), snooz_log_delete_alarm_interval_); } void SnoopLogger::Stop() { std::lock_guard<std::recursive_mutex> lock(file_mutex_); LOG_DEBUG("Dumping btsnooz log data to %s", snooz_log_path_.c_str()); DumpSnoozLogToFile(btsnooz_buffer_.Drain()); LOG_DEBUG("Closing btsnoop log data at %s", snoop_log_path_.c_str()); CloseCurrentSnoopLogFile(); // Cancel the alarm alarm_->Cancel(); alarm_.reset(); // delete any existing snooz logs delete_btsnoop_files(snooz_log_path_); } DumpsysDataFinisher SnoopLogger::GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const { Loading Loading @@ -421,7 +449,9 @@ const ModuleFactory SnoopLogger::Factory = ModuleFactory([]() { os::ParameterProvider::SnoopLogFilePath(), os::ParameterProvider::SnoozLogFilePath(), GetMaxPacketsPerFile(), GetBtSnoopMode()); GetBtSnoopMode(), kBtSnoozLogLifeTime, kBtSnoozLogDeleteRepeatingAlarmInterval); }); } // namespace hal Loading
system/gd/hal/snoop_logger.h +7 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include "common/circular_buffer.h" #include "hal/hci_hal.h" #include "module.h" #include "os/repeating_alarm.h" namespace bluetooth { namespace hal { Loading Loading @@ -96,7 +97,9 @@ class SnoopLogger : public ::bluetooth::Module { std::string snoop_log_path, std::string snooz_log_path, size_t max_packets_per_file, const std::string& btsnoop_mode); const std::string& btsnoop_mode, const std::chrono::milliseconds snooz_log_life_time, const std::chrono::milliseconds snooz_log_delete_alarm_interval); void CloseCurrentSnoopLogFile(); void OpenNextSnoopLogFile(); void DumpSnoozLogToFile(const std::vector<std::string>& data) const; Loading @@ -111,6 +114,9 @@ class SnoopLogger : public ::bluetooth::Module { common::CircularBuffer<std::string> btsnooz_buffer_; size_t packet_counter_ = 0; mutable std::recursive_mutex file_mutex_; std::unique_ptr<os::RepeatingAlarm> alarm_; std::chrono::milliseconds snooz_log_life_time_; std::chrono::milliseconds snooz_log_delete_alarm_interval_; }; } // namespace hal Loading
system/gd/hal/snoop_logger_test.cc +58 −17 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ std::vector<uint8_t> kHfpAtNrec0 = {0x02, 0x02, 0x20, 0x13, 0x00, 0x0f, 0x00, 0x using bluetooth::TestModuleRegistry; using bluetooth::hal::SnoopLogger; using namespace std::chrono_literals; // Expose protected constructor for test class TestSnoopLoggerModule : public SnoopLogger { Loading @@ -60,14 +61,22 @@ class TestSnoopLoggerModule : public SnoopLogger { std::string snooz_log_path, size_t max_packets_per_file, const std::string& btsnoop_mode) : SnoopLogger(std::move(snoop_log_path), std::move(snooz_log_path), max_packets_per_file, btsnoop_mode) {} : SnoopLogger( std::move(snoop_log_path), std::move(snooz_log_path), max_packets_per_file, btsnoop_mode, 20ms, 5ms) {} std::string ToString() const override { return std::string("TestSnoopLoggerModule"); } void CallGetDumpsysData(flatbuffers::FlatBufferBuilder* builder) { GetDumpsysData(builder); } }; class SnoopLoggerModuleTest : public Test { public: flatbuffers::FlatBufferBuilder* builder_; protected: void SetUp() override { temp_dir_ = std::filesystem::temp_directory_path(); Loading @@ -75,6 +84,8 @@ class SnoopLoggerModuleTest : public Test { 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"; builder_ = new flatbuffers::FlatBufferBuilder(); DeleteSnoopLogFiles(); ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_)); ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); Loading @@ -84,6 +95,7 @@ class SnoopLoggerModuleTest : public Test { void TearDown() override { DeleteSnoopLogFiles(); delete builder_; } void DeleteSnoopLogFiles() { Loading Loading @@ -133,7 +145,7 @@ TEST_F(SnoopLoggerModuleTest, disable_snoop_log_test) { // Verify states after test ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_)); ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_)); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); } TEST_F(SnoopLoggerModuleTest, capture_one_packet_test) { Loading Loading @@ -163,16 +175,19 @@ TEST_F(SnoopLoggerModuleTest, capture_hci_cmd_btsnooz_test) { test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger); snoop_looger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD); snoop_looger->CallGetDumpsysData(builder_); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::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_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size()); ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); } TEST_F(SnoopLoggerModuleTest, capture_l2cap_signal_packet_btsnooz_test) { Loading @@ -183,16 +198,19 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_signal_packet_btsnooz_test) { test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger); snoop_looger->Capture(kSdpConnectionRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); snoop_looger->CallGetDumpsysData(builder_); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::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_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kSdpConnectionRequest.size()); ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); } TEST_F(SnoopLoggerModuleTest, capture_l2cap_short_data_packet_btsnooz_test) { Loading @@ -203,16 +221,19 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_short_data_packet_btsnooz_test) { test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger); snoop_looger->Capture(kAvdtpSuspend, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); snoop_looger->CallGetDumpsysData(builder_); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::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_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kAvdtpSuspend.size()); ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); } TEST_F(SnoopLoggerModuleTest, capture_l2cap_long_data_packet_btsnooz_test) { Loading @@ -223,16 +244,36 @@ TEST_F(SnoopLoggerModuleTest, capture_l2cap_long_data_packet_btsnooz_test) { test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger); snoop_looger->Capture(kHfpAtNrec0, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); snoop_looger->CallGetDumpsysData(builder_); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::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, delete_old_snooz_log_files) { // Actual test auto* snoop_looger = new TestSnoopLoggerModule( temp_snoop_log_.string(), temp_snooz_log_.string(), 10, SnoopLogger::kBtSnoopLogModeDisabled); TestModuleRegistry test_registry; test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger); std::filesystem::create_directories(temp_snooz_log_); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); ASSERT_EQ( std::filesystem::file_size(temp_snooz_log_), sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + 14); std::this_thread::sleep_for(10ms); ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_)); std::this_thread::sleep_for(15ms); ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_)); test_registry.StopAll(); } TEST_F(SnoopLoggerModuleTest, rotate_file_at_new_session_test) { Loading
system/gd/os/files.h +5 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <chrono> #include <iterator> #include <optional> Loading Loading @@ -45,5 +46,9 @@ bool WriteToFile(const std::string& path, const std::string& data); // Return true on success, false on failure (e.g. file not exist, failed to remove, etc) bool RemoveFile(const std::string& path); // Returns created time_point of given file, return std::nullopt on failure std::optional<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> FileCreatedTime( const std::string& path); } // namespace os } // namespace bluetooth No newline at end of file
system/gd/os/linux_generic/files.cc +14 −0 Original line number Diff line number Diff line Loading @@ -195,5 +195,19 @@ bool RemoveFile(const std::string& path) { return true; } std::optional<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> FileCreatedTime( const std::string& path) { struct stat file_info; if (stat(path.c_str(), &file_info) != 0) { LOG_ERROR("unable to read '%s' file metadata, error: %s", path.c_str(), strerror(errno)); return std::nullopt; } using namespace std::chrono; using namespace std::chrono_literals; auto created_ts = file_info.st_ctim; auto d = seconds{created_ts.tv_sec} + nanoseconds{created_ts.tv_nsec}; return time_point<system_clock>(duration_cast<system_clock::duration>(d)); } } // namespace os } // namespace bluetooth No newline at end of file