• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <bluetooth/log.h>
20 #include <com_android_bluetooth_flags.h>
21 
22 #include <fstream>
23 #include <string>
24 #include <unordered_map>
25 #include <unordered_set>
26 #include <vector>
27 
28 #include "common/circular_buffer.h"
29 #include "hal/hci_hal.h"
30 #include "hal/snoop_logger_socket_interface.h"
31 #include "hal/snoop_logger_socket_thread.h"
32 #include "hal/syscall_wrapper_impl.h"
33 #include "hci/hci_packets.h"
34 #include "module.h"
35 #include "os/repeating_alarm.h"
36 
37 namespace bluetooth {
38 namespace hal {
39 
40 #ifdef USE_FAKE_TIMERS
41 static uint64_t file_creation_time;
42 #endif
43 
44 class FilterTracker {
45 public:
46   // NOTE: 1 is used as a static CID for L2CAP signaling
47   std::unordered_set<uint16_t> l2c_local_cid = {1};
48   std::unordered_set<uint16_t> l2c_remote_cid = {1};
49   uint16_t rfcomm_local_cid = 0;
50   uint16_t rfcomm_remote_cid = 0;
51   std::unordered_set<uint16_t> rfcomm_channels = {0};
52 
53   // Adds L2C channel to acceptlist.
54   void AddL2capCid(uint16_t local_cid, uint16_t remote_cid);
55 
56   // Sets L2CAP channel that RFCOMM uses.
57   void SetRfcommCid(uint16_t local_cid, uint16_t remote_cid);
58 
59   // Remove L2C channel from acceptlist.
60   void RemoveL2capCid(uint16_t local_cid, uint16_t remote_cid);
61 
62   void AddRfcommDlci(uint8_t channel);
63 
64   bool IsAcceptlistedL2cap(bool local, uint16_t cid);
65 
66   bool IsRfcommChannel(bool local, uint16_t cid);
67 
68   bool IsAcceptlistedDlci(uint8_t dlci);
69 };
70 
71 typedef enum {
72   FILTER_PROFILE_NONE = -1,
73   FILTER_PROFILE_PBAP = 0,
74   FILTER_PROFILE_HFP_HS,
75   FILTER_PROFILE_HFP_HF,
76   FILTER_PROFILE_MAP,
77   FILTER_PROFILE_MAX,
78 } profile_type_t;
79 
80 class ProfilesFilter {
81 public:
82   void SetupProfilesFilter(bool pbap_filtered, bool map_filtered);
83 
84   bool IsHfpProfile(bool local, uint16_t cid, uint8_t dlci);
85 
86   bool IsL2capMatch(bool local, uint16_t cid);
87 
88   bool IsL2capFlowExt(bool local, uint16_t cid);
89 
90   bool IsRfcommMatch(bool local, uint16_t cid, uint8_t dlci);
91 
92   bool IsRfcommFlowExt(bool local, uint16_t cid, uint8_t dlci);
93 
94   profile_type_t CidToProfile(bool local, uint16_t cid);
95 
96   profile_type_t DlciToProfile(bool local, uint16_t cid, uint8_t dlci);
97 
98   void ProfileL2capOpen(profile_type_t profile, uint16_t lcid, uint16_t rcid, uint16_t psm,
99                         bool flow_ext);
100 
101   void ProfileL2capClose(profile_type_t profile);
102 
103   void ProfileRfcommOpen(profile_type_t profile, uint16_t lcid, uint8_t dlci, uint16_t uuid,
104                          bool flow_ext);
105 
106   void ProfileRfcommClose(profile_type_t profile);
107 
108   bool IsRfcommChannel(bool local, uint16_t cid);
109 
110   void PrintProfilesConfig();
111 
ProfileToString(profile_type_t profile)112   static inline std::string ProfileToString(profile_type_t profile) {
113     switch (profile) {
114       case FILTER_PROFILE_NONE:
115         return "FILTER_PROFILE_NONE";
116       case FILTER_PROFILE_PBAP:
117         return "FILTER_PROFILE_PBAP";
118       case FILTER_PROFILE_HFP_HS:
119         return "FILTER_PROFILE_HFP_HS";
120       case FILTER_PROFILE_HFP_HF:
121         return "FILTER_PROFILE_HFP_HF";
122       case FILTER_PROFILE_MAP:
123         return "FILTER_PROFILE_MAP";
124       default:
125         return "[Unknown profile_type_t]";
126     }
127   }
128 
129   uint16_t ch_rfc_l, ch_rfc_r;  // local & remote L2CAP channel for RFCOMM
130   uint16_t ch_last;             // last channel seen for fragment packet
131 
132 private:
133   bool setup_done_flag = false;
134   struct {
135     profile_type_t type;
136     bool enabled, l2cap_opened, rfcomm_opened;
137     bool flow_ext_l2cap, flow_ext_rfcomm;
138     uint16_t lcid, rcid, rfcomm_uuid, psm;
139     uint8_t scn;
140   } profiles[FILTER_PROFILE_MAX];
141   profile_type_t current_profile;
142 };
143 
144 class SnoopLogger : public ::bluetooth::Module {
145 public:
146   static const ModuleFactory Factory;
147 
148   static const std::string kBtSnoopMaxPacketsPerFileProperty;
149   static const std::string kRoBuildType;
150   static const std::string kBtSnoopLogModeProperty;
151   static const std::string kBtSnoopLogPersists;
152   static const std::string kBtSnoopDefaultLogModeProperty;
153   static const std::string kBtSnoopLogFilterHeadersProperty;
154   static const std::string kBtSnoopLogFilterProfileA2dpProperty;
155   static const std::string kBtSnoopLogFilterProfileMapModeProperty;
156   static const std::string kBtSnoopLogFilterProfilePbapModeProperty;
157   static const std::string kBtSnoopLogFilterProfileRfcommProperty;
158   static const std::string kSoCManufacturerProperty;
159 
160   static const std::string kBtSnoopLogModeKernel;
161   static const std::string kBtSnoopLogModeDisabled;
162   static const std::string kBtSnoopLogModeFiltered;
163   static const std::string kBtSnoopLogModeFull;
164 
165   static const std::string kSoCManufacturerQualcomm;
166 
167   static const std::string kBtSnoopLogFilterProfileModeFullfillter;
168   static const std::string kBtSnoopLogFilterProfileModeHeader;
169   static const std::string kBtSnoopLogFilterProfileModeMagic;
170   static const std::string kBtSnoopLogFilterProfileModeDisabled;
171 
172   std::unordered_map<std::string, bool> kBtSnoopLogFilterState = {
173           {kBtSnoopLogFilterHeadersProperty, false},
174           {kBtSnoopLogFilterProfileA2dpProperty, false},
175           {kBtSnoopLogFilterProfileRfcommProperty, false}};
176 
177   std::unordered_map<std::string, std::string> kBtSnoopLogFilterMode = {
178           {kBtSnoopLogFilterProfilePbapModeProperty, kBtSnoopLogFilterProfileModeDisabled},
179           {kBtSnoopLogFilterProfileMapModeProperty, kBtSnoopLogFilterProfileModeDisabled}};
180 
181   // Put in header for test
182   struct PacketHeaderType {
183     uint32_t length_original;
184     uint32_t length_captured;
185     uint32_t flags;
186     uint32_t dropped_packets;
187     uint64_t timestamp;
188     uint8_t type;
189   } __attribute__((__packed__));
190 
191   // Struct for caching info about L2CAP Media Channel
192   struct A2dpMediaChannel {
193     uint16_t conn_handle;
194     uint16_t local_cid;
195     uint16_t remote_cid;
196   };
197 
198   SnoopLogger(os::Handler* handler);
~SnoopLogger()199   ~SnoopLogger() {
200     if (!com::android::bluetooth::flags::same_handler_for_all_modules()) {
201       GetHandler()->Clear();
202       GetHandler()->WaitUntilStopped(std::chrono::milliseconds(2000));
203       delete GetHandler();
204     }
205   }
206 
207   // Returns the maximum number of packets per file
208   // Changes to this value is only effective after restarting Bluetooth
209   static size_t GetMaxPacketsPerFile();
210 
211   static size_t GetMaxPacketsPerBuffer();
212 
213   // Get current snoop logger mode
214   std::string GetCurrentSnoopMode();
215 
216   // Returns whether the soc manufacturer is Qualcomm
217   // Changes to this value is only effective after restarting Bluetooth
218   static bool IsQualcommDebugLogEnabled();
219 
220   // Returns whether snoop log persists even after restarting Bluetooth
221   static bool IsBtSnoopLogPersisted();
222 
223   // Has to be defined from 1 to 4 per btsnoop format
224   enum PacketType {
225     CMD = 1,
226     ACL = 2,
227     SCO = 3,
228     EVT = 4,
229     ISO = 5,
230   };
231 
232   enum Direction {
233     INCOMING,
234     OUTGOING,
235   };
236 
237   void Start() override;
238   void Stop() override;
239   void Capture(const HciPacket& packet, Direction direction, PacketType type);
240 
241   // Set a L2CAP channel as acceptlisted, allowing packets with that L2CAP CID
242   // to show up in the snoop logs.
243   void AcceptlistL2capChannel(uint16_t conn_handle, uint16_t local_cid, uint16_t remote_cid);
244 
245   // Set a RFCOMM dlci as acceptlisted, allowing packets with that RFCOMM CID
246   // to show up in the snoop logs. The local_cid is used to associate it with
247   // its corresponding ACL connection. The dlci is the channel with direction
248   // so there is no chance of a collision if two services are using the same
249   // channel but in different directions.
250   void AcceptlistRfcommDlci(uint16_t conn_handle, uint16_t local_cid, uint8_t dlci);
251 
252   // Indicate that the provided L2CAP channel is being used for RFCOMM.
253   // If packets with the provided L2CAP CID are encountered, they will be
254   // filtered on RFCOMM based on channels provided to |filter_rfcomm_channel|.
255   void AddRfcommL2capChannel(uint16_t conn_handle, uint16_t local_cid, uint16_t remote_cid);
256 
257   // Clear an L2CAP channel from being filtered.
258   void ClearL2capAcceptlist(uint16_t conn_handle, uint16_t local_cid, uint16_t remote_cid);
259 
260   // Cache A2DP Media Channel info for filtering media packets.
261   void AddA2dpMediaChannel(uint16_t conn_handle, uint16_t local_cid, uint16_t remote_cid);
262 
263   // Remove A2DP Media Channel cache
264   void RemoveA2dpMediaChannel(uint16_t conn_handle, uint16_t local_cid);
265 
266   // New RFCOMM port is opened.
267   void SetRfcommPortOpen(uint16_t conn_handle, uint16_t local_cid, uint8_t dlci, uint16_t uuid,
268                          bool flow);
269   // RFCOMM port is closed.
270   void SetRfcommPortClose(uint16_t handle, uint16_t local_cid, uint8_t dlci, uint16_t uuid);
271 
272   // New L2CAP channel is opened.
273   void SetL2capChannelOpen(uint16_t handle, uint16_t local_cid, uint16_t remote_cid, uint16_t psm,
274                            bool flow);
275   // L2CAP channel is closed.
276   void SetL2capChannelClose(uint16_t handle, uint16_t local_cid, uint16_t remote_cid);
277 
278   void RegisterSocket(SnoopLoggerSocketInterface* socket);
279 
280   // Dump the contents of the snooz buffer to a file.
281   void DumpSnoozLogToFile();
282 
GetSocketThread()283   SnoopLoggerSocketThread const* GetSocketThread() { return snoop_logger_socket_thread_.get(); }
284 
285 protected:
286   // Packet type length
287   static const size_t PACKET_TYPE_LENGTH;
288   // The size of the L2CAP header. All information past this point is removed from
289   // a filtered packet.
290   static const uint32_t L2CAP_HEADER_SIZE;
291   // Max packet data size when headersfiltered option enabled
292   static const size_t MAX_HCI_ACL_LEN;
293 
ListDependencies(ModuleList *)294   void ListDependencies(ModuleList* /*list*/) const override {}
ToString()295   std::string ToString() const override { return std::string("SnoopLogger"); }
296 
297   SnoopLogger(os::Handler* handler, std::string snoop_log_path, std::string snooz_log_path,
298               size_t max_packets_per_file, size_t max_packets_per_buffer,
299               const std::string& btsnoop_mode, bool qualcomm_debug_log_enabled,
300               const std::chrono::milliseconds snooz_log_life_time,
301               const std::chrono::milliseconds snooz_log_delete_alarm_interval,
302               bool snoop_log_persists);
303 
304   void CloseCurrentSnoopLogFile();
305   void OpenNextSnoopLogFile();
306   // Enable filters according to their sysprops
307   void EnableFilters();
308   // Disable all filters
309   void DisableFilters();
310   // Check if the filter is enabled. Pass filter name as a string.
311   bool IsFilterEnabled(std::string filter_name);
312   // Check if packet should be filtered (rfcommchannelfiltered mode)
313   bool ShouldFilterLog(bool is_received, uint8_t* packet);
314   // Calculate packet length (snoopheadersfiltered mode)
315   void CalculateAclPacketLength(uint32_t& length, uint8_t* packet, bool is_received);
316   // Strip packet's payload (profilesfiltered mode)
317   uint32_t PayloadStrip(profile_type_t current_profile, uint8_t* packet, uint32_t hdr_len,
318                         uint32_t pl_len);
319   // Filter profile packet according to its filtering mode
320   uint32_t FilterProfiles(bool is_received, uint8_t* packet);
321   // Check if packet is A2DP media packet (a2dppktsfiltered mode)
322   bool IsA2dpMediaPacket(bool is_received, uint8_t* packet);
323   // Check if channel is cached in snoop logger for filtering (a2dppktsfiltered mode)
324   bool IsA2dpMediaChannel(uint16_t conn_handle, uint16_t cid, bool is_local_cid);
325   // Handle HFP filtering while profilesfiltered enabled
326   uint32_t FilterProfilesHandleHfp(uint8_t* packet, uint32_t length, uint32_t totlen,
327                                    uint32_t offset);
328   void FilterProfilesRfcommChannel(uint8_t* packet, uint8_t& current_offset, uint32_t& length,
329                                    profile_type_t& current_profile,
330                                    bluetooth::hal::ProfilesFilter& filters, bool is_received,
331                                    uint16_t l2cap_channel, uint32_t& offset, uint32_t total_length);
332   void FilterCapturedPacket(HciPacket& packet, Direction direction, PacketType type,
333                             uint32_t& length, PacketHeaderType header);
334 
335   std::unique_ptr<SnoopLoggerSocketThread> snoop_logger_socket_thread_;
336 
337 #ifdef __ANDROID__
338   void LogTracePoint(const HciPacket& packet, Direction direction, PacketType type);
339 #endif  // __ANDROID__
340 
341 private:
342   std::string btsnoop_mode_;
343   std::string snoop_log_path_;
344   std::string snooz_log_path_;
345   std::ofstream btsnoop_ostream_;
346   size_t max_packets_per_file_;
347   common::CircularBuffer<std::string> btsnooz_buffer_;
348   bool qualcomm_debug_log_enabled_ = false;
349   size_t packet_counter_ = 0;
350   mutable std::recursive_mutex file_mutex_;
351   std::unique_ptr<os::RepeatingAlarm> alarm_;
352   std::chrono::milliseconds snooz_log_life_time_;
353   std::chrono::milliseconds snooz_log_delete_alarm_interval_;
354   SnoopLoggerSocketInterface* socket_;
355   SyscallWrapperImpl syscall_if;
356   bool snoop_log_persists = false;
357 
358   friend class SnoopLoggerTest;
359 };
360 
361 }  // namespace hal
362 }  // namespace bluetooth
363 
364 namespace std {
365 template <>
366 struct formatter<bluetooth::hal::profile_type_t> : enum_formatter<bluetooth::hal::profile_type_t> {
367 };
368 }  // namespace std
369