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 15 matching lines...) Expand all Loading... | |
26 const char kIceTransportNamespace[] = "google:remoting:ice"; | 26 const char kIceTransportNamespace[] = "google:remoting:ice"; |
27 | 27 |
28 const char kWebrtcTransportNamespace[] = "google:remoting:webrtc"; | 28 const char kWebrtcTransportNamespace[] = "google:remoting:webrtc"; |
29 | 29 |
30 const char kEmptyNamespace[] = ""; | 30 const char kEmptyNamespace[] = ""; |
31 const char kXmlNamespace[] = "http://www.w3.org/XML/1998/namespace"; | 31 const char kXmlNamespace[] = "http://www.w3.org/XML/1998/namespace"; |
32 | 32 |
33 const int kPortMin = 1000; | 33 const int kPortMin = 1000; |
34 const int kPortMax = 65535; | 34 const int kPortMax = 65535; |
35 | 35 |
36 const NameMapElement<Address::Channel> kChannelTypes[] = { | |
37 { Address::LCS, "lcs" }, | |
38 { Address::XMPP, "xmpp" }, | |
39 }; | |
40 | |
36 const NameMapElement<JingleMessage::ActionType> kActionTypes[] = { | 41 const NameMapElement<JingleMessage::ActionType> kActionTypes[] = { |
37 { JingleMessage::SESSION_INITIATE, "session-initiate" }, | 42 { JingleMessage::SESSION_INITIATE, "session-initiate" }, |
38 { JingleMessage::SESSION_ACCEPT, "session-accept" }, | 43 { JingleMessage::SESSION_ACCEPT, "session-accept" }, |
39 { JingleMessage::SESSION_TERMINATE, "session-terminate" }, | 44 { JingleMessage::SESSION_TERMINATE, "session-terminate" }, |
40 { JingleMessage::SESSION_INFO, "session-info" }, | 45 { JingleMessage::SESSION_INFO, "session-info" }, |
41 { JingleMessage::TRANSPORT_INFO, "transport-info" }, | 46 { JingleMessage::TRANSPORT_INFO, "transport-info" }, |
42 }; | 47 }; |
43 | 48 |
44 const NameMapElement<JingleMessage::Reason> kReasons[] = { | 49 const NameMapElement<JingleMessage::Reason> kReasons[] = { |
45 { JingleMessage::SUCCESS, "success" }, | 50 { JingleMessage::SUCCESS, "success" }, |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
151 : name(name), | 156 : name(name), |
152 candidate(candidate) { | 157 candidate(candidate) { |
153 } | 158 } |
154 | 159 |
155 IceTransportInfo::IceCredentials::IceCredentials(std::string channel, | 160 IceTransportInfo::IceCredentials::IceCredentials(std::string channel, |
156 std::string ufrag, | 161 std::string ufrag, |
157 std::string password) | 162 std::string password) |
158 : channel(channel), ufrag(ufrag), password(password) { | 163 : channel(channel), ufrag(ufrag), password(password) { |
159 } | 164 } |
160 | 165 |
166 | |
167 //static | |
168 buzz::QName Address::GetQName(Role role, Attribute attr) { | |
169 std::string attribute_name; | |
170 bool from = role == Address::FROM; | |
171 switch (attr) { | |
172 case Address::JID: | |
173 attribute_name = (from) ? "from" : "to"; | |
174 break; | |
175 case Address::ENDPOINT_ID: | |
176 attribute_name = (from) ? "from-endpoint-id" : "to-endpoint-id"; | |
177 break; | |
178 case Address::CHANNEL: | |
179 attribute_name = (from) ? "from-channel" : "to-channel"; | |
180 break; | |
181 default: | |
182 NOTREACHED(); | |
183 } | |
184 return QName(kEmptyNamespace, attribute_name); | |
185 } | |
186 | |
187 Address::Address() | |
188 : jid(""), endpoint_id(""), channel(Address::XMPP) {} | |
Sergey Ulanov
2016/05/18 07:00:41
don't need to specify jid and endpoint_id explicit
kelvinp
2016/05/18 23:43:28
Done.
| |
189 | |
190 Address::Address(const std::string& jid) | |
191 : jid(jid), endpoint_id(jid), channel(Address::XMPP) {} | |
192 | |
193 bool Address::ParseXml(const buzz::XmlElement* stanza, | |
194 Role role, | |
195 std::string* error) { | |
196 std::string channel_str; | |
197 jid = stanza->Attr(GetQName(role, Address::JID)); | |
198 channel_str = stanza->Attr(GetQName(role, Address::CHANNEL)); | |
199 endpoint_id = stanza->Attr(GetQName(role, Address::ENDPOINT_ID)); | |
200 | |
201 if (channel_str.empty()) { | |
202 channel = Address::XMPP; | |
203 } else if (!NameToValue(kChannelTypes, channel_str, &channel)) { | |
204 *error = "Unknown channel " + channel_str; | |
205 return false; | |
206 } | |
207 | |
208 if (endpoint_id.empty()) { | |
Sergey Ulanov
2016/05/18 07:00:41
I think it's better to branch here by channel and
kelvinp
2016/05/18 23:43:28
Done.
| |
209 if (channel == Address::LCS) { | |
210 *error = "Missing |endpoint-id| for the lcs channel"; | |
211 return false; | |
212 } | |
213 endpoint_id = jid; | |
214 } else if (jid.empty()) { | |
Sergey Ulanov
2016/05/18 07:00:41
I think we always expect to have a valid jid, so t
kelvinp
2016/05/18 23:43:28
Acknowledged.
| |
215 *error = "|endpoint-id| is not empty but the |jid| is empty."; | |
Sergey Ulanov
2016/05/18 07:00:41
indentation. 'git cl format' please
kelvinp
2016/05/18 23:43:28
Done.
| |
216 return false; | |
217 } | |
218 | |
219 return true; | |
220 } | |
221 | |
222 void Address::toXml(buzz::XmlElement* iqElement, | |
223 Role role) const { | |
224 if (empty()) { | |
225 return; | |
226 } | |
227 | |
228 const char* channel_str = ValueToName(kChannelTypes, channel); | |
229 if (!channel_str) | |
230 LOG(FATAL) << "Invalid channel value " << channel; | |
Sergey Ulanov
2016/05/18 07:00:41
Don't really need this. This case is already marke
kelvinp
2016/05/18 23:43:28
Done.
| |
231 | |
232 iqElement->AddAttr(GetQName(role, Address::JID), jid); | |
233 | |
234 if (endpoint_id != jid) { | |
Sergey Ulanov
2016/05/18 07:00:41
Replace this condition with (channel == Address::L
kelvinp
2016/05/18 23:43:28
Done.
| |
235 DCHECK(channel == Address::LCS); | |
236 iqElement->AddAttr(GetQName(role, Address::ENDPOINT_ID), endpoint_id); | |
237 iqElement->AddAttr(GetQName(role, Address::CHANNEL), channel_str); | |
238 } | |
239 } | |
240 | |
241 bool Address::operator==(const Address& other) { | |
242 return (other.endpoint_id == endpoint_id) && | |
243 (other.jid == jid) && | |
244 (other.channel == channel); | |
245 } | |
246 | |
247 bool Address::operator!=(const Address& other) { | |
248 return !(*this == other); | |
249 } | |
250 | |
251 bool Address::empty() const { | |
252 return jid.empty() && endpoint_id.empty(); | |
253 } | |
254 | |
161 // static | 255 // static |
162 bool JingleMessage::IsJingleMessage(const buzz::XmlElement* stanza) { | 256 bool JingleMessage::IsJingleMessage(const buzz::XmlElement* stanza) { |
163 return stanza->Name() == QName(kJabberNamespace, "iq") && | 257 return stanza->Name() == QName(kJabberNamespace, "iq") && |
164 stanza->Attr(QName(std::string(), "type")) == "set" && | 258 stanza->Attr(QName(std::string(), "type")) == "set" && |
165 stanza->FirstNamed(QName(kJingleNamespace, "jingle")) != nullptr; | 259 stanza->FirstNamed(QName(kJingleNamespace, "jingle")) != nullptr; |
166 } | 260 } |
167 | 261 |
168 // static | 262 // static |
169 std::string JingleMessage::GetActionName(ActionType action) { | 263 std::string JingleMessage::GetActionName(ActionType action) { |
170 return ValueToName(kActionTypes, action); | 264 return ValueToName(kActionTypes, action); |
171 } | 265 } |
172 | 266 |
173 JingleMessage::JingleMessage() {} | 267 JingleMessage::JingleMessage() {} |
174 | 268 |
175 JingleMessage::JingleMessage(const std::string& to, | 269 JingleMessage::JingleMessage(const Address& to, |
176 ActionType action, | 270 ActionType action, |
177 const std::string& sid) | 271 const std::string& sid) |
178 : to(to), action(action), sid(sid) {} | 272 : to(to), action(action), sid(sid) {} |
179 | 273 |
180 JingleMessage::~JingleMessage() {} | 274 JingleMessage::~JingleMessage() {} |
181 | 275 |
182 bool JingleMessage::ParseXml(const buzz::XmlElement* stanza, | 276 bool JingleMessage::ParseXml(const buzz::XmlElement* stanza, |
183 std::string* error) { | 277 std::string* error) { |
184 if (!IsJingleMessage(stanza)) { | 278 if (!IsJingleMessage(stanza)) { |
185 *error = "Not a jingle message"; | 279 *error = "Not a jingle message"; |
186 return false; | 280 return false; |
187 } | 281 } |
188 | 282 |
189 const XmlElement* jingle_tag = | 283 const XmlElement* jingle_tag = |
190 stanza->FirstNamed(QName(kJingleNamespace, "jingle")); | 284 stanza->FirstNamed(QName(kJingleNamespace, "jingle")); |
191 if (!jingle_tag) { | 285 if (!jingle_tag) { |
192 *error = "Not a jingle message"; | 286 *error = "Not a jingle message"; |
193 return false; | 287 return false; |
194 } | 288 } |
195 | 289 |
196 from = stanza->Attr(QName(kEmptyNamespace, "from")); | 290 if(!from.ParseXml(stanza, Address::FROM, error)) { |
197 to = stanza->Attr(QName(kEmptyNamespace, "to")); | 291 *error = "Invalid from field"; |
292 return false; | |
293 } | |
294 | |
295 if (!to.ParseXml(stanza, Address::TO, error)) { | |
296 *error = "Invalid to field."; | |
297 return false; | |
298 } | |
299 | |
198 initiator = jingle_tag->Attr(QName(kEmptyNamespace, "initiator")); | 300 initiator = jingle_tag->Attr(QName(kEmptyNamespace, "initiator")); |
199 | 301 |
200 std::string action_str = jingle_tag->Attr(QName(kEmptyNamespace, "action")); | 302 std::string action_str = jingle_tag->Attr(QName(kEmptyNamespace, "action")); |
201 if (action_str.empty()) { | 303 if (action_str.empty()) { |
202 *error = "action attribute is missing"; | 304 *error = "action attribute is missing"; |
203 return false; | 305 return false; |
204 } | 306 } |
205 if (!NameToValue(kActionTypes, action_str, &action)) { | 307 if (!NameToValue(kActionTypes, action_str, &action)) { |
206 *error = "Unknown action " + action_str; | 308 *error = "Unknown action " + action_str; |
207 return false; | 309 return false; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
282 } | 384 } |
283 } | 385 } |
284 | 386 |
285 return true; | 387 return true; |
286 } | 388 } |
287 | 389 |
288 std::unique_ptr<buzz::XmlElement> JingleMessage::ToXml() const { | 390 std::unique_ptr<buzz::XmlElement> JingleMessage::ToXml() const { |
289 std::unique_ptr<XmlElement> root( | 391 std::unique_ptr<XmlElement> root( |
290 new XmlElement(QName("jabber:client", "iq"), true)); | 392 new XmlElement(QName("jabber:client", "iq"), true)); |
291 | 393 |
292 DCHECK(!to.empty()); | 394 from.toXml(root.get(), Address::FROM); |
293 root->AddAttr(QName(kEmptyNamespace, "to"), to); | 395 to.toXml(root.get(), Address::TO); |
294 if (!from.empty()) | |
295 root->AddAttr(QName(kEmptyNamespace, "from"), from); | |
296 root->SetAttr(QName(kEmptyNamespace, "type"), "set"); | 396 root->SetAttr(QName(kEmptyNamespace, "type"), "set"); |
297 | 397 |
298 XmlElement* jingle_tag = | 398 XmlElement* jingle_tag = |
299 new XmlElement(QName(kJingleNamespace, "jingle"), true); | 399 new XmlElement(QName(kJingleNamespace, "jingle"), true); |
300 root->AddElement(jingle_tag); | 400 root->AddElement(jingle_tag); |
301 jingle_tag->AddAttr(QName(kEmptyNamespace, "sid"), sid); | 401 jingle_tag->AddAttr(QName(kEmptyNamespace, "sid"), sid); |
302 | 402 |
303 const char* action_attr = ValueToName(kActionTypes, action); | 403 const char* action_attr = ValueToName(kActionTypes, action); |
304 if (!action_attr) | 404 if (!action_attr) |
305 LOG(FATAL) << "Invalid action value " << action; | 405 LOG(FATAL) << "Invalid action value " << action; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
364 error_type(error), | 464 error_type(error), |
365 text(text_value) { | 465 text(text_value) { |
366 } | 466 } |
367 | 467 |
368 JingleMessageReply::~JingleMessageReply() { } | 468 JingleMessageReply::~JingleMessageReply() { } |
369 | 469 |
370 std::unique_ptr<buzz::XmlElement> JingleMessageReply::ToXml( | 470 std::unique_ptr<buzz::XmlElement> JingleMessageReply::ToXml( |
371 const buzz::XmlElement* request_stanza) const { | 471 const buzz::XmlElement* request_stanza) const { |
372 std::unique_ptr<XmlElement> iq( | 472 std::unique_ptr<XmlElement> iq( |
373 new XmlElement(QName(kJabberNamespace, "iq"), true)); | 473 new XmlElement(QName(kJabberNamespace, "iq"), true)); |
374 iq->SetAttr(QName(kEmptyNamespace, "to"), | 474 |
375 request_stanza->Attr(QName(kEmptyNamespace, "from"))); | 475 |
Sergey Ulanov
2016/05/18 07:00:41
remove extra empty line
kelvinp
2016/05/18 23:43:28
Done.
| |
476 Address original_from; | |
477 std::string error_message; | |
478 original_from.ParseXml(request_stanza, Address::FROM, &error_message); | |
479 DCHECK(error_message.empty()); | |
480 original_from.toXml(iq.get(), Address::TO); | |
481 | |
376 iq->SetAttr(QName(kEmptyNamespace, "id"), | 482 iq->SetAttr(QName(kEmptyNamespace, "id"), |
377 request_stanza->Attr(QName(kEmptyNamespace, "id"))); | 483 request_stanza->Attr(QName(kEmptyNamespace, "id"))); |
378 | 484 |
379 if (type == REPLY_RESULT) { | 485 if (type == REPLY_RESULT) { |
380 iq->SetAttr(QName(kEmptyNamespace, "type"), "result"); | 486 iq->SetAttr(QName(kEmptyNamespace, "type"), "result"); |
381 return iq; | 487 return iq; |
382 } | 488 } |
383 | 489 |
384 DCHECK_EQ(type, REPLY_ERROR); | 490 DCHECK_EQ(type, REPLY_ERROR); |
385 | 491 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
489 result->AddElement(FormatIceCredentials(credentials)); | 595 result->AddElement(FormatIceCredentials(credentials)); |
490 } | 596 } |
491 for (const NamedCandidate& candidate : candidates) { | 597 for (const NamedCandidate& candidate : candidates) { |
492 result->AddElement(FormatIceCandidate(candidate)); | 598 result->AddElement(FormatIceCandidate(candidate)); |
493 } | 599 } |
494 return result; | 600 return result; |
495 } | 601 } |
496 | 602 |
497 } // namespace protocol | 603 } // namespace protocol |
498 } // namespace remoting | 604 } // namespace remoting |
OLD | NEW |