Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ae6dcf4a authored by Erwin Jansen's avatar Erwin Jansen Committed by Charlie Boutier
Browse files

Enable sniffing of HCI packets to std::ostream

This allows for the registration of an ostream on the hci sniffer. This
can be used by external parties to sniff hci packets and write them to
different streams.

Bug: 231598376
Bug: 199325666
Bug: 241962982
Bug: 242184809
Tag: #refactor
Test: Two emulators can discover each other
Test: gd/cert/run
Ignore-AOSP-First: Cherry-picked from AOSP
Merged-In: I0622263eaec8dd360d893817dd6a73f30a15af5f
Change-Id: I0622263eaec8dd360d893817dd6a73f30a15af5f
parent df51e189
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -73,7 +73,8 @@ void TestEnvironment::initialize(std::promise<void> barrier) {
        filename =
            device->GetAddress().ToString() + "_" + std::to_string(i) + ".pcap";
      }
      std::static_pointer_cast<HciSniffer>(transport)->Open(filename.c_str());
      auto file = std::make_shared<std::ofstream>(filename, std::ios::binary);
      std::static_pointer_cast<HciSniffer>(transport)->SetOutputStream(file);
    }
    srv->StartListening();
  });
+30 −18
Original line number Diff line number Diff line
@@ -23,9 +23,7 @@ using namespace std::literals;

namespace rootcanal {

void HciSniffer::Open(const char* filename) {
  output_.open(filename, std::ios::binary);

static void writeHeader(std::ostream* stream) {
  // https://tools.ietf.org/id/draft-gharris-opsawg-pcap-00.xml#file-header
  uint32_t magic_number = 0xa1b2c3d4;
  uint16_t major_version = 2;
@@ -36,13 +34,26 @@ void HciSniffer::Open(const char* filename) {
  uint32_t linktype = 201;  // http://www.tcpdump.org/linktypes.html
                            // LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR

  output_.write((char*)&magic_number, 4);
  output_.write((char*)&major_version, 2);
  output_.write((char*)&minor_version, 2);
  output_.write((char*)&reserved1, 4);
  output_.write((char*)&reserved2, 4);
  output_.write((char*)&snaplen, 4);
  output_.write((char*)&linktype, 4);
  stream->write((char*)&magic_number, 4);
  stream->write((char*)&major_version, 2);
  stream->write((char*)&minor_version, 2);
  stream->write((char*)&reserved1, 4);
  stream->write((char*)&reserved2, 4);
  stream->write((char*)&snaplen, 4);
  stream->write((char*)&linktype, 4);
}

HciSniffer::HciSniffer(std::shared_ptr<HciTransport> transport,
                       std::shared_ptr<std::ostream> outputStream)
    : transport_(transport), start_(std::chrono::steady_clock::now()) {
  SetOutputStream(outputStream);
}

void HciSniffer::SetOutputStream(std::shared_ptr<std::ostream> outputStream) {
  output_ = outputStream;
  if (output_) {
    writeHeader(output_.get());
  }
}

void HciSniffer::AppendRecord(PacketDirection packet_direction,
@@ -60,13 +71,14 @@ void HciSniffer::AppendRecord(PacketDirection packet_direction,
  uint32_t direction = static_cast<uint32_t>(packet_direction);
  uint8_t idc = static_cast<uint8_t>(packet_type);

  output_.write((char*)&seconds, 4);
  output_.write((char*)&microseconds, 4);
  output_.write((char*)&captured_packet_length, 4);
  output_.write((char*)&original_packet_length, 4);
  output_.write((char*)&direction, 4);
  output_.write((char*)&idc, 1);
  output_.write((char*)packet.data(), packet.size());
  output_->write((char*)&seconds, 4);
  output_->write((char*)&microseconds, 4);
  output_->write((char*)&captured_packet_length, 4);
  output_->write((char*)&original_packet_length, 4);
  output_->write((char*)&direction, 4);
  output_->write((char*)&idc, 1);
  output_->write((char*)packet.data(), packet.size());
  output_->flush();
}

void HciSniffer::RegisterCallbacks(PacketCallback command_callback,
@@ -103,7 +115,7 @@ void HciSniffer::TimerTick() { transport_->TimerTick(); }

void HciSniffer::Close() {
  transport_->Close();
  output_.close();
  output_->flush();
}

void HciSniffer::SendEvent(const std::vector<uint8_t>& packet) {
+12 −6
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#include <chrono>
#include <cstdint>
#include <fstream>
#include <memory>
#include <ostream>

#include "model/hci/h4.h"
#include "model/hci/hci_transport.h"
@@ -30,18 +32,22 @@ enum class PacketDirection : uint8_t {
  HOST_TO_CONTROLLER = 1,
};

// A Hci Transport that logs all the in and out going
// packets to a stream.
class HciSniffer : public HciTransport {
 public:
  HciSniffer(std::shared_ptr<HciTransport> transport)
      : transport_(transport), start_(std::chrono::steady_clock::now()) {}
  HciSniffer(std::shared_ptr<HciTransport> transport,
             std::shared_ptr<std::ostream> outputStream = nullptr);
  ~HciSniffer() = default;

  static std::shared_ptr<HciTransport> Create(
      std::shared_ptr<HciTransport> transport) {
    return std::make_shared<HciSniffer>(transport);
      std::shared_ptr<HciTransport> transport,
      std::shared_ptr<std::ostream> outputStream = nullptr) {
    return std::make_shared<HciSniffer>(transport, outputStream);
  }

  void Open(const char* filename);
  // Sets and initializes the output stream
  void SetOutputStream(std::shared_ptr<std::ostream> outputStream);

  void SendEvent(const std::vector<uint8_t>& packet) override;

@@ -65,7 +71,7 @@ class HciSniffer : public HciTransport {
  void AppendRecord(PacketDirection direction, PacketType type,
                    const std::vector<uint8_t>& packet);

  std::ofstream output_;
  std::shared_ptr<std::ostream> output_;
  std::shared_ptr<HciTransport> transport_;
  std::chrono::time_point<std::chrono::steady_clock> start_;
};