1 /*
2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef WEBRTC_LIBJINGLE_XMPP_XMPPCLIENT_H_
12 #define WEBRTC_LIBJINGLE_XMPP_XMPPCLIENT_H_
13 
14 #include <string>
15 #include "webrtc/libjingle/xmpp/asyncsocket.h"
16 #include "webrtc/libjingle/xmpp/xmppclientsettings.h"
17 #include "webrtc/libjingle/xmpp/xmppengine.h"
18 #include "webrtc/libjingle/xmpp/xmpptask.h"
19 #include "webrtc/base/sigslot.h"
20 #include "webrtc/base/task.h"
21 
22 namespace buzz {
23 
24 class PreXmppAuth;
25 class CaptchaChallenge;
26 
27 // Just some non-colliding number.  Could have picked "1".
28 #define XMPP_CLIENT_TASK_CODE 0x366c1e47
29 
30 /////////////////////////////////////////////////////////////////////
31 //
32 // XMPPCLIENT
33 //
34 /////////////////////////////////////////////////////////////////////
35 //
36 // See Task first.  XmppClient is a parent task for XmppTasks.
37 //
38 // XmppClient is a task which is designed to be the parent task for
39 // all tasks that depend on a single Xmpp connection.  If you want to,
40 // for example, listen for subscription requests forever, then your
41 // listener should be a task that is a child of the XmppClient that owns
42 // the connection you are using.  XmppClient has all the utility methods
43 // that basically drill through to XmppEngine.
44 //
45 // XmppClient is just a wrapper for XmppEngine, and if I were writing it
46 // all over again, I would make XmppClient == XmppEngine.  Why?
47 // XmppEngine needs tasks too, for example it has an XmppLoginTask which
48 // should just be the same kind of Task instead of an XmppEngine specific
49 // thing.  It would help do certain things like GAIA auth cleaner.
50 //
51 /////////////////////////////////////////////////////////////////////
52 
53 class XmppClient : public XmppTaskParentInterface,
54                    public XmppClientInterface,
55                    public sigslot::has_slots<>
56 {
57 public:
58   explicit XmppClient(rtc::TaskParent * parent);
59   virtual ~XmppClient();
60 
61   XmppReturnStatus Connect(const XmppClientSettings & settings,
62                            const std::string & lang,
63                            AsyncSocket * socket,
64                            PreXmppAuth * preauth);
65 
66   virtual int ProcessStart();
67   virtual int ProcessResponse();
68   XmppReturnStatus Disconnect();
69 
70   sigslot::signal1<XmppEngine::State> SignalStateChange;
71   XmppEngine::Error GetError(int *subcode);
72 
73   // When there is a <stream:error> stanza, return the stanza
74   // so that they can be handled.
75   const XmlElement *GetStreamError();
76 
77   // When there is an authentication error, we may have captcha info
78   // that the user can use to unlock their account
79   CaptchaChallenge GetCaptchaChallenge();
80 
81   // When authentication is successful, this returns the service token
82   // (if we used GAIA authentication)
83   std::string GetAuthMechanism();
84   std::string GetAuthToken();
85 
86   XmppReturnStatus SendRaw(const std::string & text);
87 
88   XmppEngine* engine();
89 
90   sigslot::signal2<const char *, int> SignalLogInput;
91   sigslot::signal2<const char *, int> SignalLogOutput;
92 
93   // As XmppTaskParentIntreface
GetClient()94   virtual XmppClientInterface* GetClient() { return this; }
95 
96   // As XmppClientInterface
97   virtual XmppEngine::State GetState() const;
98   virtual const Jid& jid() const;
99   virtual std::string NextId();
100   virtual XmppReturnStatus SendStanza(const XmlElement *stanza);
101   virtual XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal,
102                                            XmppStanzaError code,
103                                            const std::string & text);
104   virtual void AddXmppTask(XmppTask *, XmppEngine::HandlerLevel);
105   virtual void RemoveXmppTask(XmppTask *);
106 
107  private:
108   friend class XmppTask;
109 
110   void OnAuthDone();
111 
112   // Internal state management
113   enum {
114     STATE_PRE_XMPP_LOGIN = STATE_NEXT,
115     STATE_START_XMPP_LOGIN = STATE_NEXT + 1,
116   };
Process(int state)117   int Process(int state) {
118     switch (state) {
119       case STATE_PRE_XMPP_LOGIN: return ProcessTokenLogin();
120       case STATE_START_XMPP_LOGIN: return ProcessStartXmppLogin();
121       default: return Task::Process(state);
122     }
123   }
124 
GetStateName(int state)125   std::string GetStateName(int state) const {
126     switch (state) {
127       case STATE_PRE_XMPP_LOGIN:      return "PRE_XMPP_LOGIN";
128       case STATE_START_XMPP_LOGIN:  return "START_XMPP_LOGIN";
129       default: return Task::GetStateName(state);
130     }
131   }
132 
133   int ProcessTokenLogin();
134   int ProcessStartXmppLogin();
135   void EnsureClosed();
136 
137   class Private;
138   friend class Private;
139   rtc::scoped_ptr<Private> d_;
140 
141   bool delivering_signal_;
142   bool valid_;
143 };
144 
145 }
146 
147 #endif  // WEBRTC_LIBJINGLE_XMPP_XMPPCLIENT_H_
148