Home | History | Annotate | Download | only in xmpp
      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
     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   };
    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 
    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