xmppengine.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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. #ifndef THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPENGINE_H_
  11. #define THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPENGINE_H_
  12. // also part of the API
  13. #include "third_party/libjingle_xmpp/xmllite/qname.h"
  14. #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
  15. #include "third_party/libjingle_xmpp/xmpp/jid.h"
  16. namespace jingle_xmpp {
  17. class XmppEngine;
  18. class SaslHandler;
  19. typedef void * XmppIqCookie;
  20. //! XMPP stanza error codes.
  21. //! Used in XmppEngine.SendStanzaError().
  22. enum XmppStanzaError {
  23. XSE_BAD_REQUEST,
  24. XSE_CONFLICT,
  25. XSE_FEATURE_NOT_IMPLEMENTED,
  26. XSE_FORBIDDEN,
  27. XSE_GONE,
  28. XSE_INTERNAL_SERVER_ERROR,
  29. XSE_ITEM_NOT_FOUND,
  30. XSE_JID_MALFORMED,
  31. XSE_NOT_ACCEPTABLE,
  32. XSE_NOT_ALLOWED,
  33. XSE_PAYMENT_REQUIRED,
  34. XSE_RECIPIENT_UNAVAILABLE,
  35. XSE_REDIRECT,
  36. XSE_REGISTRATION_REQUIRED,
  37. XSE_SERVER_NOT_FOUND,
  38. XSE_SERVER_TIMEOUT,
  39. XSE_RESOURCE_CONSTRAINT,
  40. XSE_SERVICE_UNAVAILABLE,
  41. XSE_SUBSCRIPTION_REQUIRED,
  42. XSE_UNDEFINED_CONDITION,
  43. XSE_UNEXPECTED_REQUEST,
  44. };
  45. // XmppReturnStatus
  46. // This is used by API functions to synchronously return status.
  47. enum XmppReturnStatus {
  48. XMPP_RETURN_OK,
  49. XMPP_RETURN_BADARGUMENT,
  50. XMPP_RETURN_BADSTATE,
  51. XMPP_RETURN_PENDING,
  52. XMPP_RETURN_UNEXPECTED,
  53. XMPP_RETURN_NOTYETIMPLEMENTED,
  54. };
  55. // TlsOptions
  56. // This is used by API to identify TLS setting.
  57. enum TlsOptions {
  58. TLS_DISABLED,
  59. TLS_ENABLED,
  60. TLS_REQUIRED
  61. };
  62. //! Callback for socket output for an XmppEngine connection.
  63. //! Register via XmppEngine.SetOutputHandler. An XmppEngine
  64. //! can call back to this handler while it is processing
  65. //! Connect, SendStanza, SendIq, Disconnect, or HandleInput.
  66. class XmppOutputHandler {
  67. public:
  68. virtual ~XmppOutputHandler() {}
  69. //! Deliver the specified bytes to the XMPP socket.
  70. virtual void WriteOutput(const char * bytes, size_t len) = 0;
  71. //! Initiate TLS encryption on the socket.
  72. //! The implementation must verify that the SSL
  73. //! certificate matches the given domainname.
  74. virtual void StartTls(const std::string & domainname) = 0;
  75. //! Called when engine wants the connecton closed.
  76. virtual void CloseConnection() = 0;
  77. };
  78. //! Callback to deliver engine state change notifications
  79. //! to the object managing the engine.
  80. class XmppSessionHandler {
  81. public:
  82. virtual ~XmppSessionHandler() {}
  83. //! Called when engine changes state. Argument is new state.
  84. virtual void OnStateChange(int state) = 0;
  85. };
  86. //! Callback to deliver stanzas to an Xmpp application module.
  87. //! Register via XmppEngine.SetDefaultSessionHandler or via
  88. //! XmppEngine.AddSessionHAndler.
  89. class XmppStanzaHandler {
  90. public:
  91. virtual ~XmppStanzaHandler() {}
  92. //! Process the given stanza.
  93. //! The handler must return true if it has handled the stanza.
  94. //! A false return value causes the stanza to be passed on to
  95. //! the next registered handler.
  96. virtual bool HandleStanza(const XmlElement * stanza) = 0;
  97. };
  98. //! Callback to deliver iq responses (results and errors).
  99. //! Register while sending an iq via XmppEngine.SendIq.
  100. //! Iq responses are routed to matching XmppIqHandlers in preference
  101. //! to sending to any registered SessionHandlers.
  102. class XmppIqHandler {
  103. public:
  104. virtual ~XmppIqHandler() {}
  105. //! Called to handle the iq response.
  106. //! The response may be either a result or an error, and will have
  107. //! an 'id' that matches the request and a 'from' that matches the
  108. //! 'to' of the request. Called no more than once; once this is
  109. //! called, the handler is automatically unregistered.
  110. virtual void IqResponse(XmppIqCookie cookie, const XmlElement * pelStanza) = 0;
  111. };
  112. //! The XMPP connection engine.
  113. //! This engine implements the client side of the 'core' XMPP protocol.
  114. //! To use it, register an XmppOutputHandler to handle socket output
  115. //! and pass socket input to HandleInput. Then application code can
  116. //! set up the connection with a user, password, and other settings,
  117. //! and then call Connect() to initiate the connection.
  118. //! An application can listen for events and receive stanzas by
  119. //! registering an XmppStanzaHandler via AddStanzaHandler().
  120. class XmppEngine {
  121. public:
  122. static XmppEngine * Create();
  123. virtual ~XmppEngine() {}
  124. //! Error codes. See GetError().
  125. enum Error {
  126. ERROR_NONE = 0, //!< No error
  127. ERROR_XML, //!< Malformed XML or encoding error
  128. ERROR_STREAM, //!< XMPP stream error - see GetStreamError()
  129. ERROR_VERSION, //!< XMPP version error
  130. ERROR_UNAUTHORIZED, //!< User is not authorized (rejected credentials)
  131. ERROR_TLS, //!< TLS could not be negotiated
  132. ERROR_AUTH, //!< Authentication could not be negotiated
  133. ERROR_BIND, //!< Resource or session binding could not be negotiated
  134. ERROR_CONNECTION_CLOSED,//!< Connection closed by output handler.
  135. ERROR_DOCUMENT_CLOSED, //!< Closed by </stream:stream>
  136. ERROR_SOCKET, //!< Socket error
  137. ERROR_NETWORK_TIMEOUT, //!< Some sort of timeout (eg., we never got the roster)
  138. ERROR_MISSING_USERNAME //!< User has a Google Account but no nickname
  139. };
  140. //! States. See GetState().
  141. enum State {
  142. STATE_NONE = 0, //!< Nonexistent state
  143. STATE_START, //!< Initial state.
  144. STATE_OPENING, //!< Exchanging stream headers, authenticating and so on.
  145. STATE_OPEN, //!< Authenticated and bound.
  146. STATE_CLOSED, //!< Session closed, possibly due to error.
  147. };
  148. // SOCKET INPUT AND OUTPUT ------------------------------------------------
  149. //! Registers the handler for socket output
  150. virtual XmppReturnStatus SetOutputHandler(XmppOutputHandler *pxoh) = 0;
  151. //! Provides socket input to the engine
  152. virtual XmppReturnStatus HandleInput(const char * bytes, size_t len) = 0;
  153. //! Advises the engine that the socket has closed
  154. virtual XmppReturnStatus ConnectionClosed(int subcode) = 0;
  155. // SESSION SETUP ---------------------------------------------------------
  156. //! Indicates the (bare) JID for the user to use.
  157. virtual XmppReturnStatus SetUser(const Jid & jid)= 0;
  158. //! Get the login (bare) JID.
  159. virtual const Jid & GetUser() = 0;
  160. //! Provides different methods for credentials for login.
  161. //! Takes ownership of this object; deletes when login is done
  162. virtual XmppReturnStatus SetSaslHandler(SaslHandler * h) = 0;
  163. //! Sets whether TLS will be used within the connection (default true).
  164. virtual XmppReturnStatus SetTls(TlsOptions useTls) = 0;
  165. //! Sets an alternate domain from which we allows TLS certificates.
  166. //! This is for use in the case where a we want to allow a proxy to
  167. //! serve up its own certificate rather than one owned by the underlying
  168. //! domain.
  169. virtual XmppReturnStatus SetTlsServer(const std::string & proxy_hostname,
  170. const std::string & proxy_domain) = 0;
  171. //! Gets whether TLS will be used within the connection.
  172. virtual TlsOptions GetTls() = 0;
  173. //! Sets the request resource name, if any (optional).
  174. //! Note that the resource name may be overridden by the server; after
  175. //! binding, the actual resource name is available as part of FullJid().
  176. virtual XmppReturnStatus SetRequestedResource(const std::string& resource) = 0;
  177. //! Gets the request resource name.
  178. virtual const std::string & GetRequestedResource() = 0;
  179. //! Sets language
  180. virtual void SetLanguage(const std::string & lang) = 0;
  181. // SESSION MANAGEMENT ---------------------------------------------------
  182. //! Set callback for state changes.
  183. virtual XmppReturnStatus SetSessionHandler(XmppSessionHandler* handler) = 0;
  184. //! Initiates the XMPP connection.
  185. //! After supplying connection settings, call this once to initiate,
  186. //! (optionally) encrypt, authenticate, and bind the connection.
  187. virtual XmppReturnStatus Connect() = 0;
  188. //! The current engine state.
  189. virtual State GetState() = 0;
  190. //! Returns true if the connection is encrypted (under TLS)
  191. virtual bool IsEncrypted() = 0;
  192. //! The error code.
  193. //! Consult this after XmppOutputHandler.OnClose().
  194. virtual Error GetError(int *subcode) = 0;
  195. //! The stream:error stanza, when the error is XmppEngine::ERROR_STREAM.
  196. //! Notice the stanza returned is owned by the XmppEngine and
  197. //! is deleted when the engine is destroyed.
  198. virtual const XmlElement * GetStreamError() = 0;
  199. //! Closes down the connection.
  200. //! Sends CloseConnection to output, and disconnects and registered
  201. //! session handlers. After Disconnect completes, it is guaranteed
  202. //! that no further callbacks will be made.
  203. virtual XmppReturnStatus Disconnect() = 0;
  204. // APPLICATION USE -------------------------------------------------------
  205. enum HandlerLevel {
  206. HL_NONE = 0,
  207. HL_PEEK, //!< Sees messages before all other processing; cannot abort
  208. HL_SINGLE, //!< Watches for a single message, e.g., by id and sender
  209. HL_SENDER, //!< Watches for a type of message from a specific sender
  210. HL_TYPE, //!< Watches a type of message, e.g., all groupchat msgs
  211. HL_ALL, //!< Watches all messages - gets last shot
  212. HL_COUNT, //!< Count of handler levels
  213. };
  214. //! Adds a listener for session events.
  215. //! Stanza delivery is chained to session handlers; the first to
  216. //! return 'true' is the last to get each stanza.
  217. virtual XmppReturnStatus AddStanzaHandler(XmppStanzaHandler* handler, HandlerLevel level = HL_PEEK) = 0;
  218. //! Removes a listener for session events.
  219. virtual XmppReturnStatus RemoveStanzaHandler(XmppStanzaHandler* handler) = 0;
  220. //! Sends a stanza to the server.
  221. virtual XmppReturnStatus SendStanza(const XmlElement * pelStanza) = 0;
  222. //! Sends raw text to the server
  223. virtual XmppReturnStatus SendRaw(const std::string & text) = 0;
  224. //! Sends an iq to the server, and registers a callback for the result.
  225. //! Returns the cookie passed to the result handler.
  226. virtual XmppReturnStatus SendIq(const XmlElement* pelStanza,
  227. XmppIqHandler* iq_handler,
  228. XmppIqCookie* cookie) = 0;
  229. //! Unregisters an iq callback handler given its cookie.
  230. //! No callback will come to this handler after it's unregistered.
  231. virtual XmppReturnStatus RemoveIqHandler(XmppIqCookie cookie,
  232. XmppIqHandler** iq_handler) = 0;
  233. //! Forms and sends an error in response to the given stanza.
  234. //! Swaps to and from, sets type to "error", and adds error information
  235. //! based on the passed code. Text is optional and may be STR_EMPTY.
  236. virtual XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal,
  237. XmppStanzaError code,
  238. const std::string & text) = 0;
  239. //! The fullly bound JID.
  240. //! This JID is only valid after binding has succeeded. If the value
  241. //! is JID_NULL, the binding has not succeeded.
  242. virtual const Jid & FullJid() = 0;
  243. //! The next unused iq id for this connection.
  244. //! Call this when building iq stanzas, to ensure that each iq
  245. //! gets its own unique id.
  246. virtual std::string NextId() = 0;
  247. };
  248. }
  249. // Move these to a better location
  250. #define XMPP_FAILED(x) \
  251. ( (x) == jingle_xmpp::XMPP_RETURN_OK ? false : true) \
  252. #define XMPP_SUCCEEDED(x) \
  253. ( (x) == jingle_xmpp::XMPP_RETURN_OK ? true : false) \
  254. #define IFR(x) \
  255. do { \
  256. xmpp_status = (x); \
  257. if (XMPP_FAILED(xmpp_status)) { \
  258. return xmpp_status; \
  259. } \
  260. } while (false) \
  261. #define IFC(x) \
  262. do { \
  263. xmpp_status = (x); \
  264. if (XMPP_FAILED(xmpp_status)) { \
  265. goto Cleanup; \
  266. } \
  267. } while (false) \
  268. #endif // THIRD_PARTY_LIBJINGLE_XMPP_XMPP_XMPPENGINE_H_