3b8fdde03ef7aafe4016f026c5e4f7b7088de75f
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / xmpp / jingleinfotask.cc
1 /*
2  * libjingle
3  * Copyright 2010, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without 
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice, 
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products 
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "webrtc/libjingle/xmpp/jingleinfotask.h"
29
30 #include "webrtc/libjingle/xmpp/constants.h"
31 #include "webrtc/libjingle/xmpp/xmppclient.h"
32 #include "webrtc/libjingle/xmpp/xmpptask.h"
33 #include "webrtc/base/socketaddress.h"
34
35 namespace buzz {
36
37 class JingleInfoTask::JingleInfoGetTask : public XmppTask {
38  public:
39   explicit JingleInfoGetTask(XmppTaskParentInterface* parent)
40       : XmppTask(parent, XmppEngine::HL_SINGLE),
41         done_(false) {}
42
43   virtual int ProcessStart() {
44     rtc::scoped_ptr<XmlElement> get(
45         MakeIq(STR_GET, Jid(), task_id()));
46     get->AddElement(new XmlElement(QN_JINGLE_INFO_QUERY, true));
47     if (SendStanza(get.get()) != XMPP_RETURN_OK) {
48       return STATE_ERROR;
49     }
50     return STATE_RESPONSE;
51   }
52   virtual int ProcessResponse() {
53     if (done_)
54       return STATE_DONE;
55     return STATE_BLOCKED;
56   }
57
58  protected:
59   virtual bool HandleStanza(const XmlElement * stanza) {
60     if (!MatchResponseIq(stanza, Jid(), task_id()))
61       return false;
62
63     if (stanza->Attr(QN_TYPE) != STR_RESULT)
64       return false;
65
66     // Queue the stanza with the parent so these don't get handled out of order
67     JingleInfoTask* parent = static_cast<JingleInfoTask*>(GetParent());
68     parent->QueueStanza(stanza);
69
70     // Wake ourselves so we can go into the done state
71     done_ = true;
72     Wake();
73     return true;
74   }
75
76   bool done_;
77 };
78
79
80 void JingleInfoTask::RefreshJingleInfoNow() {
81   JingleInfoGetTask* get_task = new JingleInfoGetTask(this);
82   get_task->Start();
83 }
84
85 bool
86 JingleInfoTask::HandleStanza(const XmlElement * stanza) {
87   if (!MatchRequestIq(stanza, "set", QN_JINGLE_INFO_QUERY))
88     return false;
89
90   // only respect relay push from the server
91   Jid from(stanza->Attr(QN_FROM));
92   if (!from.IsEmpty() &&
93       !from.BareEquals(GetClient()->jid()) &&
94       from != Jid(GetClient()->jid().domain()))
95     return false;
96
97   QueueStanza(stanza);
98   return true;
99 }
100
101 int
102 JingleInfoTask::ProcessStart() {
103   std::vector<std::string> relay_hosts;
104   std::vector<rtc::SocketAddress> stun_hosts;
105   std::string relay_token;
106   const XmlElement * stanza = NextStanza();
107   if (stanza == NULL)
108     return STATE_BLOCKED;
109   const XmlElement * query = stanza->FirstNamed(QN_JINGLE_INFO_QUERY);
110   if (query == NULL)
111     return STATE_START;
112   const XmlElement *stun = query->FirstNamed(QN_JINGLE_INFO_STUN);
113   if (stun) {
114     for (const XmlElement *server = stun->FirstNamed(QN_JINGLE_INFO_SERVER);
115          server != NULL; server = server->NextNamed(QN_JINGLE_INFO_SERVER)) {
116       std::string host = server->Attr(QN_JINGLE_INFO_HOST);
117       std::string port = server->Attr(QN_JINGLE_INFO_UDP);
118       if (host != STR_EMPTY && host != STR_EMPTY) {
119         stun_hosts.push_back(rtc::SocketAddress(host, atoi(port.c_str())));
120       }
121     }
122   }
123
124   const XmlElement *relay = query->FirstNamed(QN_JINGLE_INFO_RELAY);
125   if (relay) {
126     relay_token = relay->TextNamed(QN_JINGLE_INFO_TOKEN);
127     for (const XmlElement *server = relay->FirstNamed(QN_JINGLE_INFO_SERVER);
128          server != NULL; server = server->NextNamed(QN_JINGLE_INFO_SERVER)) {
129       std::string host = server->Attr(QN_JINGLE_INFO_HOST);
130       if (host != STR_EMPTY) {
131         relay_hosts.push_back(host);
132       }
133     }
134   }
135   SignalJingleInfo(relay_token, relay_hosts, stun_hosts);
136   return STATE_START;
137 }
138 }