10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/*
20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle
30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2004--2006, Google Inc.
40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without
60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met:
70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer.
100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer in the documentation
120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     and/or other materials provided with the distribution.
130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  3. The name of the author may not be used to endorse or promote products
140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     derived from this software without specific prior written permission.
150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */
270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
28cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/xmpp/constants.h"
290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/xmpp/xmppclient.h"
300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/xmpp/xmppengine.h"
31cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/xmpp/xmpptask.h"
320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace buzz {
340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppClientInterface::XmppClientInterface() {
360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppClientInterface::~XmppClientInterface() {
390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppTask::XmppTask(XmppTaskParentInterface* parent,
420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   XmppEngine::HandlerLevel level)
430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    : XmppTaskBase(parent), stopped_(false) {
440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef _DEBUG
450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  debug_force_timeout_ = false;
460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif
470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  id_ = GetClient()->NextId();
490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  GetClient()->AddXmppTask(this, level);
500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  GetClient()->SignalDisconnected.connect(this, &XmppTask::OnDisconnect);
510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppTask::~XmppTask() {
540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  StopImpl();
550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid XmppTask::StopImpl() {
580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  while (NextStanza() != NULL) {}
590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!stopped_) {
600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GetClient()->RemoveXmppTask(this);
610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GetClient()->SignalDisconnected.disconnect(this);
620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    stopped_ = true;
630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppReturnStatus XmppTask::SendStanza(const XmlElement* stanza) {
670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (stopped_)
680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return XMPP_RETURN_BADSTATE;
690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return GetClient()->SendStanza(stanza);
700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmppReturnStatus XmppTask::SendStanzaError(const XmlElement* element_original,
730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                           XmppStanzaError code,
740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                           const std::string& text) {
750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (stopped_)
760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return XMPP_RETURN_BADSTATE;
770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return GetClient()->SendStanzaError(element_original, code, text);
780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid XmppTask::Stop() {
810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  StopImpl();
820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Task::Stop();
830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid XmppTask::OnDisconnect() {
860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Error();
870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid XmppTask::QueueStanza(const XmlElement* stanza) {
900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef _DEBUG
910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (debug_force_timeout_)
920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif
940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  stanza_queue_.push_back(new XmlElement(*stanza));
960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Wake();
970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst XmlElement* XmppTask::NextStanza() {
1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElement* result = NULL;
1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!stanza_queue_.empty()) {
1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    result = stanza_queue_.front();
1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    stanza_queue_.pop_front();
1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  next_stanza_.reset(result);
1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return result;
1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmlElement* XmppTask::MakeIq(const std::string& type,
1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             const buzz::Jid& to,
1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             const std::string& id) {
1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElement* result = new XmlElement(QN_IQ);
1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!type.empty())
1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    result->AddAttr(QN_TYPE, type);
1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!to.IsEmpty())
1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    result->AddAttr(QN_TO, to.Str());
1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!id.empty())
1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    result->AddAttr(QN_ID, id);
1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return result;
1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgXmlElement* XmppTask::MakeIqResult(const XmlElement * query) {
1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElement* result = new XmlElement(QN_IQ);
1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  result->AddAttr(QN_TYPE, STR_RESULT);
1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (query->HasAttr(QN_FROM)) {
1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    result->AddAttr(QN_TO, query->Attr(QN_FROM));
1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  result->AddAttr(QN_ID, query->Attr(QN_ID));
1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return result;
1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool XmppTask::MatchResponseIq(const XmlElement* stanza,
1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               const Jid& to,
1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               const std::string& id) {
1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (stanza->Name() != QN_IQ)
1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (stanza->Attr(QN_ID) != id)
1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return MatchStanzaFrom(stanza, to);
1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool XmppTask::MatchStanzaFrom(const XmlElement* stanza,
1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               const Jid& to) {
1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Jid from(stanza->Attr(QN_FROM));
1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (from == to)
1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return true;
1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // We address the server as "", check if we are doing so here.
1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!to.IsEmpty())
1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // It is legal for the server to identify itself with "domain" or
1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // "myself@domain"
1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Jid me = GetClient()->jid();
1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return (from == Jid(me.domain())) || (from == me.BareJid());
1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool XmppTask::MatchRequestIq(const XmlElement* stanza,
1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              const std::string& type,
1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              const QName& qn) {
1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (stanza->Name() != QN_IQ)
1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (stanza->Attr(QN_TYPE) != type)
1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (stanza->FirstNamed(qn) == NULL)
1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
176