• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 #define ATRACE_TAG ATRACE_TAG_APP
18 
19 #include "hal/snoop_logger.h"
20 
21 #include <arpa/inet.h>
22 #include <bluetooth/log.h>
23 #include <com_android_bluetooth_flags.h>
24 #ifdef __ANDROID__
25 #include <cutils/trace.h>
26 #endif  // __ANDROID__
27 #include <sys/stat.h>
28 
29 #include <algorithm>
30 #include <bitset>
31 #include <chrono>
32 #include <filesystem>
33 #include <sstream>
34 
35 #include "common/circular_buffer.h"
36 #include "common/strings.h"
37 #include "hal/snoop_logger_common.h"
38 #ifdef __ANDROID__
39 #include "hal/snoop_logger_tracing.h"
40 #endif  // __ANDROID__
41 #include "hci/hci_packets.h"
42 #include "os/files.h"
43 #include "os/parameter_provider.h"
44 #include "os/system_properties.h"
45 
46 #ifdef USE_FAKE_TIMERS
47 #include "os/fake_timer/fake_timerfd.h"
48 using bluetooth::os::fake_timer::fake_timerfd_get_clock;
49 #endif
50 
51 namespace bluetooth {
52 namespace hal {
53 
GetBtSnoopMode()54 static std::string GetBtSnoopMode() {
55   // Default mode is FILTERED on userdebug/eng build, DISABLED on user build.
56   // In userdebug/eng build, it can also be overwritten by modifying the global setting
57   std::string btsnoop_mode = SnoopLogger::kBtSnoopLogModeDisabled;
58   if (os::GetSystemProperty(SnoopLogger::kRoBuildType) != "user") {
59     btsnoop_mode = os::GetSystemProperty(SnoopLogger::kBtSnoopDefaultLogModeProperty)
60                            .value_or(SnoopLogger::kBtSnoopLogModeFiltered);
61   }
62 
63   btsnoop_mode = os::GetSystemProperty(SnoopLogger::kBtSnoopLogModeProperty).value_or(btsnoop_mode);
64 
65   // Only allow a subset of values:
66   if (!(btsnoop_mode == SnoopLogger::kBtSnoopLogModeDisabled ||
67         btsnoop_mode == SnoopLogger::kBtSnoopLogModeFull ||
68         btsnoop_mode == SnoopLogger::kBtSnoopLogModeFiltered ||
69         btsnoop_mode == SnoopLogger::kBtSnoopLogModeKernel)) {
70     log::warn("{}: Invalid btsnoop value, default back to disabled", btsnoop_mode);
71     return SnoopLogger::kBtSnoopLogModeDisabled;
72   }
73 
74   return btsnoop_mode;
75 }
76 
77 // Adds L2CAP channel to acceptlist.
AddL2capCid(uint16_t local_cid,uint16_t remote_cid)78 void FilterTracker::AddL2capCid(uint16_t local_cid, uint16_t remote_cid) {
79   l2c_local_cid.insert(local_cid);
80   l2c_remote_cid.insert(remote_cid);
81 }
82 
83 // Sets L2CAP channel that RFCOMM uses.
SetRfcommCid(uint16_t local_cid,uint16_t remote_cid)84 void FilterTracker::SetRfcommCid(uint16_t local_cid, uint16_t remote_cid) {
85   rfcomm_local_cid = local_cid;
86   rfcomm_remote_cid = remote_cid;
87 }
88 
89 // Remove L2CAP channel from acceptlist.
RemoveL2capCid(uint16_t local_cid,uint16_t remote_cid)90 void FilterTracker::RemoveL2capCid(uint16_t local_cid, uint16_t remote_cid) {
91   if (rfcomm_local_cid == local_cid) {
92     rfcomm_channels.clear();
93     rfcomm_channels.insert(0);
94     rfcomm_local_cid = 0;
95     rfcomm_remote_cid = 0;
96   }
97 
98   l2c_local_cid.erase(local_cid);
99   l2c_remote_cid.erase(remote_cid);
100 }
101 
AddRfcommDlci(uint8_t channel)102 void FilterTracker::AddRfcommDlci(uint8_t channel) { rfcomm_channels.insert(channel); }
103 
IsAcceptlistedL2cap(bool local,uint16_t cid)104 bool FilterTracker::IsAcceptlistedL2cap(bool local, uint16_t cid) {
105   const auto& set = local ? l2c_local_cid : l2c_remote_cid;
106   return set.find(cid) != set.end();
107 }
108 
IsRfcommChannel(bool local,uint16_t cid)109 bool FilterTracker::IsRfcommChannel(bool local, uint16_t cid) {
110   const auto& channel = local ? rfcomm_local_cid : rfcomm_remote_cid;
111   return cid == channel;
112 }
113 
IsAcceptlistedDlci(uint8_t dlci)114 bool FilterTracker::IsAcceptlistedDlci(uint8_t dlci) {
115   return rfcomm_channels.find(dlci) != rfcomm_channels.end();
116 }
117 
SetupProfilesFilter(bool pbap_filtered,bool map_filtered)118 void ProfilesFilter::SetupProfilesFilter(bool pbap_filtered, bool map_filtered) {
119   if (setup_done_flag) {
120     return;
121   }
122   setup_done_flag = true;
123 
124   log::debug("SetupProfilesFilter: pbap={}, map={}", pbap_filtered, map_filtered);
125 
126   for (int i = 0; i < FILTER_PROFILE_MAX; i++) {
127     profiles[i].type = (profile_type_t)i;
128     profiles[i].enabled = false;
129     profiles[i].rfcomm_opened = false;
130     profiles[i].l2cap_opened = false;
131   }
132 
133   if (pbap_filtered) {
134     profiles[FILTER_PROFILE_PBAP].enabled = profiles[FILTER_PROFILE_HFP_HS].enabled =
135             profiles[FILTER_PROFILE_HFP_HF].enabled = true;
136   }
137   if (map_filtered) {
138     profiles[FILTER_PROFILE_MAP].enabled = true;
139   }
140   ch_rfc_l = ch_rfc_r = ch_last = 0;
141 
142   PrintProfilesConfig();
143 }
144 
IsHfpProfile(bool local,uint16_t cid,uint8_t dlci)145 bool ProfilesFilter::IsHfpProfile(bool local, uint16_t cid, uint8_t dlci) {
146   profile_type_t profile = DlciToProfile(local, cid, dlci);
147   return profile == FILTER_PROFILE_HFP_HS || profile == FILTER_PROFILE_HFP_HF;
148 }
149 
IsL2capFlowExt(bool local,uint16_t cid)150 bool ProfilesFilter::IsL2capFlowExt(bool local, uint16_t cid) {
151   profile_type_t profile = CidToProfile(local, cid);
152   if (profile >= 0) {
153     return profiles[profile].flow_ext_l2cap;
154   }
155   return false;
156 }
157 
IsRfcommFlowExt(bool local,uint16_t cid,uint8_t dlci)158 bool ProfilesFilter::IsRfcommFlowExt(bool local, uint16_t cid, uint8_t dlci) {
159   profile_type_t profile = DlciToProfile(local, cid, dlci);
160   if (profile >= 0) {
161     current_profile = profile;
162   }
163   return profiles[profile].flow_ext_rfcomm;
164 }
165 
CidToProfile(bool local,uint16_t cid)166 profile_type_t ProfilesFilter::CidToProfile(bool local, uint16_t cid) {
167   uint16_t ch;
168   for (int i = 0; i < FILTER_PROFILE_MAX; i++) {
169     if (profiles[i].enabled && profiles[i].l2cap_opened) {
170       ch = local ? profiles[i].lcid : profiles[i].rcid;
171       if (ch == cid) {
172         return (profile_type_t)i;
173       }
174     }
175   }
176   return FILTER_PROFILE_NONE;
177 }
178 
DlciToProfile(bool local,uint16_t cid,uint8_t dlci)179 profile_type_t ProfilesFilter::DlciToProfile(bool local, uint16_t cid, uint8_t dlci) {
180   if (!IsRfcommChannel(local, cid)) {
181     return FILTER_PROFILE_NONE;
182   }
183 
184   for (int i = 0; i < FILTER_PROFILE_MAX; i++) {
185     if (profiles[i].enabled && profiles[i].l2cap_opened && profiles[i].rfcomm_opened &&
186         profiles[i].scn == (dlci >> 1)) {
187       return (profile_type_t)i;
188     }
189   }
190   return FILTER_PROFILE_NONE;
191 }
192 
ProfileL2capOpen(profile_type_t profile,uint16_t lcid,uint16_t rcid,uint16_t psm,bool flow_ext)193 void ProfilesFilter::ProfileL2capOpen(profile_type_t profile, uint16_t lcid, uint16_t rcid,
194                                       uint16_t psm, bool flow_ext) {
195   if (profiles[profile].l2cap_opened == true) {
196     log::debug("l2cap for {} was already opened. Override it", profile);
197   }
198   log::debug("lcid:={}, rcid={}, psm={}, flow_ext={}, filter profile={}", lcid, rcid, psm, flow_ext,
199              ProfilesFilter::ProfileToString(profile));
200   profiles[profile].lcid = lcid;
201   profiles[profile].rcid = rcid;
202   profiles[profile].psm = psm;
203   profiles[profile].flow_ext_l2cap = flow_ext;
204   profiles[profile].l2cap_opened = true;
205 
206   PrintProfilesConfig();
207 }
208 
ProfileL2capClose(profile_type_t profile)209 void ProfilesFilter::ProfileL2capClose(profile_type_t profile) {
210   if (profile < 0 || profile >= FILTER_PROFILE_MAX) {
211     return;
212   }
213   profiles[profile].l2cap_opened = false;
214 }
215 
ProfileRfcommOpen(profile_type_t profile,uint16_t lcid,uint8_t dlci,uint16_t uuid,bool flow_ext)216 void ProfilesFilter::ProfileRfcommOpen(profile_type_t profile, uint16_t lcid, uint8_t dlci,
217                                        uint16_t uuid, bool flow_ext) {
218   if (profiles[profile].rfcomm_opened == true) {
219     log::debug("rfcomm for {} was already opened. Override it", profile);
220   }
221   log::debug("lcid:={}, dlci={}, uuid={}, flow_ext={}, filter profile={}", lcid, dlci, uuid,
222              flow_ext, ProfilesFilter::ProfileToString(profile));
223   profiles[profile].rfcomm_uuid = uuid;
224   profiles[profile].scn = (dlci >> 1);
225   profiles[profile].flow_ext_rfcomm = flow_ext;
226   profiles[profile].l2cap_opened = true;
227   profiles[profile].rfcomm_opened = true;
228 
229   PrintProfilesConfig();
230 }
231 
ProfileRfcommClose(profile_type_t profile)232 void ProfilesFilter::ProfileRfcommClose(profile_type_t profile) {
233   if (profile < 0 || profile >= FILTER_PROFILE_MAX) {
234     return;
235   }
236   profiles[profile].rfcomm_opened = false;
237 }
238 
IsRfcommChannel(bool local,uint16_t cid)239 bool ProfilesFilter::IsRfcommChannel(bool local, uint16_t cid) {
240   uint16_t channel = local ? ch_rfc_l : ch_rfc_r;
241   return cid == channel;
242 }
243 
PrintProfilesConfig()244 void ProfilesFilter::PrintProfilesConfig() {
245   for (int i = 0; i < FILTER_PROFILE_MAX; i++) {
246     if (profiles[i].enabled) {
247       log::debug(
248               "\ntype: {}\nenabled: {}, l2cap_opened: {}, rfcomm_opened: {}\nflow_ext_l2cap: {}, "
249               "flow_ext_rfcomm: {}\nlcid: {}, rcid: {}, rfcomm_uuid: {}, psm: {}\nscn: {}\n",
250               ProfilesFilter::ProfileToString(profiles[i].type), profiles[i].enabled,
251               profiles[i].l2cap_opened, profiles[i].rfcomm_opened, profiles[i].flow_ext_l2cap,
252               profiles[i].flow_ext_rfcomm, profiles[i].lcid, profiles[i].rcid,
253               profiles[i].rfcomm_uuid, profiles[i].psm, profiles[i].psm);
254     }
255   }
256 }
257 
258 namespace {
259 
260 // Epoch in microseconds since 01/01/0000.
261 constexpr uint64_t kBtSnoopEpochDelta = 0x00dcddb30f2f8000ULL;
262 
263 // Qualcomm debug logs handle
264 constexpr uint16_t kQualcommDebugLogHandle = 0xedc;
265 
266 // Number of bytes into a packet where you can find the value for a channel.
267 constexpr size_t ACL_CHANNEL_OFFSET = 0;
268 constexpr size_t ACL_LENGTH_OFFSET = 2;
269 constexpr size_t L2CAP_PDU_LENGTH_OFFSET = 4;
270 constexpr size_t L2CAP_CHANNEL_OFFSET = 6;
271 constexpr size_t L2CAP_CONTROL_OFFSET = 8;
272 constexpr size_t RFCOMM_CHANNEL_OFFSET = 8;
273 constexpr size_t RFCOMM_EVENT_OFFSET = 9;
274 
275 // RFCOMM filtering consts
276 constexpr uint8_t RFCOMM_SABME = 0x2F;  // RFCOMM: Start Asynchronous Balanced Mode (startup cmd)
277 constexpr uint8_t RFCOMM_UA = 0x63;     // RFCOMM: Unnumbered Acknowledgement (rsp when connected)
278 constexpr uint8_t RFCOMM_UIH = 0xEF;    // RFCOMM: Unnumbered Information with Header check
279 
280 constexpr uint8_t START_PACKET_BOUNDARY = 0x02;
281 constexpr uint8_t CONTINUATION_PACKET_BOUNDARY = 0x01;
282 constexpr uint16_t HANDLE_MASK = 0x0FFF;
__anon695bd3640202(auto handle) 283 auto GetBoundaryFlag = [](auto handle) { return ((handle) >> 12) & 0x0003; };
284 
285 // ProfilesFilter consts
286 constexpr size_t ACL_HEADER_LENGTH = 4;
287 constexpr size_t BASIC_L2CAP_HEADER_LENGTH = 4;
288 constexpr uint8_t EXTRA_BUF_SIZE = 0x40;
289 constexpr uint16_t DEFAULT_PACKET_SIZE = 0x800;
290 
291 constexpr uint8_t PROFILE_SCN_PBAP = 19;
292 constexpr uint8_t PROFILE_SCN_MAP = 26;
293 
294 constexpr uint16_t PROFILE_PSM_PBAP = 0x1025;
295 constexpr uint16_t PROFILE_PSM_MAP = 0x1029;
296 constexpr uint16_t PROFILE_PSM_RFCOMM = 0x0003;
297 
298 constexpr uint16_t PROFILE_UUID_PBAP = 0x112f;
299 constexpr uint16_t PROFILE_UUID_MAP = 0x1132;
300 constexpr uint16_t PROFILE_UUID_HFP_HS = 0x1112;
301 constexpr uint16_t PROFILE_UUID_HFP_HF = 0x111f;
302 
htonll(uint64_t ll)303 uint64_t htonll(uint64_t ll) {
304   if constexpr (isLittleEndian) {
305     return static_cast<uint64_t>(htonl(ll & 0xffffffff)) << 32 | htonl(ll >> 32);
306   } else {
307     return ll;
308   }
309 }
310 
311 // The number of packets per btsnoop file before we rotate to the next file. As of right now there
312 // are two snoop files that are rotated through. The size can be dynamically configured by setting
313 // the relevant system property
314 constexpr size_t kDefaultBtSnoopMaxPacketsPerFile = 0xffff;
315 
316 // We restrict the maximum packet size to 150 bytes
317 constexpr size_t kDefaultBtSnoozMaxBytesPerPacket = 150;
318 constexpr size_t kDefaultBtSnoozMaxPayloadBytesPerPacket =
319         kDefaultBtSnoozMaxBytesPerPacket - sizeof(SnoopLogger::PacketHeaderType);
320 
321 using namespace std::chrono_literals;
322 constexpr std::chrono::hours kBtSnoozLogLifeTime = 12h;
323 constexpr std::chrono::hours kBtSnoozLogDeleteRepeatingAlarmInterval = 1h;
324 
325 std::mutex filter_tracker_list_mutex;
326 std::unordered_map<uint16_t, FilterTracker> filter_tracker_list;
327 std::unordered_map<uint16_t, uint16_t> local_cid_to_acl;
328 
329 std::mutex a2dpMediaChannels_mutex;
330 std::vector<SnoopLogger::A2dpMediaChannel> a2dpMediaChannels;
331 
332 std::mutex snoop_log_filters_mutex;
333 
334 std::mutex profiles_filter_mutex;
335 std::unordered_map<int16_t, ProfilesFilter> profiles_filter_table;
336 constexpr const char* payload_fill_magic = "PROHIBITED";
337 constexpr const char* cpbr_pattern = "\x0d\x0a+CPBR:";
338 constexpr const char* clcc_pattern = "\x0d\x0a+CLCC:";
339 const uint32_t magic_pat_len = strlen(payload_fill_magic);
340 const uint32_t cpbr_pat_len = strlen(cpbr_pattern);
341 const uint32_t clcc_pat_len = strlen(clcc_pattern);
342 
get_btsnoop_log_path(std::string log_dir,bool filtered)343 std::string get_btsnoop_log_path(std::string log_dir, bool filtered) {
344   if (filtered) {
345     log_dir.append(".filtered");
346   }
347   return log_dir;
348 }
349 
get_last_log_path(std::string log_file_path)350 std::string get_last_log_path(std::string log_file_path) { return log_file_path.append(".last"); }
351 
352 #ifdef __ANDROID__
create_log_directories()353 static bool create_log_directories() {
354   std::filesystem::path default_path = os::ParameterProvider::SnoopLogFilePath();
355   std::filesystem::path default_dir_path = default_path.parent_path();
356 
357   if (std::filesystem::exists(default_dir_path)) {
358     log::info("Directory {} already exists", default_dir_path.string());
359     return true;
360   }
361 
362   log::info("Creating directory: {}", default_dir_path.string());
363   return std::filesystem::create_directories(default_dir_path);
364 }
365 #endif  // __ANDROID__
366 
delete_btsnoop_files(const std::string & log_path)367 void delete_btsnoop_files(const std::string& log_path) {
368   log::info("Deleting logs if they exist");
369   if (os::FileExists(log_path)) {
370     if (!os::RemoveFile(log_path)) {
371       log::error("Failed to remove main log file at \"{}\"", log_path);
372     }
373   } else {
374     log::info("Main log file does not exist at \"{}\"", log_path);
375   }
376   auto last_log_path = get_last_log_path(log_path);
377   if (os::FileExists(last_log_path)) {
378     if (!os::RemoveFile(last_log_path)) {
379       log::error("Failed to remove last log file at \"{}\"", log_path);
380     }
381   } else {
382     log::info("Last log file does not exist at \"{}\"", log_path);
383   }
384 }
385 
delete_old_btsnooz_files(const std::string & log_path,const std::chrono::milliseconds log_life_time)386 void delete_old_btsnooz_files(const std::string& log_path,
387                               const std::chrono::milliseconds log_life_time) {
388   auto opt_created_ts = os::FileCreatedTime(log_path);
389   if (!opt_created_ts) {
390     return;
391   }
392 #ifdef USE_FAKE_TIMERS
393   auto diff = fake_timerfd_get_clock() - file_creation_time;
394   uint64_t log_lifetime = log_life_time.count();
395   if (diff >= log_lifetime) {
396 #else
397   using namespace std::chrono;
398   auto created_tp = opt_created_ts.value();
399   auto current_tp = std::chrono::system_clock::now();
400 
401   auto diff = duration_cast<milliseconds>(current_tp - created_tp);
402   if (diff >= log_life_time) {
403 #endif
404     delete_btsnoop_files(log_path);
405   }
406 }
407 
408 size_t get_btsnooz_packet_length_to_write(const HciPacket& packet, SnoopLogger::PacketType type,
409                                           bool qualcomm_debug_log_enabled) {
410   static const size_t kAclHeaderSize = 4;
411   static const size_t kL2capHeaderSize = 4;
412   static const size_t kL2capCidOffset = (kAclHeaderSize + 2);
413   static const uint16_t kL2capSignalingCid = 0x0001;
414 
415   static const size_t kHciAclHandleOffset = 0;
416 
417   // Maximum amount of ACL data to log.
418   // Enough for an RFCOMM frame up to the frame check;
419   // not enough for a HID report or audio data.
420   static const size_t kMaxBtsnoozAclSize = 14;
421 
422   // Calculate packet length to be included
423   size_t included_length = 0;
424   switch (type) {
425     case SnoopLogger::PacketType::CMD:
426     case SnoopLogger::PacketType::EVT:
427       included_length = packet.size();
428       break;
429 
430     case SnoopLogger::PacketType::ACL: {
431       // Log ACL and L2CAP header by default
432       size_t len_hci_acl = kAclHeaderSize + kL2capHeaderSize;
433       // Check if we have enough data for an L2CAP header
434       if (packet.size() > len_hci_acl) {
435         uint16_t l2cap_cid =
436                 static_cast<uint16_t>(packet[kL2capCidOffset]) |
437                 static_cast<uint16_t>(static_cast<uint16_t>(packet[kL2capCidOffset + 1])
438                                       << static_cast<uint16_t>(8));
439         uint16_t hci_acl_packet_handle =
440                 static_cast<uint16_t>(packet[kHciAclHandleOffset]) |
441                 static_cast<uint16_t>(static_cast<uint16_t>(packet[kHciAclHandleOffset + 1])
442                                       << static_cast<uint16_t>(8));
443         hci_acl_packet_handle &= 0x0fff;
444 
445         if (l2cap_cid == kL2capSignalingCid) {
446           // For the signaling CID, take the full packet.
447           // That way, the PSM setup is captured, allowing decoding of PSMs down
448           // the road.
449           return packet.size();
450         } else if (qualcomm_debug_log_enabled && hci_acl_packet_handle == kQualcommDebugLogHandle) {
451           return packet.size();
452         } else {
453           // Otherwise, return as much as we reasonably can
454           len_hci_acl = kMaxBtsnoozAclSize;
455         }
456       }
457       included_length = std::min(len_hci_acl, packet.size());
458       break;
459     }
460 
461     case SnoopLogger::PacketType::ISO:
462     case SnoopLogger::PacketType::SCO:
463     default:
464       // We are not logging SCO and ISO packets in snooz log as they may contain voice data
465       break;
466   }
467   return std::min(included_length, kDefaultBtSnoozMaxPayloadBytesPerPacket);
468 }
469 
470 }  // namespace
471 
472 // system properties
473 const std::string SnoopLogger::kBtSnoopMaxPacketsPerFileProperty = "persist.bluetooth.btsnoopsize";
474 const std::string SnoopLogger::kRoBuildType = "ro.build.type";
475 const std::string SnoopLogger::kBtSnoopLogModeProperty = "persist.bluetooth.btsnooplogmode";
476 const std::string SnoopLogger::kBtSnoopDefaultLogModeProperty =
477         "persist.bluetooth.btsnoopdefaultmode";
478 const std::string SnoopLogger::kBtSnoopLogPersists = "persist.bluetooth.btsnooplogpersists";
479 // Truncates ACL packets (non-fragment) to fixed (MAX_HCI_ACL_LEN) number of bytes
480 const std::string SnoopLogger::kBtSnoopLogFilterHeadersProperty =
481         "persist.bluetooth.snooplogfilter.headers.enabled";
482 // Discards A2DP media packets (non-split mode)
483 const std::string SnoopLogger::kBtSnoopLogFilterProfileA2dpProperty =
484         "persist.bluetooth.snooplogfilter.profiles.a2dp.enabled";
485 // Filters MAP packets based on the filter mode
486 const std::string SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty =
487         "persist.bluetooth.snooplogfilter.profiles.map";
488 // Filters PBAP and HFP packets (CPBR, CLCC) based on the filter mode
489 const std::string SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty =
490         "persist.bluetooth.snooplogfilter.profiles.pbap";
491 // Truncates RFCOMM UIH packet to fixed (L2CAP_HEADER_SIZE) number of bytes
492 const std::string SnoopLogger::kBtSnoopLogFilterProfileRfcommProperty =
493         "persist.bluetooth.snooplogfilter.profiles.rfcomm.enabled";
494 const std::string SnoopLogger::kSoCManufacturerProperty = "ro.soc.manufacturer";
495 
496 // persist.bluetooth.btsnooplogmode
497 const std::string SnoopLogger::kBtSnoopLogModeKernel = "kernel";
498 const std::string SnoopLogger::kBtSnoopLogModeDisabled = "disabled";
499 const std::string SnoopLogger::kBtSnoopLogModeFiltered = "filtered";
500 const std::string SnoopLogger::kBtSnoopLogModeFull = "full";
501 // ro.soc.manufacturer
502 const std::string SnoopLogger::kSoCManufacturerQualcomm = "Qualcomm";
503 
504 // PBAP, MAP and HFP packets filter mode - discard whole packet
505 const std::string SnoopLogger::kBtSnoopLogFilterProfileModeFullfillter = "fullfilter";
506 // PBAP, MAP and HFP packets filter mode - truncate to fixed length
507 const std::string SnoopLogger::kBtSnoopLogFilterProfileModeHeader = "header";
508 // PBAP, MAP and HFP packets filter mode - fill with a magic string, such as: "PROHIBITED"
509 const std::string SnoopLogger::kBtSnoopLogFilterProfileModeMagic = "magic";
510 // PBAP, MAP and HFP packets filter mode - disabled
511 const std::string SnoopLogger::kBtSnoopLogFilterProfileModeDisabled = "disabled";
512 
513 // Consts accessible in unit tests
514 const size_t SnoopLogger::PACKET_TYPE_LENGTH = 1;
515 const size_t SnoopLogger::MAX_HCI_ACL_LEN = 14;
516 const uint32_t SnoopLogger::L2CAP_HEADER_SIZE = 8;
517 
SnoopLogger(os::Handler * handler)518 SnoopLogger::SnoopLogger(os::Handler* handler)
519     : SnoopLogger(handler, os::ParameterProvider::SnoopLogFilePath(),
520                   os::ParameterProvider::SnoozLogFilePath(), GetMaxPacketsPerFile(),
521                   GetMaxPacketsPerBuffer(), GetBtSnoopMode(), IsQualcommDebugLogEnabled(),
522                   kBtSnoozLogLifeTime, kBtSnoozLogDeleteRepeatingAlarmInterval,
523                   IsBtSnoopLogPersisted()) {}
524 
SnoopLogger(os::Handler * handler,std::string snoop_log_path,std::string snooz_log_path,size_t max_packets_per_file,size_t max_packets_per_buffer,const std::string & btsnoop_mode,bool qualcomm_debug_log_enabled,const std::chrono::milliseconds snooz_log_life_time,const std::chrono::milliseconds snooz_log_delete_alarm_interval,bool snoop_log_persists)525 SnoopLogger::SnoopLogger(os::Handler* handler, std::string snoop_log_path,
526                          std::string snooz_log_path, size_t max_packets_per_file,
527                          size_t max_packets_per_buffer, const std::string& btsnoop_mode,
528                          bool qualcomm_debug_log_enabled,
529                          const std::chrono::milliseconds snooz_log_life_time,
530                          const std::chrono::milliseconds snooz_log_delete_alarm_interval,
531                          bool snoop_log_persists)
532     : Module(handler),
533       btsnoop_mode_(btsnoop_mode),
534       snoop_log_path_(std::move(snoop_log_path)),
535       snooz_log_path_(std::move(snooz_log_path)),
536       max_packets_per_file_(max_packets_per_file),
537       btsnooz_buffer_(max_packets_per_buffer),
538       qualcomm_debug_log_enabled_(qualcomm_debug_log_enabled),
539       snooz_log_life_time_(snooz_log_life_time),
540       snooz_log_delete_alarm_interval_(snooz_log_delete_alarm_interval),
541       snoop_log_persists(snoop_log_persists) {
542   if (btsnoop_mode_ == kBtSnoopLogModeFiltered) {
543     log::info("Snoop Logs filtered mode enabled");
544     EnableFilters();
545     // delete unfiltered logs
546     delete_btsnoop_files(get_btsnoop_log_path(snoop_log_path_, false));
547     // delete snooz logs
548     delete_btsnoop_files(snooz_log_path_);
549   } else if (btsnoop_mode_ == kBtSnoopLogModeFull) {
550     log::info("Snoop Logs full mode enabled");
551     if (!snoop_log_persists) {
552       // delete filtered logs
553       delete_btsnoop_files(get_btsnoop_log_path(snoop_log_path_, true));
554       // delete snooz logs
555       delete_btsnoop_files(snooz_log_path_);
556     }
557   } else {
558     log::info("Snoop Logs disabled");
559     // delete both filtered and unfiltered logs
560     delete_btsnoop_files(get_btsnoop_log_path(snoop_log_path_, true));
561     delete_btsnoop_files(get_btsnoop_log_path(snoop_log_path_, false));
562   }
563 
564   snoop_logger_socket_thread_ = nullptr;
565   socket_ = nullptr;
566   // Add ".filtered" extension if necessary
567   snoop_log_path_ = get_btsnoop_log_path(snoop_log_path_, btsnoop_mode_ == kBtSnoopLogModeFiltered);
568 }
569 
CloseCurrentSnoopLogFile()570 void SnoopLogger::CloseCurrentSnoopLogFile() {
571   std::lock_guard<std::recursive_mutex> lock(file_mutex_);
572   if (btsnoop_ostream_.is_open()) {
573     btsnoop_ostream_.flush();
574     btsnoop_ostream_.close();
575   }
576   packet_counter_ = 0;
577 }
578 
OpenNextSnoopLogFile()579 void SnoopLogger::OpenNextSnoopLogFile() {
580   std::lock_guard<std::recursive_mutex> lock(file_mutex_);
581   CloseCurrentSnoopLogFile();
582 
583   auto last_file_path = get_last_log_path(snoop_log_path_);
584 
585 #ifdef __ANDROID__
586   if (com::android::bluetooth::flags::snoop_logger_recreate_logs_directory() &&
587       !create_log_directories()) {
588     log::error("Could not recreate log directory");
589   }
590 #endif  // __ANDROID__
591 
592   if (os::FileExists(snoop_log_path_)) {
593     if (!os::RenameFile(snoop_log_path_, last_file_path)) {
594       log::error("Unabled to rename existing snoop log from \"{}\" to \"{}\"", snoop_log_path_,
595                  last_file_path);
596     }
597   } else {
598     log::info("Previous log file \"{}\" does not exist, skip renaming", snoop_log_path_);
599   }
600 
601   mode_t prevmask = umask(0);
602   // do not use std::ios::app as we want override the existing file
603   btsnoop_ostream_.open(snoop_log_path_, std::ios::binary | std::ios::out);
604 #ifdef USE_FAKE_TIMERS
605   file_creation_time = fake_timerfd_get_clock();
606 #endif
607   if (!btsnoop_ostream_.good()) {
608     log::fatal("Unable to open snoop log at \"{}\", error: \"{}\"", snoop_log_path_,
609                strerror(errno));
610   }
611   umask(prevmask);
612   if (!btsnoop_ostream_.write(reinterpret_cast<const char*>(&SnoopLoggerCommon::kBtSnoopFileHeader),
613                               sizeof(SnoopLoggerCommon::FileHeaderType))) {
614     log::fatal("Unable to write file header to \"{}\", error: \"{}\"", snoop_log_path_,
615                strerror(errno));
616   }
617   if (!btsnoop_ostream_.flush()) {
618     log::error("Failed to flush, error: \"{}\"", strerror(errno));
619   }
620 }
621 
EnableFilters()622 void SnoopLogger::EnableFilters() {
623   std::lock_guard<std::mutex> lock(snoop_log_filters_mutex);
624   for (auto itr = kBtSnoopLogFilterState.begin(); itr != kBtSnoopLogFilterState.end(); itr++) {
625     auto filter_enabled_property = os::GetSystemProperty(itr->first);
626     if (filter_enabled_property) {
627       itr->second = filter_enabled_property.value() == "true";
628     }
629     log::info("{}: {}", itr->first, itr->second);
630   }
631   for (auto itr = kBtSnoopLogFilterMode.begin(); itr != kBtSnoopLogFilterMode.end(); itr++) {
632     auto filter_mode_property = os::GetSystemProperty(itr->first);
633     if (filter_mode_property) {
634       itr->second = filter_mode_property.value();
635     } else {
636       itr->second = SnoopLogger::kBtSnoopLogFilterProfileModeDisabled;
637     }
638     log::info("{}: {}", itr->first, itr->second);
639   }
640 }
641 
DisableFilters()642 void SnoopLogger::DisableFilters() {
643   std::lock_guard<std::mutex> lock(snoop_log_filters_mutex);
644   for (auto itr = kBtSnoopLogFilterState.begin(); itr != kBtSnoopLogFilterState.end(); itr++) {
645     itr->second = false;
646     log::info("{}, {}", itr->first, itr->second);
647   }
648   for (auto itr = kBtSnoopLogFilterMode.begin(); itr != kBtSnoopLogFilterMode.end(); itr++) {
649     itr->second = SnoopLogger::kBtSnoopLogFilterProfileModeDisabled;
650     log::info("{}, {}", itr->first, itr->second);
651   }
652 }
653 
IsFilterEnabled(std::string filter_name)654 bool SnoopLogger::IsFilterEnabled(std::string filter_name) {
655   std::lock_guard<std::mutex> lock(snoop_log_filters_mutex);
656   for (auto itr = kBtSnoopLogFilterState.begin(); itr != kBtSnoopLogFilterState.end(); itr++) {
657     if (filter_name == itr->first) {
658       return itr->second == true;
659     }
660   }
661   for (auto itr = kBtSnoopLogFilterMode.begin(); itr != kBtSnoopLogFilterMode.end(); itr++) {
662     if (filter_name == itr->first) {
663       return itr->second != SnoopLogger::kBtSnoopLogFilterProfileModeDisabled;
664     }
665   }
666   return false;
667 }
668 
ShouldFilterLog(bool is_received,uint8_t * packet)669 bool SnoopLogger::ShouldFilterLog(bool is_received, uint8_t* packet) {
670   uint16_t conn_handle =
671           ((((uint16_t)packet[ACL_CHANNEL_OFFSET + 1]) << 8) + packet[ACL_CHANNEL_OFFSET]) & 0x0fff;
672   std::lock_guard<std::mutex> lock(filter_tracker_list_mutex);
673   auto& filters = filter_tracker_list[conn_handle];
674   uint16_t cid = (packet[L2CAP_CHANNEL_OFFSET + 1] << 8) + packet[L2CAP_CHANNEL_OFFSET];
675   if (filters.IsRfcommChannel(is_received, cid)) {
676     uint8_t rfcomm_event = packet[RFCOMM_EVENT_OFFSET] & 0b11101111;
677     if (rfcomm_event == RFCOMM_SABME || rfcomm_event == RFCOMM_UA) {
678       return false;
679     }
680 
681     uint8_t rfcomm_dlci = packet[RFCOMM_CHANNEL_OFFSET] >> 2;
682     if (!filters.IsAcceptlistedDlci(rfcomm_dlci)) {
683       return true;
684     }
685   } else if (!filters.IsAcceptlistedL2cap(is_received, cid)) {
686     return true;
687   }
688 
689   return false;
690 }
691 
CalculateAclPacketLength(uint32_t & length,uint8_t * packet,bool)692 void SnoopLogger::CalculateAclPacketLength(uint32_t& length, uint8_t* packet,
693                                            bool /* is_received */) {
694   uint32_t def_len =
695           ((((uint16_t)packet[ACL_LENGTH_OFFSET + 1]) << 8) + packet[ACL_LENGTH_OFFSET]) +
696           ACL_HEADER_LENGTH + PACKET_TYPE_LENGTH;
697   constexpr uint16_t L2CAP_SIGNALING_CID = 0x0001;
698 
699   if (length == 0) {
700     return;
701   }
702 
703   uint16_t handle =
704           ((((uint16_t)packet[ACL_CHANNEL_OFFSET + 1]) << 8) + packet[ACL_CHANNEL_OFFSET]);
705   uint8_t boundary_flag = GetBoundaryFlag(handle);
706   handle = handle & HANDLE_MASK;
707 
708   if (boundary_flag == START_PACKET_BOUNDARY) {
709     uint16_t l2cap_cid = packet[L2CAP_CHANNEL_OFFSET] | (packet[L2CAP_CHANNEL_OFFSET + 1] << 8);
710     if (l2cap_cid == L2CAP_SIGNALING_CID || handle == kQualcommDebugLogHandle) {
711       length = def_len;
712     } else {
713       if (def_len < MAX_HCI_ACL_LEN) {
714         length = def_len;
715       } else {
716         // Otherwise, return as much as we reasonably can
717         length = MAX_HCI_ACL_LEN;
718       }
719     }
720   }
721 }
722 
PayloadStrip(profile_type_t current_profile,uint8_t * packet,uint32_t hdr_len,uint32_t pl_len)723 uint32_t SnoopLogger::PayloadStrip(profile_type_t current_profile, uint8_t* packet,
724                                    uint32_t hdr_len, uint32_t pl_len) {
725   uint32_t len = 0;
726   std::string profile_filter_mode = "";
727   log::debug("current_profile={}, hdr len={}, total len={}",
728              ProfilesFilter::ProfileToString(current_profile), hdr_len, pl_len);
729   std::lock_guard<std::mutex> lock(snoop_log_filters_mutex);
730   switch (current_profile) {
731     case FILTER_PROFILE_PBAP:
732     case FILTER_PROFILE_HFP_HF:
733     case FILTER_PROFILE_HFP_HS:
734       profile_filter_mode =
735               kBtSnoopLogFilterMode[SnoopLogger::kBtSnoopLogFilterProfilePbapModeProperty];
736       break;
737     case FILTER_PROFILE_MAP:
738       profile_filter_mode =
739               kBtSnoopLogFilterMode[SnoopLogger::kBtSnoopLogFilterProfileMapModeProperty];
740       break;
741     default:
742       profile_filter_mode = kBtSnoopLogFilterProfileModeDisabled;
743   }
744 
745   if (profile_filter_mode == SnoopLogger::kBtSnoopLogFilterProfileModeFullfillter) {
746     return 0;
747   } else if (profile_filter_mode == SnoopLogger::kBtSnoopLogFilterProfileModeHeader) {
748     len = hdr_len;
749 
750     packet[ACL_LENGTH_OFFSET] = static_cast<uint8_t>(hdr_len - BASIC_L2CAP_HEADER_LENGTH);
751     packet[ACL_LENGTH_OFFSET + 1] =
752             static_cast<uint8_t>((hdr_len - BASIC_L2CAP_HEADER_LENGTH) >> 8);
753 
754     packet[L2CAP_PDU_LENGTH_OFFSET] =
755             static_cast<uint8_t>(hdr_len - (ACL_HEADER_LENGTH + BASIC_L2CAP_HEADER_LENGTH));
756     packet[L2CAP_PDU_LENGTH_OFFSET + 1] =
757             static_cast<uint8_t>((hdr_len - (ACL_HEADER_LENGTH + BASIC_L2CAP_HEADER_LENGTH)) >> 8);
758 
759   } else if (profile_filter_mode == SnoopLogger::kBtSnoopLogFilterProfileModeMagic) {
760     strcpy(reinterpret_cast<char*>(&packet[hdr_len]), payload_fill_magic);
761 
762     packet[ACL_LENGTH_OFFSET] =
763             static_cast<uint8_t>(hdr_len + magic_pat_len - BASIC_L2CAP_HEADER_LENGTH);
764     packet[ACL_LENGTH_OFFSET + 1] =
765             static_cast<uint8_t>((hdr_len + magic_pat_len - BASIC_L2CAP_HEADER_LENGTH) >> 8);
766 
767     packet[L2CAP_PDU_LENGTH_OFFSET] = static_cast<uint8_t>(
768             hdr_len + magic_pat_len - (ACL_HEADER_LENGTH + BASIC_L2CAP_HEADER_LENGTH));
769     packet[L2CAP_PDU_LENGTH_OFFSET + 1] = static_cast<uint8_t>(
770             (hdr_len + magic_pat_len - (ACL_HEADER_LENGTH + BASIC_L2CAP_HEADER_LENGTH)) >> 8);
771 
772     len = hdr_len + magic_pat_len;
773   } else {
774     // Return unchanged
775     len = hdr_len + pl_len;
776   }
777   return len + PACKET_TYPE_LENGTH;  // including packet type byte
778 }
779 
FilterProfilesHandleHfp(uint8_t * packet,uint32_t length,uint32_t totlen,uint32_t offset)780 uint32_t SnoopLogger::FilterProfilesHandleHfp(uint8_t* packet, uint32_t length, uint32_t totlen,
781                                               uint32_t offset) {
782   // CPBR packet
783   if ((totlen - offset) > cpbr_pat_len &&
784       memcmp(&packet[offset], cpbr_pattern, cpbr_pat_len) == 0) {
785     length = offset + cpbr_pat_len + 1;
786     packet[ACL_LENGTH_OFFSET] = offset + cpbr_pat_len - BASIC_L2CAP_HEADER_LENGTH;
787     packet[ACL_LENGTH_OFFSET + 1] = (offset + cpbr_pat_len - BASIC_L2CAP_HEADER_LENGTH) >> 8;
788 
789     packet[L2CAP_PDU_LENGTH_OFFSET] =
790             offset + cpbr_pat_len - (ACL_HEADER_LENGTH + BASIC_L2CAP_HEADER_LENGTH);
791     packet[L2CAP_PDU_LENGTH_OFFSET + 1] =
792             (offset + cpbr_pat_len - (ACL_HEADER_LENGTH + BASIC_L2CAP_HEADER_LENGTH)) >> 8;
793     return length;
794   }
795   // CLCC packet
796   if ((totlen - offset) > clcc_pat_len &&
797       memcmp(&packet[offset], clcc_pattern, clcc_pat_len) == 0) {
798     length = offset + cpbr_pat_len + 1;
799     packet[ACL_LENGTH_OFFSET] = offset + clcc_pat_len - BASIC_L2CAP_HEADER_LENGTH;
800     packet[ACL_LENGTH_OFFSET + 1] = (offset + clcc_pat_len - BASIC_L2CAP_HEADER_LENGTH) >> 8;
801 
802     packet[L2CAP_PDU_LENGTH_OFFSET] =
803             offset + clcc_pat_len - (ACL_HEADER_LENGTH + BASIC_L2CAP_HEADER_LENGTH);
804     packet[L2CAP_PDU_LENGTH_OFFSET + 1] =
805             (offset + clcc_pat_len - (ACL_HEADER_LENGTH + BASIC_L2CAP_HEADER_LENGTH)) >> 8;
806   }
807 
808   return length;
809 }
810 
FilterProfilesRfcommChannel(uint8_t * packet,uint8_t & current_offset,uint32_t & length,profile_type_t & current_profile,bluetooth::hal::ProfilesFilter & filters,bool is_received,uint16_t l2cap_channel,uint32_t & offset,uint32_t total_length)811 void SnoopLogger::FilterProfilesRfcommChannel(uint8_t* packet, uint8_t& current_offset,
812                                               uint32_t& length, profile_type_t& current_profile,
813                                               bluetooth::hal::ProfilesFilter& filters,
814                                               bool is_received, uint16_t l2cap_channel,
815                                               uint32_t& offset, uint32_t total_length) {
816   uint8_t addr, ctrl, pf;
817 
818   addr = packet[current_offset];
819   current_offset += 1;
820   ctrl = packet[RFCOMM_EVENT_OFFSET];
821   current_offset += 1;
822 
823   pf = ctrl & 0x10;
824   ctrl = ctrl & 0xef;
825   addr >>= 2;
826   if (ctrl != RFCOMM_UIH) {
827     return;
828   }
829   current_profile = filters.DlciToProfile(is_received, l2cap_channel, addr);
830   if (current_profile != FILTER_PROFILE_NONE) {
831     uint16_t len;
832     uint8_t ea;
833 
834     len = packet[current_offset];
835     current_offset += 1;
836     ea = len & 1;
837 
838     if (!ea) {
839       current_offset += 1;
840     }
841 
842     if (filters.IsRfcommFlowExt(is_received, l2cap_channel, addr) && pf) {
843       current_offset += 1;  // credit byte
844     }
845     offset = current_offset;
846 
847     if ((filters).IsHfpProfile(is_received, l2cap_channel, addr)) {
848       length = FilterProfilesHandleHfp(packet, length, total_length, offset);
849     } else {
850       length = PayloadStrip(current_profile, packet, offset, total_length - offset);
851     }
852   }
853 }
854 
FilterProfiles(bool is_received,uint8_t * packet)855 uint32_t SnoopLogger::FilterProfiles(bool is_received, uint8_t* packet) {
856   bool frag;
857   uint16_t handle, l2c_chan, l2c_ctl;
858   uint32_t length, totlen, offset;
859   uint8_t current_offset = 0;
860   profile_type_t current_profile = FILTER_PROFILE_NONE;
861   constexpr uint16_t L2CAP_SIGNALING_CID = 0x0001;
862 
863   std::lock_guard<std::mutex> lock(profiles_filter_mutex);
864 
865   handle = ((((uint16_t)packet[ACL_CHANNEL_OFFSET + 1]) << 8) + packet[ACL_CHANNEL_OFFSET]);
866   frag = (GetBoundaryFlag(handle) == CONTINUATION_PACKET_BOUNDARY);
867 
868   handle = handle & HANDLE_MASK;
869   current_offset += 2;
870 
871   length = (((uint16_t)packet[ACL_LENGTH_OFFSET + 1]) << 8) + packet[ACL_LENGTH_OFFSET];
872   current_offset += 2;
873   totlen = length + ACL_HEADER_LENGTH;
874   length += PACKET_TYPE_LENGTH + ACL_HEADER_LENGTH;  // Additional byte is added for packet type
875 
876   l2c_chan = ((uint16_t)packet[L2CAP_CHANNEL_OFFSET + 1] << 8) + packet[L2CAP_CHANNEL_OFFSET];
877   current_offset += 4;
878 
879   auto& filters = profiles_filter_table[handle];
880   if (frag) {
881     l2c_chan = filters.ch_last;
882   } else {
883     filters.ch_last = l2c_chan;
884   }
885 
886   if (l2c_chan != L2CAP_SIGNALING_CID && handle != kQualcommDebugLogHandle) {
887     if (filters.IsL2capFlowExt(is_received, l2c_chan)) {
888       l2c_ctl = ((uint16_t)packet[L2CAP_CONTROL_OFFSET + 1] << 8) + packet[L2CAP_CONTROL_OFFSET];
889       if (!(l2c_ctl & 1)) {                     // I-Frame
890         if (((l2c_ctl >> 14) & 0x3) == 0x01) {  // Start of L2CAP SDU
891           current_offset += 2;
892         }
893       }
894     }
895     offset = current_offset;
896     current_profile = filters.CidToProfile(is_received, l2c_chan);
897     if (current_profile != FILTER_PROFILE_NONE) {
898       if (frag) {
899         return PACKET_TYPE_LENGTH + ACL_HEADER_LENGTH;
900       }
901       return PayloadStrip(current_profile, packet, offset, totlen - offset);
902     }
903 
904     if (filters.IsRfcommChannel(is_received, l2c_chan)) {
905       FilterProfilesRfcommChannel(packet, current_offset, length, current_profile, filters,
906                                   is_received, l2c_chan, offset, totlen);
907     }
908   }
909 
910   return length;
911 }
912 
AcceptlistL2capChannel(uint16_t conn_handle,uint16_t local_cid,uint16_t remote_cid)913 void SnoopLogger::AcceptlistL2capChannel(uint16_t conn_handle, uint16_t local_cid,
914                                          uint16_t remote_cid) {
915   if (btsnoop_mode_ != kBtSnoopLogModeFiltered ||
916       !IsFilterEnabled(kBtSnoopLogFilterProfileRfcommProperty)) {
917     return;
918   }
919 
920   log::debug("Acceptlisting l2cap channel: conn_handle={}, local cid={}, remote cid={}",
921              conn_handle, local_cid, remote_cid);
922   std::lock_guard<std::mutex> lock(filter_tracker_list_mutex);
923 
924   // This will create the entry if there is no associated filter with the
925   // connection.
926   filter_tracker_list[conn_handle].AddL2capCid(local_cid, remote_cid);
927 }
928 
AcceptlistRfcommDlci(uint16_t conn_handle,uint16_t local_cid,uint8_t dlci)929 void SnoopLogger::AcceptlistRfcommDlci(uint16_t conn_handle, uint16_t local_cid, uint8_t dlci) {
930   if (btsnoop_mode_ != kBtSnoopLogModeFiltered ||
931       !IsFilterEnabled(kBtSnoopLogFilterProfileRfcommProperty)) {
932     return;
933   }
934 
935   log::debug("Acceptlisting rfcomm channel: local cid={}, dlci={}", local_cid, dlci);
936   std::lock_guard<std::mutex> lock(filter_tracker_list_mutex);
937 
938   filter_tracker_list[conn_handle].AddRfcommDlci(dlci);
939 }
940 
AddRfcommL2capChannel(uint16_t conn_handle,uint16_t local_cid,uint16_t remote_cid)941 void SnoopLogger::AddRfcommL2capChannel(uint16_t conn_handle, uint16_t local_cid,
942                                         uint16_t remote_cid) {
943   if (btsnoop_mode_ != kBtSnoopLogModeFiltered ||
944       !IsFilterEnabled(kBtSnoopLogFilterProfileRfcommProperty)) {
945     return;
946   }
947 
948   log::debug("Rfcomm data going over l2cap channel: conn_handle={} local cid={} remote cid={}",
949              conn_handle, local_cid, remote_cid);
950   std::lock_guard<std::mutex> lock(filter_tracker_list_mutex);
951 
952   filter_tracker_list[conn_handle].SetRfcommCid(local_cid, remote_cid);
953   local_cid_to_acl.insert({local_cid, conn_handle});
954 }
955 
ClearL2capAcceptlist(uint16_t conn_handle,uint16_t local_cid,uint16_t remote_cid)956 void SnoopLogger::ClearL2capAcceptlist(uint16_t conn_handle, uint16_t local_cid,
957                                        uint16_t remote_cid) {
958   if (btsnoop_mode_ != kBtSnoopLogModeFiltered ||
959       !IsFilterEnabled(kBtSnoopLogFilterProfileRfcommProperty)) {
960     return;
961   }
962 
963   log::debug("Clearing acceptlist from l2cap channel. conn_handle={} local cid={} remote cid={}",
964              conn_handle, local_cid, remote_cid);
965   std::lock_guard<std::mutex> lock(filter_tracker_list_mutex);
966 
967   filter_tracker_list[conn_handle].RemoveL2capCid(local_cid, remote_cid);
968 }
969 
IsA2dpMediaChannel(uint16_t conn_handle,uint16_t cid,bool is_local_cid)970 bool SnoopLogger::IsA2dpMediaChannel(uint16_t conn_handle, uint16_t cid, bool is_local_cid) {
971   if (btsnoop_mode_ != kBtSnoopLogModeFiltered ||
972       !IsFilterEnabled(kBtSnoopLogFilterProfileA2dpProperty)) {
973     return false;
974   }
975 
976   std::lock_guard<std::mutex> lock(a2dpMediaChannels_mutex);
977   auto iter = std::find_if(a2dpMediaChannels.begin(), a2dpMediaChannels.end(),
978                            [conn_handle, cid, is_local_cid](auto& el) {
979                              if (el.conn_handle != conn_handle) {
980                                return false;
981                              }
982 
983                              if (is_local_cid) {
984                                return el.local_cid == cid;
985                              }
986 
987                              return el.remote_cid == cid;
988                            });
989 
990   return iter != a2dpMediaChannels.end();
991 }
992 
IsA2dpMediaPacket(bool is_received,uint8_t * packet)993 bool SnoopLogger::IsA2dpMediaPacket(bool is_received, uint8_t* packet) {
994   uint16_t cid, conn_handle;
995   bool is_local_cid = is_received;
996   /*is_received signifies Rx packet so packet will have local_cid at offset 6
997    * Tx packet with is_received as false and have remote_cid at the offset*/
998 
999   conn_handle = (uint16_t)((packet[0] + (packet[1] << 8)) & 0x0FFF);
1000   cid = (uint16_t)(packet[6] + (packet[7] << 8));
1001 
1002   return IsA2dpMediaChannel(conn_handle, cid, is_local_cid);
1003 }
1004 
AddA2dpMediaChannel(uint16_t conn_handle,uint16_t local_cid,uint16_t remote_cid)1005 void SnoopLogger::AddA2dpMediaChannel(uint16_t conn_handle, uint16_t local_cid,
1006                                       uint16_t remote_cid) {
1007   if (btsnoop_mode_ != kBtSnoopLogModeFiltered ||
1008       !IsFilterEnabled(kBtSnoopLogFilterProfileA2dpProperty)) {
1009     return;
1010   }
1011 
1012   if (!SnoopLogger::IsA2dpMediaChannel(conn_handle, local_cid, true)) {
1013     log::info("Add A2DP media channel filtering. conn_handle={} local cid={} remote cid={}",
1014               conn_handle, local_cid, remote_cid);
1015     std::lock_guard<std::mutex> lock(a2dpMediaChannels_mutex);
1016     a2dpMediaChannels.push_back({conn_handle, local_cid, remote_cid});
1017   }
1018 }
1019 
RemoveA2dpMediaChannel(uint16_t conn_handle,uint16_t local_cid)1020 void SnoopLogger::RemoveA2dpMediaChannel(uint16_t conn_handle, uint16_t local_cid) {
1021   if (btsnoop_mode_ != kBtSnoopLogModeFiltered ||
1022       !IsFilterEnabled(kBtSnoopLogFilterProfileA2dpProperty)) {
1023     return;
1024   }
1025 
1026   std::lock_guard<std::mutex> lock(a2dpMediaChannels_mutex);
1027   a2dpMediaChannels.erase(std::remove_if(a2dpMediaChannels.begin(), a2dpMediaChannels.end(),
1028                                          [conn_handle, local_cid](auto& el) {
1029                                            return el.conn_handle == conn_handle &&
1030                                                   el.local_cid == local_cid;
1031                                          }),
1032                           a2dpMediaChannels.end());
1033 }
1034 
SetRfcommPortOpen(uint16_t conn_handle,uint16_t local_cid,uint8_t dlci,uint16_t uuid,bool flow)1035 void SnoopLogger::SetRfcommPortOpen(uint16_t conn_handle, uint16_t local_cid, uint8_t dlci,
1036                                     uint16_t uuid, bool flow) {
1037   if (btsnoop_mode_ != kBtSnoopLogModeFiltered ||
1038       (!IsFilterEnabled(kBtSnoopLogFilterProfilePbapModeProperty) &&
1039        !IsFilterEnabled(kBtSnoopLogFilterProfileMapModeProperty))) {
1040     return;
1041   }
1042 
1043   std::lock_guard<std::mutex> lock(profiles_filter_mutex);
1044 
1045   profile_type_t profile = FILTER_PROFILE_NONE;
1046   auto& filters = profiles_filter_table[conn_handle];
1047   {
1048     filters.SetupProfilesFilter(IsFilterEnabled(kBtSnoopLogFilterProfilePbapModeProperty),
1049                                 IsFilterEnabled(kBtSnoopLogFilterProfileMapModeProperty));
1050   }
1051 
1052   log::info(
1053           "RFCOMM port is opened: handle={}(0x{:x}), lcid={}(0x{:x}), dlci={}(0x{:x}), "
1054           "uuid={}(0x{:x}){}",
1055           conn_handle, conn_handle, local_cid, local_cid, dlci, dlci, uuid, uuid,
1056           flow ? " Credit Based Flow Control enabled" : "");
1057 
1058   if (uuid == PROFILE_UUID_PBAP || (dlci >> 1) == PROFILE_SCN_PBAP) {
1059     profile = FILTER_PROFILE_PBAP;
1060   } else if (uuid == PROFILE_UUID_MAP || (dlci >> 1) == PROFILE_SCN_MAP) {
1061     profile = FILTER_PROFILE_MAP;
1062   } else if (uuid == PROFILE_UUID_HFP_HS) {
1063     profile = FILTER_PROFILE_HFP_HS;
1064   } else if (uuid == PROFILE_UUID_HFP_HF) {
1065     profile = FILTER_PROFILE_HFP_HF;
1066   }
1067 
1068   if (profile >= 0) {
1069     filters.ProfileRfcommOpen(profile, local_cid, dlci, uuid, flow);
1070   }
1071 }
1072 
SetRfcommPortClose(uint16_t handle,uint16_t local_cid,uint8_t dlci,uint16_t uuid)1073 void SnoopLogger::SetRfcommPortClose(uint16_t handle, uint16_t local_cid, uint8_t dlci,
1074                                      uint16_t uuid) {
1075   if (btsnoop_mode_ != kBtSnoopLogModeFiltered ||
1076       (!IsFilterEnabled(kBtSnoopLogFilterProfilePbapModeProperty) &&
1077        !IsFilterEnabled(kBtSnoopLogFilterProfileMapModeProperty))) {
1078     return;
1079   }
1080 
1081   std::lock_guard<std::mutex> lock(profiles_filter_mutex);
1082 
1083   auto& filters = profiles_filter_table[handle];
1084   log::info(
1085           "RFCOMM port is closed: handle={}(0x{:x}), lcid={}(0x{:x}), dlci={}(0x{:x}), "
1086           "uuid={}(0x{:x})",
1087           handle, handle, local_cid, local_cid, dlci, dlci, uuid, uuid);
1088 
1089   filters.ProfileRfcommClose(filters.DlciToProfile(true, local_cid, dlci));
1090 }
1091 
SetL2capChannelOpen(uint16_t handle,uint16_t local_cid,uint16_t remote_cid,uint16_t psm,bool flow)1092 void SnoopLogger::SetL2capChannelOpen(uint16_t handle, uint16_t local_cid, uint16_t remote_cid,
1093                                       uint16_t psm, bool flow) {
1094   if (btsnoop_mode_ != kBtSnoopLogModeFiltered ||
1095       (!IsFilterEnabled(kBtSnoopLogFilterProfilePbapModeProperty) &&
1096        !IsFilterEnabled(kBtSnoopLogFilterProfileMapModeProperty))) {
1097     return;
1098   }
1099 
1100   std::lock_guard<std::mutex> lock(profiles_filter_mutex);
1101   profile_type_t profile = FILTER_PROFILE_NONE;
1102   auto& filters = profiles_filter_table[handle];
1103   {
1104     filters.SetupProfilesFilter(IsFilterEnabled(kBtSnoopLogFilterProfilePbapModeProperty),
1105                                 IsFilterEnabled(kBtSnoopLogFilterProfileMapModeProperty));
1106   }
1107 
1108   log::info(
1109           "L2CAP channel is opened: handle={}(0x{:x}), lcid={}(0x{:x}), rcid={}(0x{:x}), "
1110           "psm=0x{:x}{}",
1111           handle, handle, local_cid, local_cid, remote_cid, remote_cid, psm,
1112           flow ? " Standard or Enhanced Control enabled" : "");
1113 
1114   if (psm == PROFILE_PSM_RFCOMM) {
1115     filters.ch_rfc_l = local_cid;
1116     filters.ch_rfc_r = remote_cid;
1117   } else if (psm == PROFILE_PSM_PBAP) {
1118     profile = FILTER_PROFILE_PBAP;
1119   } else if (psm == PROFILE_PSM_MAP) {
1120     profile = FILTER_PROFILE_MAP;
1121   }
1122 
1123   if (profile >= 0) {
1124     filters.ProfileL2capOpen(profile, local_cid, remote_cid, psm, flow);
1125   }
1126 }
1127 
SetL2capChannelClose(uint16_t handle,uint16_t local_cid,uint16_t remote_cid)1128 void SnoopLogger::SetL2capChannelClose(uint16_t handle, uint16_t local_cid, uint16_t remote_cid) {
1129   if (btsnoop_mode_ != kBtSnoopLogModeFiltered ||
1130       (!IsFilterEnabled(kBtSnoopLogFilterProfilePbapModeProperty) &&
1131        !IsFilterEnabled(kBtSnoopLogFilterProfileMapModeProperty))) {
1132     return;
1133   }
1134 
1135   std::lock_guard<std::mutex> lock(profiles_filter_mutex);
1136 
1137   auto& filters = profiles_filter_table[handle];
1138 
1139   log::info("L2CAP channel is closed: handle={}(0x{:x}), lcid={}(0x{:x}), rcid={}(0x{:x})", handle,
1140             handle, local_cid, local_cid, remote_cid, remote_cid);
1141 
1142   filters.ProfileL2capClose(filters.CidToProfile(true, local_cid));
1143 }
1144 
FilterCapturedPacket(HciPacket & packet,Direction direction,PacketType type,uint32_t & length,PacketHeaderType header)1145 void SnoopLogger::FilterCapturedPacket(HciPacket& packet, Direction direction, PacketType type,
1146                                        uint32_t& length, PacketHeaderType header) {
1147   if (btsnoop_mode_ != kBtSnoopLogModeFiltered || type != PacketType::ACL) {
1148     return;
1149   }
1150 
1151   if (IsFilterEnabled(kBtSnoopLogFilterProfileA2dpProperty)) {
1152     if (IsA2dpMediaPacket(direction == Direction::INCOMING, (uint8_t*)packet.data())) {
1153       length = 0;
1154       return;
1155     }
1156   }
1157 
1158   if (IsFilterEnabled(kBtSnoopLogFilterHeadersProperty)) {
1159     CalculateAclPacketLength(length, (uint8_t*)packet.data(), direction == Direction::INCOMING);
1160   }
1161 
1162   if (IsFilterEnabled(kBtSnoopLogFilterProfilePbapModeProperty) ||
1163       IsFilterEnabled(kBtSnoopLogFilterProfileMapModeProperty)) {
1164     // If HeadersFiltered applied, do not use ProfilesFiltered
1165     if (length == ntohl(header.length_original)) {
1166       if (packet.size() + EXTRA_BUF_SIZE > DEFAULT_PACKET_SIZE) {
1167         // Add additional bytes for magic string in case
1168         // payload length is less than the length of magic string.
1169         packet.resize((size_t)(packet.size() + EXTRA_BUF_SIZE));
1170       }
1171 
1172       length = FilterProfiles(direction == Direction::INCOMING, (uint8_t*)packet.data());
1173       if (length == 0) {
1174         return;
1175       }
1176     }
1177   }
1178 
1179   if (IsFilterEnabled(kBtSnoopLogFilterProfileRfcommProperty)) {
1180     bool shouldFilter =
1181             SnoopLogger::ShouldFilterLog(direction == Direction::INCOMING, (uint8_t*)packet.data());
1182     if (shouldFilter) {
1183       length = L2CAP_HEADER_SIZE + PACKET_TYPE_LENGTH;
1184     }
1185   }
1186 }
1187 
Capture(const HciPacket & immutable_packet,Direction direction,PacketType type)1188 void SnoopLogger::Capture(const HciPacket& immutable_packet, Direction direction, PacketType type) {
1189   //// TODO(b/335520123) update FilterCapture to stop modifying packets ////
1190   HciPacket mutable_packet(immutable_packet);
1191   HciPacket& packet = mutable_packet;
1192   //////////////////////////////////////////////////////////////////////////
1193 
1194   uint64_t timestamp_us = std::chrono::duration_cast<std::chrono::microseconds>(
1195                                   std::chrono::system_clock::now().time_since_epoch())
1196                                   .count();
1197 #ifdef __ANDROID__
1198   if (com::android::bluetooth::flags::snoop_logger_tracing()) {
1199     LogTracePoint(packet, direction, type);
1200   }
1201 #endif  // __ANDROID__
1202 
1203   std::bitset<32> flags = 0;
1204   switch (type) {
1205     case PacketType::CMD:
1206       flags.set(0, false);
1207       flags.set(1, true);
1208       break;
1209     case PacketType::ACL:
1210     case PacketType::ISO:
1211     case PacketType::SCO:
1212       flags.set(0, direction == Direction::INCOMING);
1213       flags.set(1, false);
1214       break;
1215     case PacketType::EVT:
1216       flags.set(0, true);
1217       flags.set(1, true);
1218       break;
1219   }
1220   uint32_t length = packet.size() + /* type byte */ PACKET_TYPE_LENGTH;
1221   PacketHeaderType header = {.length_original = htonl(length),
1222                              .length_captured = htonl(length),
1223                              .flags = htonl(static_cast<uint32_t>(flags.to_ulong())),
1224                              .dropped_packets = 0,
1225                              .timestamp = htonll(timestamp_us + kBtSnoopEpochDelta),
1226                              .type = static_cast<uint8_t>(type)};
1227   {
1228     std::lock_guard<std::recursive_mutex> lock(file_mutex_);
1229     if (btsnoop_mode_ == kBtSnoopLogModeDisabled) {
1230       // btsnoop disabled, log in-memory btsnooz log only
1231       std::stringstream ss;
1232       size_t included_length =
1233               get_btsnooz_packet_length_to_write(packet, type, qualcomm_debug_log_enabled_);
1234       header.length_captured = htonl(included_length + /* type byte */ PACKET_TYPE_LENGTH);
1235       if (!ss.write(reinterpret_cast<const char*>(&header), sizeof(PacketHeaderType))) {
1236         log::error("Failed to write packet header for btsnooz, error: \"{}\"", strerror(errno));
1237       }
1238       if (!ss.write(reinterpret_cast<const char*>(packet.data()), included_length)) {
1239         log::error("Failed to write packet payload for btsnooz, error: \"{}\"", strerror(errno));
1240       }
1241       btsnooz_buffer_.Push(ss.str());
1242       return;
1243     } else if (btsnoop_mode_ == kBtSnoopLogModeKernel) {
1244       // Skip logging as btsnoop is done in kernel space
1245       return;
1246     }
1247 
1248     FilterCapturedPacket(packet, direction, type, length, header);
1249 
1250     if (length == 0) {
1251       return;
1252     } else if (length != ntohl(header.length_original)) {
1253       header.length_captured = htonl(length);
1254     }
1255 
1256     packet_counter_++;
1257     if (packet_counter_ > max_packets_per_file_) {
1258       OpenNextSnoopLogFile();
1259     }
1260     if (!btsnoop_ostream_.write(reinterpret_cast<const char*>(&header), sizeof(PacketHeaderType))) {
1261       log::error("Failed to write packet header for btsnoop, error: \"{}\"", strerror(errno));
1262     }
1263     if (!btsnoop_ostream_.write(reinterpret_cast<const char*>(packet.data()), length - 1)) {
1264       log::error("Failed to write packet payload for btsnoop, error: \"{}\"", strerror(errno));
1265     }
1266 
1267     if (socket_ != nullptr) {
1268       socket_->Write(&header, sizeof(PacketHeaderType));
1269       socket_->Write(packet.data(), (size_t)(length - 1));
1270     }
1271 
1272     // std::ofstream::flush() pushes user data into kernel memory. The data will be written even if
1273     // this process crashes. However, data will be lost if there is a kernel panic, which is out of
1274     // scope of BT snoop log. NOTE: std::ofstream::write() followed by std::ofstream::flush() has
1275     // similar effect as UNIX write(fd, data, len)
1276     //       as write() syscall dumps data into kernel memory directly
1277     if (!btsnoop_ostream_.flush()) {
1278       log::error("Failed to flush, error: \"{}\"", strerror(errno));
1279     }
1280   }
1281 }
1282 
DumpSnoozLogToFile()1283 void SnoopLogger::DumpSnoozLogToFile() {
1284   std::lock_guard<std::recursive_mutex> lock(file_mutex_);
1285   std::vector<std::string> data = btsnooz_buffer_.Pull();
1286 
1287   if (btsnoop_mode_ != kBtSnoopLogModeDisabled) {
1288     log::debug("btsnoop log is enabled, skip dumping btsnooz log");
1289     return;
1290   }
1291 
1292   log::debug("Dumping btsnooz log data to {}", snooz_log_path_);
1293   auto last_file_path = get_last_log_path(snooz_log_path_);
1294 
1295   if (os::FileExists(snooz_log_path_)) {
1296     if (!os::RenameFile(snooz_log_path_, last_file_path)) {
1297       log::error("Unabled to rename existing snooz log from \"{}\" to \"{}\"", snooz_log_path_,
1298                  last_file_path);
1299     }
1300   } else {
1301     log::info("Previous log file \"{}\" does not exist, skip renaming", snooz_log_path_);
1302   }
1303 
1304   mode_t prevmask = umask(0);
1305   // do not use std::ios::app as we want override the existing file
1306   std::ofstream btsnooz_ostream(snooz_log_path_, std::ios::binary | std::ios::out);
1307   if (!btsnooz_ostream.good()) {
1308     log::fatal("Unable to open snoop log at \"{}\", error: \"{}\"", snooz_log_path_,
1309                strerror(errno));
1310   }
1311   umask(prevmask);
1312   if (!btsnooz_ostream.write(reinterpret_cast<const char*>(&SnoopLoggerCommon::kBtSnoopFileHeader),
1313                              sizeof(SnoopLoggerCommon::FileHeaderType))) {
1314     log::fatal("Unable to write file header to \"{}\", error: \"{}\"", snooz_log_path_,
1315                strerror(errno));
1316   }
1317   for (const auto& packet : data) {
1318     if (!btsnooz_ostream.write(packet.data(), packet.size())) {
1319       log::error("Failed to write packet payload for btsnooz, error: \"{}\"", strerror(errno));
1320     }
1321   }
1322   if (!btsnooz_ostream.flush()) {
1323     log::error("Failed to flush, error: \"{}\"", strerror(errno));
1324   }
1325 }
1326 
Start()1327 void SnoopLogger::Start() {
1328   std::lock_guard<std::recursive_mutex> lock(file_mutex_);
1329   if (btsnoop_mode_ != kBtSnoopLogModeDisabled && btsnoop_mode_ != kBtSnoopLogModeKernel) {
1330     OpenNextSnoopLogFile();
1331 
1332     if (btsnoop_mode_ == kBtSnoopLogModeFiltered) {
1333       EnableFilters();
1334     }
1335 
1336     if (os::GetSystemProperty(kRoBuildType) != "user") {
1337       // Cf b/375056207: The implementation must pass a security review
1338       // in order to enable the snoop logger socket in user builds.
1339       auto snoop_logger_socket = std::make_unique<SnoopLoggerSocket>(&syscall_if);
1340       snoop_logger_socket_thread_ =
1341               std::make_unique<SnoopLoggerSocketThread>(std::move(snoop_logger_socket));
1342       auto thread_started_future = snoop_logger_socket_thread_->Start();
1343       thread_started_future.wait();
1344       if (thread_started_future.get()) {
1345         RegisterSocket(snoop_logger_socket_thread_.get());
1346       } else {
1347         snoop_logger_socket_thread_->Stop();
1348         snoop_logger_socket_thread_.reset();
1349         snoop_logger_socket_thread_ = nullptr;
1350       }
1351     }
1352   }
1353 
1354 #ifdef __ANDROID__
1355   SnoopLoggerTracing::InitializePerfetto();
1356 #endif  // __ANDROID__
1357 
1358   alarm_ = std::make_unique<os::RepeatingAlarm>(GetHandler());
1359   alarm_->Schedule(common::Bind(&delete_old_btsnooz_files, snooz_log_path_, snooz_log_life_time_),
1360                    snooz_log_delete_alarm_interval_);
1361 }
1362 
Stop()1363 void SnoopLogger::Stop() {
1364   std::lock_guard<std::recursive_mutex> lock(file_mutex_);
1365   log::debug("Closing btsnoop log data at {}", snoop_log_path_);
1366   CloseCurrentSnoopLogFile();
1367 
1368   if (snoop_logger_socket_thread_ != nullptr) {
1369     snoop_logger_socket_thread_->Stop();
1370     snoop_logger_socket_thread_.reset();
1371     snoop_logger_socket_thread_ = nullptr;
1372     socket_ = nullptr;
1373   }
1374 
1375   btsnoop_mode_ = kBtSnoopLogModeDisabled;
1376   // Disable all filters
1377   DisableFilters();
1378 
1379   // Cancel the alarm
1380   alarm_->Cancel();
1381   alarm_.reset();
1382   // delete any existing snooz logs
1383   if (!snoop_log_persists) {
1384     delete_btsnoop_files(snooz_log_path_);
1385   }
1386 }
1387 
GetMaxPacketsPerFile()1388 size_t SnoopLogger::GetMaxPacketsPerFile() {
1389   // Allow override max packet per file via system property
1390   auto max_packets_per_file = kDefaultBtSnoopMaxPacketsPerFile;
1391   {
1392     auto max_packets_per_file_prop = os::GetSystemProperty(kBtSnoopMaxPacketsPerFileProperty);
1393     if (max_packets_per_file_prop) {
1394       auto max_packets_per_file_number =
1395               common::Uint64FromString(max_packets_per_file_prop.value());
1396       if (max_packets_per_file_number) {
1397         max_packets_per_file = max_packets_per_file_number.value();
1398       }
1399     }
1400   }
1401   return max_packets_per_file;
1402 }
1403 
GetMaxPacketsPerBuffer()1404 size_t SnoopLogger::GetMaxPacketsPerBuffer() {
1405   // We want to use at most 256 KB memory for btsnooz log for release builds
1406   // and 512 KB memory for userdebug/eng builds
1407   auto is_debug_build = (os::GetSystemProperty(kRoBuildType) != "user");
1408 
1409   size_t btsnooz_max_memory_usage_bytes = (is_debug_build ? 1024 : 256) * 1024;
1410   // Calculate max number of packets based on max memory usage and max packet size
1411   return btsnooz_max_memory_usage_bytes / kDefaultBtSnoozMaxBytesPerPacket;
1412 }
1413 
GetCurrentSnoopMode()1414 std::string SnoopLogger::GetCurrentSnoopMode() { return btsnoop_mode_; }
1415 
RegisterSocket(SnoopLoggerSocketInterface * socket)1416 void SnoopLogger::RegisterSocket(SnoopLoggerSocketInterface* socket) {
1417   std::lock_guard<std::recursive_mutex> lock(file_mutex_);
1418   socket_ = socket;
1419 }
1420 
IsBtSnoopLogPersisted()1421 bool SnoopLogger::IsBtSnoopLogPersisted() {
1422   auto is_debug_build = (os::GetSystemProperty(kRoBuildType) != "user");
1423   return is_debug_build && os::GetSystemPropertyBool(kBtSnoopLogPersists, false);
1424 }
1425 
IsQualcommDebugLogEnabled()1426 bool SnoopLogger::IsQualcommDebugLogEnabled() {
1427   // Check system prop if the soc manufacturer is Qualcomm
1428   bool qualcomm_debug_log_enabled = false;
1429   {
1430     auto soc_manufacturer_prop = os::GetSystemProperty(kSoCManufacturerProperty);
1431     qualcomm_debug_log_enabled =
1432             soc_manufacturer_prop.has_value() &&
1433             common::StringTrim(soc_manufacturer_prop.value()) == kSoCManufacturerQualcomm;
1434   }
1435   return qualcomm_debug_log_enabled;
1436 }
1437 
1438 #ifdef __ANDROID__
LogTracePoint(const HciPacket & packet,Direction direction,PacketType type)1439 void SnoopLogger::LogTracePoint(const HciPacket& packet, Direction direction, PacketType type) {
1440   switch (type) {
1441     case PacketType::EVT: {
1442       uint8_t evt_code = packet[0];
1443 
1444       if (evt_code == static_cast<uint8_t>(hci::EventCode::LE_META_EVENT) ||
1445           evt_code == static_cast<uint8_t>(hci::EventCode::VENDOR_SPECIFIC)) {
1446         uint8_t subevt_code = packet[2];
1447         std::string message =
1448                 std::format("BTSL:{}/{}/{}/{:02x}/{:02x}", static_cast<uint8_t>(type),
1449                             static_cast<uint8_t>(direction), packet.size(), evt_code, subevt_code);
1450 
1451         ATRACE_INSTANT_FOR_TRACK(LOG_TAG, message.c_str());
1452       } else {
1453         std::string message = std::format("BTSL:{}/{}/{}/{:02x}", static_cast<uint8_t>(type),
1454                                           static_cast<uint8_t>(direction), packet.size(), evt_code);
1455 
1456         ATRACE_INSTANT_FOR_TRACK(LOG_TAG, message.c_str());
1457       }
1458     } break;
1459     case PacketType::CMD: {
1460       uint16_t op_code = packet[0] | (packet[1] << 8);
1461 
1462       std::string message = std::format("BTSL:{}/{}/{}/{:04x}", static_cast<uint8_t>(type),
1463                                         static_cast<uint8_t>(direction), packet.size(), op_code);
1464 
1465       ATRACE_INSTANT_FOR_TRACK(LOG_TAG, message.c_str());
1466     } break;
1467     case PacketType::ACL: {
1468       uint16_t handle = (packet[0] | (packet[1] << 8)) & 0x0fff;
1469       uint8_t pb_flag = (packet[1] & 0x30) >> 4;
1470 
1471       std::string message =
1472               std::format("BTSL:{}/{}/{}/{:03x}/{}", static_cast<uint8_t>(type),
1473                           static_cast<uint8_t>(direction), packet.size(), handle, pb_flag);
1474 
1475       ATRACE_INSTANT_FOR_TRACK(LOG_TAG, message.c_str());
1476     } break;
1477     case PacketType::ISO:
1478     case PacketType::SCO: {
1479       std::string message = std::format("BTSL:{}/{}/{}", static_cast<uint8_t>(type),
1480                                         static_cast<uint8_t>(direction), packet.size());
1481 
1482       ATRACE_INSTANT_FOR_TRACK(LOG_TAG, message.c_str());
1483     } break;
1484   }
1485 
1486   SnoopLoggerTracing::TracePacket(packet, direction, type);
1487 }
1488 #endif  // __ANDROID__
1489 
1490 }  // namespace hal
1491 }  // namespace bluetooth
1492