Bug 1343640: dump RT(C)P as raw hex into log files. r=bwc
authorNils Ohlmeier [:drno] <drno@ohlmeier.org>
Wed, 01 Mar 2017 23:22:36 -0800
changeset 395466 e51ffbba045f02e4dc4e2efed5ff8c162c26260f
parent 395465 335a2fee24a89a49eaac0507d24968418fb3f430
child 395467 8ffb5d661b03c94c2e22314f727899f659f1a68b
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbwc
bugs1343640
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1343640: dump RT(C)P as raw hex into log files. r=bwc MozReview-Commit-ID: 5vNitjQJmih
media/webrtc/signaling/signaling.gyp
media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
media/webrtc/signaling/src/mediapipeline/RtpLogger.cpp
media/webrtc/signaling/src/mediapipeline/RtpLogger.h
--- a/media/webrtc/signaling/signaling.gyp
+++ b/media/webrtc/signaling/signaling.gyp
@@ -125,16 +125,18 @@
         './src/peerconnection/PeerConnectionImpl.h',
         './src/peerconnection/PeerConnectionMedia.cpp',
         './src/peerconnection/PeerConnectionMedia.h',
         # Media pipeline
         './src/mediapipeline/MediaPipeline.h',
         './src/mediapipeline/MediaPipeline.cpp',
         './src/mediapipeline/MediaPipelineFilter.h',
         './src/mediapipeline/MediaPipelineFilter.cpp',
+        './src/mediapipeline/RtpLogger.h',
+        './src/mediapipeline/RtpLogger.cpp',
          # SDP
          './src/sdp/sipcc/ccsdp.h',
          './src/sdp/sipcc/cpr_string.c',
          './src/sdp/sipcc/sdp_access.c',
          './src/sdp/sipcc/sdp_attr.c',
          './src/sdp/sipcc/sdp_attr_access.c',
          './src/sdp/sipcc/sdp_base64.c',
          './src/sdp/sipcc/sdp_config.c',
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -29,16 +29,17 @@
 #include "GrallocImages.h"
 #include "mozilla/layers/GrallocTextureClient.h"
 #endif
 
 #include "nsError.h"
 #include "AudioSegment.h"
 #include "MediaSegment.h"
 #include "MediaPipelineFilter.h"
+#include "RtpLogger.h"
 #include "databuffer.h"
 #include "transportflow.h"
 #include "transportlayer.h"
 #include "transportlayerdtls.h"
 #include "transportlayerice.h"
 #include "runnable_utils.h"
 #include "libyuv/convert.h"
 #include "mozilla/SharedThreadPool.h"
@@ -1071,16 +1072,19 @@ void MediaPipeline::RtpPacketReceived(Tr
 
     MOZ_MTLOG(ML_NOTICE, "Error unprotecting RTP in " << description_
               << "len= " << len << "[" << tmp << "...]");
     return;
   }
   MOZ_MTLOG(ML_DEBUG, description_ << " received RTP packet.");
   increment_rtp_packets_received(out_len);
 
