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