QXmppRpcManager.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * Copyright (C) 2008-2012 The QXmpp developers
  3. *
  4. * Author:
  5. * Jeremy Lainé
  6. *
  7. * Source:
  8. * http://code.google.com/p/qxmpp
  9. *
  10. * This file is a part of QXmpp library.
  11. *
  12. * This library is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU Lesser General Public
  14. * License as published by the Free Software Foundation; either
  15. * version 2.1 of the License, or (at your option) any later version.
  16. *
  17. * This library is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20. * Lesser General Public License for more details.
  21. *
  22. */
  23. #include "QXmppClient.h"
  24. #include "QXmppConstants.h"
  25. #include "QXmppInvokable.h"
  26. #include "QXmppRemoteMethod.h"
  27. #include "QXmppRpcIq.h"
  28. #include "QXmppRpcManager.h"
  29. /// Constructs a QXmppRpcManager.
  30. QXmppRpcManager::QXmppRpcManager()
  31. {
  32. }
  33. /// Adds a local interface which can be queried using RPC.
  34. ///
  35. /// \param interface
  36. void QXmppRpcManager::addInvokableInterface( QXmppInvokable *interface )
  37. {
  38. m_interfaces[ interface->metaObject()->className() ] = interface;
  39. }
  40. /// Invokes a remote interface using RPC.
  41. ///
  42. /// \param iq
  43. void QXmppRpcManager::invokeInterfaceMethod( const QXmppRpcInvokeIq &iq )
  44. {
  45. QXmppStanza::Error error;
  46. const QStringList methodBits = iq.method().split('.');
  47. if (methodBits.size() != 2)
  48. return;
  49. const QString interface = methodBits.first();
  50. const QString method = methodBits.last();
  51. QXmppInvokable *iface = m_interfaces.value(interface);
  52. if (iface)
  53. {
  54. if ( iface->isAuthorized( iq.from() ) )
  55. {
  56. if ( iface->interfaces().contains(method) )
  57. {
  58. QVariant result = iface->dispatch(method.toLatin1(),
  59. iq.arguments() );
  60. QXmppRpcResponseIq resultIq;
  61. resultIq.setId(iq.id());
  62. resultIq.setTo(iq.from());
  63. resultIq.setValues(QVariantList() << result);
  64. client()->sendPacket( resultIq );
  65. return;
  66. }
  67. else
  68. {
  69. error.setType(QXmppStanza::Error::Cancel);
  70. error.setCondition(QXmppStanza::Error::ItemNotFound);
  71. }
  72. }
  73. else
  74. {
  75. error.setType(QXmppStanza::Error::Auth);
  76. error.setCondition(QXmppStanza::Error::Forbidden);
  77. }
  78. }
  79. else
  80. {
  81. error.setType(QXmppStanza::Error::Cancel);
  82. error.setCondition(QXmppStanza::Error::ItemNotFound);
  83. }
  84. QXmppRpcErrorIq errorIq;
  85. errorIq.setId(iq.id());
  86. errorIq.setTo(iq.from());
  87. errorIq.setQuery(iq);
  88. errorIq.setError(error);
  89. client()->sendPacket(errorIq);
  90. }
  91. /// Calls a remote method using RPC with the specified arguments.
  92. ///
  93. /// \note This method blocks until the response is received, and it may
  94. /// cause XMPP stanzas to be lost!
  95. QXmppRemoteMethodResult QXmppRpcManager::callRemoteMethod( const QString &jid,
  96. const QString &interface,
  97. const QVariant &arg1,
  98. const QVariant &arg2,
  99. const QVariant &arg3,
  100. const QVariant &arg4,
  101. const QVariant &arg5,
  102. const QVariant &arg6,
  103. const QVariant &arg7,
  104. const QVariant &arg8,
  105. const QVariant &arg9,
  106. const QVariant &arg10 )
  107. {
  108. QVariantList args;
  109. if( arg1.isValid() ) args << arg1;
  110. if( arg2.isValid() ) args << arg2;
  111. if( arg3.isValid() ) args << arg3;
  112. if( arg4.isValid() ) args << arg4;
  113. if( arg5.isValid() ) args << arg5;
  114. if( arg6.isValid() ) args << arg6;
  115. if( arg7.isValid() ) args << arg7;
  116. if( arg8.isValid() ) args << arg8;
  117. if( arg9.isValid() ) args << arg9;
  118. if( arg10.isValid() ) args << arg10;
  119. QXmppRemoteMethod method( jid, interface, args, client() );
  120. connect(this, SIGNAL(rpcCallResponse(QXmppRpcResponseIq)),
  121. &method, SLOT(gotResult(QXmppRpcResponseIq)));
  122. connect(this, SIGNAL(rpcCallError(QXmppRpcErrorIq)),
  123. &method, SLOT(gotError(QXmppRpcErrorIq)));
  124. return method.call();
  125. }
  126. /// \cond
  127. QStringList QXmppRpcManager::discoveryFeatures() const
  128. {
  129. // XEP-0009: Jabber-RPC
  130. return QStringList() << ns_rpc;
  131. }
  132. QList<QXmppDiscoveryIq::Identity> QXmppRpcManager::discoveryIdentities() const
  133. {
  134. QXmppDiscoveryIq::Identity identity;
  135. identity.setCategory("automation");
  136. identity.setType("rpc");
  137. return QList<QXmppDiscoveryIq::Identity>() << identity;
  138. }
  139. bool QXmppRpcManager::handleStanza(const QDomElement &element)
  140. {
  141. // XEP-0009: Jabber-RPC
  142. if (QXmppRpcInvokeIq::isRpcInvokeIq(element))
  143. {
  144. QXmppRpcInvokeIq rpcIqPacket;
  145. rpcIqPacket.parse(element);
  146. invokeInterfaceMethod(rpcIqPacket);
  147. return true;
  148. }
  149. else if(QXmppRpcResponseIq::isRpcResponseIq(element))
  150. {
  151. QXmppRpcResponseIq rpcResponseIq;
  152. rpcResponseIq.parse(element);
  153. emit rpcCallResponse(rpcResponseIq);
  154. return true;
  155. }
  156. else if(QXmppRpcErrorIq::isRpcErrorIq(element))
  157. {
  158. QXmppRpcErrorIq rpcErrorIq;
  159. rpcErrorIq.parse(element);
  160. emit rpcCallError(rpcErrorIq);
  161. return true;
  162. }
  163. return false;
  164. }
  165. /// \endcond