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