• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2004--2006, 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 #ifndef _XMPPTASK_H_
29 #define _XMPPTASK_H_
30 
31 #include <string>
32 #include <deque>
33 #include "talk/base/sigslot.h"
34 #include "talk/xmpp/xmppengine.h"
35 #include "talk/base/task.h"
36 
37 namespace buzz {
38 
39 /////////////////////////////////////////////////////////////////////
40 //
41 // XMPPTASK
42 //
43 /////////////////////////////////////////////////////////////////////
44 //
45 // See Task and XmppClient first.
46 //
47 // XmppTask is a task that is designed to go underneath XmppClient and be
48 // useful there.  It has a way of finding its XmppClient parent so you
49 // can have it nested arbitrarily deep under an XmppClient and it can
50 // still find the XMPP services.
51 //
52 // Tasks register themselves to listen to particular kinds of stanzas
53 // that are sent out by the client.  Rather than processing stanzas
54 // right away, they should decide if they own the sent stanza,
55 // and if so, queue it and Wake() the task, or if a stanza does not belong
56 // to you, return false right away so the next XmppTask can take a crack.
57 // This technique (synchronous recognize, but asynchronous processing)
58 // allows you to have arbitrary logic for recognizing stanzas yet still,
59 // for example, disconnect a client while processing a stanza -
60 // without reentrancy problems.
61 //
62 /////////////////////////////////////////////////////////////////////
63 
64 class XmppClient;
65 
66 class XmppTask :
67   public talk_base::Task,
68   public XmppStanzaHandler,
69   public sigslot::has_slots<>
70 {
71  public:
72   XmppTask(talk_base::TaskParent* parent,
73            XmppEngine::HandlerLevel level = XmppEngine::HL_NONE);
74   virtual ~XmppTask();
75 
GetClient()76   virtual XmppClient* GetClient() const { return client_; }
task_id()77   std::string task_id() const { return id_; }
set_task_id(std::string id)78   void set_task_id(std::string id) { id_ = id; }
79 
80 #ifdef _DEBUG
set_debug_force_timeout(const bool f)81   void set_debug_force_timeout(const bool f) { debug_force_timeout_ = f; }
82 #endif
83 
84  protected:
85   friend class XmppClient;
86 
87   XmppReturnStatus SendStanza(const XmlElement* stanza);
88   XmppReturnStatus SetResult(const std::string& code);
89   XmppReturnStatus SendStanzaError(const XmlElement* element_original,
90                                    XmppStanzaError code,
91                                    const std::string& text);
92 
93   virtual void Stop();
HandleStanza(const XmlElement * stanza)94   virtual bool HandleStanza(const XmlElement* stanza) { return false; }
95   virtual void OnDisconnect();
ProcessReponse()96   virtual int ProcessReponse() { return STATE_DONE; }
97 
98   virtual void QueueStanza(const XmlElement* stanza);
99   const XmlElement* NextStanza();
100 
101   bool MatchResponseIq(const XmlElement* stanza, const Jid& to,
102                        const std::string& task_id);
103 
104   static bool MatchRequestIq(const XmlElement* stanza, const std::string& type,
105                              const QName& qn);
106   static XmlElement *MakeIqResult(const XmlElement* query);
107   static XmlElement *MakeIq(const std::string& type,
108                             const Jid& to, const std::string& task_id);
109 
110   // Returns true if the task is under the specified rate limit and updates the
111   // rate limit accordingly
112   bool VerifyTaskRateLimit(const std::string task_name, int max_count,
113                            int per_x_seconds);
114 
115 private:
116   void StopImpl();
117 
118   XmppClient* client_;
119   std::deque<XmlElement*> stanza_queue_;
120   talk_base::scoped_ptr<XmlElement> next_stanza_;
121   std::string id_;
122 
123 #ifdef _DEBUG
124   bool debug_force_timeout_;
125 #endif
126 };
127 
128 }
129 
130 #endif
131