dcsctp: Extract logging packet observer as utility

It is useful for more than just the transport.

Bug: webrtc:12961
Change-Id: Iad064c8fb707ca589a1c232e17436338fb06623d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/225543
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34451}
diff --git a/media/BUILD.gn b/media/BUILD.gn
index 30f642a..5f0f527 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -405,6 +405,7 @@
       "../net/dcsctp/public:factory",
       "../net/dcsctp/public:socket",
       "../net/dcsctp/public:types",
+      "../net/dcsctp/public:utils",
       "../net/dcsctp/timer:task_queue_timeout",
       "../p2p:rtc_p2p",
       "../rtc_base:checks",
diff --git a/media/sctp/dcsctp_transport.cc b/media/sctp/dcsctp_transport.cc
index d913f0c..3b89af1 100644
--- a/media/sctp/dcsctp_transport.cc
+++ b/media/sctp/dcsctp_transport.cc
@@ -21,6 +21,7 @@
 #include "media/base/media_channel.h"
 #include "net/dcsctp/public/dcsctp_socket_factory.h"
 #include "net/dcsctp/public/packet_observer.h"
+#include "net/dcsctp/public/text_pcap_packet_observer.h"
 #include "net/dcsctp/public/types.h"
 #include "p2p/base/packet_transport_internal.h"
 #include "rtc_base/checks.h"
@@ -100,46 +101,6 @@
   return webrtc_ppid == WebrtcPPID::kStringEmpty ||
          webrtc_ppid == WebrtcPPID::kBinaryEmpty;
 }
-
-// Print outs all sent and received packets to the logs, at LS_VERBOSE severity.
-class TextPcapPacketObserver : public dcsctp::PacketObserver {
- public:
-  explicit TextPcapPacketObserver(absl::string_view name) : name_(name) {}
-
-  void OnSentPacket(dcsctp::TimeMs now, rtc::ArrayView<const uint8_t> payload) {
-    PrintPacket("O ", now, payload);
-  }
-
-  void OnReceivedPacket(dcsctp::TimeMs now,
-                        rtc::ArrayView<const uint8_t> payload) {
-    PrintPacket("I ", now, payload);
-  }
-
- private:
-  void PrintPacket(absl::string_view prefix,
-                   dcsctp::TimeMs now,
-                   rtc::ArrayView<const uint8_t> payload) {
-    rtc::StringBuilder s;
-    s << "\n" << prefix;
-    int64_t remaining = *now % (24 * 60 * 60 * 1000);
-    int hours = remaining / (60 * 60 * 1000);
-    remaining = remaining % (60 * 60 * 1000);
-    int minutes = remaining / (60 * 1000);
-    remaining = remaining % (60 * 1000);
-    int seconds = remaining / 1000;
-    int ms = remaining % 1000;
-    s.AppendFormat("%02d:%02d:%02d.%03d", hours, minutes, seconds, ms);
-    s << " 0000";
-    for (uint8_t byte : payload) {
-      s.AppendFormat(" %02x", byte);
-    }
-    s << " # SCTP_PACKET " << name_;
-    RTC_LOG(LS_VERBOSE) << s.str();
-  }
-
-  const std::string name_;
-};
-
 }  // namespace
 
 DcSctpTransport::DcSctpTransport(rtc::Thread* network_thread,
@@ -196,7 +157,8 @@
 
     std::unique_ptr<dcsctp::PacketObserver> packet_observer;
     if (RTC_LOG_CHECK_LEVEL(LS_VERBOSE)) {
-      packet_observer = std::make_unique<TextPcapPacketObserver>(debug_name_);
+      packet_observer =
+          std::make_unique<dcsctp::TextPcapPacketObserver>(debug_name_);
     }
 
     dcsctp::DcSctpSocketFactory factory;
diff --git a/net/dcsctp/public/BUILD.gn b/net/dcsctp/public/BUILD.gn
index 495083f..ced94de 100644
--- a/net/dcsctp/public/BUILD.gn
+++ b/net/dcsctp/public/BUILD.gn
@@ -65,6 +65,22 @@
   ]
 }
 
