/src/libtomahawk/sip/SipHandler.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 249 lines · 169 code · 46 blank · 34 comment · 10 complexity · cbe55550022df103ad35317b8b82caf7 MD5 · raw file

  1. /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2. *
  3. * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  4. * Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
  5. * Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
  6. *
  7. * Tomahawk is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * Tomahawk is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include "SipHandler.h"
  21. #include "sip/SipPlugin.h"
  22. #include <QCoreApplication>
  23. #include <QDir>
  24. #include <QPluginLoader>
  25. #ifndef ENABLE_HEADLESS
  26. #include <QMessageBox>
  27. #endif
  28. #include "FuncTimeout.h"
  29. #include "database/Database.h"
  30. #include "database/DatabaseImpl.h"
  31. #include "network/ControlConnection.h"
  32. #include "network/Servent.h"
  33. #include "SourceList.h"
  34. #include "TomahawkSettings.h"
  35. #include "utils/Logger.h"
  36. #include "accounts/AccountManager.h"
  37. #include "config.h"
  38. SipHandler* SipHandler::s_instance = 0;
  39. SipHandler*
  40. SipHandler::instance()
  41. {
  42. if ( !s_instance )
  43. new SipHandler( 0 );
  44. return s_instance;
  45. }
  46. SipHandler::SipHandler( QObject* parent )
  47. : QObject( parent )
  48. {
  49. s_instance = this;
  50. }
  51. SipHandler::~SipHandler()
  52. {
  53. qDebug() << Q_FUNC_INFO;
  54. s_instance = 0;
  55. }
  56. #ifndef ENABLE_HEADLESS
  57. const QPixmap
  58. SipHandler::avatar( const QString& name ) const
  59. {
  60. // qDebug() << Q_FUNC_INFO << "Getting avatar" << name; // << m_usernameAvatars.keys();
  61. if( m_usernameAvatars.contains( name ) )
  62. {
  63. // qDebug() << Q_FUNC_INFO << "Getting avatar and avatar != null ";
  64. Q_ASSERT(!m_usernameAvatars.value( name ).isNull());
  65. return m_usernameAvatars.value( name );
  66. }
  67. else
  68. {
  69. // qDebug() << Q_FUNC_INFO << "Getting avatar and avatar == null :-(";
  70. return QPixmap();
  71. }
  72. }
  73. #endif
  74. const SipInfo
  75. SipHandler::sipInfo( const QString& peerId ) const
  76. {
  77. return m_peersSipInfos.value( peerId );
  78. }
  79. const QString
  80. SipHandler::versionString( const QString& peerId ) const
  81. {
  82. return m_peersSoftwareVersions.value( peerId );
  83. }
  84. void
  85. SipHandler::hookUpPlugin( SipPlugin* sip )
  86. {
  87. QObject::connect( sip, SIGNAL( peerOnline( QString ) ), SLOT( onPeerOnline( QString ) ) );
  88. QObject::connect( sip, SIGNAL( peerOffline( QString ) ), SLOT( onPeerOffline( QString ) ) );
  89. QObject::connect( sip, SIGNAL( msgReceived( QString, QString ) ), SLOT( onMessage( QString, QString ) ) );
  90. QObject::connect( sip, SIGNAL( sipInfoReceived( QString, SipInfo ) ), SLOT( onSipInfo( QString, SipInfo ) ) );
  91. QObject::connect( sip, SIGNAL( softwareVersionReceived( QString, QString ) ), SLOT( onSoftwareVersion( QString, QString ) ) );
  92. QObject::connect( sip, SIGNAL( avatarReceived( QString, QPixmap ) ), SLOT( onAvatarReceived( QString, QPixmap ) ) );
  93. QObject::connect( sip, SIGNAL( avatarReceived( QPixmap ) ), SLOT( onAvatarReceived( QPixmap ) ) );
  94. QObject::connect( sip->account(), SIGNAL( configurationChanged() ), sip, SLOT( configurationChanged() ) );
  95. }
  96. void
  97. SipHandler::onPeerOnline( const QString& peerId )
  98. {
  99. // qDebug() << Q_FUNC_INFO;
  100. tDebug() << "SIP online:" << peerId;
  101. SipPlugin* sip = qobject_cast<SipPlugin*>(sender());
  102. SipInfo info;
  103. if( Servent::instance()->visibleExternally() )
  104. {
  105. QString key = uuid();
  106. ControlConnection* conn = new ControlConnection( Servent::instance(), QString() );
  107. const QString& nodeid = Database::instance()->impl()->dbid();
  108. conn->setName( peerId.left( peerId.indexOf( "/" ) ) );
  109. conn->setId( nodeid );
  110. Servent::instance()->registerOffer( key, conn );
  111. info.setVisible( true );
  112. info.setHost( Servent::instance()->externalAddress() );
  113. info.setPort( Servent::instance()->externalPort() );
  114. info.setKey( key );
  115. info.setUniqname( nodeid );
  116. tDebug() << "Asking them to connect to us:" << info;
  117. }
  118. else
  119. {
  120. info.setVisible( false );
  121. tDebug() << "We are not visible externally:" << info;
  122. }
  123. sip->sendMsg( peerId, info );
  124. }
  125. void
  126. SipHandler::onPeerOffline( const QString& peerId )
  127. {
  128. // qDebug() << Q_FUNC_INFO;
  129. tDebug() << "SIP offline:" << peerId;
  130. }
  131. void
  132. SipHandler::onSipInfo( const QString& peerId, const SipInfo& info )
  133. {
  134. tDebug() << Q_FUNC_INFO << "SIP Message:" << peerId << info;
  135. QString barePeerId = peerId.left( peerId.indexOf( "/" ) );
  136. //FIXME: We should probably be using barePeerId in the connectToPeer call below.
  137. //But, verify this doesn't cause any problems (there is still a uniquename after all)
  138. /*
  139. If only one party is externally visible, connection is obvious
  140. If both are, peer with lowest IP address initiates the connection.
  141. This avoids dupe connections.
  142. */
  143. if ( info.isVisible() )
  144. {
  145. if( !Servent::instance()->visibleExternally() ||
  146. Servent::instance()->externalAddress() < info.host() ||
  147. ( Servent::instance()->externalAddress() == info.host() && Servent::instance()->externalPort() < info.port() ) )
  148. {
  149. tDebug() << "Initiate connection to" << peerId << "at" << info.host();
  150. Servent::instance()->connectToPeer( info.host(),
  151. info.port(),
  152. info.key(),
  153. peerId,
  154. info.uniqname() );
  155. }
  156. else
  157. {
  158. tDebug() << Q_FUNC_INFO << "They should be conecting to us...";
  159. }
  160. }
  161. else
  162. {
  163. tDebug() << Q_FUNC_INFO << "They are not visible, doing nothing atm";
  164. }
  165. m_peersSipInfos.insert( peerId, info );
  166. }
  167. void SipHandler::onSoftwareVersion( const QString& peerId, const QString& versionString )
  168. {
  169. m_peersSoftwareVersions.insert( peerId, versionString );
  170. }
  171. void
  172. SipHandler::onMessage( const QString& from, const QString& msg )
  173. {
  174. qDebug() << Q_FUNC_INFO << from << msg;
  175. }
  176. #ifndef ENABLE_HEADLESS
  177. void
  178. SipHandler::onAvatarReceived( const QString& from, const QPixmap& avatar )
  179. {
  180. // qDebug() << Q_FUNC_INFO << "setting avatar on source for" << from;
  181. if ( avatar.isNull() )
  182. {
  183. return;
  184. }
  185. m_usernameAvatars.insert( from, avatar );
  186. ControlConnection *conn = Servent::instance()->lookupControlConnection( from );
  187. if( conn )
  188. {
  189. Tomahawk::source_ptr source = conn->source();
  190. if( source )
  191. {
  192. // qDebug() << Q_FUNC_INFO << from << "got source, setting avatar on source:" << source->friendlyName();
  193. source->setAvatar( avatar );
  194. }
  195. }
  196. }
  197. void
  198. SipHandler::onAvatarReceived( const QPixmap& avatar )
  199. {
  200. // qDebug() << Q_FUNC_INFO << "Set own avatar on MyCollection";
  201. SourceList::instance()->getLocal()->setAvatar( avatar );
  202. }
  203. #endif