/* * Copyright (c) 2010 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once #include "Swiften/Base/boost_bsignals.h" #include <boost/shared_ptr.hpp> #include "Swiften/Network/PlatformDomainNameResolver.h" #include "Swiften/Network/Connector.h" #include "Swiften/Base/Error.h" #include "Swiften/Client/ClientSession.h" #include "Swiften/Client/ClientError.h" #include "Swiften/Elements/Presence.h" #include "Swiften/Elements/Message.h" #include "Swiften/JID/JID.h" #include "Swiften/Base/String.h" #include "Swiften/Client/StanzaChannel.h" #include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" #include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h" #include "Swiften/Client/ClientSessionStanzaChannel.h" namespace Swift { class IQRouter; class TLSContextFactory; class ConnectionFactory; class TimerFactory; class ClientSession; class BasicSessionStream; class EventLoop; class PlatformTLSFactories; class CertificateTrustChecker; /** * The central class for communicating with an XMPP server. * * This class is responsible for setting up the connection with the XMPP * server, authenticating, and initializing the session. * * This class can be used directly in your application, although the Client * subclass provides more functionality and interfaces, and is better suited * for most needs. */ class CoreClient { public: /** * Constructs a client for the given JID with the given password. * The given eventLoop will be used to post events to. */ CoreClient(EventLoop* eventLoop, const JID& jid, const String& password); ~CoreClient(); void setCertificate(const String& certificate); /** * Connects the client to the server. * * After the connection is established, the client will set * initialize the stream and authenticate. */ void connect(); /** * Disconnects the client from the server. */ void disconnect(); void connect(const JID& jid); void connect(const String& host); /** * Sends a message. */ void sendMessage(Message::ref); /** * Sends a presence stanza. */ void sendPresence(Presence::ref); /** * Returns the IQ router for this client. */ IQRouter* getIQRouter() const { return iqRouter_; } /** * Checks whether the client is connected to the server, * and stanzas can be sent. */ bool isAvailable() const { return stanzaChannel_->isAvailable(); } /** * Checks whether the client is active. * * A client is active when it is connected or connecting to the server. */ bool isActive() const; /** * Returns the JID of the client. * After the session was initialized, this returns the bound JID. */ const JID& getJID() const { if (session_) { return session_->getLocalJID(); } else { return jid_; } } /** * Checks whether stream management is enabled. * * If stream management is enabled, onStanzaAcked will be * emitted when a stanza is received by the server. * * \see onStanzaAcked */ bool getStreamManagementEnabled() const { return stanzaChannel_->getStreamManagementEnabled(); } StanzaChannel* getStanzaChannel() const { return stanzaChannel_; } /** * Sets the certificate trust checker. * * This checker will be called when the server sends a * TLS certificate that does not validate. If the trust checker * says the certificate is trusted, then connecting will proceed; * if not, the connection will end with an error. */ void setCertificateTrustChecker(CertificateTrustChecker*); public: /** * Emitted when the client was disconnected from the network. * * If the connection was due to a non-recoverable error, the type * of error will be passed as a parameter. */ boost::signal<void (const boost::optional<ClientError>&)> onDisconnected; /** * Emitted when the client is connected and authenticated, * and stanzas can be sent. */ boost::signal<void ()> onConnected; /** * Emitted when the client receives data. * * This signal is emitted before the XML data is parsed, * so this data is unformatted. */ boost::signal<void (const String&)> onDataRead; /** * Emitted when the client sends data. * * This signal is emitted after the XML was serialized, and * is unformatted. */ boost::signal<void (const String&)> onDataWritten; /** * Emitted when a message is received. */ boost::signal<void (Message::ref)> onMessageReceived; /** * Emitted when a presence stanza is received. */ boost::signal<void (Presence::ref) > onPresenceReceived; /** * Emitted when the server acknowledges receipt of a * stanza (if acknowledgements are available). * * \see getStreamManagementEnabled() */ boost::signal<void (Stanza::ref)> onStanzaAcked; private: void handleConnectorFinished(boost::shared_ptr<Connection>); void handleStanzaChannelAvailableChanged(bool available); void handleSessionFinished(boost::shared_ptr<Error>); void handleNeedCredentials(); void handleDataRead(const String&); void handleDataWritten(const String&); private: PlatformDomainNameResolver resolver_; JID jid_; String password_; EventLoop* eventLoop; ClientSessionStanzaChannel* stanzaChannel_; IQRouter* iqRouter_; Connector::ref connector_; ConnectionFactory* connectionFactory_; TimerFactory* timerFactory_; PlatformTLSFactories* tlsFactories; FullPayloadParserFactoryCollection payloadParserFactories_; FullPayloadSerializerCollection payloadSerializers_; boost::shared_ptr<Connection> connection_; boost::shared_ptr<BasicSessionStream> sessionStream_; boost::shared_ptr<ClientSession> session_; String certificate_; bool disconnectRequested_; CertificateTrustChecker* certificateTrustChecker; }; }