1 /* 2 * libjingle 3 * Copyright 2004--2005, 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 _XMPPCLIENT_H_ 29 #define _XMPPCLIENT_H_ 30 31 #include <string> 32 #include "talk/base/basicdefs.h" 33 #include "talk/base/sigslot.h" 34 #include "talk/xmpp/xmppengine.h" 35 #include "talk/xmpp/asyncsocket.h" 36 #include "talk/xmpp/xmppclientsettings.h" 37 #include "talk/base/task.h" 38 39 namespace buzz { 40 41 class XmppTask; 42 class PreXmppAuth; 43 class CaptchaChallenge; 44 45 // Just some non-colliding number. Could have picked "1". 46 #define XMPP_CLIENT_TASK_CODE 0x366c1e47 47 48 ///////////////////////////////////////////////////////////////////// 49 // 50 // XMPPCLIENT 51 // 52 ///////////////////////////////////////////////////////////////////// 53 // 54 // See Task first. XmppClient is a parent task for XmppTasks. 55 // 56 // XmppClient is a task which is designed to be the parent task for 57 // all tasks that depend on a single Xmpp connection. If you want to, 58 // for example, listen for subscription requests forever, then your 59 // listener should be a task that is a child of the XmppClient that owns 60 // the connection you are using. XmppClient has all the utility methods 61 // that basically drill through to XmppEngine. 62 // 63 // XmppClient is just a wrapper for XmppEngine, and if I were writing it 64 // all over again, I would make XmppClient == XmppEngine. Why? 65 // XmppEngine needs tasks too, for example it has an XmppLoginTask which 66 // should just be the same kind of Task instead of an XmppEngine specific 67 // thing. It would help do certain things like GAIA auth cleaner. 68 // 69 ///////////////////////////////////////////////////////////////////// 70 71 class XmppClient : public talk_base::Task, public sigslot::has_slots<> 72 { 73 public: 74 explicit XmppClient(talk_base::TaskParent * parent); 75 ~XmppClient(); 76 77 XmppReturnStatus Connect(const XmppClientSettings & settings, 78 const std::string & lang, 79 AsyncSocket * socket, 80 PreXmppAuth * preauth); 81 82 virtual talk_base::TaskParent* GetParent(int code); 83 virtual int ProcessStart(); 84 virtual int ProcessResponse(); 85 XmppReturnStatus Disconnect(); 86 const Jid & jid(); 87 88 sigslot::signal1<XmppEngine::State> SignalStateChange; 89 XmppEngine::State GetState(); 90 XmppEngine::Error GetError(int *subcode); 91 92 // When there is a <stream:error> stanza, return the stanza 93 // so that they can be handled. 94 const XmlElement *GetStreamError(); 95 96 // When there is an authentication error, we may have captcha info 97 // that the user can use to unlock their account 98 CaptchaChallenge GetCaptchaChallenge(); 99 100 // When authentication is successful, this returns the service cookie 101 // (if we used GAIA authentication) 102 std::string GetAuthCookie(); 103 104 std::string NextId(); 105 XmppReturnStatus SendStanza(const XmlElement *stanza); 106 XmppReturnStatus SendRaw(const std::string & text); 107 XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal, 108 XmppStanzaError code, 109 const std::string & text); 110 111 XmppEngine* engine(); 112 113 sigslot::signal2<const char *, int> SignalLogInput; 114 sigslot::signal2<const char *, int> SignalLogOutput; 115 116 private: 117 friend class XmppTask; 118 119 void OnAuthDone(); 120 121 // managed tasks and dispatching 122 void AddXmppTask(XmppTask *, XmppEngine::HandlerLevel); 123 void RemoveXmppTask(XmppTask *); 124 125 sigslot::signal0<> SignalDisconnected; 126 127 private: 128 // Internal state management 129 enum { 130 STATE_PRE_XMPP_LOGIN = STATE_NEXT, 131 STATE_START_XMPP_LOGIN = STATE_NEXT + 1, 132 }; 133 int Process(int state) { 134 switch (state) { 135 case STATE_PRE_XMPP_LOGIN: return ProcessCookieLogin(); 136 case STATE_START_XMPP_LOGIN: return ProcessStartXmppLogin(); 137 default: return Task::Process(state); 138 } 139 } 140 141 std::string GetStateName(int state) const { 142 switch (state) { 143 case STATE_PRE_XMPP_LOGIN: return "PRE_XMPP_LOGIN"; 144 case STATE_START_XMPP_LOGIN: return "START_XMPP_LOGIN"; 145 default: return Task::GetStateName(state); 146 } 147 } 148 149 int ProcessCookieLogin(); 150 int ProcessStartXmppLogin(); 151 void EnsureClosed(); 152 153 class Private; 154 friend class Private; 155 talk_base::scoped_ptr<Private> d_; 156 157 bool delivering_signal_; 158 bool valid_; 159 }; 160 161 } 162 163 #endif 164