Bug 1343640: dump RT(C)P as raw hex into log files. r?bwc
MozReview-Commit-ID: 5vNitjQJmih
--- 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
+