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 280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifndef TALK_XMPP_XMPPTASK_H_ 290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define TALK_XMPP_XMPPTASK_H_ 300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <deque> 32cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include <string> 33cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/xmpp/xmppengine.h" 342a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/sigslot.h" 352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/task.h" 362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/taskparent.h" 370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace buzz { 390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org///////////////////////////////////////////////////////////////////// 410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// XMPPTASK 430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org///////////////////////////////////////////////////////////////////// 450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// See Task and XmppClient first. 470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// XmppTask is a task that is designed to go underneath XmppClient and be 490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// useful there. It has a way of finding its XmppClient parent so you 500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// can have it nested arbitrarily deep under an XmppClient and it can 510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// still find the XMPP services. 520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Tasks register themselves to listen to particular kinds of stanzas 540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// that are sent out by the client. Rather than processing stanzas 550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// right away, they should decide if they own the sent stanza, 560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// and if so, queue it and Wake() the task, or if a stanza does not belong 570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// to you, return false right away so the next XmppTask can take a crack. 580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// This technique (synchronous recognize, but asynchronous processing) 590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// allows you to have arbitrary logic for recognizing stanzas yet still, 600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// for example, disconnect a client while processing a stanza - 610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// without reentrancy problems. 620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org///////////////////////////////////////////////////////////////////// 640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass XmppTask; 660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// XmppClientInterface is an abstract interface for sending and 680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// handling stanzas. It can be implemented for unit tests or 690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// different network environments. It will usually be implemented by 700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// XmppClient. 710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass XmppClientInterface { 720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public: 730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmppClientInterface(); 740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual ~XmppClientInterface(); 750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual XmppEngine::State GetState() const = 0; 770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual const Jid& jid() const = 0; 780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual std::string NextId() = 0; 790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual XmppReturnStatus SendStanza(const XmlElement* stanza) = 0; 800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual XmppReturnStatus SendStanzaError(const XmlElement* original_stanza, 810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmppStanzaError error_code, 820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& message) = 0; 830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual void AddXmppTask(XmppTask* task, XmppEngine::HandlerLevel level) = 0; 840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual void RemoveXmppTask(XmppTask* task) = 0; 850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org sigslot::signal0<> SignalDisconnected; 860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org DISALLOW_EVIL_CONSTRUCTORS(XmppClientInterface); 880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// XmppTaskParentInterface is the interface require for any parent of 910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// an XmppTask. It needs, for example, a way to get an 920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// XmppClientInterface. 930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// We really ought to inherit from a TaskParentInterface, but we tried 950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// that and it's way too complicated to change 960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Task/TaskParent/TaskRunner. For now, this works. 972a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgclass XmppTaskParentInterface : public rtc::Task { 980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public: 992a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org explicit XmppTaskParentInterface(rtc::TaskParent* parent) 1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : Task(parent) { 1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual ~XmppTaskParentInterface() {} 1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual XmppClientInterface* GetClient() = 0; 1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org DISALLOW_EVIL_CONSTRUCTORS(XmppTaskParentInterface); 1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass XmppTaskBase : public XmppTaskParentInterface { 1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public: 1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org explicit XmppTaskBase(XmppTaskParentInterface* parent) 1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : XmppTaskParentInterface(parent), 1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org parent_(parent) { 1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual ~XmppTaskBase() {} 1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual XmppClientInterface* GetClient() { 1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return parent_->GetClient(); 1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org protected: 1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmppTaskParentInterface* parent_; 1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org DISALLOW_EVIL_CONSTRUCTORS(XmppTaskBase); 1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass XmppTask : public XmppTaskBase, 1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public XmppStanzaHandler, 1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public sigslot::has_slots<> 1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{ 1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public: 1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmppTask(XmppTaskParentInterface* parent, 1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmppEngine::HandlerLevel level = XmppEngine::HL_NONE); 1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual ~XmppTask(); 1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::string task_id() const { return id_; } 1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void set_task_id(std::string id) { id_ = id; } 1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef _DEBUG 1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void set_debug_force_timeout(const bool f) { debug_force_timeout_ = f; } 1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif 1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual bool HandleStanza(const XmlElement* stanza) { return false; } 1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org protected: 1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmppReturnStatus SendStanza(const XmlElement* stanza); 1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmppReturnStatus SetResult(const std::string& code); 1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmppReturnStatus SendStanzaError(const XmlElement* element_original, 1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org XmppStanzaError code, 1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& text); 1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual void Stop(); 1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual void OnDisconnect(); 1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual void QueueStanza(const XmlElement* stanza); 1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const XmlElement* NextStanza(); 1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool MatchStanzaFrom(const XmlElement* stanza, const Jid& match_jid); 1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool MatchResponseIq(const XmlElement* stanza, const Jid& to, 1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& task_id); 1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org static bool MatchRequestIq(const XmlElement* stanza, const std::string& type, 1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const QName& qn); 1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org static XmlElement *MakeIqResult(const XmlElement* query); 1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org static XmlElement *MakeIq(const std::string& type, 1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const Jid& to, const std::string& task_id); 1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Returns true if the task is under the specified rate limit and updates the 1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // rate limit accordingly 1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool VerifyTaskRateLimit(const std::string task_name, int max_count, 1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int per_x_seconds); 1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgprivate: 1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void StopImpl(); 1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool stopped_; 1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::deque<XmlElement*> stanza_queue_; 1792a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::scoped_ptr<XmlElement> next_stanza_; 1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::string id_; 1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef _DEBUG 1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool debug_force_timeout_; 1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif 1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} // namespace buzz 1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif // TALK_XMPP_XMPPTASK_H_ 190