3 * Copyright 2004--2005, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
28 #ifndef _xmppengine_h_
29 #define _xmppengine_h_
31 // also part of the API
32 #include "talk/xmllite/qname.h"
33 #include "talk/xmllite/xmlelement.h"
34 #include "talk/xmpp/jid.h"
41 typedef void * XmppIqCookie;
43 //! XMPP stanza error codes.
44 //! Used in XmppEngine.SendStanzaError().
45 enum XmppStanzaError {
48 XSE_FEATURE_NOT_IMPLEMENTED,
51 XSE_INTERNAL_SERVER_ERROR,
57 XSE_RECIPIENT_UNAVAILABLE,
59 XSE_REGISTRATION_REQUIRED,
62 XSE_RESOURCE_CONSTRAINT,
63 XSE_SERVICE_UNAVAILABLE,
64 XSE_SUBSCRIPTION_REQUIRED,
65 XSE_UNDEFINED_CONDITION,
66 XSE_UNEXPECTED_REQUEST,
70 // This is used by API functions to synchronously return status.
71 enum XmppReturnStatus {
73 XMPP_RETURN_BADARGUMENT,
76 XMPP_RETURN_UNEXPECTED,
77 XMPP_RETURN_NOTYETIMPLEMENTED,
81 // This is used by API to identify TLS setting.
88 //! Callback for socket output for an XmppEngine connection.
89 //! Register via XmppEngine.SetOutputHandler. An XmppEngine
90 //! can call back to this handler while it is processing
91 //! Connect, SendStanza, SendIq, Disconnect, or HandleInput.
92 class XmppOutputHandler {
94 virtual ~XmppOutputHandler() {}
96 //! Deliver the specified bytes to the XMPP socket.
97 virtual void WriteOutput(const char * bytes, size_t len) = 0;
99 //! Initiate TLS encryption on the socket.
100 //! The implementation must verify that the SSL
101 //! certificate matches the given domainname.
102 virtual void StartTls(const std::string & domainname) = 0;
104 //! Called when engine wants the connecton closed.
105 virtual void CloseConnection() = 0;
108 //! Callback to deliver engine state change notifications
109 //! to the object managing the engine.
110 class XmppSessionHandler {
112 virtual ~XmppSessionHandler() {}
113 //! Called when engine changes state. Argument is new state.
114 virtual void OnStateChange(int state) = 0;
117 //! Callback to deliver stanzas to an Xmpp application module.
118 //! Register via XmppEngine.SetDefaultSessionHandler or via
119 //! XmppEngine.AddSessionHAndler.
120 class XmppStanzaHandler {
122 virtual ~XmppStanzaHandler() {}
123 //! Process the given stanza.
124 //! The handler must return true if it has handled the stanza.
125 //! A false return value causes the stanza to be passed on to
126 //! the next registered handler.
127 virtual bool HandleStanza(const XmlElement * stanza) = 0;
130 //! Callback to deliver iq responses (results and errors).
131 //! Register while sending an iq via XmppEngine.SendIq.
132 //! Iq responses are routed to matching XmppIqHandlers in preference
133 //! to sending to any registered SessionHandlers.
134 class XmppIqHandler {
136 virtual ~XmppIqHandler() {}
137 //! Called to handle the iq response.
138 //! The response may be either a result or an error, and will have
139 //! an 'id' that matches the request and a 'from' that matches the
140 //! 'to' of the request. Called no more than once; once this is
141 //! called, the handler is automatically unregistered.
142 virtual void IqResponse(XmppIqCookie cookie, const XmlElement * pelStanza) = 0;
145 //! The XMPP connection engine.
146 //! This engine implements the client side of the 'core' XMPP protocol.
147 //! To use it, register an XmppOutputHandler to handle socket output
148 //! and pass socket input to HandleInput. Then application code can
149 //! set up the connection with a user, password, and other settings,
150 //! and then call Connect() to initiate the connection.
151 //! An application can listen for events and receive stanzas by
152 //! registering an XmppStanzaHandler via AddStanzaHandler().
155 static XmppEngine * Create();
156 virtual ~XmppEngine() {}
158 //! Error codes. See GetError().
160 ERROR_NONE = 0, //!< No error
161 ERROR_XML, //!< Malformed XML or encoding error
162 ERROR_STREAM, //!< XMPP stream error - see GetStreamError()
163 ERROR_VERSION, //!< XMPP version error
164 ERROR_UNAUTHORIZED, //!< User is not authorized (rejected credentials)
165 ERROR_TLS, //!< TLS could not be negotiated
166 ERROR_AUTH, //!< Authentication could not be negotiated
167 ERROR_BIND, //!< Resource or session binding could not be negotiated
168 ERROR_CONNECTION_CLOSED,//!< Connection closed by output handler.
169 ERROR_DOCUMENT_CLOSED, //!< Closed by </stream:stream>
170 ERROR_SOCKET, //!< Socket error
171 ERROR_NETWORK_TIMEOUT, //!< Some sort of timeout (eg., we never got the roster)
172 ERROR_MISSING_USERNAME //!< User has a Google Account but no nickname
175 //! States. See GetState().
177 STATE_NONE = 0, //!< Nonexistent state
178 STATE_START, //!< Initial state.
179 STATE_OPENING, //!< Exchanging stream headers, authenticating and so on.
180 STATE_OPEN, //!< Authenticated and bound.
181 STATE_CLOSED, //!< Session closed, possibly due to error.
184 // SOCKET INPUT AND OUTPUT ------------------------------------------------
186 //! Registers the handler for socket output
187 virtual XmppReturnStatus SetOutputHandler(XmppOutputHandler *pxoh) = 0;
189 //! Provides socket input to the engine
190 virtual XmppReturnStatus HandleInput(const char * bytes, size_t len) = 0;
192 //! Advises the engine that the socket has closed
193 virtual XmppReturnStatus ConnectionClosed(int subcode) = 0;
195 // SESSION SETUP ---------------------------------------------------------
197 //! Indicates the (bare) JID for the user to use.
198 virtual XmppReturnStatus SetUser(const Jid & jid)= 0;
200 //! Get the login (bare) JID.
201 virtual const Jid & GetUser() = 0;
203 //! Provides different methods for credentials for login.
204 //! Takes ownership of this object; deletes when login is done
205 virtual XmppReturnStatus SetSaslHandler(SaslHandler * h) = 0;
207 //! Sets whether TLS will be used within the connection (default true).
208 virtual XmppReturnStatus SetTls(TlsOptions useTls) = 0;
210 //! Sets an alternate domain from which we allows TLS certificates.
211 //! This is for use in the case where a we want to allow a proxy to
212 //! serve up its own certificate rather than one owned by the underlying
214 virtual XmppReturnStatus SetTlsServer(const std::string & proxy_hostname,
215 const std::string & proxy_domain) = 0;
217 //! Gets whether TLS will be used within the connection.
218 virtual TlsOptions GetTls() = 0;
220 //! Sets the request resource name, if any (optional).
221 //! Note that the resource name may be overridden by the server; after
222 //! binding, the actual resource name is available as part of FullJid().
223 virtual XmppReturnStatus SetRequestedResource(const std::string& resource) = 0;
225 //! Gets the request resource name.
226 virtual const std::string & GetRequestedResource() = 0;
229 virtual void SetLanguage(const std::string & lang) = 0;
231 // SESSION MANAGEMENT ---------------------------------------------------
233 //! Set callback for state changes.
234 virtual XmppReturnStatus SetSessionHandler(XmppSessionHandler* handler) = 0;
236 //! Initiates the XMPP connection.
237 //! After supplying connection settings, call this once to initiate,
238 //! (optionally) encrypt, authenticate, and bind the connection.
239 virtual XmppReturnStatus Connect() = 0;
241 //! The current engine state.
242 virtual State GetState() = 0;
244 //! Returns true if the connection is encrypted (under TLS)
245 virtual bool IsEncrypted() = 0;
248 //! Consult this after XmppOutputHandler.OnClose().
249 virtual Error GetError(int *subcode) = 0;
251 //! The stream:error stanza, when the error is XmppEngine::ERROR_STREAM.
252 //! Notice the stanza returned is owned by the XmppEngine and
253 //! is deleted when the engine is destroyed.
254 virtual const XmlElement * GetStreamError() = 0;
256 //! Closes down the connection.
257 //! Sends CloseConnection to output, and disconnects and registered
258 //! session handlers. After Disconnect completes, it is guaranteed
259 //! that no further callbacks will be made.
260 virtual XmppReturnStatus Disconnect() = 0;
262 // APPLICATION USE -------------------------------------------------------
266 HL_PEEK, //!< Sees messages before all other processing; cannot abort
267 HL_SINGLE, //!< Watches for a single message, e.g., by id and sender
268 HL_SENDER, //!< Watches for a type of message from a specific sender
269 HL_TYPE, //!< Watches a type of message, e.g., all groupchat msgs
270 HL_ALL, //!< Watches all messages - gets last shot
271 HL_COUNT, //!< Count of handler levels
274 //! Adds a listener for session events.
275 //! Stanza delivery is chained to session handlers; the first to
276 //! return 'true' is the last to get each stanza.
277 virtual XmppReturnStatus AddStanzaHandler(XmppStanzaHandler* handler, HandlerLevel level = HL_PEEK) = 0;
279 //! Removes a listener for session events.
280 virtual XmppReturnStatus RemoveStanzaHandler(XmppStanzaHandler* handler) = 0;
282 //! Sends a stanza to the server.
283 virtual XmppReturnStatus SendStanza(const XmlElement * pelStanza) = 0;
285 //! Sends raw text to the server
286 virtual XmppReturnStatus SendRaw(const std::string & text) = 0;
288 //! Sends an iq to the server, and registers a callback for the result.
289 //! Returns the cookie passed to the result handler.
290 virtual XmppReturnStatus SendIq(const XmlElement* pelStanza,
291 XmppIqHandler* iq_handler,
292 XmppIqCookie* cookie) = 0;
294 //! Unregisters an iq callback handler given its cookie.
295 //! No callback will come to this handler after it's unregistered.
296 virtual XmppReturnStatus RemoveIqHandler(XmppIqCookie cookie,
297 XmppIqHandler** iq_handler) = 0;
300 //! Forms and sends an error in response to the given stanza.
301 //! Swaps to and from, sets type to "error", and adds error information
302 //! based on the passed code. Text is optional and may be STR_EMPTY.
303 virtual XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal,
304 XmppStanzaError code,
305 const std::string & text) = 0;
307 //! The fullly bound JID.
308 //! This JID is only valid after binding has succeeded. If the value
309 //! is JID_NULL, the binding has not succeeded.
310 virtual const Jid & FullJid() = 0;
312 //! The next unused iq id for this connection.
313 //! Call this when building iq stanzas, to ensure that each iq
314 //! gets its own unique id.
315 virtual std::string NextId() = 0;
322 // Move these to a better location
324 #define XMPP_FAILED(x) \
325 ( (x) == buzz::XMPP_RETURN_OK ? false : true) \
328 #define XMPP_SUCCEEDED(x) \
329 ( (x) == buzz::XMPP_RETURN_OK ? true : false) \
334 if (XMPP_FAILED(xmpp_status)) { \
335 return xmpp_status; \
343 if (XMPP_FAILED(xmpp_status)) { \