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 
24 #include "common/circular_buffer.h"
25 #include "hal/hci_hal.h"
26 #include "module.h"
27 
28 namespace bluetooth {
29 namespace hal {
30 
31 class SnoopLogger : public ::bluetooth::Module {
32  public:
33   static const ModuleFactory Factory;
34 
35   static const std::string kBtSnoopLogModeDisabled;
36   static const std::string kBtSnoopLogModeFiltered;
37   static const std::string kBtSnoopLogModeFull;
38 
39   static const std::string kBtSnoopMaxPacketsPerFileProperty;
40   static const std::string kIsDebuggableProperty;
41   static const std::string kBtSnoopLogModeProperty;
42   static const std::string kBtSnoopDefaultLogModeProperty;
43 
44   // Put in header for test
45   struct PacketHeaderType {
46     uint32_t length_original;
47     uint32_t length_captured;
48     uint32_t flags;
49     uint32_t dropped_packets;
50     uint64_t timestamp;
51     uint8_t type;
52   } __attribute__((__packed__));
53 
54   // Put in header for test
55   struct FileHeaderType {
56     uint8_t identification_pattern[8];
57     uint32_t version_number;
58     uint32_t datalink_type;
59   } __attribute__((__packed__));
60 
61   // Returns the maximum number of packets per file
62   // Changes to this value is only effective after restarting Bluetooth
63   static size_t GetMaxPacketsPerFile();
64 
65   // Get snoop logger mode based on current system setup
66   // Changes to this values is only effective after restarting Bluetooth
67   static std::string GetBtSnoopMode();
68 
69   // Has to be defined from 1 to 4 per btsnoop format
70   enum PacketType {
71     CMD = 1,
72     ACL = 2,
73     SCO = 3,
74     EVT = 4,
75     ISO = 5,
76   };
77 
78   enum Direction {
79     INCOMING,
80     OUTGOING,
81   };
82 
83   void Capture(const HciPacket& packet, Direction direction, PacketType type);
84 
85  protected:
86   void ListDependencies(ModuleList* list) override;
87   void Start() override;
88   void Stop() override;
89   DumpsysDataFinisher GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const override;
ToString()90   std::string ToString() const override {
91     return std::string("SnoopLogger");
92   }
93 
94   // Visible for testing
95   SnoopLogger(
96       std::string snoop_log_path,
97       std::string snooz_log_path,
98       size_t max_packets_per_file,
99       const std::string& btsnoop_mode);
100   void CloseCurrentSnoopLogFile();
101   void OpenNextSnoopLogFile();
102   void DumpSnoozLogToFile(const std::vector<std::string>& data) const;
103 
104  private:
105   std::string snoop_log_path_;
106   std::string snooz_log_path_;
107   std::ofstream btsnoop_ostream_;
108   bool is_enabled_ = false;
109   bool is_filtered_ = false;
110   size_t max_packets_per_file_;
111   common::CircularBuffer<std::string> btsnooz_buffer_;
112   size_t packet_counter_ = 0;
113   mutable std::recursive_mutex file_mutex_;
114 };
115 
116 }  // namespace hal
117 }  // namespace bluetooth
118