Chromium Code Reviews| 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 |