diff options
| author | Ian Geiser <ian.geiser@gmail.com> | 2009-11-11 11:09:28 +0000 |
|---|---|---|
| committer | Ian Geiser <ian.geiser@gmail.com> | 2009-11-11 11:09:28 +0000 |
| commit | d9745efcd24e547ba0185732bfc9b0c9f931162e (patch) | |
| tree | c66bc1c52329ea1a21771b74845009a9a0addd70 /source | |
| parent | 5b0870ddaac421af2639058648a218c7061cdd6f (diff) | |
| download | qxmpp-d9745efcd24e547ba0185732bfc9b0c9f931162e.tar.gz | |
This is the rest of XEP-009. This needs some cleanup and testing still. I am not happy with the implementation, but I am happy with the interface on QXmppClient.
Diffstat (limited to 'source')
| -rw-r--r-- | source/QXmppClient.cpp | 36 | ||||
| -rw-r--r-- | source/QXmppClient.h | 14 | ||||
| -rw-r--r-- | source/QXmppInvokable.h | 6 | ||||
| -rw-r--r-- | source/QXmppRemoteMethod.cpp | 51 | ||||
| -rw-r--r-- | source/QXmppRemoteMethod.h | 41 | ||||
| -rw-r--r-- | source/QXmppStream.cpp | 12 | ||||
| -rw-r--r-- | source/QXmppStream.h | 4 | ||||
| -rw-r--r-- | source/source.pro | 6 |
8 files changed, 166 insertions, 4 deletions
diff --git a/source/QXmppClient.cpp b/source/QXmppClient.cpp index c8b16041..21c96d23 100644 --- a/source/QXmppClient.cpp +++ b/source/QXmppClient.cpp @@ -30,6 +30,7 @@ #include "QXmppIbbTransferManager.h" #include "QXmppInvokable.h" #include "QXmppRpcIq.h" +#include "QXmppRemoteMethod.h" #include "QXmppUtils.h" /// Creates a QXmppClient object. @@ -436,3 +437,38 @@ QXmppIbbTransferManager* QXmppClient::getIbbTransferManager() const { return m_ibbTransferManager; } + +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(); +} diff --git a/source/QXmppClient.h b/source/QXmppClient.h index 06d2b7b6..0503195b 100644 --- a/source/QXmppClient.h +++ b/source/QXmppClient.h @@ -59,6 +59,7 @@ class QXmppInvokable; class QXmppRpcInvokeIq; class QXmppRemoteMethod; class QXmppIbbTransferManager; +class QXmppRemoteMethodResult; class QXmppClient : public QObject { @@ -156,8 +157,21 @@ signals: public: QAbstractSocket::SocketError getSocketError(); + void addInvokableInterface( QXmppInvokable *interface ); void invokeInterfaceMethod( const QXmppRpcInvokeIq &iq ); + QXmppRemoteMethodResult callRemoteMethod( const QString &jid, + const QString &interface, + const QVariant &arg1 = QVariant(), + const QVariant &arg2 = QVariant(), + const QVariant &arg3 = QVariant(), + const QVariant &arg4 = QVariant(), + const QVariant &arg5 = QVariant(), + const QVariant &arg6 = QVariant(), + const QVariant &arg7 = QVariant(), + const QVariant &arg8 = QVariant(), + const QVariant &arg9 = QVariant(), + const QVariant &arg10 = QVariant() ); // QXmppStanza::Error getXmppStreamError(); diff --git a/source/QXmppInvokable.h b/source/QXmppInvokable.h index c7f9c687..a55299a3 100644 --- a/source/QXmppInvokable.h +++ b/source/QXmppInvokable.h @@ -52,9 +52,15 @@ public: */ static QList<QByteArray> paramTypes( const QList<QVariant> ¶ms ); + /** + * Reimplement this method to return a true if the invoking JID is allowed to execute the method. + */ virtual bool isAuthorized( const QString &jid ) const = 0; public slots: + /** + * This provides a list of interfaces for introspection of the presented interface. + */ QStringList interfaces() const; private: diff --git a/source/QXmppRemoteMethod.cpp b/source/QXmppRemoteMethod.cpp new file mode 100644 index 00000000..835a67bf --- /dev/null +++ b/source/QXmppRemoteMethod.cpp @@ -0,0 +1,51 @@ +#include "QXmppRemoteMethod.h" +#include "QXmppClient.h" +#include "QXmppUtils.h" +#include "QXmppConfiguration.h" + +#include <QEventLoop> +#include <QTimer> + +QXmppRemoteMethod::QXmppRemoteMethod(const QString &jid, const QString &method, const QVariantList &args, QXmppClient *client) : + QObject(client), m_client(client) +{ + m_payload.setId( generateStanzaHash() ); + m_payload.setTo( jid ); + m_payload.setFrom( client->getConfiguration().getJid() ); + m_payload.setInterface( method.section('.', 0 ) ); + m_payload.setMethod( method.section('.', 1) ); + m_payload.setPayload( args ); +} + +QXmppRemoteMethodResult QXmppRemoteMethod::call( ) +{ + QEventLoop loop(this); + connect( this, SIGNAL(callDone()), &loop, SLOT(quit())); + QTimer::singleShot(30000,&loop, SLOT(quit())); // Timeout incase the other end hangs... + + m_client->sendPacket( m_payload ); + + loop.exec( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents ); + return m_result; +} + +void QXmppRemoteMethod::gotError( const QXmppRpcErrorIq &iq ) +{ + if ( iq.getId() == m_payload.getId() ) + { + m_result.hasError = true; + m_result.errorMessage = iq.getError().getText(); + m_result.code = iq.getError().getType(); + emit callDone(); + } +} + +void QXmppRemoteMethod::gotResult( const QXmppRpcResponseIq &iq ) +{ + if ( iq.getId() == m_payload.getId() ) + { + m_result.hasError = false; + m_result.result = iq.getPayload(); + emit callDone(); + } +} diff --git a/source/QXmppRemoteMethod.h b/source/QXmppRemoteMethod.h new file mode 100644 index 00000000..b1a8c00d --- /dev/null +++ b/source/QXmppRemoteMethod.h @@ -0,0 +1,41 @@ +#ifndef QXMPPREMOTEMETHOD_H +#define QXMPPREMOTEMETHOD_H + +#include <QObject> +#include <QVariant> + +#include "QXmppRpcIq.h" + +class QXmppClient; +class QXmppStream; + +struct QXmppRemoteMethodResult { + QXmppRemoteMethodResult() : hasError(false), code(0) { } + bool hasError; + int code; + QString errorMessage; + QVariant result; +}; + +class QXmppRemoteMethod : public QObject +{ + Q_OBJECT +public: + QXmppRemoteMethod(const QString &jid, const QString &method, const QVariantList &args, QXmppClient *client); + QXmppRemoteMethodResult call( ); + +private slots: + void gotError( const QXmppRpcErrorIq &iq ); + void gotResult( const QXmppRpcResponseIq &iq ); + +signals: + void callDone(); + +private: + QXmppRpcInvokeIq m_payload; + QXmppClient *m_client; + QXmppRemoteMethodResult m_result; + +}; + +#endif // QXMPPREMOTEMETHOD_H diff --git a/source/QXmppStream.cpp b/source/QXmppStream.cpp index 307ad543..0e18b404 100644 --- a/source/QXmppStream.cpp +++ b/source/QXmppStream.cpp @@ -431,6 +431,18 @@ void QXmppStream::parser(const QByteArray& data) rpcIqPacket.parse(nodeRecv); m_client->invokeInterfaceMethod(rpcIqPacket); } + else if ( QXmppRpcResponseIq::isRpcResponseIq( nodeRecv ) ) + { + QXmppRpcResponseIq rpcResponseIq; + rpcResponseIq.parse(nodeRecv); + emit rpcCallResponse( rpcResponseIq ); + } + else if ( QXmppRpcErrorIq::isRpcErrorIq( nodeRecv ) ) + { + QXmppRpcErrorIq rpcErrorIq; + rpcErrorIq.parse(nodeRecv); + emit rpcCallError( rpcErrorIq ); + } else if(id == m_sessionId) { // get back add configuration whether to send diff --git a/source/QXmppStream.h b/source/QXmppStream.h index 8936abe3..d31e7a27 100644 --- a/source/QXmppStream.h +++ b/source/QXmppStream.h @@ -85,8 +85,8 @@ signals: void rosterRequestIqReceived(const QXmppRosterIq&); void vCardIqReceived(const QXmppVCard&); - void rpcRequestFinished( const QString &id, const QXmppRpcResponseIq& result ); - void rpcRequestError( const QString &id, const QXmppRpcErrorIq& err ); + void rpcCallResponse(const QXmppRpcResponseIq& result ); + void rpcCallError(const QXmppRpcErrorIq& err ); private slots: void socketHostFound(); diff --git a/source/source.pro b/source/source.pro index a61972ed..6866e87b 100644 --- a/source/source.pro +++ b/source/source.pro @@ -39,7 +39,8 @@ HEADERS += QXmppUtils.h \ QXmppIbbTransferManager.h \ xmlrpc.h \ QXmppInvokable.h \ - QXmppRpcIq.h + QXmppRpcIq.h \ + QXmppRemoteMethod.h # Source files SOURCES += QXmppUtils.cpp \ @@ -68,4 +69,5 @@ SOURCES += QXmppUtils.cpp \ QXmppIbbTransferManager.cpp \ xmlrpc.cpp \ QXmppInvokable.cpp \ - QXmppRpcIq.cpp + QXmppRpcIq.cpp \ + QXmppRemoteMethod.cpp |
