OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/protocol/jingle_messages.h" | 5 #include "remoting/protocol/jingle_messages.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "remoting/base/constants.h" | 9 #include "remoting/base/constants.h" |
10 #include "remoting/protocol/content_description.h" | 10 #include "remoting/protocol/content_description.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 | 41 |
42 const NameMapElement<JingleMessage::Reason> kReasons[] = { | 42 const NameMapElement<JingleMessage::Reason> kReasons[] = { |
43 { JingleMessage::SUCCESS, "success" }, | 43 { JingleMessage::SUCCESS, "success" }, |
44 { JingleMessage::DECLINE, "decline" }, | 44 { JingleMessage::DECLINE, "decline" }, |
45 { JingleMessage::CANCEL, "cancel" }, | 45 { JingleMessage::CANCEL, "cancel" }, |
46 { JingleMessage::GENERAL_ERROR, "general-error" }, | 46 { JingleMessage::GENERAL_ERROR, "general-error" }, |
47 { JingleMessage::INCOMPATIBLE_PARAMETERS, "incompatible-parameters" }, | 47 { JingleMessage::INCOMPATIBLE_PARAMETERS, "incompatible-parameters" }, |
48 }; | 48 }; |
49 | 49 |
50 bool ParseIceCredentials(const buzz::XmlElement* element, | 50 bool ParseIceCredentials(const buzz::XmlElement* element, |
51 IceTransportInfo::IceCredentials* credentials) { | 51 JingleMessage::IceCredentials* credentials) { |
52 DCHECK(element->Name() == QName(kIceTransportNamespace, "credentials")); | 52 DCHECK(element->Name() == QName(kIceTransportNamespace, "credentials")); |
53 | 53 |
54 const std::string& channel = element->Attr(QName(kEmptyNamespace, "channel")); | 54 const std::string& channel = element->Attr(QName(kEmptyNamespace, "channel")); |
55 const std::string& ufrag = | 55 const std::string& ufrag = |
56 element->Attr(QName(kEmptyNamespace, "ufrag")); | 56 element->Attr(QName(kEmptyNamespace, "ufrag")); |
57 const std::string& password = | 57 const std::string& password = |
58 element->Attr(QName(kEmptyNamespace, "password")); | 58 element->Attr(QName(kEmptyNamespace, "password")); |
59 | 59 |
60 if (channel.empty() || ufrag.empty() || password.empty()) { | 60 if (channel.empty() || ufrag.empty() || password.empty()) { |
61 return false; | 61 return false; |
62 } | 62 } |
63 | 63 |
64 credentials->channel = channel; | 64 credentials->channel = channel; |
65 credentials->ufrag = ufrag; | 65 credentials->ufrag = ufrag; |
66 credentials->password = password; | 66 credentials->password = password; |
67 | 67 |
68 return true; | 68 return true; |
69 } | 69 } |
70 | 70 |
71 bool ParseIceCandidate(const buzz::XmlElement* element, | 71 bool ParseIceCandidate(const buzz::XmlElement* element, |
72 IceTransportInfo::NamedCandidate* candidate) { | 72 JingleMessage::NamedCandidate* candidate) { |
73 DCHECK(element->Name() == QName(kIceTransportNamespace, "candidate")); | 73 DCHECK(element->Name() == QName(kIceTransportNamespace, "candidate")); |
74 | 74 |
75 const std::string& name = element->Attr(QName(kEmptyNamespace, "name")); | 75 const std::string& name = element->Attr(QName(kEmptyNamespace, "name")); |
76 const std::string& foundation = | 76 const std::string& foundation = |
77 element->Attr(QName(kEmptyNamespace, "foundation")); | 77 element->Attr(QName(kEmptyNamespace, "foundation")); |
78 const std::string& address = element->Attr(QName(kEmptyNamespace, "address")); | 78 const std::string& address = element->Attr(QName(kEmptyNamespace, "address")); |
79 const std::string& port_str = element->Attr(QName(kEmptyNamespace, "port")); | 79 const std::string& port_str = element->Attr(QName(kEmptyNamespace, "port")); |
80 const std::string& type = element->Attr(QName(kEmptyNamespace, "type")); | 80 const std::string& type = element->Attr(QName(kEmptyNamespace, "type")); |
81 const std::string& protocol = | 81 const std::string& protocol = |
82 element->Attr(QName(kEmptyNamespace, "protocol")); | 82 element->Attr(QName(kEmptyNamespace, "protocol")); |
(...skipping 18 matching lines...) Expand all Loading... |
101 candidate->candidate.set_foundation(foundation); | 101 candidate->candidate.set_foundation(foundation); |
102 candidate->candidate.set_address(rtc::SocketAddress(address, port)); | 102 candidate->candidate.set_address(rtc::SocketAddress(address, port)); |
103 candidate->candidate.set_type(type); | 103 candidate->candidate.set_type(type); |
104 candidate->candidate.set_protocol(protocol); | 104 candidate->candidate.set_protocol(protocol); |
105 candidate->candidate.set_priority(priority); | 105 candidate->candidate.set_priority(priority); |
106 candidate->candidate.set_generation(generation); | 106 candidate->candidate.set_generation(generation); |
107 | 107 |
108 return true; | 108 return true; |
109 } | 109 } |
110 | 110 |
| 111 bool ParseIceTransportInfo( |
| 112 const buzz::XmlElement* element, |
| 113 std::list<JingleMessage::IceCredentials>* ice_credentials, |
| 114 std::list<JingleMessage::NamedCandidate>* candidates) { |
| 115 DCHECK(element->Name() == QName(kIceTransportNamespace, "transport")); |
| 116 |
| 117 ice_credentials->clear(); |
| 118 candidates->clear(); |
| 119 |
| 120 QName qn_credentials(kIceTransportNamespace, "credentials"); |
| 121 for (const XmlElement* credentials_tag = element->FirstNamed(qn_credentials); |
| 122 credentials_tag; |
| 123 credentials_tag = credentials_tag->NextNamed(qn_credentials)) { |
| 124 JingleMessage::IceCredentials credentials; |
| 125 if (!ParseIceCredentials(credentials_tag, &credentials)) |
| 126 return false; |
| 127 ice_credentials->push_back(credentials); |
| 128 } |
| 129 |
| 130 QName qn_candidate(kIceTransportNamespace, "candidate"); |
| 131 for (const XmlElement* candidate_tag = element->FirstNamed(qn_candidate); |
| 132 candidate_tag; candidate_tag = candidate_tag->NextNamed(qn_candidate)) { |
| 133 JingleMessage::NamedCandidate candidate; |
| 134 if (!ParseIceCandidate(candidate_tag, &candidate)) |
| 135 return false; |
| 136 candidates->push_back(candidate); |
| 137 } |
| 138 |
| 139 return true; |
| 140 } |
| 141 |
111 XmlElement* FormatIceCredentials( | 142 XmlElement* FormatIceCredentials( |
112 const IceTransportInfo::IceCredentials& credentials) { | 143 const JingleMessage::IceCredentials& credentials) { |
113 XmlElement* result = | 144 XmlElement* result = |
114 new XmlElement(QName(kIceTransportNamespace, "credentials")); | 145 new XmlElement(QName(kIceTransportNamespace, "credentials")); |
115 result->SetAttr(QName(kEmptyNamespace, "channel"), credentials.channel); | 146 result->SetAttr(QName(kEmptyNamespace, "channel"), credentials.channel); |
116 result->SetAttr(QName(kEmptyNamespace, "ufrag"), credentials.ufrag); | 147 result->SetAttr(QName(kEmptyNamespace, "ufrag"), credentials.ufrag); |
117 result->SetAttr(QName(kEmptyNamespace, "password"), credentials.password); | 148 result->SetAttr(QName(kEmptyNamespace, "password"), credentials.password); |
118 return result; | 149 return result; |
119 } | 150 } |
120 | 151 |
121 XmlElement* FormatIceCandidate( | 152 XmlElement* FormatIceCandidate(const JingleMessage::NamedCandidate& candidate) { |
122 const IceTransportInfo::NamedCandidate& candidate) { | |
123 XmlElement* result = | 153 XmlElement* result = |
124 new XmlElement(QName(kIceTransportNamespace, "candidate")); | 154 new XmlElement(QName(kIceTransportNamespace, "candidate")); |
125 result->SetAttr(QName(kEmptyNamespace, "name"), candidate.name); | 155 result->SetAttr(QName(kEmptyNamespace, "name"), candidate.name); |
126 result->SetAttr(QName(kEmptyNamespace, "foundation"), | 156 result->SetAttr(QName(kEmptyNamespace, "foundation"), |
127 candidate.candidate.foundation()); | 157 candidate.candidate.foundation()); |
128 result->SetAttr(QName(kEmptyNamespace, "address"), | 158 result->SetAttr(QName(kEmptyNamespace, "address"), |
129 candidate.candidate.address().ipaddr().ToString()); | 159 candidate.candidate.address().ipaddr().ToString()); |
130 result->SetAttr(QName(kEmptyNamespace, "port"), | 160 result->SetAttr(QName(kEmptyNamespace, "port"), |
131 base::UintToString(candidate.candidate.address().port())); | 161 base::UintToString(candidate.candidate.address().port())); |
132 result->SetAttr(QName(kEmptyNamespace, "type"), candidate.candidate.type()); | 162 result->SetAttr(QName(kEmptyNamespace, "type"), candidate.candidate.type()); |
133 result->SetAttr(QName(kEmptyNamespace, "protocol"), | 163 result->SetAttr(QName(kEmptyNamespace, "protocol"), |
134 candidate.candidate.protocol()); | 164 candidate.candidate.protocol()); |
135 result->SetAttr(QName(kEmptyNamespace, "priority"), | 165 result->SetAttr(QName(kEmptyNamespace, "priority"), |
136 base::UintToString(candidate.candidate.priority())); | 166 base::UintToString(candidate.candidate.priority())); |
137 result->SetAttr(QName(kEmptyNamespace, "generation"), | 167 result->SetAttr(QName(kEmptyNamespace, "generation"), |
138 base::UintToString(candidate.candidate.generation())); | 168 base::UintToString(candidate.candidate.generation())); |
139 return result; | 169 return result; |
140 } | 170 } |
141 | 171 |
142 } // namespace | 172 } // namespace |
143 | 173 |
144 IceTransportInfo::NamedCandidate::NamedCandidate( | 174 JingleMessage::NamedCandidate::NamedCandidate( |
145 const std::string& name, | 175 const std::string& name, |
146 const cricket::Candidate& candidate) | 176 const cricket::Candidate& candidate) |
147 : name(name), | 177 : name(name), |
148 candidate(candidate) { | 178 candidate(candidate) { |
149 } | 179 } |
150 | 180 |
151 IceTransportInfo::IceCredentials::IceCredentials(std::string channel, | 181 JingleMessage::IceCredentials::IceCredentials(std::string channel, |
152 std::string ufrag, | 182 std::string ufrag, |
153 std::string password) | 183 std::string password) |
154 : channel(channel), ufrag(ufrag), password(password) { | 184 : channel(channel), ufrag(ufrag), password(password) { |
155 } | 185 } |
156 | 186 |
157 // static | 187 // static |
158 bool JingleMessage::IsJingleMessage(const buzz::XmlElement* stanza) { | 188 bool JingleMessage::IsJingleMessage(const buzz::XmlElement* stanza) { |
159 return stanza->Name() == QName(kJabberNamespace, "iq") && | 189 return stanza->Name() == QName(kJabberNamespace, "iq") && |
160 stanza->Attr(QName(std::string(), "type")) == "set" && | 190 stanza->Attr(QName(std::string(), "type")) == "set" && |
161 stanza->FirstNamed(QName(kJingleNamespace, "jingle")) != nullptr; | 191 stanza->FirstNamed(QName(kJingleNamespace, "jingle")) != nullptr; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 description = ContentDescription::ParseXml(description_tag); | 289 description = ContentDescription::ParseXml(description_tag); |
260 if (!description.get()) { | 290 if (!description.get()) { |
261 *error = "Failed to parse content description"; | 291 *error = "Failed to parse content description"; |
262 return false; | 292 return false; |
263 } | 293 } |
264 } | 294 } |
265 | 295 |
266 const XmlElement* ice_transport_tag = content_tag->FirstNamed( | 296 const XmlElement* ice_transport_tag = content_tag->FirstNamed( |
267 QName(kIceTransportNamespace, "transport")); | 297 QName(kIceTransportNamespace, "transport")); |
268 if (ice_transport_tag) { | 298 if (ice_transport_tag) { |
269 transport_info.reset(new buzz::XmlElement(*ice_transport_tag)); | 299 if (!ParseIceTransportInfo(ice_transport_tag, &ice_credentials, |
| 300 &candidates)) { |
| 301 *error = "Failed to parse transport info"; |
| 302 return false; |
| 303 } |
270 } | 304 } |
271 | 305 |
272 return true; | 306 return true; |
273 } | 307 } |
274 | 308 |
275 scoped_ptr<buzz::XmlElement> JingleMessage::ToXml() const { | 309 scoped_ptr<buzz::XmlElement> JingleMessage::ToXml() const { |
276 scoped_ptr<XmlElement> root( | 310 scoped_ptr<XmlElement> root( |
277 new XmlElement(QName("jabber:client", "iq"), true)); | 311 new XmlElement(QName("jabber:client", "iq"), true)); |
278 | 312 |
279 DCHECK(!to.empty()); | 313 DCHECK(!to.empty()); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 new XmlElement(QName(kJingleNamespace, "content")); | 351 new XmlElement(QName(kJingleNamespace, "content")); |
318 jingle_tag->AddElement(content_tag); | 352 jingle_tag->AddElement(content_tag); |
319 | 353 |
320 content_tag->AddAttr(QName(kEmptyNamespace, "name"), | 354 content_tag->AddAttr(QName(kEmptyNamespace, "name"), |
321 ContentDescription::kChromotingContentName); | 355 ContentDescription::kChromotingContentName); |
322 content_tag->AddAttr(QName(kEmptyNamespace, "creator"), "initiator"); | 356 content_tag->AddAttr(QName(kEmptyNamespace, "creator"), "initiator"); |
323 | 357 |
324 if (description.get()) | 358 if (description.get()) |
325 content_tag->AddElement(description->ToXml()); | 359 content_tag->AddElement(description->ToXml()); |
326 | 360 |
327 if (transport_info) | 361 if (!ice_credentials.empty() || !candidates.empty()) { |
328 content_tag->AddElement(new XmlElement(*transport_info)); | 362 XmlElement* transport_tag = |
| 363 new XmlElement(QName(kIceTransportNamespace, "transport"), true); |
| 364 content_tag->AddElement(transport_tag); |
| 365 for (const IceCredentials& credentials : ice_credentials) { |
| 366 transport_tag->AddElement(FormatIceCredentials(credentials)); |
| 367 } |
| 368 for (const NamedCandidate& candidate : candidates) { |
| 369 transport_tag->AddElement(FormatIceCandidate(candidate)); |
| 370 } |
| 371 } |
329 } | 372 } |
330 | 373 |
331 return root.Pass(); | 374 return root.Pass(); |
332 } | 375 } |
333 | 376 |
334 JingleMessageReply::JingleMessageReply() | 377 JingleMessageReply::JingleMessageReply() |
335 : type(REPLY_RESULT), | 378 : type(REPLY_RESULT), |
336 error_type(NONE) { | 379 error_type(NONE) { |
337 } | 380 } |
338 | 381 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 buzz::XmlElement* text_elem = | 468 buzz::XmlElement* text_elem = |
426 new buzz::XmlElement(QName(kJabberNamespace, "text")); | 469 new buzz::XmlElement(QName(kJabberNamespace, "text")); |
427 text_elem->SetAttr(QName(kXmlNamespace, "lang"), "en"); | 470 text_elem->SetAttr(QName(kXmlNamespace, "lang"), "en"); |
428 text_elem->SetBodyText(error_text); | 471 text_elem->SetBodyText(error_text); |
429 error->AddElement(text_elem); | 472 error->AddElement(text_elem); |
430 } | 473 } |
431 | 474 |
432 return iq.Pass(); | 475 return iq.Pass(); |
433 } | 476 } |
434 | 477 |
435 IceTransportInfo::IceTransportInfo() {} | |
436 IceTransportInfo::~IceTransportInfo() {} | |
437 | |
438 bool IceTransportInfo::ParseXml( | |
439 const buzz::XmlElement* element) { | |
440 if (element->Name() != QName(kIceTransportNamespace, "transport")) | |
441 return false; | |
442 | |
443 ice_credentials.clear(); | |
444 candidates.clear(); | |
445 | |
446 QName qn_credentials(kIceTransportNamespace, "credentials"); | |
447 for (const XmlElement* credentials_tag = element->FirstNamed(qn_credentials); | |
448 credentials_tag; | |
449 credentials_tag = credentials_tag->NextNamed(qn_credentials)) { | |
450 IceTransportInfo::IceCredentials credentials; | |
451 if (!ParseIceCredentials(credentials_tag, &credentials)) | |
452 return false; | |
453 ice_credentials.push_back(credentials); | |
454 } | |
455 | |
456 QName qn_candidate(kIceTransportNamespace, "candidate"); | |
457 for (const XmlElement* candidate_tag = element->FirstNamed(qn_candidate); | |
458 candidate_tag; candidate_tag = candidate_tag->NextNamed(qn_candidate)) { | |
459 IceTransportInfo::NamedCandidate candidate; | |
460 if (!ParseIceCandidate(candidate_tag, &candidate)) | |
461 return false; | |
462 candidates.push_back(candidate); | |
463 } | |
464 | |
465 return true; | |
466 } | |
467 | |
468 scoped_ptr<buzz::XmlElement> IceTransportInfo::ToXml() const { | |
469 scoped_ptr<buzz::XmlElement> result( | |
470 new XmlElement(QName(kIceTransportNamespace, "transport"), true)); | |
471 for (const IceCredentials& credentials : ice_credentials) { | |
472 result->AddElement(FormatIceCredentials(credentials)); | |
473 } | |
474 for (const NamedCandidate& candidate : candidates) { | |
475 result->AddElement(FormatIceCandidate(candidate)); | |
476 } | |
477 return result.Pass(); | |
478 } | |
479 | |
480 } // namespace protocol | 478 } // namespace protocol |
481 } // namespace remoting | 479 } // namespace remoting |
OLD | NEW |