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
22namespace buzz {
23
24class PreXmppAuth;
25class 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
53class XmppClient : public XmppTaskParentInterface,
54                   public XmppClientInterface,
55                   public sigslot::has_slots<>
56{
57public:
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