OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "remoting/jingle_glue/jingle_info_task.h" |
| 6 |
| 7 #include "base/scoped_ptr.h" |
| 8 #include "talk/base/socketaddress.h" |
| 9 #include "talk/xmpp/constants.h" |
| 10 #include "talk/xmpp/xmppclient.h" |
| 11 |
| 12 namespace remoting { |
| 13 |
| 14 // This code is a copy of googleclient/talk/app/jingleinfotask.cc . |
| 15 |
| 16 class JingleInfoTask::JingleInfoGetTask : public XmppTask { |
| 17 public: |
| 18 explicit JingleInfoGetTask(talk_base::TaskParent* parent) : |
| 19 XmppTask(parent, buzz::XmppEngine::HL_SINGLE), |
| 20 done_(false) { } |
| 21 |
| 22 virtual int ProcessStart() { |
| 23 // Set jingle info query IQ stanza. |
| 24 scoped_ptr<buzz::XmlElement> get_iq( |
| 25 MakeIq(buzz::STR_GET, buzz::JID_EMPTY, task_id())); |
| 26 get_iq->AddElement(new buzz::XmlElement(buzz::QN_JINGLE_INFO_QUERY, true)); |
| 27 if (SendStanza(get_iq.get()) != buzz::XMPP_RETURN_OK) { |
| 28 return STATE_ERROR; |
| 29 } |
| 30 return STATE_RESPONSE; |
| 31 } |
| 32 |
| 33 virtual int ProcessResponse() { |
| 34 if (done_) { |
| 35 return STATE_DONE; |
| 36 } |
| 37 return STATE_BLOCKED; |
| 38 } |
| 39 |
| 40 protected: |
| 41 virtual bool HandleStanza(const buzz::XmlElement* stanza) { |
| 42 if (!MatchResponseIq(stanza, buzz::JID_EMPTY, task_id())) { |
| 43 return false; |
| 44 } |
| 45 |
| 46 if (stanza->Attr(buzz::QN_TYPE) != buzz::STR_RESULT) { |
| 47 return false; |
| 48 } |
| 49 |
| 50 // Queue the stanza with the parent so these don't get handled out of order. |
| 51 JingleInfoTask* parent = static_cast<JingleInfoTask*>(GetParent()); |
| 52 parent->QueueStanza(stanza); |
| 53 |
| 54 // Wake ourselves so we can go into the done state. |
| 55 done_ = true; |
| 56 Wake(); |
| 57 return true; |
| 58 } |
| 59 |
| 60 bool done_; |
| 61 }; |
| 62 |
| 63 |
| 64 void JingleInfoTask::RefreshJingleInfoNow() { |
| 65 JingleInfoGetTask* get_task = new JingleInfoGetTask(this); |
| 66 get_task->Start(); |
| 67 } |
| 68 |
| 69 bool JingleInfoTask::HandleStanza(const buzz::XmlElement* stanza) { |
| 70 if (!MatchRequestIq(stanza, "set", buzz::QN_JINGLE_INFO_QUERY)) { |
| 71 return false; |
| 72 } |
| 73 |
| 74 // Only respect relay push from the server. |
| 75 buzz::Jid from(stanza->Attr(buzz::QN_FROM)); |
| 76 if (from != buzz::JID_EMPTY && |
| 77 !from.BareEquals(GetClient()->jid()) && |
| 78 from != buzz::Jid(GetClient()->jid().domain())) { |
| 79 return false; |
| 80 } |
| 81 |
| 82 QueueStanza(stanza); |
| 83 return true; |
| 84 } |
| 85 |
| 86 int JingleInfoTask::ProcessStart() { |
| 87 std::vector<std::string> relay_hosts; |
| 88 std::vector<talk_base::SocketAddress> stun_hosts; |
| 89 std::string relay_token; |
| 90 const buzz::XmlElement* stanza = NextStanza(); |
| 91 if (stanza == NULL) { |
| 92 return STATE_BLOCKED; |
| 93 } |
| 94 const buzz::XmlElement* query = |
| 95 stanza->FirstNamed(buzz::QN_JINGLE_INFO_QUERY); |
| 96 if (query == NULL) { |
| 97 return STATE_START; |
| 98 } |
| 99 const buzz::XmlElement* stun = query->FirstNamed(buzz::QN_JINGLE_INFO_STUN); |
| 100 if (stun) { |
| 101 for (const buzz::XmlElement* server = |
| 102 stun->FirstNamed(buzz::QN_JINGLE_INFO_SERVER); |
| 103 server != NULL; |
| 104 server = server->NextNamed(buzz::QN_JINGLE_INFO_SERVER)) { |
| 105 std::string host = server->Attr(buzz::QN_JINGLE_INFO_HOST); |
| 106 std::string port = server->Attr(buzz::QN_JINGLE_INFO_UDP); |
| 107 if (host != buzz::STR_EMPTY && host != buzz::STR_EMPTY) { |
| 108 // TODO(sergeyu): Avoid atoi() here. |
| 109 stun_hosts.push_back( |
| 110 talk_base::SocketAddress(host, atoi(port.c_str()))); |
| 111 } |
| 112 } |
| 113 } |
| 114 |
| 115 const buzz::XmlElement* relay = query->FirstNamed(buzz::QN_JINGLE_INFO_RELAY); |
| 116 if (relay) { |
| 117 relay_token = relay->TextNamed(buzz::QN_JINGLE_INFO_TOKEN); |
| 118 for (const buzz::XmlElement* server = |
| 119 relay->FirstNamed(buzz::QN_JINGLE_INFO_SERVER); |
| 120 server != NULL; |
| 121 server = server->NextNamed(buzz::QN_JINGLE_INFO_SERVER)) { |
| 122 std::string host = server->Attr(buzz::QN_JINGLE_INFO_HOST); |
| 123 if (host != buzz::STR_EMPTY) { |
| 124 relay_hosts.push_back(host); |
| 125 } |
| 126 } |
| 127 } |
| 128 SignalJingleInfo(relay_token, relay_hosts, stun_hosts); |
| 129 return STATE_START; |
| 130 } |
| 131 |
| 132 } // namespace remoting |
OLD | NEW |