+rtc_source_set("utils") {
+  deps = [
+    ":socket",
+    ":types",
+    "../../../api:array_view",
+    "../../../rtc_base:logging",
+    "../../../rtc_base:stringutils",
+    "../socket:dcsctp_socket",
+  ]
+  sources = [
+    "text_pcap_packet_observer.cc",
+    "text_pcap_packet_observer.h",
+  ]
+  absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+}
+
 if (rtc_include_tests) {
   rtc_library("dcsctp_public_unittests") {
     testonly = true
diff --git a/net/dcsctp/public/text_pcap_packet_observer.cc b/net/dcsctp/public/text_pcap_packet_observer.cc
new file mode 100644
index 0000000..2b13060
--- /dev/null
+++ b/net/dcsctp/public/text_pcap_packet_observer.cc
@@ -0,0 +1,54 @@
+/*
+ *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+#include "net/dcsctp/public/text_pcap_packet_observer.h"
+
+#include "api/array_view.h"
+#include "net/dcsctp/public/types.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace dcsctp {
+
+void TextPcapPacketObserver::OnSentPacket(
+    dcsctp::TimeMs now,
+    rtc::ArrayView<const uint8_t> payload) {
+  PrintPacket("O ", name_, now, payload);
+}
+
+void TextPcapPacketObserver::OnReceivedPacket(
+    dcsctp::TimeMs now,
+    rtc::ArrayView<const uint8_t> payload) {
+  PrintPacket("I ", name_, now, payload);
+}
+
+void TextPcapPacketObserver::PrintPacket(
+    absl::string_view prefix,
+    absl::string_view socket_name,
+    dcsctp::TimeMs now,
+    rtc::ArrayView<const uint8_t> payload) {
+  rtc::StringBuilder s;
+  s << "\n" << prefix;
+  int64_t remaining = *now % (24 * 60 * 60 * 1000);
+  int hours = remaining / (60 * 60 * 1000);
+  remaining = remaining % (60 * 60 * 1000);
+  int minutes = remaining / (60 * 1000);
+  remaining = remaining % (60 * 1000);
+  int seconds = remaining / 1000;
+  int ms = remaining % 1000;
+  s.AppendFormat("%02d:%02d:%02d.%03d", hours, minutes, seconds, ms);
+  s << " 0000";
+  for (uint8_t byte : payload) {
+    s.AppendFormat(" %02x", byte);
+  }
+  s << " # SCTP_PACKET " << socket_name;
+  RTC_LOG(LS_VERBOSE) << s.str();
+}
+
+}  // namespace dcsctp
diff --git a/net/dcsctp/public/text_pcap_packet_observer.h b/net/dcsctp/public/text_pcap_packet_observer.h
new file mode 100644
index 0000000..0685771
--- /dev/null
+++ b/net/dcsctp/public/text_pcap_packet_observer.h
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef NET_DCSCTP_PUBLIC_TEXT_PCAP_PACKET_OBSERVER_H_
+#define NET_DCSCTP_PUBLIC_TEXT_PCAP_PACKET_OBSERVER_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "api/array_view.h"
+#include "net/dcsctp/public/packet_observer.h"
+#include "net/dcsctp/public/types.h"
+
+namespace dcsctp {
+
+// Print outs all sent and received packets to the logs, at LS_VERBOSE severity.
+class TextPcapPacketObserver : public dcsctp::PacketObserver {
+ public:
+  explicit TextPcapPacketObserver(absl::string_view name) : name_(name) {}
+
+  // Implementation of `dcsctp::PacketObserver`.
+  void OnSentPacket(dcsctp::TimeMs now,
+                    rtc::ArrayView<const uint8_t> payload) override;
+
+  void OnReceivedPacket(dcsctp::TimeMs now,
+                        rtc::ArrayView<const uint8_t> payload) override;
+
+  // Prints a packet to the log. Exposed to allow it to be used in compatibility
+  // tests suites that don't use PacketObserver.
+  static void PrintPacket(absl::string_view prefix,
+                          absl::string_view socket_name,
+                          dcsctp::TimeMs now,
+                          rtc::ArrayView<const uint8_t> payload);
+
+ private:
+  const std::string name_;
+};
+
+}  // namespace dcsctp
+#endif  // NET_DCSCTP_PUBLIC_TEXT_PCAP_PACKET_OBSERVER_H_