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