summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorjiayl@webrtc.org <jiayl@webrtc.org>2014-09-05 16:31:56 +0000
committerjiayl@webrtc.org <jiayl@webrtc.org>2014-09-05 16:31:56 +0000
commit6ea7f028683dcb7195a2a12ca2105d90350f8e03 (patch)
treebaa858ed505f985ed5cd5b3a23efc35ea62c80e7 /app
parentec9284d99b92c19d03d924f814e9484184f2075d (diff)
downloadtalk-6ea7f028683dcb7195a2a12ca2105d90350f8e03.tar.gz
Updated SCTP SDP attributes according to draft-ietf-mmusic-sctp-sdp-07
- SDP sctpmap attribute replaced with fmtp attribute - SDP sctp-port attribute is newly added BUG=3592 R=jiayl@webrtc.org, juberti@webrtc.org Review URL: https://webrtc-codereview.appspot.com/16169004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7087 4adac7df-926f-26a2-2b94-8c16560cd09d
Diffstat (limited to 'app')
-rw-r--r--app/webrtc/webrtcsdp.cc88
-rw-r--r--app/webrtc/webrtcsdp_unittest.cc53
2 files changed, 120 insertions, 21 deletions
diff --git a/app/webrtc/webrtcsdp.cc b/app/webrtc/webrtcsdp.cc
index 792a091..f4b38c5 100644
--- a/app/webrtc/webrtcsdp.cc
+++ b/app/webrtc/webrtcsdp.cc
@@ -155,6 +155,9 @@ static const char kAttributeRecvOnly[] = "recvonly";
static const char kAttributeRtcpFb[] = "rtcp-fb";
static const char kAttributeSendRecv[] = "sendrecv";
static const char kAttributeInactive[] = "inactive";
+// draft-ietf-mmusic-sctp-sdp-07
+// a=sctp-port
+static const char kAttributeSctpPort[] = "sctp-port";
// Experimental flags
static const char kAttributeXGoogleFlag[] = "x-google-flag";
@@ -1100,6 +1103,26 @@ bool ParseIceOptions(const std::string& line,
return true;
}
+bool ParseSctpPort(const std::string& line,
+ int* sctp_port,
+ SdpParseError* error) {
+ // draft-ietf-mmusic-sctp-sdp-07
+ // a=sctp-port
+ std::vector<std::string> fields;
+ rtc::split(line.substr(kLinePrefixLength),
+ kSdpDelimiterSpace, &fields);
+ const size_t expected_min_fields = 2;
+ if (fields.size() < expected_min_fields) {
+ return ParseFailedExpectMinFieldNum(line, expected_min_fields, error);
+ }
+ if (!rtc::FromString(fields[1], sctp_port)) {
+ return ParseFailed(line,
+ "Invalid sctp port value.",
+ error);
+ }
+ return true;
+}
+
bool ParseExtmap(const std::string& line, RtpHeaderExtension* extmap,
SdpParseError* error) {
// RFC 5285
@@ -1563,6 +1586,24 @@ void AddRtcpFbLines(const T& codec, std::string* message) {
}
}
+bool AddSctpDataCodec(DataContentDescription* media_desc,
+ int sctp_port) {
+ if (media_desc->HasCodec(cricket::kGoogleSctpDataCodecId)) {
+ return ParseFailed("",
+ "Can't have multiple sctp port attributes.",
+ NULL);
+ }
+ // Add the SCTP Port number as a pseudo-codec "port" parameter
+ cricket::DataCodec codec_port(
+ cricket::kGoogleSctpDataCodecId, cricket::kGoogleSctpDataCodecName,
+ 0);
+ codec_port.SetParam(cricket::kCodecParamPort, sctp_port);
+ LOG(INFO) << "AddSctpDataCodec: Got SCTP Port Number "
+ << sctp_port;
+ media_desc->AddCodec(codec_port);
+ return true;
+}
+
bool GetMinValue(const std::vector<int>& values, int* value) {
if (values.empty()) {
return false;
@@ -2129,18 +2170,20 @@ bool ParseMediaDescription(const std::string& message,
// <fmt>
std::vector<int> codec_preference;
- for (size_t j = 3 ; j < fields.size(); ++j) {
- // TODO(wu): Remove when below bug is fixed.
- // https://bugzilla.mozilla.org/show_bug.cgi?id=996329
- if (fields[j] == "" && j == fields.size() - 1) {
- continue;
- }
+ if (!is_sctp) {
+ for (size_t j = 3 ; j < fields.size(); ++j) {
+ // TODO(wu): Remove when below bug is fixed.
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=996329
+ if (fields[j] == "" && j == fields.size() - 1) {
+ continue;
+ }
- int pl = 0;
- if (!GetValueFromString(line, fields[j], &pl, error)) {
- return false;
+ int pl = 0;
+ if (!GetValueFromString(line, fields[j], &pl, error)) {
+ return false;
+ }
+ codec_preference.push_back(pl);
}
- codec_preference.push_back(pl);
}
// Make a temporary TransportDescription based on |session_td|.
@@ -2173,20 +2216,14 @@ bool ParseMediaDescription(const std::string& message,
codec_preference, pos, &content_name,
&transport, candidates, error);
- if (desc && protocol == cricket::kMediaProtocolDtlsSctp) {
- // Add the SCTP Port number as a pseudo-codec "port" parameter
- cricket::DataCodec codec_port(
- cricket::kGoogleSctpDataCodecId, cricket::kGoogleSctpDataCodecName,
- 0);
- codec_port.SetParam(cricket::kCodecParamPort, fields[3]);
- LOG(INFO) << "ParseMediaDescription: Got SCTP Port Number "
- << fields[3];
- ASSERT(!desc->HasCodec(cricket::kGoogleSctpDataCodecId));
- desc->AddCodec(codec_port);
+ int p;
+ if (desc && protocol == cricket::kMediaProtocolDtlsSctp &&
+ rtc::FromString(fields[3], &p)) {
+ if (!AddSctpDataCodec(desc, p))
+ return false;
}
content.reset(desc);
-
// We should always use the default bandwidth for RTP-based data
// channels. Don't allow SDP to set the bandwidth, because that
// would give JS the opportunity to "break the Internet".
@@ -2518,6 +2555,15 @@ bool ParseContent(const std::string& message,
if (!ParseDtlsSetup(line, &(transport->connection_role), error)) {
return false;
}
+ } else if (HasAttribute(line, kAttributeSctpPort)) {
+ int sctp_port;
+ if (!ParseSctpPort(line, &sctp_port, error)) {
+ return false;
+ }
+ if (!AddSctpDataCodec(static_cast<DataContentDescription*>(media_desc),
+ sctp_port)) {
+ return false;
+ }
} else if (is_rtp) {
//
// RTP specific attrubtes
diff --git a/app/webrtc/webrtcsdp_unittest.cc b/app/webrtc/webrtcsdp_unittest.cc
index 6a22e38..560d5da 100644
--- a/app/webrtc/webrtcsdp_unittest.cc
+++ b/app/webrtc/webrtcsdp_unittest.cc
@@ -284,6 +284,16 @@ static const char kSdpSctpDataChannelString[] =
"a=mid:data_content_name\r\n"
"a=sctpmap:5000 webrtc-datachannel 1024\r\n";
+// draft-ietf-mmusic-sctp-sdp-07
+static const char kSdpSctpDataChannelStringWithSctpPort[] =
+ "m=application 1 DTLS/SCTP webrtc-datachannel\r\n"
+ "a=fmtp:webrtc-datachannel max-message-size=100000\r\n"
+ "a=sctp-port 5000\r\n"
+ "c=IN IP4 0.0.0.0\r\n"
+ "a=ice-ufrag:ufrag_data\r\n"
+ "a=ice-pwd:pwd_data\r\n"
+ "a=mid:data_content_name\r\n";
+
static const char kSdpSctpDataChannelWithCandidatesString[] =
"m=application 2345 DTLS/SCTP 5000\r\n"
"c=IN IP4 74.125.127.126\r\n"
@@ -2023,6 +2033,36 @@ TEST_F(WebRtcSdpTest, DeserializeSdpWithSctpDataChannels) {
EXPECT_TRUE(CompareSessionDescription(jdesc, jdesc_output));
}
+TEST_F(WebRtcSdpTest, DeserializeSdpWithSctpDataChannelsWithSctpPort) {
+ AddSctpDataChannel();
+ JsepSessionDescription jdesc(kDummyString);
+ ASSERT_TRUE(jdesc.Initialize(desc_.Copy(), kSessionId, kSessionVersion));
+
+ std::string sdp_with_data = kSdpString;
+ sdp_with_data.append(kSdpSctpDataChannelStringWithSctpPort);
+ JsepSessionDescription jdesc_output(kDummyString);
+
+ EXPECT_TRUE(SdpDeserialize(sdp_with_data, &jdesc_output));
+ EXPECT_TRUE(CompareSessionDescription(jdesc, jdesc_output));
+}
+
+// Test to check the behaviour if sctp-port is specified
+// on the m= line and in a=sctp-port.
+TEST_F(WebRtcSdpTest, DeserializeSdpWithMultiSctpPort) {
+ AddSctpDataChannel();
+ JsepSessionDescription jdesc(kDummyString);
+ ASSERT_TRUE(jdesc.Initialize(desc_.Copy(), kSessionId, kSessionVersion));
+
+ std::string sdp_with_data = kSdpString;
+ // Append m= attributes
+ sdp_with_data.append(kSdpSctpDataChannelString);
+ // Append a=sctp-port attribute
+ sdp_with_data.append("a=sctp-port 5000\r\n");
+ JsepSessionDescription jdesc_output(kDummyString);
+
+ EXPECT_FALSE(SdpDeserialize(sdp_with_data, &jdesc_output));
+}
+
// For crbug/344475.
TEST_F(WebRtcSdpTest, DeserializeSdpWithCorruptedSctpDataChannels) {
std::string sdp_with_data = kSdpString;
@@ -2071,6 +2111,19 @@ TEST_F(WebRtcSdpTest, DeserializeSdpWithSctpDataChannelAndNewPort) {
EXPECT_TRUE(SdpDeserialize(sdp_with_data, &jdesc_output));
EXPECT_TRUE(CompareSessionDescription(jdesc, jdesc_output));
+
+ // We need to test the deserialized JsepSessionDescription from
+ // kSdpSctpDataChannelStringWithSctpPort for
+ // draft-ietf-mmusic-sctp-sdp-07
+ // a=sctp-port
+ sdp_with_data = kSdpString;
+ sdp_with_data.append(kSdpSctpDataChannelStringWithSctpPort);
+ rtc::replace_substrs(default_portstr, strlen(default_portstr),
+ unusual_portstr, strlen(unusual_portstr),
+ &sdp_with_data);
+
+ EXPECT_TRUE(SdpDeserialize(sdp_with_data, &jdesc_output));
+ EXPECT_TRUE(CompareSessionDescription(jdesc, jdesc_output));
}
TEST_F(WebRtcSdpTest, DeserializeSdpWithRtpDataChannelsAndBandwidth) {