+  RtpLogger::LogPacket(inner_data.get(), out_len, true, true, header.headerLength,
+                       description_);
+
   (void)conduit_->ReceivedRTPPacket(inner_data.get(), out_len, header.ssrc);  // Ignore error codes
 }
 
 void MediaPipeline::RtcpPacketReceived(TransportLayer *layer,
                                        const unsigned char *data,
                                        size_t len) {
   if (!transport_->pipeline()) {
     MOZ_MTLOG(ML_DEBUG, "Discarding incoming packet; transport disconnected");
@@ -1132,16 +1136,18 @@ void MediaPipeline::RtcpPacketReceived(T
                                                  &out_len);
 
   if (!NS_SUCCEEDED(res))
     return;
 
   MOZ_MTLOG(ML_DEBUG, description_ << " received RTCP packet.");
   increment_rtcp_packets_received();
 
+  RtpLogger::LogPacket(inner_data.get(), out_len, true, false, 0, description_);
+
   MOZ_ASSERT(rtcp_.recv_srtp_);  // This should never happen
 
   (void)conduit_->ReceivedRTCPPacket(inner_data.get(), out_len);  // Ignore error codes
 }
 
 bool MediaPipeline::IsRtp(const unsigned char *data, size_t len) {
   if (len < 2)
     return false;
@@ -1622,16 +1628,27 @@ nsresult MediaPipeline::PipelineTranspor
   }
 
   MOZ_ASSERT(transport.transport_);
   NS_ENSURE_TRUE(transport.transport_, NS_ERROR_NULL_POINTER);
 
   // libsrtp enciphers in place, so we need a big enough buffer.
   MOZ_ASSERT(data->capacity() >= data->len() + SRTP_MAX_EXPANSION);
 
+  if (RtpLogger::IsPacketLoggingOn()) {
+    int header_len = 12;
+    webrtc::RTPHeader header;
+    if (pipeline_->rtp_parser_ &&
+        pipeline_->rtp_parser_->Parse(data->data(), data->len(), &header)) {
+        header_len = header.headerLength;
+    }
+    RtpLogger::LogPacket(data->data(), data->len(), false, is_rtp, header_len,
+                         pipeline_->description_);
+  }
+
   int out_len;
   nsresult res;
   if (is_rtp) {
     res = transport.send_srtp_->ProtectRtp(data->data(),
                                            data->len(),
                                            data->capacity(),
                                            &out_len);
   } else {
new file mode 100644
--- /dev/null
+++ b/media/webrtc/signaling/src/mediapipeline/RtpLogger.cpp
@@ -0,0 +1,74 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Original author: nohlmeier@mozilla.com
+
+#include "RtpLogger.h"
+#include "logging.h"
+
+#include <sstream>
+#ifdef _WIN32
+#include <time.h>
+#include <sys/timeb.h>
+#else
+#include <sys/time.h>
+#endif
+
+// Logging context
+using namespace mozilla;
+MOZ_MTLOG_MODULE("rtplogger")
+
+namespace mozilla {
+
+bool RtpLogger::IsPacketLoggingOn() {
+  return MOZ_LOG_TEST(getLogModule(), ML_DEBUG);
+}
+
+void RtpLogger::LogPacket(const unsigned char *data, int len, bool input,
+                          bool isRtp, int headerLength, std::string desc) {
+  if (MOZ_LOG_TEST(getLogModule(), ML_DEBUG)) {
+    std::stringstream ss;
+    /* This creates text2pcap compatible format, e.g.:
+     *   O 10:36:26.864934  000000 80 c8 00 06 6d ... RTCP_PACKET
+     */
+    ss << (input ? "I " : "O ");
+    std::time_t t = std::time(nullptr);
+    std::tm tm = *std::localtime(&t);
+    char buf[9];
+    if (0 < strftime(buf, sizeof(buf), "%H:%M:%S", &tm)) {
+      ss << buf;
+    }
+    ss << std::setfill('0');
+#ifdef _WIN32
+    struct timeb tb;
+    ftime(&tb);
+    ss << "." << (tb.millitm) << " ";
+#else
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    ss << "." << (tv.tv_usec) << " ";
+#endif
+    ss << " 000000";
+    ss << std::hex << std::setfill('0');
+    int offset_ = headerLength;
+    if (isRtp && (offset_ + 5 < len)) {
+      // Allow the first 5 bytes of the payload in clear
+      offset_ += 5;
+    }
+    for (int i=0; i < len; ++i) {
+      if (isRtp && i > offset_) {
+        ss << " 00";
+      }
+      else {
+        ss << " " << std::setw(2) << (int)data[i];
+      }
+    }
+    MOZ_MTLOG(ML_DEBUG, "\n" << ss.str() <<
+              (isRtp ? " RTP_PACKET " : " RTCP_PACKET ") <<
+              desc);
+  }
+}
+
+}  // end of namespace
+
new file mode 100644
--- /dev/null
+++ b/media/webrtc/signaling/src/mediapipeline/RtpLogger.h
@@ -0,0 +1,28 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Original author: nohlmeier@mozilla.com
+
+#ifndef rtplogger_h__
+#define rtplogger_h__
+
+#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
+
+namespace mozilla {
+
+/* This class logs RTP and RTCP packets in hex in a format compatible to
+ * text2pcap.
+ * Example to convert the MOZ log file into a PCAP file:
+ *   egrep '(RTP_PACKET|RTCP_PACKET)' moz.log | text2pcap -D -n -l 1 -i 17 -u 1234,1235 -t '%H:%M:%S.' - rtp.pcap
+ */
+class RtpLogger {
+public:
+  static bool IsPacketLoggingOn();
+  static void LogPacket(const unsigned char *data, int len, bool input,
+                        bool isRtp, int headerLength, std::string desc);
+};
+
+}  // End of namespace
+#endif
+