OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 static const char kSsrcAttributeMsid[] = "msid"; | 133 static const char kSsrcAttributeMsid[] = "msid"; |
134 static const char kDefaultMsid[] = "default"; | 134 static const char kDefaultMsid[] = "default"; |
135 static const char kSsrcAttributeMslabel[] = "mslabel"; | 135 static const char kSsrcAttributeMslabel[] = "mslabel"; |
136 static const char kSSrcAttributeLabel[] = "label"; | 136 static const char kSSrcAttributeLabel[] = "label"; |
137 static const char kAttributeSsrcGroup[] = "ssrc-group"; | 137 static const char kAttributeSsrcGroup[] = "ssrc-group"; |
138 static const char kAttributeCrypto[] = "crypto"; | 138 static const char kAttributeCrypto[] = "crypto"; |
139 static const char kAttributeCandidate[] = "candidate"; | 139 static const char kAttributeCandidate[] = "candidate"; |
140 static const char kAttributeCandidateTyp[] = "typ"; | 140 static const char kAttributeCandidateTyp[] = "typ"; |
141 static const char kAttributeCandidateRaddr[] = "raddr"; | 141 static const char kAttributeCandidateRaddr[] = "raddr"; |
142 static const char kAttributeCandidateRport[] = "rport"; | 142 static const char kAttributeCandidateRport[] = "rport"; |
143 static const char kAttributeCandidateUsername[] = "username"; | 143 static const char kAttributeCandidateUfrag[] = "ufrag"; |
144 static const char kAttributeCandidatePassword[] = "password"; | 144 static const char kAttributeCandidatePwd[] = "pwd"; |
145 static const char kAttributeCandidateGeneration[] = "generation"; | 145 static const char kAttributeCandidateGeneration[] = "generation"; |
146 static const char kAttributeFingerprint[] = "fingerprint"; | 146 static const char kAttributeFingerprint[] = "fingerprint"; |
147 static const char kAttributeSetup[] = "setup"; | 147 static const char kAttributeSetup[] = "setup"; |
148 static const char kAttributeFmtp[] = "fmtp"; | 148 static const char kAttributeFmtp[] = "fmtp"; |
149 static const char kAttributeRtpmap[] = "rtpmap"; | 149 static const char kAttributeRtpmap[] = "rtpmap"; |
150 static const char kAttributeSctpmap[] = "sctpmap"; | 150 static const char kAttributeSctpmap[] = "sctpmap"; |
151 static const char kAttributeRtcp[] = "rtcp"; | 151 static const char kAttributeRtcp[] = "rtcp"; |
152 static const char kAttributeIceUfrag[] = "ice-ufrag"; | 152 static const char kAttributeIceUfrag[] = "ice-ufrag"; |
153 static const char kAttributeIcePwd[] = "ice-pwd"; | 153 static const char kAttributeIcePwd[] = "ice-pwd"; |
154 static const char kAttributeIceLite[] = "ice-lite"; | 154 static const char kAttributeIceLite[] = "ice-lite"; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 std::string* message); | 255 std::string* message); |
256 static void BuildSctpContentAttributes(std::string* message, int sctp_port); | 256 static void BuildSctpContentAttributes(std::string* message, int sctp_port); |
257 static void BuildRtpContentAttributes( | 257 static void BuildRtpContentAttributes( |
258 const MediaContentDescription* media_desc, | 258 const MediaContentDescription* media_desc, |
259 const MediaType media_type, | 259 const MediaType media_type, |
260 std::string* message); | 260 std::string* message); |
261 static void BuildRtpMap(const MediaContentDescription* media_desc, | 261 static void BuildRtpMap(const MediaContentDescription* media_desc, |
262 const MediaType media_type, | 262 const MediaType media_type, |
263 std::string* message); | 263 std::string* message); |
264 static void BuildCandidate(const std::vector<Candidate>& candidates, | 264 static void BuildCandidate(const std::vector<Candidate>& candidates, |
| 265 bool include_ufrag, |
265 std::string* message); | 266 std::string* message); |
266 static void BuildIceOptions(const std::vector<std::string>& transport_options, | 267 static void BuildIceOptions(const std::vector<std::string>& transport_options, |
267 std::string* message); | 268 std::string* message); |
268 static bool IsRtp(const std::string& protocol); | 269 static bool IsRtp(const std::string& protocol); |
269 static bool IsDtlsSctp(const std::string& protocol); | 270 static bool IsDtlsSctp(const std::string& protocol); |
270 static bool ParseSessionDescription(const std::string& message, size_t* pos, | 271 static bool ParseSessionDescription(const std::string& message, size_t* pos, |
271 std::string* session_id, | 272 std::string* session_id, |
272 std::string* session_version, | 273 std::string* session_version, |
273 TransportDescription* session_td, | 274 TransportDescription* session_td, |
274 RtpHeaderExtensions* session_extmaps, | 275 RtpHeaderExtensions* session_extmaps, |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 return message; | 872 return message; |
872 } | 873 } |
873 | 874 |
874 // Serializes the passed in IceCandidateInterface to a SDP string. | 875 // Serializes the passed in IceCandidateInterface to a SDP string. |
875 // candidate - The candidate to be serialized. | 876 // candidate - The candidate to be serialized. |
876 std::string SdpSerializeCandidate( | 877 std::string SdpSerializeCandidate( |
877 const IceCandidateInterface& candidate) { | 878 const IceCandidateInterface& candidate) { |
878 std::string message; | 879 std::string message; |
879 std::vector<cricket::Candidate> candidates; | 880 std::vector<cricket::Candidate> candidates; |
880 candidates.push_back(candidate.candidate()); | 881 candidates.push_back(candidate.candidate()); |
881 BuildCandidate(candidates, &message); | 882 BuildCandidate(candidates, true, &message); |
882 // From WebRTC draft section 4.8.1.1 candidate-attribute will be | 883 // From WebRTC draft section 4.8.1.1 candidate-attribute will be |
883 // just candidate:<candidate> not a=candidate:<blah>CRLF | 884 // just candidate:<candidate> not a=candidate:<blah>CRLF |
884 ASSERT(message.find("a=") == 0); | 885 ASSERT(message.find("a=") == 0); |
885 message.erase(0, 2); | 886 message.erase(0, 2); |
886 ASSERT(message.find(kLineBreak) == message.size() - 2); | 887 ASSERT(message.find(kLineBreak) == message.size() - 2); |
887 message.resize(message.size() - 2); | 888 message.resize(message.size() - 2); |
888 return message; | 889 return message; |
889 } | 890 } |
890 | 891 |
891 bool SdpDeserialize(const std::string& message, | 892 bool SdpDeserialize(const std::string& message, |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 tcptype != cricket::TCPTYPE_SIMOPEN_STR) { | 1066 tcptype != cricket::TCPTYPE_SIMOPEN_STR) { |
1066 return ParseFailed(first_line, "Invalid TCP candidate type.", error); | 1067 return ParseFailed(first_line, "Invalid TCP candidate type.", error); |
1067 } | 1068 } |
1068 | 1069 |
1069 if (protocol != cricket::PROTO_TCP) { | 1070 if (protocol != cricket::PROTO_TCP) { |
1070 return ParseFailed(first_line, "Invalid non-TCP candidate", error); | 1071 return ParseFailed(first_line, "Invalid non-TCP candidate", error); |
1071 } | 1072 } |
1072 } | 1073 } |
1073 | 1074 |
1074 // Extension | 1075 // Extension |
1075 // Empty string as the candidate username and password. | 1076 // Though non-standard, we support the ICE ufrag and pwd being signaled on |
1076 // Will be updated later with the ice-ufrag and ice-pwd. | 1077 // the candidate to avoid issues with confusing which generation a candidate |
1077 // TODO: Remove the username/password extension, which is currently | 1078 // belongs to when trickling multiple generations at the same time. |
1078 // kept for backwards compatibility. | |
1079 std::string username; | 1079 std::string username; |
1080 std::string password; | 1080 std::string password; |
1081 uint32_t generation = 0; | 1081 uint32_t generation = 0; |
1082 for (size_t i = current_position; i + 1 < fields.size(); ++i) { | 1082 for (size_t i = current_position; i + 1 < fields.size(); ++i) { |
1083 // RFC 5245 | 1083 // RFC 5245 |
1084 // *(SP extension-att-name SP extension-att-value) | 1084 // *(SP extension-att-name SP extension-att-value) |
1085 if (fields[i] == kAttributeCandidateGeneration) { | 1085 if (fields[i] == kAttributeCandidateGeneration) { |
1086 if (!GetValueFromString(first_line, fields[++i], &generation, error)) { | 1086 if (!GetValueFromString(first_line, fields[++i], &generation, error)) { |
1087 return false; | 1087 return false; |
1088 } | 1088 } |
1089 } else if (fields[i] == kAttributeCandidateUsername) { | 1089 } else if (fields[i] == kAttributeCandidateUfrag) { |
1090 username = fields[++i]; | 1090 username = fields[++i]; |
1091 } else if (fields[i] == kAttributeCandidatePassword) { | 1091 } else if (fields[i] == kAttributeCandidatePwd) { |
1092 password = fields[++i]; | 1092 password = fields[++i]; |
1093 } else { | 1093 } else { |
1094 // Skip the unknown extension. | 1094 // Skip the unknown extension. |
1095 ++i; | 1095 ++i; |
1096 } | 1096 } |
1097 } | 1097 } |
1098 | 1098 |
1099 *candidate = Candidate(component_id, cricket::ProtoToString(protocol), | 1099 *candidate = Candidate(component_id, cricket::ProtoToString(protocol), |
1100 address, priority, username, password, candidate_type, | 1100 address, priority, username, password, candidate_type, |
1101 generation, foundation); | 1101 generation, foundation); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1278 } | 1278 } |
1279 | 1279 |
1280 // Add the a=rtcp line. | 1280 // Add the a=rtcp line. |
1281 if (IsRtp(media_desc->protocol())) { | 1281 if (IsRtp(media_desc->protocol())) { |
1282 std::string rtcp_line = GetRtcpLine(candidates); | 1282 std::string rtcp_line = GetRtcpLine(candidates); |
1283 if (!rtcp_line.empty()) { | 1283 if (!rtcp_line.empty()) { |
1284 AddLine(rtcp_line, message); | 1284 AddLine(rtcp_line, message); |
1285 } | 1285 } |
1286 } | 1286 } |
1287 | 1287 |
1288 // Build the a=candidate lines. | 1288 // Build the a=candidate lines. We don't include ufrag and pwd in the |
1289 BuildCandidate(candidates, message); | 1289 // candidates in the SDP to avoid redundancy. |
| 1290 BuildCandidate(candidates, false, message); |
1290 | 1291 |
1291 // Use the transport_info to build the media level ice-ufrag and ice-pwd. | 1292 // Use the transport_info to build the media level ice-ufrag and ice-pwd. |
1292 if (transport_info) { | 1293 if (transport_info) { |
1293 // RFC 5245 | 1294 // RFC 5245 |
1294 // ice-pwd-att = "ice-pwd" ":" password | 1295 // ice-pwd-att = "ice-pwd" ":" password |
1295 // ice-ufrag-att = "ice-ufrag" ":" ufrag | 1296 // ice-ufrag-att = "ice-ufrag" ":" ufrag |
1296 // ice-ufrag | 1297 // ice-ufrag |
1297 InitAttrLine(kAttributeIceUfrag, &os); | 1298 InitAttrLine(kAttributeIceUfrag, &os); |
1298 os << kSdpDelimiterColon << transport_info->description.ice_ufrag; | 1299 os << kSdpDelimiterColon << transport_info->description.ice_ufrag; |
1299 AddLine(os.str(), message); | 1300 AddLine(os.str(), message); |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1710 // [/<encodingparameters>] | 1711 // [/<encodingparameters>] |
1711 InitAttrLine(kAttributeRtpmap, &os); | 1712 InitAttrLine(kAttributeRtpmap, &os); |
1712 os << kSdpDelimiterColon << it->id << " " | 1713 os << kSdpDelimiterColon << it->id << " " |
1713 << it->name << "/" << it->clockrate; | 1714 << it->name << "/" << it->clockrate; |
1714 AddLine(os.str(), message); | 1715 AddLine(os.str(), message); |
1715 } | 1716 } |
1716 } | 1717 } |
1717 } | 1718 } |
1718 | 1719 |
1719 void BuildCandidate(const std::vector<Candidate>& candidates, | 1720 void BuildCandidate(const std::vector<Candidate>& candidates, |
| 1721 bool include_ufrag, |
1720 std::string* message) { | 1722 std::string* message) { |
1721 std::ostringstream os; | 1723 std::ostringstream os; |
1722 | 1724 |
1723 for (std::vector<Candidate>::const_iterator it = candidates.begin(); | 1725 for (std::vector<Candidate>::const_iterator it = candidates.begin(); |
1724 it != candidates.end(); ++it) { | 1726 it != candidates.end(); ++it) { |
1725 // RFC 5245 | 1727 // RFC 5245 |
1726 // a=candidate:<foundation> <component-id> <transport> <priority> | 1728 // a=candidate:<foundation> <component-id> <transport> <priority> |
1727 // <connection-address> <port> typ <candidate-types> | 1729 // <connection-address> <port> typ <candidate-types> |
1728 // [raddr <connection-address>] [rport <port>] | 1730 // [raddr <connection-address>] [rport <port>] |
1729 // *(SP extension-att-name SP extension-att-value) | 1731 // *(SP extension-att-name SP extension-att-value) |
(...skipping 29 matching lines...) Expand all Loading... |
1759 << kAttributeCandidateRport << " " | 1761 << kAttributeCandidateRport << " " |
1760 << it->related_address().PortAsString() << " "; | 1762 << it->related_address().PortAsString() << " "; |
1761 } | 1763 } |
1762 | 1764 |
1763 if (it->protocol() == cricket::TCP_PROTOCOL_NAME) { | 1765 if (it->protocol() == cricket::TCP_PROTOCOL_NAME) { |
1764 os << kTcpCandidateType << " " << it->tcptype() << " "; | 1766 os << kTcpCandidateType << " " << it->tcptype() << " "; |
1765 } | 1767 } |
1766 | 1768 |
1767 // Extensions | 1769 // Extensions |
1768 os << kAttributeCandidateGeneration << " " << it->generation(); | 1770 os << kAttributeCandidateGeneration << " " << it->generation(); |
| 1771 if (include_ufrag && !it->username().empty()) { |
| 1772 os << " " << kAttributeCandidateUfrag << " " << it->username(); |
| 1773 } |
1769 | 1774 |
1770 AddLine(os.str(), message); | 1775 AddLine(os.str(), message); |
1771 } | 1776 } |
1772 } | 1777 } |
1773 | 1778 |
1774 void BuildIceOptions(const std::vector<std::string>& transport_options, | 1779 void BuildIceOptions(const std::vector<std::string>& transport_options, |
1775 std::string* message) { | 1780 std::string* message) { |
1776 if (!transport_options.empty()) { | 1781 if (!transport_options.empty()) { |
1777 std::ostringstream os; | 1782 std::ostringstream os; |
1778 InitAttrLine(kAttributeIceOption, &os); | 1783 InitAttrLine(kAttributeIceOption, &os); |
(...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2670 // only rtcp-fb. | 2675 // only rtcp-fb. |
2671 if (!VerifyVideoCodecs(video_desc)) { | 2676 if (!VerifyVideoCodecs(video_desc)) { |
2672 return ParseFailed("Failed to parse video codecs correctly.", error); | 2677 return ParseFailed("Failed to parse video codecs correctly.", error); |
2673 } | 2678 } |
2674 } | 2679 } |
2675 | 2680 |
2676 // RFC 5245 | 2681 // RFC 5245 |
2677 // Update the candidates with the media level "ice-pwd" and "ice-ufrag". | 2682 // Update the candidates with the media level "ice-pwd" and "ice-ufrag". |
2678 for (Candidates::iterator it = candidates_orig.begin(); | 2683 for (Candidates::iterator it = candidates_orig.begin(); |
2679 it != candidates_orig.end(); ++it) { | 2684 it != candidates_orig.end(); ++it) { |
2680 ASSERT((*it).username().empty()); | 2685 ASSERT((*it).username().empty() || |
| 2686 (*it).username() == transport->ice_ufrag); |
2681 (*it).set_username(transport->ice_ufrag); | 2687 (*it).set_username(transport->ice_ufrag); |
2682 ASSERT((*it).password().empty()); | 2688 ASSERT((*it).password().empty()); |
2683 (*it).set_password(transport->ice_pwd); | 2689 (*it).set_password(transport->ice_pwd); |
2684 candidates->push_back( | 2690 candidates->push_back( |
2685 new JsepIceCandidate(mline_id, mline_index, *it)); | 2691 new JsepIceCandidate(mline_id, mline_index, *it)); |
2686 } | 2692 } |
2687 return true; | 2693 return true; |
2688 } | 2694 } |
2689 | 2695 |
2690 bool ParseSsrcAttribute(const std::string& line, SsrcInfoVec* ssrc_infos, | 2696 bool ParseSsrcAttribute(const std::string& line, SsrcInfoVec* ssrc_infos, |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3067 UpdateCodec<AudioContentDescription, cricket::AudioCodec>( | 3073 UpdateCodec<AudioContentDescription, cricket::AudioCodec>( |
3068 media_desc, payload_type, feedback_param); | 3074 media_desc, payload_type, feedback_param); |
3069 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { | 3075 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { |
3070 UpdateCodec<VideoContentDescription, cricket::VideoCodec>( | 3076 UpdateCodec<VideoContentDescription, cricket::VideoCodec>( |
3071 media_desc, payload_type, feedback_param); | 3077 media_desc, payload_type, feedback_param); |
3072 } | 3078 } |
3073 return true; | 3079 return true; |
3074 } | 3080 } |
3075 | 3081 |
3076 } // namespace webrtc | 3082 } // namespace webrtc |
OLD | NEW |