• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "hal/snoop_logger.h"
18 
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 
22 namespace testing {
23 
24 namespace {
25 std::vector<uint8_t> kInformationRequest = {
26     0xfe,
27     0x2e,
28     0x0a,
29     0x00,
30     0x06,
31     0x00,
32     0x01,
33     0x00,
34     0x0a,
35     0x02,
36     0x02,
37     0x00,
38     0x02,
39     0x00,
40 };
41 
42 std::vector<uint8_t> kSdpConnectionRequest = {
43     0x08, 0x20, 0x0c, 0x00, 0x08, 0x00, 0x01, 0x00, 0x02, 0x0c, 0x04, 0x00, 0x01, 0x00, 0x44, 0x00};
44 
45 std::vector<uint8_t> kAvdtpSuspend = {0x02, 0x02, 0x00, 0x07, 0x00, 0x03, 0x00, 0x8d, 0x00, 0x90, 0x09, 0x04};
46 
47 std::vector<uint8_t> kHfpAtNrec0 = {0x02, 0x02, 0x20, 0x13, 0x00, 0x0f, 0x00, 0x41, 0x00, 0x09, 0xff, 0x15,
48                                     0x01, 0x41, 0x54, 0x2b, 0x4e, 0x52, 0x45, 0x43, 0x3d, 0x30, 0x0d, 0x5c};
49 
50 }  // namespace
51 
52 using bluetooth::TestModuleRegistry;
53 using bluetooth::hal::SnoopLogger;
54 
55 // Expose protected constructor for test
56 class TestSnoopLoggerModule : public SnoopLogger {
57  public:
TestSnoopLoggerModule(std::string snoop_log_path,std::string snooz_log_path,size_t max_packets_per_file,const std::string & btsnoop_mode)58   TestSnoopLoggerModule(
59       std::string snoop_log_path,
60       std::string snooz_log_path,
61       size_t max_packets_per_file,
62       const std::string& btsnoop_mode)
63       : SnoopLogger(std::move(snoop_log_path), std::move(snooz_log_path), max_packets_per_file, btsnoop_mode) {}
64 
ToString() const65   std::string ToString() const override {
66     return std::string("TestSnoopLoggerModule");
67   }
68 };
69 
70 class SnoopLoggerModuleTest : public Test {
71  protected:
SetUp()72   void SetUp() override {
73     temp_dir_ = std::filesystem::temp_directory_path();
74     temp_snoop_log_ = temp_dir_ / "btsnoop_hci.log";
75     temp_snoop_log_last_ = temp_dir_ / "btsnoop_hci.log.last";
76     temp_snooz_log_ = temp_dir_ / "btsnooz_hci.log";
77     temp_snooz_log_last_ = temp_dir_ / "btsnooz_hci.log.last";
78     DeleteSnoopLogFiles();
79     ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
80     ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
81     ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_));
82     ASSERT_FALSE(std::filesystem::exists(temp_snooz_log_last_));
83   }
84 
TearDown()85   void TearDown() override {
86     DeleteSnoopLogFiles();
87   }
88 
DeleteSnoopLogFiles()89   void DeleteSnoopLogFiles() {
90     if (std::filesystem::exists(temp_snoop_log_)) {
91       ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_));
92     }
93     if (std::filesystem::exists(temp_snoop_log_last_)) {
94       ASSERT_TRUE(std::filesystem::remove(temp_snoop_log_last_));
95     }
96     if (std::filesystem::exists(temp_snooz_log_)) {
97       ASSERT_TRUE(std::filesystem::remove(temp_snooz_log_));
98     }
99     if (std::filesystem::exists(temp_snooz_log_last_)) {
100       ASSERT_TRUE(std::filesystem::remove(temp_snooz_log_last_));
101     }
102   }
103 
104   std::filesystem::path temp_dir_;
105   std::filesystem::path temp_snoop_log_;
106   std::filesystem::path temp_snoop_log_last_;
107   std::filesystem::path temp_snooz_log_;
108   std::filesystem::path temp_snooz_log_last_;
109 };
110 
TEST_F(SnoopLoggerModuleTest,empty_snoop_log_test)111 TEST_F(SnoopLoggerModuleTest, empty_snoop_log_test) {
112   // Actual test
113   auto* snoop_looger = new TestSnoopLoggerModule(
114       temp_snoop_log_.string(), temp_snooz_log_.string(), 10, SnoopLogger::kBtSnoopLogModeFull);
115   TestModuleRegistry test_registry;
116   test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
117   test_registry.StopAll();
118 
119   // Verify states after test
120   ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_));
121   ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
122   ASSERT_EQ(std::filesystem::file_size(temp_snoop_log_), sizeof(SnoopLogger::FileHeaderType));
123 }
124 
TEST_F(SnoopLoggerModuleTest,disable_snoop_log_test)125 TEST_F(SnoopLoggerModuleTest, disable_snoop_log_test) {
126   // Actual test
127   auto* snoop_looger = new TestSnoopLoggerModule(
128       temp_snoop_log_.string(), temp_snooz_log_.string(), 10, SnoopLogger::kBtSnoopLogModeDisabled);
129   TestModuleRegistry test_registry;
130   test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
131   test_registry.StopAll();
132 
133   // Verify states after test
134   ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
135   ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
136   ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
137 }
138 
TEST_F(SnoopLoggerModuleTest,capture_one_packet_test)139 TEST_F(SnoopLoggerModuleTest, capture_one_packet_test) {
140   // Actual test
141   auto* snoop_looger = new TestSnoopLoggerModule(
142       temp_snoop_log_.string(), temp_snooz_log_.string(), 10, SnoopLogger::kBtSnoopLogModeFull);
143   TestModuleRegistry test_registry;
144   test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
145 
146   snoop_looger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
147 
148   test_registry.StopAll();
149 
150   // Verify states after test
151   ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_));
152   ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
153   ASSERT_EQ(
154       std::filesystem::file_size(temp_snoop_log_),
155       sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size());
156 }
157 
TEST_F(SnoopLoggerModuleTest,capture_hci_cmd_btsnooz_test)158 TEST_F(SnoopLoggerModuleTest, capture_hci_cmd_btsnooz_test) {
159   // Actual test
160   auto* snoop_looger = new TestSnoopLoggerModule(
161       temp_snoop_log_.string(), temp_snooz_log_.string(), 10, SnoopLogger::kBtSnoopLogModeDisabled);
162   TestModuleRegistry test_registry;
163   test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
164 
165   snoop_looger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
166 
167   test_registry.StopAll();
168 
169   // Verify states after test
170   ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
171   ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
172   ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
173   ASSERT_EQ(
174       std::filesystem::file_size(temp_snooz_log_),
175       sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size());
176 }
177 
TEST_F(SnoopLoggerModuleTest,capture_l2cap_signal_packet_btsnooz_test)178 TEST_F(SnoopLoggerModuleTest, capture_l2cap_signal_packet_btsnooz_test) {
179   // Actual test
180   auto* snoop_looger = new TestSnoopLoggerModule(
181       temp_snoop_log_.string(), temp_snooz_log_.string(), 10, SnoopLogger::kBtSnoopLogModeDisabled);
182   TestModuleRegistry test_registry;
183   test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
184 
185   snoop_looger->Capture(kSdpConnectionRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL);
186 
187   test_registry.StopAll();
188 
189   // Verify states after test
190   ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
191   ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
192   ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
193   ASSERT_EQ(
194       std::filesystem::file_size(temp_snooz_log_),
195       sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kSdpConnectionRequest.size());
196 }
197 
TEST_F(SnoopLoggerModuleTest,capture_l2cap_short_data_packet_btsnooz_test)198 TEST_F(SnoopLoggerModuleTest, capture_l2cap_short_data_packet_btsnooz_test) {
199   // Actual test
200   auto* snoop_looger = new TestSnoopLoggerModule(
201       temp_snoop_log_.string(), temp_snooz_log_.string(), 10, SnoopLogger::kBtSnoopLogModeDisabled);
202   TestModuleRegistry test_registry;
203   test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
204 
205   snoop_looger->Capture(kAvdtpSuspend, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL);
206 
207   test_registry.StopAll();
208 
209   // Verify states after test
210   ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
211   ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
212   ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
213   ASSERT_EQ(
214       std::filesystem::file_size(temp_snooz_log_),
215       sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kAvdtpSuspend.size());
216 }
217 
TEST_F(SnoopLoggerModuleTest,capture_l2cap_long_data_packet_btsnooz_test)218 TEST_F(SnoopLoggerModuleTest, capture_l2cap_long_data_packet_btsnooz_test) {
219   // Actual test
220   auto* snoop_looger = new TestSnoopLoggerModule(
221       temp_snoop_log_.string(), temp_snooz_log_.string(), 10, SnoopLogger::kBtSnoopLogModeDisabled);
222   TestModuleRegistry test_registry;
223   test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
224 
225   snoop_looger->Capture(kHfpAtNrec0, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL);
226 
227   test_registry.StopAll();
228 
229   // Verify states after test
230   ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_));
231   ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
232   ASSERT_TRUE(std::filesystem::exists(temp_snooz_log_));
233   ASSERT_EQ(
234       std::filesystem::file_size(temp_snooz_log_),
235       sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + 14);
236 }
237 
TEST_F(SnoopLoggerModuleTest,rotate_file_at_new_session_test)238 TEST_F(SnoopLoggerModuleTest, rotate_file_at_new_session_test) {
239   // Start once
240   {
241     auto* snoop_looger = new TestSnoopLoggerModule(
242         temp_snoop_log_.string(), temp_snooz_log_.string(), 10, SnoopLogger::kBtSnoopLogModeFull);
243     TestModuleRegistry test_registry;
244     test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
245     snoop_looger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
246     test_registry.StopAll();
247   }
248 
249   // Verify states after test
250   ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_));
251   ASSERT_FALSE(std::filesystem::exists(temp_snoop_log_last_));
252   ASSERT_EQ(
253       std::filesystem::file_size(temp_snoop_log_),
254       sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size());
255 
256   // Start again
257   {
258     auto* snoop_looger = new TestSnoopLoggerModule(
259         temp_snoop_log_.string(), temp_snooz_log_.string(), 10, SnoopLogger::kBtSnoopLogModeFull);
260     TestModuleRegistry test_registry;
261     test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
262     snoop_looger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
263     snoop_looger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
264     test_registry.StopAll();
265   }
266 
267   // Verify states after test
268   ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_));
269   ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_last_));
270   ASSERT_EQ(
271       std::filesystem::file_size(temp_snoop_log_),
272       sizeof(SnoopLogger::FileHeaderType) + (sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size()) * 2);
273   ASSERT_EQ(
274       std::filesystem::file_size(temp_snoop_log_last_),
275       sizeof(SnoopLogger::FileHeaderType) + sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size());
276 }
277 
TEST_F(SnoopLoggerModuleTest,rotate_file_after_full_test)278 TEST_F(SnoopLoggerModuleTest, rotate_file_after_full_test) {
279   // Actual test
280   auto* snoop_looger = new TestSnoopLoggerModule(
281       temp_snoop_log_.string(), temp_snooz_log_.string(), 10, SnoopLogger::kBtSnoopLogModeFull);
282   TestModuleRegistry test_registry;
283   test_registry.InjectTestModule(&SnoopLogger::Factory, snoop_looger);
284 
285   for (int i = 0; i < 11; i++) {
286     snoop_looger->Capture(kInformationRequest, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD);
287   }
288 
289   test_registry.StopAll();
290 
291   // Verify states after test
292   ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_));
293   ASSERT_TRUE(std::filesystem::exists(temp_snoop_log_last_));
294   ASSERT_EQ(
295       std::filesystem::file_size(temp_snoop_log_),
296       sizeof(SnoopLogger::FileHeaderType) + (sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size()) * 1);
297   ASSERT_EQ(
298       std::filesystem::file_size(temp_snoop_log_last_),
299       sizeof(SnoopLogger::FileHeaderType) + (sizeof(SnoopLogger::PacketHeaderType) + kInformationRequest.size()) * 10);
300 }
301 
302 }  // namespace testing
303