| 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 |