Chromium Code Reviews| 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"))); |