mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-03-23 09:19:41 +01:00
Refactor peer announcement and disable Twitter until it's ported
This commit is contained in:
parent
54d0f23a44
commit
07887a4ade
@ -27,7 +27,7 @@
|
||||
|
||||
#include "accounts/AccountManager.h"
|
||||
#include "network/Servent.h"
|
||||
#include "sip/SipHandler.h"
|
||||
#include "sip/PeerInfo.h"
|
||||
#include "utils/TomahawkUtilsGui.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "infosystem/InfoSystem.h"
|
||||
@ -109,10 +109,7 @@ DiagnosticsDialog::updateLogView()
|
||||
|
||||
connect( account, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), SLOT( updateLogView() ), Qt::UniqueConnection );
|
||||
connect( account, SIGNAL( error( int, QString ) ), SLOT( updateLogView() ), Qt::UniqueConnection );
|
||||
connect( account->sipPlugin(), SIGNAL( peerOnline( QString ) ), SLOT( updateLogView() ), Qt::UniqueConnection );
|
||||
connect( account->sipPlugin(), SIGNAL( peerOffline( QString ) ), SLOT( updateLogView() ), Qt::UniqueConnection );
|
||||
connect( account->sipPlugin(), SIGNAL( sipInfoReceived( QString, SipInfo ) ), SLOT( updateLogView() ), Qt::UniqueConnection );
|
||||
connect( account->sipPlugin(), SIGNAL( softwareVersionReceived( QString, QString ) ), SLOT( updateLogView() ), Qt::UniqueConnection );
|
||||
connect( account->sipPlugin(), SIGNAL( peerOnline( Tomahawk::peerinfo_ptr ) ), SLOT( updateLogView() ), Qt::UniqueConnection );
|
||||
|
||||
log.append( accountLog( account ) + "\n" );
|
||||
}
|
||||
@ -163,15 +160,16 @@ DiagnosticsDialog::accountLog( Tomahawk::Accounts::Account* account )
|
||||
.arg( stateString )
|
||||
);
|
||||
|
||||
foreach( const QString& peerId, account->sipPlugin()->peersOnline() )
|
||||
foreach( const Tomahawk::peerinfo_ptr& peerInfo, account->sipPlugin()->peersOnline() )
|
||||
{
|
||||
QString versionString = SipHandler::instance()->versionString( peerId );
|
||||
SipInfo sipInfo = SipHandler::instance()->sipInfo( peerId );
|
||||
QString peerId = peerInfo->id();
|
||||
QString versionString = peerInfo->versionString();
|
||||
SipInfo sipInfo = peerInfo->sipInfo();
|
||||
if ( !sipInfo.isValid() )
|
||||
{
|
||||
accountInfo.append(
|
||||
QString(" %1: %2 %3" /*"(%4)"*/ "\n")
|
||||
.arg( peerId )
|
||||
QString(" %1: %2 %3" /*"(%4)"*/)
|
||||
.arg( peerInfo->id() )
|
||||
.arg( "sipinfo invalid" )
|
||||
.arg( versionString )
|
||||
// .arg( connected ? "connected" : "not connected")
|
||||
@ -180,7 +178,7 @@ DiagnosticsDialog::accountLog( Tomahawk::Accounts::Account* account )
|
||||
else if ( sipInfo.isVisible() )
|
||||
{
|
||||
accountInfo.append(
|
||||
QString(" %1: %2:%3 %4" /*" (%5)"*/ "\n")
|
||||
QString(" %1: %2:%3 %4" /*" (%5)"*/)
|
||||
.arg( peerId )
|
||||
.arg( sipInfo.host() )
|
||||
.arg( sipInfo.port() )
|
||||
@ -191,14 +189,29 @@ DiagnosticsDialog::accountLog( Tomahawk::Accounts::Account* account )
|
||||
else
|
||||
{
|
||||
accountInfo.append(
|
||||
QString(" %1: visible: false %2" /*" (%3)"*/ "\n")
|
||||
QString(" %1: visible: false %2" /*" (%3)"*/)
|
||||
.arg( peerId )
|
||||
.arg( versionString )
|
||||
// .arg( connected ? "connected" : "not connected")
|
||||
);
|
||||
}
|
||||
|
||||
if( sipInfo.isValid() )
|
||||
{
|
||||
if( !Servent::instance()->visibleExternally() ||
|
||||
Servent::instance()->externalAddress() < sipInfo.host() ||
|
||||
( Servent::instance()->externalAddress() == sipInfo.host() && Servent::instance()->externalPort() < sipInfo.port() ) )
|
||||
{
|
||||
accountInfo.append(" (outbound)");
|
||||
}
|
||||
else
|
||||
{
|
||||
accountInfo.append(" (inbound)");
|
||||
}
|
||||
}
|
||||
accountInfo.append("\n");
|
||||
}
|
||||
accountInfo.append( "\n" );
|
||||
|
||||
return accountInfo;
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ IF( JREEN_FOUND )
|
||||
add_subdirectory( xmpp )
|
||||
ENDIF()
|
||||
|
||||
IF( QTWEETLIB_FOUND AND BUILD_GUI )
|
||||
ADD_SUBDIRECTORY( twitter )
|
||||
ENDIF()
|
||||
|
||||
# IF( QTWEETLIB_FOUND AND BUILD_GUI )
|
||||
# ADD_SUBDIRECTORY( twitter )
|
||||
# ENDIF()
|
||||
#
|
||||
ADD_SUBDIRECTORY( zeroconf )
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "accounts/AccountManager.h"
|
||||
#include "TomahawkSettings.h"
|
||||
#include "utils/TomahawkUtilsGui.h"
|
||||
#include "sip/PeerInfo.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "TomahawkVersion.h"
|
||||
@ -432,9 +433,9 @@ XmppSipPlugin::errorMessage( Jreen::Client::DisconnectReason reason )
|
||||
|
||||
|
||||
void
|
||||
XmppSipPlugin::sendMsg( const QString& to, const SipInfo& info )
|
||||
XmppSipPlugin::sendSipInfo( const Tomahawk::peerinfo_ptr& receiver, const SipInfo& info )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << to << info;
|
||||
qDebug() << Q_FUNC_INFO << receiver << info;
|
||||
|
||||
if ( !m_client )
|
||||
return;
|
||||
@ -447,8 +448,8 @@ XmppSipPlugin::sendMsg( const QString& to, const SipInfo& info )
|
||||
else
|
||||
sipMessage = new TomahawkXmppMessage();
|
||||
|
||||
qDebug() << "Send sip messsage to" << to;
|
||||
Jreen::IQ iq( Jreen::IQ::Set, to );
|
||||
qDebug() << "Send sip messsage to" << receiver;
|
||||
Jreen::IQ iq( Jreen::IQ::Set, receiver->id() );
|
||||
iq.addExtension( sipMessage );
|
||||
Jreen::IQReply *reply = m_client->send( iq );
|
||||
reply->setData( SipMessageSent );
|
||||
@ -689,13 +690,10 @@ XmppSipPlugin::onNewMessage( const Jreen::Message& message )
|
||||
|
||||
// this is not a sip message, so we send it directly through the client
|
||||
m_client->send( Jreen::Message ( Jreen::Message::Error, Jreen::JID( to ), response) );
|
||||
|
||||
emit msgReceived( from, msg );
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "From:" << message.from().full() << ":" << message.body();
|
||||
emit sipInfoReceived( from, info );
|
||||
}
|
||||
|
||||
|
||||
@ -864,7 +862,11 @@ XmppSipPlugin::onNewIq( const Jreen::IQ& iq )
|
||||
{
|
||||
QString versionString = QString( "%1 %2 %3" ).arg( softwareVersion->name(), softwareVersion->os(), softwareVersion->version() );
|
||||
qDebug() << Q_FUNC_INFO << "Received software version for" << iq.from().full() << ":" << versionString;
|
||||
emit softwareVersionReceived( iq.from().full(), versionString );
|
||||
Tomahawk::peerinfo_ptr peerInfo = PeerInfo::get( this, iq.from().full() );
|
||||
if( !peerInfo.isNull() )
|
||||
{
|
||||
peerInfo->setVersionString( versionString );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( context == RequestedDisco )
|
||||
@ -902,7 +904,13 @@ XmppSipPlugin::onNewIq( const Jreen::IQ& iq )
|
||||
Q_ASSERT( info.isValid() );
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "From:" << iq.from().full() << ":" << info;
|
||||
emit sipInfoReceived( iq.from().full(), info );
|
||||
Tomahawk::peerinfo_ptr peerInfo = PeerInfo::get( this, iq.from().full() );
|
||||
if( peerInfo.isNull() )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "no valid peerInfo for " << iq.from().full();
|
||||
return;
|
||||
}
|
||||
peerInfo->setSipInfo( info );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -930,14 +938,23 @@ XmppSipPlugin::handlePeerStatus( const Jreen::JID& jid, Jreen::Presence::Type pr
|
||||
{
|
||||
QString fulljid = jid.full();
|
||||
|
||||
if(fulljid.contains("public.talk.google.com"))
|
||||
return;
|
||||
|
||||
// "going offline" event
|
||||
if ( !presenceMeansOnline( presenceType ) &&
|
||||
( !m_peers.contains( jid ) || presenceMeansOnline( m_peers.value( jid ) ) ) )
|
||||
{
|
||||
m_peers[ jid ] = presenceType;
|
||||
qDebug() << Q_FUNC_INFO << "* Peer goes offline:" << fulljid;
|
||||
|
||||
emit peerOffline( fulljid );
|
||||
m_peers[ jid ] = presenceType;
|
||||
|
||||
Tomahawk::peerinfo_ptr peerInfo = PeerInfo::get( this, fulljid );
|
||||
if( !peerInfo.isNull() )
|
||||
{
|
||||
peerInfo->setStatus( PeerInfo::Offline );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -945,10 +962,12 @@ XmppSipPlugin::handlePeerStatus( const Jreen::JID& jid, Jreen::Presence::Type pr
|
||||
if ( presenceMeansOnline( presenceType ) &&
|
||||
( !m_peers.contains( jid ) || !presenceMeansOnline( m_peers.value( jid ) ) ) )
|
||||
{
|
||||
m_peers[ jid ] = presenceType;
|
||||
qDebug() << Q_FUNC_INFO << "* Peer goes online:" << fulljid;
|
||||
|
||||
emit peerOnline( fulljid );
|
||||
m_peers[ jid ] = presenceType;
|
||||
|
||||
Tomahawk::peerinfo_ptr peerInfo = PeerInfo::get( this, fulljid, PeerInfo::AutoCreate );
|
||||
peerInfo->setStatus( PeerInfo::Online );
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
if ( !m_avatarManager->avatar( jid.bare() ).isNull() )
|
||||
@ -986,16 +1005,17 @@ XmppSipPlugin::onNewAvatar( const QString& jid )
|
||||
{
|
||||
if ( peer.bare() == jid )
|
||||
{
|
||||
emit avatarReceived( peer.full(), m_avatarManager->avatar( jid ) );
|
||||
Tomahawk::peerinfo_ptr peerInfo = PeerInfo::get( this, peer.full() );
|
||||
if( !peerInfo.isNull() )
|
||||
peerInfo->setAvatar( m_avatarManager->avatar( jid ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( jid == m_client->jid().bare() )
|
||||
{
|
||||
// own avatar
|
||||
emit avatarReceived( m_avatarManager->avatar( jid ) );
|
||||
else
|
||||
// someone else's avatar
|
||||
emit avatarReceived( jid, m_avatarManager->avatar( jid ) );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -88,9 +88,10 @@ public slots:
|
||||
virtual void disconnectPlugin();
|
||||
virtual void checkSettings();
|
||||
virtual void configurationChanged();
|
||||
virtual void sendMsg( const QString& peerId, const SipInfo& info );
|
||||
virtual void addContact( const QString& peerId, const QString& msg = QString() );
|
||||
|
||||
virtual void sendSipInfo( const Tomahawk::peerinfo_ptr& receiver, const SipInfo& info );
|
||||
|
||||
void showAddFriendDialog();
|
||||
void publishTune( const QUrl& url, const Tomahawk::InfoSystem::InfoStringHash& trackInfo );
|
||||
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "utils/Logger.h"
|
||||
#include "ZeroconfAccount.h"
|
||||
#include "Source.h"
|
||||
#include "sip/PeerInfo.h"
|
||||
#include "network/ControlConnection.h"
|
||||
|
||||
#include <QtPlugin>
|
||||
#include <QTimer>
|
||||
@ -56,6 +58,12 @@ ZeroconfPlugin::accountName() const
|
||||
return QString( MYNAME );
|
||||
}
|
||||
|
||||
const QString
|
||||
ZeroconfPlugin::serviceName() const
|
||||
{
|
||||
return QString( MYNAME );
|
||||
}
|
||||
|
||||
const QString
|
||||
ZeroconfPlugin::friendlyName() const
|
||||
{
|
||||
@ -82,8 +90,7 @@ ZeroconfPlugin::connectPlugin()
|
||||
|
||||
foreach( const QStringList& nodeSet, m_cachedNodes )
|
||||
{
|
||||
if ( !Servent::instance()->connectedToSession( nodeSet[3] ) )
|
||||
Servent::instance()->connectToPeer( nodeSet[0], nodeSet[1].toInt(), "whitelist", nodeSet[2], nodeSet[3] );
|
||||
lanHostFound( nodeSet[0], nodeSet[1].toInt(), nodeSet[2], nodeSet[3]);
|
||||
}
|
||||
m_cachedNodes.clear();
|
||||
|
||||
@ -135,9 +142,18 @@ ZeroconfPlugin::lanHostFound( const QString& host, int port, const QString& name
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !Servent::instance()->connectedToSession( nodeid ) )
|
||||
Servent::instance()->connectToPeer( host, port, "whitelist", name, nodeid );
|
||||
else
|
||||
qDebug() << "Already connected to" << host;
|
||||
SipInfo sipInfo;
|
||||
sipInfo.setHost( host );
|
||||
sipInfo.setPort( port );
|
||||
sipInfo.setUniqname( nodeid );
|
||||
sipInfo.setKey( "whitelist" );
|
||||
sipInfo.setVisible( true );
|
||||
|
||||
Tomahawk::peerinfo_ptr peerInfo = Tomahawk::PeerInfo::get( this, host, Tomahawk::PeerInfo::AutoCreate );
|
||||
peerInfo->setSipInfo( sipInfo );
|
||||
peerInfo->setFriendlyName( name );
|
||||
peerInfo->setType( PeerInfo::Local );
|
||||
peerInfo->setStatus( PeerInfo::Online );
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
#define MYNAME "Local Network"
|
||||
#define MYNAME "zeroconf"
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
@ -50,6 +50,7 @@ public:
|
||||
virtual const QString name() const;
|
||||
virtual const QString friendlyName() const;
|
||||
virtual const QString accountName() const;
|
||||
virtual const QString serviceName() const;
|
||||
virtual Account::ConnectionState connectionState() const;
|
||||
virtual bool isValid() const { return true; }
|
||||
#ifndef ENABLE_HEADLESS
|
||||
@ -64,7 +65,7 @@ public slots:
|
||||
|
||||
void advertise();
|
||||
|
||||
void sendMsg( const QString&, const SipInfo& ) {}
|
||||
void sendSipInfo( const Tomahawk::peerinfo_ptr&, const SipInfo& ) {}
|
||||
void broadcastMsg( const QString & ) {}
|
||||
void addContact( const QString &, const QString& ) {}
|
||||
|
||||
|
@ -212,8 +212,8 @@ list(APPEND libSources
|
||||
accounts/lastfm/LastFmInfoPlugin.cpp
|
||||
|
||||
sip/SipPlugin.cpp
|
||||
sip/SipHandler.cpp
|
||||
sip/SipInfo.cpp
|
||||
sip/PeerInfo.cpp
|
||||
|
||||
audio/AudioEngine.cpp
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "database/Database.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QBuffer>
|
||||
|
||||
#include "utils/TomahawkCache.h"
|
||||
#include "database/DatabaseCommand_SocialAction.h"
|
||||
@ -42,6 +41,7 @@
|
||||
#endif
|
||||
|
||||
#include "utils/Logger.h"
|
||||
#include "sip/PeerInfo.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@ -53,12 +53,9 @@ Source::Source( int id, const QString& username )
|
||||
, m_username( username )
|
||||
, m_id( id )
|
||||
, m_updateIndexWhenSynced( false )
|
||||
, m_avatarUpdated( true )
|
||||
, m_state( DBSyncConnection::UNKNOWN )
|
||||
, m_cc( 0 )
|
||||
, m_commandCount( 0 )
|
||||
, m_avatar( 0 )
|
||||
, m_fancyAvatar( 0 )
|
||||
{
|
||||
m_scrubFriendlyName = qApp->arguments().contains( "--demo" );
|
||||
|
||||
@ -79,8 +76,6 @@ Source::Source( int id, const QString& username )
|
||||
Source::~Source()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << friendlyName();
|
||||
delete m_avatar;
|
||||
delete m_fancyAvatar;
|
||||
}
|
||||
|
||||
|
||||
@ -129,80 +124,27 @@ Source::friendlyName() const
|
||||
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
void
|
||||
Source::setAvatar( const QPixmap& avatar )
|
||||
{
|
||||
QByteArray ba;
|
||||
QBuffer buffer( &ba );
|
||||
buffer.open( QIODevice::WriteOnly );
|
||||
avatar.save( &buffer, "PNG" );
|
||||
|
||||
// Check if the avatar is different by comparing a hash of the first 4096 bytes
|
||||
const QByteArray hash = QCryptographicHash::hash( ba.left( 4096 ), QCryptographicHash::Sha1 );
|
||||
if ( m_avatarHash == hash )
|
||||
return;
|
||||
else
|
||||
m_avatarHash = hash;
|
||||
|
||||
delete m_avatar;
|
||||
m_avatar = new QPixmap( avatar );
|
||||
m_fancyAvatar = 0;
|
||||
|
||||
TomahawkUtils::Cache::instance()->putData( "Sources", 7776000000 /* 90 days */, m_username, ba );
|
||||
m_avatarUpdated = true;
|
||||
}
|
||||
|
||||
|
||||
QPixmap
|
||||
Source::avatar( TomahawkUtils::ImageMode style, const QSize& size )
|
||||
{
|
||||
if ( !m_avatar && m_avatarUpdated )
|
||||
if( controlConnection() )
|
||||
{
|
||||
m_avatar = new QPixmap();
|
||||
QByteArray ba = TomahawkUtils::Cache::instance()->getData( "Sources", m_username ).toByteArray();
|
||||
|
||||
if ( ba.count() )
|
||||
m_avatar->loadFromData( ba );
|
||||
|
||||
if ( m_avatar->isNull() )
|
||||
// tLog() << "****************************************************************************************";
|
||||
// tLog() << controlConnection()->peerInfos().count() << "PEERS FOR " << friendlyName();
|
||||
QPixmap result;
|
||||
foreach( const peerinfo_ptr& peerInfo, controlConnection()->peerInfos() )
|
||||
{
|
||||
delete m_avatar;
|
||||
m_avatar = 0;
|
||||
// peerInfoDebug(peerInfo);
|
||||
if( !peerInfo.isNull() && !peerInfo->avatar( style, size ).isNull() )
|
||||
{
|
||||
result = peerInfo->avatar( style, size );
|
||||
}
|
||||
}
|
||||
m_avatarUpdated = false;
|
||||
// tLog() << "****************************************************************************************";
|
||||
return result;
|
||||
}
|
||||
|
||||
if ( style == TomahawkUtils::RoundedCorners && m_avatar && !m_avatar->isNull() && !m_fancyAvatar )
|
||||
m_fancyAvatar = new QPixmap( TomahawkUtils::createRoundedImage( QPixmap( *m_avatar ), QSize( 0, 0 ) ) );
|
||||
|
||||
QPixmap pixmap;
|
||||
if ( style == TomahawkUtils::RoundedCorners && m_fancyAvatar )
|
||||
{
|
||||
pixmap = *m_fancyAvatar;
|
||||
}
|
||||
else if ( m_avatar )
|
||||
{
|
||||
pixmap = *m_avatar;
|
||||
}
|
||||
|
||||
if ( !pixmap.isNull() && !size.isEmpty() )
|
||||
{
|
||||
if ( m_coverCache[ style ].contains( size.width() ) )
|
||||
{
|
||||
return m_coverCache[ style ].value( size.width() );
|
||||
}
|
||||
|
||||
QPixmap scaledCover;
|
||||
scaledCover = pixmap.scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
QHash< int, QPixmap > innerCache = m_coverCache[ style ];
|
||||
innerCache.insert( size.width(), scaledCover );
|
||||
m_coverCache[ style ] = innerCache;
|
||||
|
||||
return scaledCover;
|
||||
}
|
||||
|
||||
return pixmap;
|
||||
return QPixmap();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -66,7 +66,6 @@ public:
|
||||
void setFriendlyName( const QString& fname );
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
void setAvatar( const QPixmap& avatar );
|
||||
QPixmap avatar( TomahawkUtils::ImageMode style = TomahawkUtils::Original, const QSize& size = QSize() );
|
||||
#endif
|
||||
|
||||
@ -147,7 +146,6 @@ private:
|
||||
int m_id;
|
||||
bool m_scrubFriendlyName;
|
||||
bool m_updateIndexWhenSynced;
|
||||
bool m_avatarUpdated;
|
||||
|
||||
Tomahawk::query_ptr m_currentTrack;
|
||||
QString m_textStatus;
|
||||
@ -160,11 +158,6 @@ private:
|
||||
QString m_lastCmdGuid;
|
||||
mutable QMutex m_cmdMutex;
|
||||
|
||||
mutable QPixmap* m_avatar;
|
||||
mutable QPixmap* m_fancyAvatar;
|
||||
mutable QByteArray m_avatarHash;
|
||||
mutable QHash< TomahawkUtils::ImageMode, QHash< int, QPixmap > > m_coverCache;
|
||||
|
||||
Tomahawk::playlistinterface_ptr m_playlistInterface;
|
||||
};
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include <QDir>
|
||||
|
||||
#include "Source.h"
|
||||
#include "sip/SipHandler.h"
|
||||
#include "PlaylistInterface.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
|
@ -46,6 +46,7 @@ namespace Tomahawk
|
||||
class Source;
|
||||
class DynamicControl;
|
||||
class GeneratorInterface;
|
||||
class PeerInfo;
|
||||
|
||||
typedef QSharedPointer<Collection> collection_ptr;
|
||||
typedef QSharedPointer<Playlist> playlist_ptr;
|
||||
@ -57,6 +58,7 @@ namespace Tomahawk
|
||||
typedef QSharedPointer<Source> source_ptr;
|
||||
typedef QSharedPointer<Artist> artist_ptr;
|
||||
typedef QSharedPointer<Album> album_ptr;
|
||||
typedef QSharedPointer<PeerInfo> peerinfo_ptr;
|
||||
|
||||
typedef QSharedPointer<DynamicControl> dyncontrol_ptr;
|
||||
typedef QSharedPointer<GeneratorInterface> geninterface_ptr;
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include <QtCore/QPluginLoader>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QTimer>
|
||||
#include <sip/SipHandler.h>
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
@ -58,8 +57,6 @@ AccountManager::AccountManager( QObject *parent )
|
||||
|
||||
AccountManager::~AccountManager()
|
||||
{
|
||||
delete SipHandler::instance();
|
||||
|
||||
disconnectAll();
|
||||
qDeleteAll( m_accounts );
|
||||
qDeleteAll( m_accountFactories );
|
||||
@ -397,6 +394,18 @@ AccountManager::addAccountFactory( AccountFactory* factory )
|
||||
}
|
||||
|
||||
|
||||
Account*
|
||||
AccountManager::zeroconfAccount() const
|
||||
{
|
||||
foreach( Account* account, accounts() )
|
||||
{
|
||||
if( account->sipPlugin() && account->sipPlugin()->serviceName() == "zeroconf" )
|
||||
return account;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
AccountManager::hookupAccount( Account* account ) const
|
||||
{
|
||||
@ -411,9 +420,6 @@ AccountManager::hookupAndEnable( Account* account, bool startup )
|
||||
Q_UNUSED( startup );
|
||||
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
||||
SipPlugin* p = account->sipPlugin();
|
||||
if ( p )
|
||||
SipHandler::instance()->hookUpPlugin( p );
|
||||
|
||||
hookupAccount( account );
|
||||
if ( account->enabled() )
|
||||
|
@ -80,6 +80,8 @@ public:
|
||||
|
||||
void addAccountFactory( AccountFactory* factory );
|
||||
|
||||
Account* zeroconfAccount() const;
|
||||
|
||||
public slots:
|
||||
void connectAll();
|
||||
void disconnectAll();
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "SourceList.h"
|
||||
#include "network/DbSyncConnection.h"
|
||||
#include "network/Servent.h"
|
||||
#include "sip/SipHandler.h"
|
||||
#include "sip/PeerInfo.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#define TCP_TIMEOUT 600
|
||||
@ -34,7 +34,7 @@
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
ControlConnection::ControlConnection( Servent* parent, const QHostAddress &ha )
|
||||
ControlConnection::ControlConnection( Servent* parent )
|
||||
: Connection( parent )
|
||||
, m_dbsyncconn( 0 )
|
||||
, m_registered( false )
|
||||
@ -48,38 +48,6 @@ ControlConnection::ControlConnection( Servent* parent, const QHostAddress &ha )
|
||||
|
||||
this->setMsgProcessorModeIn( MsgProcessor::UNCOMPRESS_ALL | MsgProcessor::PARSE_JSON );
|
||||
this->setMsgProcessorModeOut( MsgProcessor::COMPRESS_IF_LARGE );
|
||||
|
||||
m_peerIpAddress = ha;
|
||||
}
|
||||
|
||||
|
||||
ControlConnection::ControlConnection( Servent* parent, const QString &ha )
|
||||
: Connection( parent )
|
||||
, m_dbsyncconn( 0 )
|
||||
, m_registered( false )
|
||||
, m_pingtimer( 0 )
|
||||
{
|
||||
qDebug() << "CTOR controlconnection";
|
||||
setId("ControlConnection()");
|
||||
|
||||
// auto delete when connection closes:
|
||||
connect( this, SIGNAL( finished() ), SLOT( deleteLater() ) );
|
||||
|
||||
this->setMsgProcessorModeIn( MsgProcessor::UNCOMPRESS_ALL | MsgProcessor::PARSE_JSON );
|
||||
this->setMsgProcessorModeOut( MsgProcessor::COMPRESS_IF_LARGE );
|
||||
|
||||
if ( !ha.isEmpty() )
|
||||
{
|
||||
QHostAddress qha( ha );
|
||||
if ( !qha.isNull() )
|
||||
m_peerIpAddress = qha;
|
||||
else
|
||||
{
|
||||
QHostInfo qhi = QHostInfo::fromName( ha );
|
||||
if ( !qhi.addresses().isEmpty() )
|
||||
m_peerIpAddress = qhi.addresses().first();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -107,7 +75,7 @@ ControlConnection::source() const
|
||||
Connection*
|
||||
ControlConnection::clone()
|
||||
{
|
||||
ControlConnection* clone = new ControlConnection( servent(), m_peerIpAddress.toString() );
|
||||
ControlConnection* clone = new ControlConnection( servent() );
|
||||
clone->setOnceOnly( onceOnly() );
|
||||
clone->setName( name() );
|
||||
return clone;
|
||||
@ -158,16 +126,7 @@ ControlConnection::registerSource()
|
||||
Q_UNUSED( source )
|
||||
Q_ASSERT( source == m_source.data() );
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
// qDebug() << Q_FUNC_INFO << "Setting avatar ... " << name() << !SipHandler::instance()->avatar( name() ).isNull();
|
||||
if ( !SipHandler::instance()->avatar( name() ).isNull() )
|
||||
{
|
||||
source->setAvatar( SipHandler::instance()->avatar( name() ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
m_registered = true;
|
||||
m_servent->registerControlConnection( this );
|
||||
setupDbSyncConnection();
|
||||
}
|
||||
|
||||
@ -311,3 +270,18 @@ ControlConnection::onPingTimer()
|
||||
|
||||
sendMsg( Msg::factory( QByteArray(), Msg::PING ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ControlConnection::addPeerInfo( const peerinfo_ptr& peerInfo )
|
||||
{
|
||||
peerInfo->setControlConnection( this );
|
||||
m_peerInfos.insert( peerInfo );
|
||||
}
|
||||
|
||||
|
||||
const QSet< peerinfo_ptr >
|
||||
ControlConnection::peerInfos() const
|
||||
{
|
||||
return m_peerInfos;
|
||||
}
|
||||
|
@ -40,8 +40,7 @@ class DLLEXPORT ControlConnection : public Connection
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ControlConnection( Servent* parent = 0, const QHostAddress &ha = QHostAddress() );
|
||||
explicit ControlConnection( Servent* parent = 0, const QString &ha = QString() );
|
||||
ControlConnection( Servent* parent );
|
||||
~ControlConnection();
|
||||
Connection* clone();
|
||||
|
||||
@ -49,6 +48,9 @@ public:
|
||||
|
||||
Tomahawk::source_ptr source() const;
|
||||
|
||||
void addPeerInfo( const Tomahawk::peerinfo_ptr& peerInfo );
|
||||
const QSet< Tomahawk::peerinfo_ptr > peerInfos() const;
|
||||
|
||||
protected:
|
||||
virtual void setup();
|
||||
|
||||
@ -71,6 +73,8 @@ private:
|
||||
|
||||
QTimer* m_pingtimer;
|
||||
QTime m_pingtimer_mark;
|
||||
|
||||
QSet< Tomahawk::peerinfo_ptr > m_peerInfos;
|
||||
};
|
||||
|
||||
#endif // CONTROLCONNECTION_H
|
||||
|
@ -19,6 +19,25 @@
|
||||
|
||||
#include "Servent.h"
|
||||
|
||||
#include "Result.h"
|
||||
#include "Source.h"
|
||||
#include "BufferIoDevice.h"
|
||||
#include "Connection.h"
|
||||
#include "ControlConnection.h"
|
||||
#include "database/Database.h"
|
||||
#include "database/DatabaseImpl.h"
|
||||
#include "StreamConnection.h"
|
||||
#include "SourceList.h"
|
||||
#include "sip/SipInfo.h"
|
||||
#include "sip/PeerInfo.h"
|
||||
#include "sip/SipPlugin.h"
|
||||
#include "PortFwdThread.h"
|
||||
#include "TomahawkSettings.h"
|
||||
#include "utils/TomahawkUtils.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "accounts/AccountManager.h"
|
||||
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QMutexLocker>
|
||||
#include <QtNetwork/QNetworkInterface>
|
||||
@ -30,21 +49,6 @@
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include "Result.h"
|
||||
#include "Source.h"
|
||||
#include "BufferIoDevice.h"
|
||||
#include "Connection.h"
|
||||
#include "ControlConnection.h"
|
||||
#include "database/Database.h"
|
||||
#include "database/DatabaseImpl.h"
|
||||
#include "StreamConnection.h"
|
||||
#include "SourceList.h"
|
||||
|
||||
#include "PortFwdThread.h"
|
||||
#include "TomahawkSettings.h"
|
||||
#include "utils/TomahawkUtils.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
Servent* Servent::s_instance = 0;
|
||||
@ -168,7 +172,7 @@ Servent::createConnectionKey( const QString& name, const QString &nodeid, const
|
||||
Q_ASSERT( this->thread() == QThread::currentThread() );
|
||||
|
||||
QString _key = ( key.isEmpty() ? uuid() : key );
|
||||
ControlConnection* cc = new ControlConnection( this, name );
|
||||
ControlConnection* cc = new ControlConnection( this );
|
||||
cc->setName( name.isEmpty() ? QString( "KEY(%1)" ).arg( key ) : name );
|
||||
if ( !nodeid.isEmpty() )
|
||||
cc->setId( nodeid );
|
||||
@ -268,16 +272,142 @@ Servent::unregisterControlConnection( ControlConnection* conn )
|
||||
|
||||
|
||||
ControlConnection*
|
||||
Servent::lookupControlConnection( const QString& name )
|
||||
Servent::lookupControlConnection( const SipInfo& sipInfo )
|
||||
{
|
||||
foreach( ControlConnection* c, m_controlconnections )
|
||||
if( c->name() == name )
|
||||
return c;
|
||||
{
|
||||
tLog() << sipInfo.port() << c->peerPort() << sipInfo.host() << c->peerIpAddress().toString();
|
||||
if ( sipInfo.port() == c->peerPort() && sipInfo.host() == c->peerIpAddress().toString() )
|
||||
return c;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Servent::registerPeer( const Tomahawk::peerinfo_ptr& peerInfo )
|
||||
{
|
||||
if( peerInfo->hasControlConnection() )
|
||||
{
|
||||
peerInfoDebug(peerInfo) << "already had control connection, not doin nuffin: " << peerInfo->controlConnection()->name();
|
||||
tLog() << "existing control connection has following peers:";
|
||||
foreach(const peerinfo_ptr& otherPeerInfo, peerInfo->controlConnection()->peerInfos())
|
||||
{
|
||||
peerInfoDebug(otherPeerInfo);
|
||||
}
|
||||
|
||||
tLog() << "end peers";
|
||||
return;
|
||||
}
|
||||
|
||||
if( peerInfo->type() == Tomahawk::PeerInfo::Local )
|
||||
{
|
||||
peerInfoDebug(peerInfo) << "YAY, we need to establish the connection now.. thinking";
|
||||
if ( !connectedToSession( peerInfo->sipInfo().uniqname() ) )
|
||||
{
|
||||
Servent::instance()->connectToPeer( peerInfo );
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: do we need to port this?!
|
||||
|
||||
// qDebug() << "Already connected to" << host; // so peerInfo was 0 before
|
||||
// qDebug() << "They connected to us and we don't have a PeerInfo object, created one...";
|
||||
// m_peersOnline.append( peerInfo );
|
||||
|
||||
// // attach to control connection
|
||||
// ControlConnection* conn = Servent::instance()->lookupControlConnection( sipInfo );
|
||||
|
||||
// // we're connected to this nodeid, so we should find a control connection for this sipinfo, no?
|
||||
// Q_ASSERT( conn );
|
||||
|
||||
// conn->addPeerInfo( peerInfo );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SipInfo info;
|
||||
if( Servent::instance()->visibleExternally() )
|
||||
{
|
||||
QString peerId = peerInfo->id();
|
||||
QString key = uuid();
|
||||
ControlConnection* conn = new ControlConnection( Servent::instance() );
|
||||
|
||||
const QString& nodeid = Database::instance()->impl()->dbid();
|
||||
conn->setName( peerId.left( peerId.indexOf( "/" ) ) );
|
||||
conn->setId( nodeid );
|
||||
conn->addPeerInfo( peerInfo );
|
||||
|
||||
Servent::instance()->registerOffer( key, conn );
|
||||
info.setVisible( true );
|
||||
info.setHost( Servent::instance()->externalAddress() );
|
||||
info.setPort( Servent::instance()->externalPort() );
|
||||
info.setKey( key );
|
||||
info.setUniqname( nodeid );
|
||||
|
||||
tDebug() << "Asking them ( " << peerInfo->id() << " ) to connect to us:" << info;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.setVisible( false );
|
||||
tDebug() << "We are not visible externally:" << info;
|
||||
}
|
||||
|
||||
peerInfo->sendLocalSipInfo( info );
|
||||
|
||||
handleSipInfo( peerInfo );
|
||||
connect( peerInfo.data(), SIGNAL( sipInfoChanged() ), SLOT( onSipInfoChanged() ) );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Servent::onSipInfoChanged()
|
||||
{
|
||||
Tomahawk::PeerInfo* peerInfo = qobject_cast< Tomahawk::PeerInfo* >( sender() );
|
||||
|
||||
if( !peerInfo )
|
||||
return;
|
||||
|
||||
handleSipInfo( peerInfo->weakRef().toStrongRef() );
|
||||
}
|
||||
|
||||
|
||||
void Servent::handleSipInfo( const Tomahawk::peerinfo_ptr& peerInfo )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << peerInfo->id() << peerInfo->sipInfo();
|
||||
|
||||
SipInfo info = peerInfo->sipInfo();
|
||||
if( !info.isValid() )
|
||||
return;
|
||||
|
||||
/*
|
||||
If only one party is externally visible, connection is obvious
|
||||
If both are, peer with lowest IP address initiates the connection.
|
||||
|
||||
This avoids dupe connections.
|
||||
*/
|
||||
if ( info.isVisible() )
|
||||
{
|
||||
if( !Servent::instance()->visibleExternally() ||
|
||||
Servent::instance()->externalAddress() < info.host() ||
|
||||
( Servent::instance()->externalAddress() == info.host() && Servent::instance()->externalPort() < info.port() ) )
|
||||
{
|
||||
|
||||
tDebug() << "Initiate connection to" << peerInfo->id() << "at" << info.host() << " peer of: " << peerInfo->sipPlugin()->account()->accountFriendlyName();
|
||||
Servent::instance()->connectToPeer( peerInfo );
|
||||
}
|
||||
else
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "They should be conecting to us...";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "They are not visible, doing nothing atm";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Servent::incomingConnection( int sd )
|
||||
{
|
||||
@ -344,16 +474,21 @@ Servent::readyRead()
|
||||
controlid = m.value( "controlid" ).toString();
|
||||
|
||||
tDebug( LOGVERBOSE ) << "Incoming connection details:" << m;
|
||||
|
||||
if( !nodeid.isEmpty() ) // only control connections send nodeid
|
||||
{
|
||||
bool dupe = false;
|
||||
if ( m_connectedNodes.contains( nodeid ) )
|
||||
{
|
||||
tDebug() << "connected nodes contains it.";
|
||||
dupe = true;
|
||||
}
|
||||
|
||||
foreach( ControlConnection* con, m_controlconnections )
|
||||
{
|
||||
tLog( LOGVERBOSE ) << "known connection:" << con->id() << con->source()->friendlyName();
|
||||
if(!con)
|
||||
continue;
|
||||
|
||||
tLog() << "known connection:" << con->id();
|
||||
if( con->id() == nodeid )
|
||||
{
|
||||
dupe = true;
|
||||
@ -361,16 +496,47 @@ Servent::readyRead()
|
||||
}
|
||||
}
|
||||
|
||||
if ( dupe )
|
||||
// for zeroconf there might be no offer, that case is handled later
|
||||
ControlConnection* ccMatch = qobject_cast< ControlConnection* >( m_offers.value( key ).data() );
|
||||
if ( dupe && ccMatch )
|
||||
{
|
||||
tLog() << "Duplicate control connection detected, dropping:" << nodeid << conntype;
|
||||
|
||||
tDebug() << "PEERINFO: to be dropped connection has following peers";
|
||||
foreach(const peerinfo_ptr& currentPeerInfo, ccMatch->peerInfos() )
|
||||
{
|
||||
peerInfoDebug(currentPeerInfo);
|
||||
}
|
||||
|
||||
|
||||
foreach(ControlConnection* keepConnection, m_controlconnections)
|
||||
{
|
||||
Q_ASSERT(keepConnection);
|
||||
if( !keepConnection )
|
||||
continue;
|
||||
|
||||
if( keepConnection->id() == nodeid )
|
||||
{
|
||||
tDebug() << "Keep connection" << keepConnection->name() << "with following peers";
|
||||
foreach( const peerinfo_ptr& currentPeerInfo, keepConnection->peerInfos() )
|
||||
peerInfoDebug(currentPeerInfo);
|
||||
|
||||
tDebug() << "Add these peers now";
|
||||
foreach( const peerinfo_ptr& currentPeerInfo, ccMatch->peerInfos() )
|
||||
{
|
||||
tDebug() << "Adding " << currentPeerInfo->id();
|
||||
keepConnection->addPeerInfo( currentPeerInfo );
|
||||
}
|
||||
tDebug() << "Done adding.";
|
||||
}
|
||||
}
|
||||
goto closeconnection;
|
||||
}
|
||||
}
|
||||
|
||||
foreach( ControlConnection* con, m_controlconnections )
|
||||
{
|
||||
if ( con->id() == controlid )
|
||||
if ( con && con->id() == controlid )
|
||||
{
|
||||
cc = con;
|
||||
break;
|
||||
@ -398,7 +564,9 @@ Servent::readyRead()
|
||||
tLog() << "Socket has become invalid, possibly took too long to make an ACL decision, key:" << key << nodeid;
|
||||
goto closeconnection;
|
||||
}
|
||||
tDebug( LOGVERBOSE ) << "claimOffer OK:" << key << nodeid;
|
||||
tDebug( LOGVERBOSE ) << "claimOffer OK:" << key << nodeid;
|
||||
|
||||
registerControlConnection( qobject_cast<ControlConnection*>(conn) );
|
||||
|
||||
m_connectedNodes << nodeid;
|
||||
if( !nodeid.isEmpty() )
|
||||
@ -526,26 +694,84 @@ Servent::socketError( QAbstractSocket::SocketError e )
|
||||
|
||||
|
||||
void
|
||||
Servent::connectToPeer( const QString& ha, int port, const QString &key, const QString& name, const QString& id )
|
||||
Servent::connectToPeer( const peerinfo_ptr& peerInfo )
|
||||
{
|
||||
Q_ASSERT( this->thread() == QThread::currentThread() );
|
||||
|
||||
ControlConnection* conn = new ControlConnection( this, ha );
|
||||
SipInfo sipInfo = peerInfo->sipInfo();
|
||||
|
||||
peerInfoDebug(peerInfo) << "connectToPeer: search for already established connections to the same nodeid: " << m_controlconnections.count() << "connections";
|
||||
|
||||
bool isDupe = false;
|
||||
ControlConnection* conn = 0;
|
||||
// try to find a ControlConnection with the same SipInfo, then we dont need to try to connect again
|
||||
foreach( ControlConnection* c, m_controlconnections )
|
||||
{
|
||||
if( !c )
|
||||
continue;
|
||||
|
||||
if( c->id() == sipInfo.uniqname() )
|
||||
{
|
||||
conn = c;
|
||||
|
||||
|
||||
foreach(const peerinfo_ptr& currentPeerInfo, c->peerInfos())
|
||||
{
|
||||
tLog() << "peerInfo:" << currentPeerInfo->debugName() << "same object: " << (peerInfo == currentPeerInfo) << (peerInfo.data() == currentPeerInfo.data()) << (peerInfo->debugName() == currentPeerInfo->debugName());
|
||||
|
||||
if(peerInfo == currentPeerInfo)
|
||||
{
|
||||
isDupe = true;
|
||||
tLog() << "Not adding " << peerInfo->debugName() << ", because it's a dupe: peerInfoCount remains " << conn->peerInfos().count();
|
||||
}
|
||||
}
|
||||
|
||||
if( !c->peerInfos().contains( peerInfo ) )
|
||||
{
|
||||
c->addPeerInfo( peerInfo );
|
||||
// peerInfoDebug(peerInfo) << "Adding " << peerInfo->debugName() << ", not a dupe... new peerInfoCount:" << c->peerInfos().count();
|
||||
// foreach(const peerinfo_ptr& kuh, c->peerInfos())
|
||||
// {
|
||||
// peerInfoDebug(peerInfo) << " ** " << kuh->debugName();
|
||||
// }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
peerInfoDebug(peerInfo) << "connectToPeer: found a match: " << ( conn ? conn->name() : "false" ) << "dupe: " << isDupe;
|
||||
|
||||
if(isDupe)
|
||||
{
|
||||
peerInfoDebug(peerInfo) << "it's a dupe, nothing to do here, returning and stopping processing: peerInfoCount:" << conn->peerInfos().count();
|
||||
}
|
||||
|
||||
if(conn)
|
||||
return;
|
||||
|
||||
QVariantMap m;
|
||||
m["conntype"] = "accept-offer";
|
||||
m["key"] = key;
|
||||
m["key"] = sipInfo.key();
|
||||
m["port"] = externalPort();
|
||||
m["nodeid"] = Database::instance()->impl()->dbid();
|
||||
|
||||
peerInfoDebug(peerInfo) << "No match found, creating a new ControlConnection...";
|
||||
conn = new ControlConnection( this );
|
||||
conn->addPeerInfo( peerInfo );
|
||||
conn->setFirstMessage( m );
|
||||
if( name.length() )
|
||||
conn->setName( name );
|
||||
if( id.length() )
|
||||
conn->setId( id );
|
||||
|
||||
conn->setProperty( "nodeid", id );
|
||||
if( peerInfo->id().length() )
|
||||
conn->setName( peerInfo->id() );
|
||||
|
||||
connectToPeer( ha, port, key, conn );
|
||||
if( sipInfo.uniqname().length() )
|
||||
conn->setId( sipInfo.uniqname() );
|
||||
|
||||
conn->setProperty( "nodeid", sipInfo.uniqname() );
|
||||
|
||||
registerControlConnection( conn );
|
||||
|
||||
connectToPeer( sipInfo.host(), sipInfo.port(), sipInfo.key(), conn );
|
||||
}
|
||||
|
||||
|
||||
@ -654,8 +880,19 @@ Servent::claimOffer( ControlConnection* cc, const QString &nodeid, const QString
|
||||
if( isIPWhitelisted( peer ) )
|
||||
{
|
||||
tDebug() << "Connection is from whitelisted IP range (LAN)";
|
||||
Connection* conn = new ControlConnection( this, peer.toString() );
|
||||
ControlConnection* conn = new ControlConnection( this );
|
||||
conn->setName( peer.toString() );
|
||||
|
||||
Tomahawk::Accounts::Account* account = Tomahawk::Accounts::AccountManager::instance()->zeroconfAccount();
|
||||
// if we get this connection the account should exist and be enabled
|
||||
Q_ASSERT( account );
|
||||
Q_ASSERT( account->enabled() );
|
||||
|
||||
// this is terrible, actually there should be a way to let this be created by the zeroconf plugin
|
||||
// because this way we rely on the ip being used as id in two totally different parts of the code
|
||||
Tomahawk::peerinfo_ptr peerInfo = Tomahawk::PeerInfo::get( account->sipPlugin(), peer.toString(), Tomahawk::PeerInfo::AutoCreate );
|
||||
peerInfoDebug(peerInfo);
|
||||
conn->addPeerInfo(peerInfo);
|
||||
return conn;
|
||||
}
|
||||
else
|
||||
@ -698,7 +935,7 @@ Servent::claimOffer( ControlConnection* cc, const QString &nodeid, const QString
|
||||
else if ( noauth )
|
||||
{
|
||||
Connection* conn;
|
||||
conn = new ControlConnection( this, peer );
|
||||
conn = new ControlConnection( this );
|
||||
conn->setName( key );
|
||||
return conn;
|
||||
}
|
||||
@ -803,6 +1040,10 @@ Servent::connectedToSession( const QString& session )
|
||||
{
|
||||
foreach( ControlConnection* cc, m_controlconnections )
|
||||
{
|
||||
Q_ASSERT( cc );
|
||||
if( !cc )
|
||||
continue;
|
||||
|
||||
if( cc->id() == session )
|
||||
return true;
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ class StreamConnection;
|
||||
class ProxyConnection;
|
||||
class RemoteCollectionConnection;
|
||||
class PortFwdThread;
|
||||
class PeerInfo;
|
||||
class SipInfo;
|
||||
|
||||
// this is used to hold a bit of state, so when a connected signal is emitted
|
||||
// from a socket, we can associate it with a Connection object etc.
|
||||
@ -101,9 +103,17 @@ public:
|
||||
|
||||
void registerControlConnection( ControlConnection* conn );
|
||||
void unregisterControlConnection( ControlConnection* conn );
|
||||
ControlConnection* lookupControlConnection( const QString& name );
|
||||
ControlConnection* lookupControlConnection( const SipInfo& sipInfo );
|
||||
|
||||
void connectToPeer( const QString& ha, int port, const QString &key, const QString& name = "", const QString& id = "" );
|
||||
// you may call this method as often as you like for the same peerInfo, dupe checking is done inside
|
||||
void registerPeer( const Tomahawk::peerinfo_ptr& peerInfo );
|
||||
void handleSipInfo( const Tomahawk::peerinfo_ptr& peerInfo );
|
||||
|
||||
public slots:
|
||||
void onSipInfoChanged();
|
||||
|
||||
public:
|
||||
void connectToPeer( const Tomahawk::peerinfo_ptr& ha );
|
||||
void connectToPeer( const QString& ha, int port, const QString &key, Connection* conn );
|
||||
void reverseOfferRequest( ControlConnection* orig_conn, const QString &theirdbid, const QString& key, const QString& theirkey );
|
||||
|
||||
|
315
src/libtomahawk/sip/PeerInfo.cpp
Normal file
315
src/libtomahawk/sip/PeerInfo.cpp
Normal file
@ -0,0 +1,315 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2012, Dominik Schmidt <dev@dominik-schmidt.de>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PeerInfo.h"
|
||||
#include "SipPlugin.h"
|
||||
#include "utils/TomahawkCache.h"
|
||||
#include "utils/TomahawkUtilsGui.h"
|
||||
#include "network/ControlConnection.h"
|
||||
#include "network/Servent.h"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QBuffer>
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
QHash< QString, peerinfo_ptr > PeerInfo::s_peersByCacheKey = QHash< QString, peerinfo_ptr >();
|
||||
|
||||
inline QString
|
||||
peerCacheKey( SipPlugin* plugin, const QString& peerId )
|
||||
{
|
||||
return QString( "%1\t\t%2" ).arg( (quintptr) plugin ).arg( peerId );
|
||||
}
|
||||
|
||||
|
||||
Tomahawk::peerinfo_ptr
|
||||
PeerInfo::get(SipPlugin* parent, const QString& id, GetOptions options )
|
||||
{
|
||||
const QString key = peerCacheKey( parent, id );
|
||||
if ( s_peersByCacheKey.contains( key ) )
|
||||
{
|
||||
return s_peersByCacheKey.value( key );
|
||||
}
|
||||
|
||||
// if AutoCreate isn't enabled nothing to do here
|
||||
if( ! ( options & AutoCreate ) )
|
||||
{
|
||||
return peerinfo_ptr();
|
||||
}
|
||||
|
||||
peerinfo_ptr peerInfo( new PeerInfo( parent, id ) );
|
||||
peerInfo->setWeakRef( peerInfo.toWeakRef() );
|
||||
s_peersByCacheKey.insert( key, peerInfo);
|
||||
|
||||
return peerInfo;
|
||||
}
|
||||
|
||||
|
||||
QList< Tomahawk::peerinfo_ptr >
|
||||
PeerInfo::getAll()
|
||||
{
|
||||
return s_peersByCacheKey.values();
|
||||
}
|
||||
|
||||
PeerInfo::PeerInfo( SipPlugin* parent, const QString& id )
|
||||
: QObject( parent )
|
||||
, m_type( External )
|
||||
, m_avatar( 0 )
|
||||
, m_fancyAvatar( 0 )
|
||||
, m_avatarUpdated( true )
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PeerInfo::~PeerInfo()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
delete m_avatar;
|
||||
delete m_fancyAvatar;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PeerInfo::announce()
|
||||
{
|
||||
Servent::instance()->registerPeer( weakRef().toStrongRef() );
|
||||
}
|
||||
|
||||
|
||||
QWeakPointer< PeerInfo >
|
||||
PeerInfo::weakRef()
|
||||
{
|
||||
return m_ownRef;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PeerInfo::setWeakRef( QWeakPointer< PeerInfo > weakRef )
|
||||
{
|
||||
m_ownRef = weakRef;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PeerInfo::setControlConnection( ControlConnection* controlConnection )
|
||||
{
|
||||
m_controlConnection = controlConnection;
|
||||
}
|
||||
|
||||
ControlConnection*
|
||||
PeerInfo::controlConnection() const
|
||||
{
|
||||
return m_controlConnection;
|
||||
}
|
||||
|
||||
bool PeerInfo::hasControlConnection()
|
||||
{
|
||||
return !m_controlConnection.isNull();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
PeerInfo::setType( Tomahawk::PeerInfo::Type type )
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
PeerInfo::Type
|
||||
PeerInfo::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
const
|
||||
QString PeerInfo::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SipPlugin*
|
||||
PeerInfo::sipPlugin() const
|
||||
{
|
||||
return qobject_cast< SipPlugin* >( parent() );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PeerInfo::sendLocalSipInfo( const SipInfo& sipInfo )
|
||||
{
|
||||
sipPlugin()->sendSipInfo( weakRef().toStrongRef(), sipInfo );
|
||||
}
|
||||
|
||||
|
||||
const QString
|
||||
PeerInfo::debugName() const
|
||||
{
|
||||
return QString("%1 : %2").arg( sipPlugin()->account()->accountFriendlyName() ).arg( id() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
PeerInfo::setStatus( PeerInfo::Status status )
|
||||
{
|
||||
m_status = status;
|
||||
|
||||
if( status == Online )
|
||||
announce();
|
||||
}
|
||||
|
||||
|
||||
PeerInfo::Status
|
||||
PeerInfo::status() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PeerInfo::setSipInfo( const SipInfo& sipInfo )
|
||||
{
|
||||
if(sipInfo == m_sipInfo)
|
||||
return;
|
||||
|
||||
m_sipInfo = sipInfo;
|
||||
|
||||
tLog() << "id: " << id() << " info changed" << sipInfo;
|
||||
emit sipInfoChanged();
|
||||
}
|
||||
|
||||
|
||||
const SipInfo
|
||||
PeerInfo::sipInfo() const
|
||||
{
|
||||
return m_sipInfo;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PeerInfo::setFriendlyName( const QString& friendlyName )
|
||||
{
|
||||
m_friendlyName = friendlyName;
|
||||
}
|
||||
|
||||
|
||||
const QString
|
||||
PeerInfo::friendlyName() const
|
||||
{
|
||||
return m_friendlyName;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PeerInfo::setAvatar( const QPixmap& avatar )
|
||||
{
|
||||
QByteArray ba;
|
||||
QBuffer buffer( &ba );
|
||||
buffer.open( QIODevice::WriteOnly );
|
||||
avatar.save( &buffer, "PNG" );
|
||||
|
||||
// Check if the avatar is different by comparing a hash of the first 4096 bytes
|
||||
const QByteArray hash = QCryptographicHash::hash( ba.left( 4096 ), QCryptographicHash::Sha1 );
|
||||
if ( m_avatarHash == hash )
|
||||
return;
|
||||
else
|
||||
m_avatarHash = hash;
|
||||
|
||||
delete m_avatar;
|
||||
m_avatar = new QPixmap( avatar );
|
||||
m_fancyAvatar = 0;
|
||||
|
||||
TomahawkUtils::Cache::instance()->putData( "Sources", 7776000000 /* 90 days */, id(), ba );
|
||||
m_avatarUpdated = true;
|
||||
}
|
||||
|
||||
|
||||
const QPixmap
|
||||
PeerInfo::avatar( TomahawkUtils::ImageMode style, const QSize& size ) const
|
||||
{
|
||||
// tLog() << "*****************************************" << Q_FUNC_INFO << id();
|
||||
|
||||
if ( !m_avatar && m_avatarUpdated )
|
||||
{
|
||||
m_avatar = new QPixmap();
|
||||
QByteArray ba = TomahawkUtils::Cache::instance()->getData( "Sources", id() ).toByteArray();
|
||||
|
||||
if ( ba.count() )
|
||||
m_avatar->loadFromData( ba );
|
||||
|
||||
if ( m_avatar->isNull() )
|
||||
{
|
||||
delete m_avatar;
|
||||
m_avatar = 0;
|
||||
}
|
||||
m_avatarUpdated = false;
|
||||
}
|
||||
|
||||
if ( style == TomahawkUtils::RoundedCorners && m_avatar && !m_avatar->isNull() && !m_fancyAvatar )
|
||||
m_fancyAvatar = new QPixmap( TomahawkUtils::createRoundedImage( QPixmap( *m_avatar ), QSize( 0, 0 ) ) );
|
||||
|
||||
QPixmap pixmap;
|
||||
if ( style == TomahawkUtils::RoundedCorners && m_fancyAvatar )
|
||||
{
|
||||
pixmap = *m_fancyAvatar;
|
||||
}
|
||||
else if ( m_avatar )
|
||||
{
|
||||
pixmap = *m_avatar;
|
||||
}
|
||||
|
||||
if ( !pixmap.isNull() && !size.isEmpty() )
|
||||
{
|
||||
if ( m_coverCache[ style ].contains( size.width() ) )
|
||||
{
|
||||
return m_coverCache[ style ].value( size.width() );
|
||||
}
|
||||
|
||||
QPixmap scaledCover;
|
||||
scaledCover = pixmap.scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
QHash< int, QPixmap > innerCache = m_coverCache[ style ];
|
||||
innerCache.insert( size.width(), scaledCover );
|
||||
m_coverCache[ style ] = innerCache;
|
||||
|
||||
return scaledCover;
|
||||
}
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
void
|
||||
PeerInfo::setVersionString(const QString& versionString)
|
||||
{
|
||||
m_versionString = versionString;
|
||||
}
|
||||
|
||||
|
||||
const QString
|
||||
PeerInfo::versionString() const
|
||||
{
|
||||
return m_versionString;
|
||||
}
|
||||
|
||||
|
||||
} // ns
|
132
src/libtomahawk/sip/PeerInfo.h
Normal file
132
src/libtomahawk/sip/PeerInfo.h
Normal file
@ -0,0 +1,132 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2012, Dominik Schmidt <dev@dominik-schmidt.de>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PEERINFO_H
|
||||
#define PEERINFO_H
|
||||
|
||||
|
||||
|
||||
#include "DllMacro.h"
|
||||
|
||||
#include "SipInfo.h"
|
||||
#include "accounts/Account.h"
|
||||
#include "utils/TomahawkUtils.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QPixmap>
|
||||
|
||||
|
||||
#define peerInfoDebug(peerInfo) tDebug() << "PEERINFO:" << ( !peerInfo.isNull() ? peerInfo->debugName() : "Invalid PeerInfo" ).toLatin1().constData()
|
||||
|
||||
class SipPlugin;
|
||||
class ControlConnection;
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
class DLLEXPORT PeerInfo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Status
|
||||
{
|
||||
Online,
|
||||
Offline
|
||||
};
|
||||
|
||||
enum GetOptions
|
||||
{
|
||||
None,
|
||||
AutoCreate
|
||||
};
|
||||
|
||||
// this is a uberstupid hack, identify characteristics of the type
|
||||
enum Type
|
||||
{
|
||||
External, // this is the default
|
||||
Local
|
||||
};
|
||||
|
||||
static Tomahawk::peerinfo_ptr get( SipPlugin* parent, const QString& id, GetOptions options = None);
|
||||
static QList< Tomahawk::peerinfo_ptr > getAll();
|
||||
|
||||
virtual ~PeerInfo();
|
||||
|
||||
const QString id() const;
|
||||
SipPlugin* sipPlugin() const;
|
||||
const QString debugName() const;
|
||||
void sendLocalSipInfo( const SipInfo& sipInfo );
|
||||
|
||||
QWeakPointer< Tomahawk::PeerInfo > weakRef();
|
||||
void setWeakRef( QWeakPointer< Tomahawk::PeerInfo > weakRef );
|
||||
|
||||
void setControlConnection( ControlConnection* controlConnection );
|
||||
ControlConnection* controlConnection() const;
|
||||
bool hasControlConnection();
|
||||
|
||||
void setType( Tomahawk::PeerInfo::Type type );
|
||||
PeerInfo::Type type() const;
|
||||
|
||||
// actual data
|
||||
void setStatus( Status status );
|
||||
Status status() const;
|
||||
|
||||
void setSipInfo( const SipInfo& sipInfo );
|
||||
const SipInfo sipInfo() const;
|
||||
|
||||
void setFriendlyName( const QString& friendlyName );
|
||||
const QString friendlyName() const;
|
||||
|
||||
void setAvatar( const QPixmap& avatar );
|
||||
const QPixmap avatar( TomahawkUtils::ImageMode style = TomahawkUtils::Original, const QSize& size = QSize() ) const;
|
||||
|
||||
void setVersionString( const QString& versionString );
|
||||
const QString versionString() const;
|
||||
|
||||
signals:
|
||||
void sipInfoChanged();
|
||||
|
||||
private:
|
||||
PeerInfo( SipPlugin* parent, const QString& id );
|
||||
void announce();
|
||||
|
||||
static QHash< QString, peerinfo_ptr > s_peersByCacheKey;
|
||||
QWeakPointer< Tomahawk::PeerInfo > m_ownRef;
|
||||
QPointer< ControlConnection > m_controlConnection;
|
||||
|
||||
PeerInfo::Type m_type;
|
||||
|
||||
QString m_id;
|
||||
Status m_status;
|
||||
SipInfo m_sipInfo;
|
||||
QString m_friendlyName;
|
||||
QString m_versionString;
|
||||
|
||||
mutable QPixmap* m_avatar;
|
||||
mutable QPixmap* m_fancyAvatar;
|
||||
mutable QByteArray m_avatarHash;
|
||||
mutable bool m_avatarUpdated;
|
||||
mutable QHash< TomahawkUtils::ImageMode, QHash< int, QPixmap > > m_coverCache;
|
||||
};
|
||||
|
||||
|
||||
} // ns
|
||||
|
||||
|
||||
#endif // PEERINFO_H
|
@ -1,247 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SipHandler.h"
|
||||
#include "sip/SipPlugin.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QPluginLoader>
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QMessageBox>
|
||||
#endif
|
||||
|
||||
#include "database/Database.h"
|
||||
#include "database/DatabaseImpl.h"
|
||||
#include "network/ControlConnection.h"
|
||||
#include "network/Servent.h"
|
||||
#include "SourceList.h"
|
||||
#include "TomahawkSettings.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "accounts/AccountManager.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
SipHandler* SipHandler::s_instance = 0;
|
||||
|
||||
|
||||
SipHandler*
|
||||
SipHandler::instance()
|
||||
{
|
||||
if ( !s_instance )
|
||||
new SipHandler( 0 );
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
|
||||
SipHandler::SipHandler( QObject* parent )
|
||||
: QObject( parent )
|
||||
{
|
||||
s_instance = this;
|
||||
}
|
||||
|
||||
|
||||
SipHandler::~SipHandler()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
s_instance = 0;
|
||||
}
|
||||
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
const QPixmap
|
||||
SipHandler::avatar( const QString& name ) const
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << "Getting avatar" << name; // << m_usernameAvatars.keys();
|
||||
if( m_usernameAvatars.contains( name ) )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << "Getting avatar and avatar != null ";
|
||||
Q_ASSERT(!m_usernameAvatars.value( name ).isNull());
|
||||
return m_usernameAvatars.value( name );
|
||||
}
|
||||
else
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << "Getting avatar and avatar == null :-(";
|
||||
return QPixmap();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const SipInfo
|
||||
SipHandler::sipInfo( const QString& peerId ) const
|
||||
{
|
||||
return m_peersSipInfos.value( peerId );
|
||||
}
|
||||
|
||||
const QString
|
||||
SipHandler::versionString( const QString& peerId ) const
|
||||
{
|
||||
return m_peersSoftwareVersions.value( peerId );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::hookUpPlugin( SipPlugin* sip )
|
||||
{
|
||||
QObject::connect( sip, SIGNAL( peerOnline( QString ) ), SLOT( onPeerOnline( QString ) ) );
|
||||
QObject::connect( sip, SIGNAL( peerOffline( QString ) ), SLOT( onPeerOffline( QString ) ) );
|
||||
QObject::connect( sip, SIGNAL( msgReceived( QString, QString ) ), SLOT( onMessage( QString, QString ) ) );
|
||||
QObject::connect( sip, SIGNAL( sipInfoReceived( QString, SipInfo ) ), SLOT( onSipInfo( QString, SipInfo ) ) );
|
||||
QObject::connect( sip, SIGNAL( softwareVersionReceived( QString, QString ) ), SLOT( onSoftwareVersion( QString, QString ) ) );
|
||||
|
||||
QObject::connect( sip, SIGNAL( avatarReceived( QString, QPixmap ) ), SLOT( onAvatarReceived( QString, QPixmap ) ) );
|
||||
QObject::connect( sip, SIGNAL( avatarReceived( QPixmap ) ), SLOT( onAvatarReceived( QPixmap ) ) );
|
||||
|
||||
QObject::connect( sip->account(), SIGNAL( configurationChanged() ), sip, SLOT( configurationChanged() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::onPeerOnline( const QString& peerId )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO;
|
||||
tDebug() << "SIP online:" << peerId;
|
||||
|
||||
SipPlugin* sip = qobject_cast<SipPlugin*>(sender());
|
||||
|
||||
SipInfo info;
|
||||
if( Servent::instance()->visibleExternally() )
|
||||
{
|
||||
QString key = uuid();
|
||||
ControlConnection* conn = new ControlConnection( Servent::instance(), QString() );
|
||||
|
||||
const QString& nodeid = Database::instance()->impl()->dbid();
|
||||
conn->setName( peerId.left( peerId.indexOf( "/" ) ) );
|
||||
conn->setId( nodeid );
|
||||
|
||||
Servent::instance()->registerOffer( key, conn );
|
||||
info.setVisible( true );
|
||||
info.setHost( Servent::instance()->externalAddress() );
|
||||
info.setPort( Servent::instance()->externalPort() );
|
||||
info.setKey( key );
|
||||
info.setUniqname( nodeid );
|
||||
|
||||
tDebug() << "Asking them to connect to us:" << info;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.setVisible( false );
|
||||
tDebug() << "We are not visible externally:" << info;
|
||||
}
|
||||
|
||||
sip->sendMsg( peerId, info );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::onPeerOffline( const QString& peerId )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO;
|
||||
tDebug() << "SIP offline:" << peerId;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::onSipInfo( const QString& peerId, const SipInfo& info )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "SIP Message:" << peerId << info;
|
||||
|
||||
QString barePeerId = peerId.left( peerId.indexOf( "/" ) );
|
||||
|
||||
//FIXME: We should probably be using barePeerId in the connectToPeer call below.
|
||||
//But, verify this doesn't cause any problems (there is still a uniquename after all)
|
||||
|
||||
/*
|
||||
If only one party is externally visible, connection is obvious
|
||||
If both are, peer with lowest IP address initiates the connection.
|
||||
This avoids dupe connections.
|
||||
*/
|
||||
if ( info.isVisible() )
|
||||
{
|
||||
if( !Servent::instance()->visibleExternally() ||
|
||||
Servent::instance()->externalAddress() < info.host() ||
|
||||
( Servent::instance()->externalAddress() == info.host() && Servent::instance()->externalPort() < info.port() ) )
|
||||
{
|
||||
tDebug() << "Initiate connection to" << peerId << "at" << info.host();
|
||||
Servent::instance()->connectToPeer( info.host(),
|
||||
info.port(),
|
||||
info.key(),
|
||||
peerId,
|
||||
info.uniqname() );
|
||||
}
|
||||
else
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "They should be conecting to us...";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "They are not visible, doing nothing atm";
|
||||
}
|
||||
|
||||
m_peersSipInfos.insert( peerId, info );
|
||||
}
|
||||
|
||||
void SipHandler::onSoftwareVersion( const QString& peerId, const QString& versionString )
|
||||
{
|
||||
m_peersSoftwareVersions.insert( peerId, versionString );
|
||||
}
|
||||
|
||||
void
|
||||
SipHandler::onMessage( const QString& from, const QString& msg )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << from << msg;
|
||||
}
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
void
|
||||
SipHandler::onAvatarReceived( const QString& from, const QPixmap& avatar )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << "setting avatar on source for" << from;
|
||||
if ( avatar.isNull() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_usernameAvatars.insert( from, avatar );
|
||||
|
||||
ControlConnection *conn = Servent::instance()->lookupControlConnection( from );
|
||||
if( conn )
|
||||
{
|
||||
Tomahawk::source_ptr source = conn->source();
|
||||
if( source )
|
||||
{
|
||||
|
||||
// qDebug() << Q_FUNC_INFO << from << "got source, setting avatar on source:" << source->friendlyName();
|
||||
source->setAvatar( avatar );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::onAvatarReceived( const QPixmap& avatar )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << "Set own avatar on MyCollection";
|
||||
SourceList::instance()->getLocal()->setAvatar( avatar );
|
||||
}
|
||||
#endif
|
@ -1,88 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SIPHANDLER_H
|
||||
#define SIPHANDLER_H
|
||||
|
||||
#include "sip/SipPlugin.h"
|
||||
#include "DllMacro.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QPixmap>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Manages SIP plugins for connecting to friends. External interface to SIP plugins is
|
||||
* through AccountManager, this is an internal class.
|
||||
*/
|
||||
|
||||
class DLLEXPORT SipHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static SipHandler* instance();
|
||||
|
||||
SipHandler( QObject* parent );
|
||||
~SipHandler();
|
||||
|
||||
void loadFromAccountManager();
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
const QPixmap avatar( const QString& name ) const;
|
||||
#endif
|
||||
|
||||
//TODO: implement a proper SipInfo class and maybe attach it to the source
|
||||
const SipInfo sipInfo( const QString& peerId ) const;
|
||||
const QString versionString( const QString& peerId ) const;
|
||||
|
||||
void hookUpPlugin( SipPlugin* p );
|
||||
|
||||
private slots:
|
||||
void onSipInfo( const QString& peerId, const SipInfo& info );
|
||||
void onSoftwareVersion( const QString& peerId, const QString& versionString );
|
||||
void onMessage( const QString&, const QString& );
|
||||
void onPeerOffline( const QString& );
|
||||
void onPeerOnline( const QString& );
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
// set data for local source
|
||||
void onAvatarReceived( const QPixmap& avatar );
|
||||
|
||||
// set data for other sources
|
||||
void onAvatarReceived( const QString& from, const QPixmap& avatar );
|
||||
#endif
|
||||
|
||||
private:
|
||||
static SipHandler *s_instance;
|
||||
|
||||
//TODO: move this to source
|
||||
QHash<QString, SipInfo> m_peersSipInfos;
|
||||
QHash<QString, QString> m_peersSoftwareVersions;
|
||||
#ifndef ENABLE_HEADLESS
|
||||
QHash<QString, QPixmap> m_usernameAvatars;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
@ -237,7 +237,8 @@ SipInfo::fromJson( QString json )
|
||||
}
|
||||
|
||||
|
||||
QDebug operator<< ( QDebug dbg, const SipInfo& info )
|
||||
QDebug
|
||||
operator<< ( QDebug dbg, const SipInfo& info )
|
||||
{
|
||||
if( !info.isValid() )
|
||||
dbg.nospace() << "info is invalid";
|
||||
@ -246,3 +247,31 @@ QDebug operator<< ( QDebug dbg, const SipInfo& info )
|
||||
|
||||
return dbg.maybeSpace();
|
||||
}
|
||||
|
||||
bool operator==( const SipInfo& one, const SipInfo& two )
|
||||
{
|
||||
// check valid/invalid combinations first, so we don't try to access any invalid sipInfos (->assert)
|
||||
if( !one.isValid() && !two.isValid() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( ( one.isValid() && !two.isValid() ) || ( !one.isValid() && two.isValid() ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if( one.isValid() && two.isValid() )
|
||||
{
|
||||
if( one.isVisible() == two.isVisible()
|
||||
&& one.host() == two.host()
|
||||
&& one.port() == two.port()
|
||||
&& one.uniqname() == two.uniqname()
|
||||
&& one.key() == two.key()
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ private:
|
||||
};
|
||||
|
||||
DLLEXPORT QDebug operator<<( QDebug dbg, const SipInfo &info );
|
||||
DLLEXPORT bool operator==( const SipInfo& one, const SipInfo& two );
|
||||
|
||||
|
||||
|
||||
#endif // SIPINFO_H
|
||||
#endif // SIPINFO_H
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "utils/Logger.h"
|
||||
#include "Source.h"
|
||||
#include "sip/PeerInfo.h"
|
||||
|
||||
|
||||
SipPlugin::SipPlugin() : QObject() {}
|
||||
@ -32,8 +33,7 @@ SipPlugin::SipPlugin( Tomahawk::Accounts::Account *account, QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_account( account )
|
||||
{
|
||||
connect( this, SIGNAL( peerOnline( QString ) ), this, SLOT( onPeerOnline( QString ) ) );
|
||||
connect( this, SIGNAL( peerOffline( QString ) ), this, SLOT( onPeerOffline( QString ) ) );
|
||||
connect( account, SIGNAL( configurationChanged() ), SLOT( configurationChanged() ) );
|
||||
}
|
||||
|
||||
|
||||
@ -82,25 +82,16 @@ SipPlugin::account() const
|
||||
}
|
||||
|
||||
|
||||
const QStringList
|
||||
const QList< Tomahawk::peerinfo_ptr >
|
||||
SipPlugin::peersOnline() const
|
||||
{
|
||||
return m_peersOnline;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipPlugin::onPeerOnline( const QString& peerId )
|
||||
{
|
||||
if( !m_peersOnline.contains( peerId ) )
|
||||
{
|
||||
m_peersOnline.append( peerId );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipPlugin::onPeerOffline( const QString& peerId )
|
||||
{
|
||||
m_peersOnline.removeAll( peerId );
|
||||
QList< Tomahawk::peerinfo_ptr > result;
|
||||
|
||||
foreach( const Tomahawk::peerinfo_ptr& peerInfo, Tomahawk::PeerInfo::getAll() )
|
||||
{
|
||||
if(peerInfo->sipPlugin() == this)
|
||||
result.append( peerInfo );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
virtual Tomahawk::Accounts::Account* account() const;
|
||||
|
||||
// peer infos
|
||||
virtual const QStringList peersOnline() const;
|
||||
virtual const QList< Tomahawk::peerinfo_ptr > peersOnline() const;
|
||||
|
||||
public slots:
|
||||
virtual void connectPlugin() = 0;
|
||||
@ -67,38 +67,23 @@ public slots:
|
||||
virtual void checkSettings() = 0;
|
||||
virtual void configurationChanged() = 0;
|
||||
|
||||
virtual void addContact( const QString &jid, const QString& msg = QString() ) = 0;
|
||||
virtual void sendMsg( const QString& to, const SipInfo& info ) = 0;
|
||||
virtual void addContact( const QString& peerId, const QString& msg = QString() ) = 0;
|
||||
virtual void sendSipInfo( const Tomahawk::peerinfo_ptr& receiver, const SipInfo& info ) = 0;
|
||||
|
||||
signals:
|
||||
void peerOnline( const QString& );
|
||||
void peerOffline( const QString& );
|
||||
void msgReceived( const QString& from, const QString& msg );
|
||||
void sipInfoReceived( const QString& peerId, const SipInfo& info );
|
||||
void softwareVersionReceived( const QString& peerId, const QString& versionString );
|
||||
void peerOnline( const Tomahawk::peerinfo_ptr& );
|
||||
void dataError( bool );
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
// new data for own source
|
||||
void avatarReceived ( const QPixmap& avatar );
|
||||
|
||||
// new data for other sources;
|
||||
void avatarReceived ( const QString& from, const QPixmap& avatar);
|
||||
|
||||
void addMenu( QMenu* menu );
|
||||
void removeMenu( QMenu* menu );
|
||||
#endif
|
||||
|
||||
void dataError( bool );
|
||||
|
||||
private slots:
|
||||
void onPeerOnline( const QString &peerId );
|
||||
void onPeerOffline( const QString &peerId );
|
||||
|
||||
protected:
|
||||
Tomahawk::Accounts::Account *m_account;
|
||||
|
||||
private:
|
||||
QStringList m_peersOnline;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user