Index: remoting/protocol/jingle_messages.cc |
diff --git a/remoting/protocol/jingle_messages.cc b/remoting/protocol/jingle_messages.cc |
index bc8846a0e3833bef62fa6f3fd8ec1b554d4f1577..4dc36f32c4a6ec99657dfc0ccc9894fe3520a07a 100644 |
--- a/remoting/protocol/jingle_messages.cc |
+++ b/remoting/protocol/jingle_messages.cc |
@@ -33,6 +33,11 @@ const char kXmlNamespace[] = "http://www.w3.org/XML/1998/namespace"; |
const int kPortMin = 1000; |
const int kPortMax = 65535; |
+const NameMapElement<Address::Channel> kChannelTypes[] = { |
+ { Address::LCS, "lcs" }, |
+ { Address::XMPP, "xmpp" }, |
+}; |
+ |
const NameMapElement<JingleMessage::ActionType> kActionTypes[] = { |
{ JingleMessage::SESSION_INITIATE, "session-initiate" }, |
{ JingleMessage::SESSION_ACCEPT, "session-accept" }, |
@@ -158,6 +163,95 @@ IceTransportInfo::IceCredentials::IceCredentials(std::string channel, |
: channel(channel), ufrag(ufrag), password(password) { |
} |
+ |
+//static |
+buzz::QName Address::GetQName(Role role, Attribute attr) { |
+ std::string attribute_name; |
+ bool from = role == Address::FROM; |
+ switch (attr) { |
+ case Address::JID: |
+ attribute_name = (from) ? "from" : "to"; |
+ break; |
+ case Address::ENDPOINT_ID: |
+ attribute_name = (from) ? "from-endpoint-id" : "to-endpoint-id"; |
+ break; |
+ case Address::CHANNEL: |
+ attribute_name = (from) ? "from-channel" : "to-channel"; |
+ break; |
+ default: |
+ NOTREACHED(); |
+ } |
+ return QName(kEmptyNamespace, attribute_name); |
+} |
+ |
+Address::Address() |
+ : 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.
|
+ |
+Address::Address(const std::string& jid) |
+ : jid(jid), endpoint_id(jid), channel(Address::XMPP) {} |
+ |
+bool Address::ParseXml(const buzz::XmlElement* stanza, |
+ Role role, |
+ std::string* error) { |
+ std::string channel_str; |
+ jid = stanza->Attr(GetQName(role, Address::JID)); |
+ channel_str = stanza->Attr(GetQName(role, Address::CHANNEL)); |
+ endpoint_id = stanza->Attr(GetQName(role, Address::ENDPOINT_ID)); |
+ |
+ if (channel_str.empty()) { |
+ channel = Address::XMPP; |
+ } else if (!NameToValue(kChannelTypes, channel_str, &channel)) { |
+ *error = "Unknown channel " + channel_str; |
+ return false; |
+ } |
+ |
+ 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.
|
+ if (channel == Address::LCS) { |
+ *error = "Missing |endpoint-id| for the lcs channel"; |
+ return false; |
+ } |
+ endpoint_id = jid; |
+ } 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.
|
+ *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.
|
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+void Address::toXml(buzz::XmlElement* iqElement, |
+ Role role) const { |
+ if (empty()) { |
+ return; |
+ } |
+ |
+ const char* channel_str = ValueToName(kChannelTypes, channel); |
+ if (!channel_str) |
+ 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.
|
+ |
+ iqElement->AddAttr(GetQName(role, Address::JID), jid); |
+ |
+ 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.
|
+ DCHECK(channel == Address::LCS); |
+ iqElement->AddAttr(GetQName(role, Address::ENDPOINT_ID), endpoint_id); |
+ iqElement->AddAttr(GetQName(role, Address::CHANNEL), channel_str); |
+ } |
+} |
+ |
+bool Address::operator==(const Address& other) { |
+ return (other.endpoint_id == endpoint_id) && |
+ (other.jid == jid) && |
+ (other.channel == channel); |
+} |
+ |
+bool Address::operator!=(const Address& other) { |
+ return !(*this == other); |
+} |
+ |
+bool Address::empty() const { |
+ return jid.empty() && endpoint_id.empty(); |
+} |
+ |
// static |
bool JingleMessage::IsJingleMessage(const buzz::XmlElement* stanza) { |
return stanza->Name() == QName(kJabberNamespace, "iq") && |
@@ -172,7 +266,7 @@ std::string JingleMessage::GetActionName(ActionType action) { |
JingleMessage::JingleMessage() {} |
-JingleMessage::JingleMessage(const std::string& to, |
+JingleMessage::JingleMessage(const Address& to, |
ActionType action, |
const std::string& sid) |
: to(to), action(action), sid(sid) {} |
@@ -193,8 +287,16 @@ bool JingleMessage::ParseXml(const buzz::XmlElement* stanza, |
return false; |
} |
- from = stanza->Attr(QName(kEmptyNamespace, "from")); |
- to = stanza->Attr(QName(kEmptyNamespace, "to")); |
+ if(!from.ParseXml(stanza, Address::FROM, error)) { |
+ *error = "Invalid from field"; |
+ return false; |
+ } |
+ |
+ if (!to.ParseXml(stanza, Address::TO, error)) { |
+ *error = "Invalid to field."; |
+ return false; |
+ } |
+ |
initiator = jingle_tag->Attr(QName(kEmptyNamespace, "initiator")); |
std::string action_str = jingle_tag->Attr(QName(kEmptyNamespace, "action")); |
@@ -289,10 +391,8 @@ std::unique_ptr<buzz::XmlElement> JingleMessage::ToXml() const { |
std::unique_ptr<XmlElement> root( |
new XmlElement(QName("jabber:client", "iq"), true)); |
- DCHECK(!to.empty()); |
- root->AddAttr(QName(kEmptyNamespace, "to"), to); |
- if (!from.empty()) |
- root->AddAttr(QName(kEmptyNamespace, "from"), from); |
+ from.toXml(root.get(), Address::FROM); |
+ to.toXml(root.get(), Address::TO); |
root->SetAttr(QName(kEmptyNamespace, "type"), "set"); |
XmlElement* jingle_tag = |
@@ -371,8 +471,14 @@ std::unique_ptr<buzz::XmlElement> JingleMessageReply::ToXml( |
const buzz::XmlElement* request_stanza) const { |
std::unique_ptr<XmlElement> iq( |
new XmlElement(QName(kJabberNamespace, "iq"), true)); |
- iq->SetAttr(QName(kEmptyNamespace, "to"), |
- request_stanza->Attr(QName(kEmptyNamespace, "from"))); |
+ |
+ |
Sergey Ulanov
2016/05/18 07:00:41
remove extra empty line
kelvinp
2016/05/18 23:43:28
Done.
|
+ Address original_from; |
+ std::string error_message; |
+ original_from.ParseXml(request_stanza, Address::FROM, &error_message); |
+ DCHECK(error_message.empty()); |
+ original_from.toXml(iq.get(), Address::TO); |
+ |
iq->SetAttr(QName(kEmptyNamespace, "id"), |
request_stanza->Attr(QName(kEmptyNamespace, "id"))); |