diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2010-08-11 07:31:23 +0000 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2010-08-11 07:31:23 +0000 |
| commit | 40c39853816cfab113d79682c34bc76a2c79c357 (patch) | |
| tree | e4d6a184cf565cb87477339ce738299ff9787bc3 /src/QXmppClient.cpp | |
| parent | 551c284e35280b7b91a939fe7352e496ffea402a (diff) | |
| download | qxmpp-40c39853816cfab113d79682c34bc76a2c79c357.tar.gz | |
rename "source" directory to "src"
Diffstat (limited to 'src/QXmppClient.cpp')
| -rw-r--r-- | src/QXmppClient.cpp | 642 |
1 files changed, 642 insertions, 0 deletions
diff --git a/src/QXmppClient.cpp b/src/QXmppClient.cpp new file mode 100644 index 00000000..e88449b0 --- /dev/null +++ b/src/QXmppClient.cpp @@ -0,0 +1,642 @@ +/* + * Copyright (C) 2008-2010 The QXmpp developers + * + * Author: + * Manjeet Dahiya + * + * Source: + * http://code.google.com/p/qxmpp + * + * This file is a part of QXmpp library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + + +#include "QXmppClient.h" +#include "QXmppLogger.h" +#include "QXmppStream.h" +#include "QXmppMessage.h" + +#include "QXmppArchiveManager.h" +#include "QXmppCallManager.h" +#include "QXmppInvokable.h" +#include "QXmppMucManager.h" +#include "QXmppReconnectionManager.h" +#include "QXmppRpcIq.h" +#include "QXmppRemoteMethod.h" +#include "QXmppRosterManager.h" +#include "QXmppUtils.h" +#include "QXmppTransferManager.h" +#include "QXmppVCardManager.h" + +/// \mainpage +/// +/// QXmpp is a cross-platform C++ XMPP client library based on the Qt +/// framework. It tries to use Qt's programming conventions in order to ease +/// the learning curve for new programmers. +/// +/// QXmpp based clients are built using QXmppClient instances which handle the +/// establishment of the XMPP connection and provide a number of high-level +/// "managers" to perform specific tasks: +/// +/// \sa QXmppCallManager +/// \sa QXmppMucManager +/// \sa QXmppRosterManager +/// \sa QXmppVCardManager +/// \sa QXmppTransferManager +/// +/// If you are interested in a more low-level API, you can refer to the +/// classes which represent XMPP stanzas. +/// +/// \sa QXmppIq +/// \sa QXmppMessage +/// \sa QXmppPresence + +/// Creates a QXmppClient object. +/// \param parent is passed to the QObject's contructor. +/// The default value is 0. + +QXmppClient::QXmppClient(QObject *parent) + : QObject(parent), + m_stream(0), + m_clientPresence(QXmppPresence::Available), + m_reconnectionManager(0) +{ + m_stream = new QXmppStream(this); + m_clientPresence.setExtensions(m_stream->presenceExtensions()); + + bool check = connect(m_stream, SIGNAL(elementReceived(const QDomElement&, bool&)), + this, SIGNAL(elementReceived(const QDomElement&, bool&))); + Q_ASSERT(check); + + check = connect(m_stream, SIGNAL(messageReceived(const QXmppMessage&)), + this, SIGNAL(messageReceived(const QXmppMessage&))); + Q_ASSERT(check); + + check = connect(m_stream, SIGNAL(presenceReceived(const QXmppPresence&)), + this, SIGNAL(presenceReceived(const QXmppPresence&))); + Q_ASSERT(check); + + check = connect(m_stream, SIGNAL(iqReceived(const QXmppIq&)), this, + SIGNAL(iqReceived(const QXmppIq&))); + Q_ASSERT(check); + + check = connect(m_stream, SIGNAL(discoveryIqReceived(const QXmppDiscoveryIq&)), this, + SIGNAL(discoveryIqReceived(const QXmppDiscoveryIq&))); + Q_ASSERT(check); + + check = connect(m_stream, SIGNAL(disconnected()), this, + SIGNAL(disconnected())); + Q_ASSERT(check); + + check = connect(m_stream, SIGNAL(xmppConnected()), this, + SLOT(xmppConnected())); + Q_ASSERT(check); + + check = connect(m_stream, SIGNAL(xmppConnected()), this, + SIGNAL(connected())); + Q_ASSERT(check); + + check = connect(m_stream, SIGNAL(error(QXmppClient::Error)), this, + SIGNAL(error(QXmppClient::Error))); + Q_ASSERT(check); + + check = setReconnectionManager(new QXmppReconnectionManager(this)); + Q_ASSERT(check); + + // rpc + check = connect(m_stream, SIGNAL(rpcCallInvoke(QXmppRpcInvokeIq)), + this, SLOT(invokeInterfaceMethod(QXmppRpcInvokeIq))); + Q_ASSERT(check); + + // logging + check = connect(this, SIGNAL(logMessage(QXmppLogger::MessageType, QString)), + m_stream, SIGNAL(logMessage(QXmppLogger::MessageType, QString))); + Q_ASSERT(check); + + // create managers + m_rosterManager = new QXmppRosterManager(m_stream, this); + m_archiveManager = new QXmppArchiveManager(m_stream, this); + m_callManager = new QXmppCallManager(m_stream, this); + m_mucManager = new QXmppMucManager(m_stream, this); + m_transferManager = new QXmppTransferManager(m_stream, this); + m_vCardManager = new QXmppVCardManager(m_stream, this); +} + +/// Destructor, destroys the QXmppClient object. +/// + +QXmppClient::~QXmppClient() +{ +} + +/// Returns a modifiable reference to the current configuration of QXmppClient. +/// \return Reference to the QXmppClient's configuration for the connection. + +QXmppConfiguration& QXmppClient::configuration() +{ + return m_stream->configuration(); +} + +/// Attempts to connect to the XMPP server. Server details and other configurations +/// are specified using the config parameter. Use signals connected(), error(QXmppClient::Error) +/// and disconnected() to know the status of the connection. +/// \param config Specifies the configuration object for connecting the XMPP server. +/// This contains the host name, user, passwd etc. See QXmppConfiguration for details. +/// \param initialPresence The initial presence which will be set for this user +/// after establishing the session. The default value is QXmppPresence::Available + +void QXmppClient::connectToServer(const QXmppConfiguration& config, + const QXmppPresence& initialPresence) +{ + m_stream->configuration() = config; + if(!config.autoReconnectionEnabled()) + { + delete m_reconnectionManager; + m_reconnectionManager = 0; + } + + m_clientPresence = initialPresence; + m_clientPresence.setExtensions(m_stream->presenceExtensions()); + + m_stream->connect(); +} + +/// Overloaded function. +/// \param host host name of the XMPP server where connection has to be made +/// (e.g. "jabber.org" and "talk.google.com"). It can also be an IP address in +/// the form of a string (e.g. "192.168.1.25"). +/// \param user Username of the account at the specified XMPP server. It should +/// be the name without the domain name. E.g. "qxmpp.test1" and not +/// "qxmpp.test1@gmail.com" +/// \param passwd Password for the specified username +/// \param domain Domain name e.g. "gmail.com" and "jabber.org". +/// \param port Port number at which the XMPP server is listening. The default +/// value is 5222. +/// \param initialPresence The initial presence which will be set for this user +/// after establishing the session. The default value is QXmppPresence::Available + +void QXmppClient::connectToServer(const QString& host, const QString& user, + const QString& passwd, const QString& domain, + int port, + const QXmppPresence& initialPresence) +{ + QXmppConfiguration &config = m_stream->configuration(); + config.setHost(host); + config.setUser(user); + config.setPasswd(passwd); + config.setDomain(domain); + config.setPort(port); + + m_clientPresence = initialPresence; + m_clientPresence.setExtensions(m_stream->presenceExtensions()); + + m_stream->connect(); +} + +/// Overloaded function. +/// \param host host name of the XMPP server where connection has to be made +/// (e.g. "jabber.org" and "talk.google.com"). It can also be an IP address in +/// the form of a string (e.g. "192.168.1.25"). +/// \param bareJid BareJid of the account at the specified XMPP server. +/// (e.g. "qxmpp.test1@gmail.com" or qxmpptest@jabber.org.) +/// \param passwd Password for the specified username +/// \param port Port number at which the XMPP server is listening. The default +/// value is 5222. +/// \param initialPresence The initial presence which will be set for this user +/// after establishing the session. The default value is QXmppPresence::Available + +void QXmppClient::connectToServer(const QString& host, + const QString& bareJid, + const QString& passwd, + int port, + const QXmppPresence& initialPresence) +{ + QString user, domain; + QStringList list = bareJid.split("@"); + if(list.size() == 2) + { + user = list.at(0); + domain = list.at(1); + connectToServer(host, user, passwd, domain, port, initialPresence); + } + else + { + emit logMessage(QXmppLogger::WarningMessage, "Invalid bareJid"); + } +} + +/// After successfully connecting to the server use this function to send +/// stanzas to the server. This function can solely be used to send various kind +/// of stanzas to the server. QXmppPacket is a parent class of all the stanzas +/// QXmppMessage, QXmppPresence, QXmppIq, QXmppBind, QXmppRosterIq, QXmppSession +/// and QXmppVCard. +/// +/// \return Returns true if the packet was sent, false otherwise. +/// +/// Following code snippet illustrates how to send a message using this function: +/// \code +/// QXmppMessage message(from, to, message); +/// client.sendPacket(message); +/// \endcode +/// +/// \param packet A valid XMPP stanza. It can be an iq, a message or a presence stanza. +/// + +bool QXmppClient::sendPacket(const QXmppPacket& packet) +{ + return m_stream->sendPacket(packet); +} + +/// Disconnects the client and the current presence of client changes to +/// QXmppPresence::Unavailable and status text changes to "Logged out". +/// +/// \note Make sure that the clientPresence is changed to +/// QXmppPresence::Available, if you are again calling connectToServer() after +/// calling the disconnect() function. +/// + +void QXmppClient::disconnect() +{ + m_clientPresence.setType(QXmppPresence::Unavailable); + m_clientPresence.status().setType(QXmppPresence::Status::Offline); + m_clientPresence.status().setStatusText("Logged out"); + if (m_stream->isConnected()) + { + sendPacket(m_clientPresence); + m_stream->disconnect(); + } +} + +/// Returns true if the client is connected to the XMPP server. +/// + +bool QXmppClient::isConnected() const +{ + return m_stream && m_stream->isConnected(); +} + +/// Returns the reference to QXmppRosterManager object of the client. +/// \return Reference to the roster object of the connected client. Use this to +/// get the list of friends in the roster and their presence information. +/// + +QXmppRosterManager& QXmppClient::rosterManager() +{ + return *m_rosterManager; +} + +/// Utility function to send message to all the resources associated with the +/// specified bareJid. +/// +/// \param bareJid bareJid of the receiving entity +/// \param message Message string to be sent. + +void QXmppClient::sendMessage(const QString& bareJid, const QString& message) +{ + QStringList resources = rosterManager().getResources(bareJid); + for(int i = 0; i < resources.size(); ++i) + { + sendPacket(QXmppMessage("", bareJid + "/" + resources.at(i), message)); + } +} + +/// Returns the client's current presence. +/// + +QXmppPresence QXmppClient::clientPresence() const +{ + return m_clientPresence; +} + +/// Changes the presence of the connected client. +/// +/// The connection to the server will be updated accordingly: +/// +/// \li If the presence type is QXmppPresence::Unavailable, the connection +/// to the server will be closed. +/// +/// \li Otherwise, the connection to the server will be established +/// as needed. +/// +/// \param presence QXmppPresence object +/// + +void QXmppClient::setClientPresence(const QXmppPresence& presence) +{ + if (presence.type() == QXmppPresence::Unavailable) + { + m_clientPresence = presence; + + // NOTE: we can't call disconnect() because it alters + // the client presence + if (m_stream->isConnected()) + { + sendPacket(m_clientPresence); + m_stream->disconnect(); + } + } + else if (!m_stream->isConnected()) + connectToServer(m_stream->configuration(), presence); + else + { + m_clientPresence = presence; + m_clientPresence.setExtensions(m_stream->presenceExtensions()); + sendPacket(m_clientPresence); + } +} + +/// Function to get reconnection manager. By default there exists a reconnection +/// manager. See QXmppReconnectionManager for more details of the reconnection +/// mechanism. +/// +/// \return Pointer to QXmppReconnectionManager +/// + +QXmppReconnectionManager* QXmppClient::getReconnectionManager() +{ + return m_reconnectionManager; +} + +/// Sets the user defined reconnection manager. +/// +/// \return true if all the signal-slot connections are made correctly. +/// + +bool QXmppClient::setReconnectionManager(QXmppReconnectionManager* + reconnectionManager) +{ + if(!reconnectionManager) + return false; + + if(m_reconnectionManager) + delete m_reconnectionManager; + + m_reconnectionManager = reconnectionManager; + + bool check = connect(this, SIGNAL(connected()), m_reconnectionManager, + SLOT(connected())); + Q_ASSERT(check); + if(!check) + return false; + + check = connect(this, SIGNAL(error(QXmppClient::Error)), + m_reconnectionManager, SLOT(error(QXmppClient::Error))); + Q_ASSERT(check); + if(!check) + return false; + + return true; +} + +/// Returns the socket error if error() is QXmppClient::SocketError. +/// + +QAbstractSocket::SocketError QXmppClient::socketError() +{ + return m_stream->socketError(); +} + +/// Returns the XMPP stream error if QXmppClient::Error is QXmppClient::XmppStreamError. +/// + +QXmppStanza::Error::Condition QXmppClient::xmppStreamError() +{ + return m_stream->xmppStreamError(); +} + +/// Returns the reference to QXmppVCardManager, implimentation of XEP-0054. +/// http://xmpp.org/extensions/xep-0054.html +/// + +QXmppVCardManager& QXmppClient::vCardManager() +{ + return *m_vCardManager; +} + +void QXmppClient::addInvokableInterface( QXmppInvokable *interface ) +{ + m_interfaces[ interface->metaObject()->className() ] = interface; +} + + +void QXmppClient::invokeInterfaceMethod( const QXmppRpcInvokeIq &iq ) +{ + QXmppStanza::Error error; + + const QStringList methodBits = iq.method().split('.'); + if (methodBits.size() != 2) + return; + const QString interface = methodBits.first(); + const QString method = methodBits.last(); + QXmppInvokable *iface = m_interfaces.value(interface); + if (iface) + { + if ( iface->isAuthorized( iq.from() ) ) + { + + if ( iface->interfaces().contains(method) ) + { + QVariant result = iface->dispatch(method.toLatin1(), + iq.arguments() ); + QXmppRpcResponseIq resultIq; + resultIq.setId(iq.id()); + resultIq.setTo(iq.from()); + resultIq.setFrom(m_stream->configuration().jid()); + resultIq.setValues(QVariantList() << result); + m_stream->sendPacket( resultIq ); + return; + } + else + { + error.setType(QXmppStanza::Error::Cancel); + error.setCondition(QXmppStanza::Error::ItemNotFound); + + } + } + else + { + error.setType(QXmppStanza::Error::Auth); + error.setCondition(QXmppStanza::Error::Forbidden); + } + } + else + { + error.setType(QXmppStanza::Error::Cancel); + error.setCondition(QXmppStanza::Error::ItemNotFound); + } + QXmppRpcErrorIq errorIq; + errorIq.setId(iq.id()); + errorIq.setTo(iq.from()); + errorIq.setFrom(m_stream->configuration().jid()); + errorIq.setQuery( iq ); + errorIq.setError( error ); + m_stream->sendPacket( errorIq ); +} + +QXmppRemoteMethodResult QXmppClient::callRemoteMethod( const QString &jid, + const QString &interface, + const QVariant &arg1, + const QVariant &arg2, + const QVariant &arg3, + const QVariant &arg4, + const QVariant &arg5, + const QVariant &arg6, + const QVariant &arg7, + const QVariant &arg8, + const QVariant &arg9, + const QVariant &arg10 ) +{ + QVariantList args; + if( arg1.isValid() ) args << arg1; + if( arg2.isValid() ) args << arg2; + if( arg3.isValid() ) args << arg3; + if( arg4.isValid() ) args << arg4; + if( arg5.isValid() ) args << arg5; + if( arg6.isValid() ) args << arg6; + if( arg7.isValid() ) args << arg7; + if( arg8.isValid() ) args << arg8; + if( arg9.isValid() ) args << arg9; + if( arg10.isValid() ) args << arg10; + + QXmppRemoteMethod method( jid, interface, args, this ); + connect( m_stream, SIGNAL(rpcCallResponse(QXmppRpcResponseIq)), + &method, SLOT(gotResult(QXmppRpcResponseIq))); + connect( m_stream, SIGNAL(rpcCallError(QXmppRpcErrorIq)), + &method, SLOT(gotError(QXmppRpcErrorIq))); + + + return method.call(); +} + +/// Returns the reference to QXmppArchiveManager, implementation of XEP-0136. +/// http://xmpp.org/extensions/xep-0136.html +/// + +QXmppArchiveManager& QXmppClient::archiveManager() +{ + return *m_archiveManager; +} + +/// Returns the reference to QXmppCallManager, implementation of XEP-0166. +/// http://xmpp.org/extensions/xep-0166.html +/// + +QXmppCallManager& QXmppClient::callManager() +{ + return *m_callManager; +} + +/// Returns the reference to QXmppMucManager, implementation of XEP-0045. +/// http://xmpp.org/extensions/xep-045.html +/// +QXmppMucManager& QXmppClient::mucManager() +{ + return *m_mucManager; +} + +/// Returns the reference to QXmppTransferManager, implementation of: +/// +/// * XEP-0047: In-Band Bytestreams +/// * XEP-0095: Stream Initiation +/// * XEP-0096: SI File Transfer +/// + +QXmppTransferManager& QXmppClient::transferManager() +{ + return *m_transferManager; +} + +/// Returns the QXmppLogger associated with the current QXmppClient. + +QXmppLogger *QXmppClient::logger() +{ + return m_stream->logger(); +} + +/// Sets the QXmppLogger associated with the current QXmppClient. + +void QXmppClient::setLogger(QXmppLogger *logger) +{ + m_stream->setLogger(logger); +} + +/// At connection establishment, send initial presence. + +void QXmppClient::xmppConnected() +{ + sendPacket(m_clientPresence); +} + +// obsolete + +const QXmppPresence& QXmppClient::getClientPresence() const +{ + return m_clientPresence; +} + +QXmppConfiguration& QXmppClient::getConfiguration() +{ + return m_stream->configuration(); +} + +const QXmppConfiguration& QXmppClient::getConfiguration() const +{ + return m_stream->configuration(); +} + +QXmppRosterManager& QXmppClient::getRoster() +{ + return *m_rosterManager; +} + +QAbstractSocket::SocketError QXmppClient::getSocketError() +{ + return m_stream->socketError(); +} + +QXmppVCardManager& QXmppClient::getVCardManager() +{ + return *m_vCardManager; +} + +QXmppStanza::Error::Condition QXmppClient::getXmppStreamError() +{ + return m_stream->xmppStreamError(); +} + +void QXmppClient::setClientPresence(const QString& statusText) +{ + QXmppPresence newPresence = m_clientPresence; + newPresence.status().setStatusText(statusText); + setClientPresence(newPresence); +} + +void QXmppClient::setClientPresence(QXmppPresence::Type presenceType) +{ + QXmppPresence newPresence = m_clientPresence; + newPresence.setType(presenceType); + setClientPresence(newPresence); +} + +void QXmppClient::setClientPresence(QXmppPresence::Status::Type statusType) +{ + QXmppPresence newPresence = m_clientPresence; + if (statusType == QXmppPresence::Status::Offline) + newPresence.setType(QXmppPresence::Unavailable); + else + newPresence.setType(QXmppPresence::Available); + newPresence.status().setType(statusType); + setClientPresence(newPresence); +} + |
