• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 #ifdef __ANDROID__
19 
20 #include <perfetto/trace/android/bluetooth_trace.pbzero.h>
21 #include <perfetto/tracing.h>
22 
23 #include "hal/snoop_logger.h"
24 
25 namespace bluetooth {
26 namespace hal {
27 
28 // BundleKey is used to group packets into bundles organized by direction, type,
29 // and eventual op_code or event_code
30 struct BundleKey {
31   explicit BundleKey(const HciPacket& packet, SnoopLogger::Direction direction,
32                      SnoopLogger::PacketType type);
33 
34   SnoopLogger::PacketType packet_type;
35   SnoopLogger::Direction direction;
36   std::optional<uint16_t> op_code;
37   std::optional<uint8_t> event_code;
38   std::optional<uint8_t> subevent_code;
39   std::optional<uint16_t> handle;
40 
41   bool operator==(const BundleKey& b) const;
42 };
43 
44 // BundleHash is used to hash BundleKeys.
45 struct BundleHash {
46   std::size_t operator()(const BundleKey& a) const;
47 };
48 
49 // BundleDetails contains information about a bundle.
50 struct BundleDetails {
51   uint32_t count = 0;
52   uint32_t total_length = 0;
53   uint64_t start_ts = std::numeric_limits<uint64_t>::max();
54   uint64_t end_ts = std::numeric_limits<uint64_t>::min();
55 };
56 
57 class SnoopLoggerTracing : public perfetto::DataSource<SnoopLoggerTracing> {
58 public:
59   static void InitializePerfetto();
60   static void TracePacket(const HciPacket& packet, SnoopLogger::Direction direction,
61                           SnoopLogger::PacketType type);
62 
63   void OnSetup(const SetupArgs&) override;
64   void OnStart(const StartArgs&) override;
65   void OnStop(const StopArgs&) override;
66   void OnFlush(const FlushArgs&) override;
67 
68 private:
69   static perfetto::protos::pbzero::BluetoothTracePacketType HciToTracePacketType(
70           SnoopLogger::PacketType hci_packet_type, SnoopLogger::Direction direction);
71 
72   // Records the packet into the internal buffers.
73   void Record(TraceContext& ctx, const HciPacket& packet, SnoopLogger::Direction direction,
74               SnoopLogger::PacketType type);
75 
76   // Writes all pending data from the internal buffer as a new trace packet.
77   void Write(TraceContext& ctx, const BundleKey& key, const BundleDetails& details);
78 
79   uint64_t last_flush_ns_ = 0;
80   std::unordered_map<BundleKey, BundleDetails, BundleHash> bttrace_bundles_;
81 };
82 }  // namespace hal
83 }  // namespace bluetooth
84 
85 PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(bluetooth::hal::SnoopLoggerTracing);
86 
87 #endif  // __ANDROID__
88