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