mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-07-31 19:30:21 +02:00
* Added SipHandler class. This class is supposed to load SIP plugins, manage und communicate with them.
* Our Jabber classes are now a SipPlugin, which gets loaded by SipHandler.
This commit is contained in:
@@ -21,8 +21,8 @@ public:
|
||||
void remove( Tomahawk::Source* s );
|
||||
|
||||
QList<Tomahawk::source_ptr> sources() const;
|
||||
Tomahawk::source_ptr lookup( const QString& username ) const;
|
||||
Tomahawk::source_ptr lookup( unsigned int id ) const;
|
||||
Tomahawk::source_ptr get( const QString& username ) const;
|
||||
Tomahawk::source_ptr get( unsigned int id ) const;
|
||||
unsigned int count() const;
|
||||
|
||||
signals:
|
||||
|
@@ -29,10 +29,10 @@
|
||||
|
||||
class AudioEngine;
|
||||
class Database;
|
||||
class Jabber;
|
||||
class XMPPBot;
|
||||
class SipHandler;
|
||||
class TomahawkZeroconf;
|
||||
class TomahawkSettings;
|
||||
class XMPPBot;
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
@@ -72,6 +72,7 @@ public:
|
||||
Database* database() { return m_db; }
|
||||
SourceList& sourcelist() { return m_sources; }
|
||||
Servent& servent() { return m_servent; }
|
||||
SipHandler* sipHandler() { return m_sipHandler; }
|
||||
QNetworkAccessManager* nam() { return m_nam; }
|
||||
QNetworkProxy* proxy() { return m_proxy; }
|
||||
Tomahawk::InfoSystem::InfoSystem* infoSystem() { return m_infoSystem; }
|
||||
@@ -95,17 +96,8 @@ signals:
|
||||
|
||||
public slots:
|
||||
QSharedPointer<QIODevice> getIODeviceForUrl( const Tomahawk::result_ptr& result );
|
||||
void reconnectJabber();
|
||||
void jabberAddContact( const QString& jid );
|
||||
|
||||
private slots:
|
||||
void jabberMessage( const QString&, const QString& );
|
||||
void jabberPeerOffline( const QString& );
|
||||
void jabberPeerOnline( const QString& );
|
||||
void jabberAuthError( int code, const QString& msg );
|
||||
void jabberDisconnected();
|
||||
void jabberConnected();
|
||||
|
||||
void lanHostFound( const QString&, int, const QString&, const QString& );
|
||||
|
||||
private:
|
||||
@@ -114,7 +106,7 @@ private:
|
||||
void registerMetaTypes();
|
||||
void startServent();
|
||||
void setupDatabase();
|
||||
void setupJabber();
|
||||
void setupSIP();
|
||||
void setupPipeline();
|
||||
void startHTTP();
|
||||
|
||||
@@ -127,7 +119,7 @@ private:
|
||||
Servent m_servent;
|
||||
SourceList m_sources;
|
||||
TomahawkZeroconf* m_zeroconf;
|
||||
QSharedPointer<Jabber> m_jabber;
|
||||
SipHandler* m_sipHandler;
|
||||
XMPPBot* m_xmppBot;
|
||||
|
||||
#ifndef NO_LIBLASTFM
|
||||
|
@@ -43,7 +43,9 @@ SET( tomahawkSources ${tomahawkSources}
|
||||
audio/audioengine.cpp
|
||||
|
||||
utils/tomahawkutils.cpp
|
||||
jabber/jabber_p.cpp
|
||||
|
||||
sip/SipHandler.cpp
|
||||
sip/SipPlugin.cpp
|
||||
|
||||
infosystem/infosystem.cpp
|
||||
infosystem/infoplugins/echonestplugin.cpp
|
||||
@@ -205,8 +207,8 @@ SET( tomahawkHeaders ${tomahawkHeaders}
|
||||
database/databasecommand_updatesearchindex.h
|
||||
database/databasecollection.h
|
||||
|
||||
jabber/jabber.h
|
||||
jabber/jabber_p.h
|
||||
sip/SipHandler.h
|
||||
sip/SipPlugin.h
|
||||
|
||||
infosystem/infoplugins/echonestplugin.h
|
||||
infosystem/infoplugins/musixmatchplugin.h
|
||||
@@ -329,6 +331,8 @@ IF( UNIX )
|
||||
INCLUDE( "CMakeLists.unix.txt" )
|
||||
ENDIF( UNIX )
|
||||
|
||||
ADD_SUBDIRECTORY( sip/jabber )
|
||||
|
||||
kde4_add_app_icon( tomahawkSources "${CMAKE_CURRENT_SOURCE_DIR}/../data/icons/tomahawk-icon-*.png" )
|
||||
qt4_add_resources( RC_SRCS "../resources.qrc" )
|
||||
qt4_wrap_cpp( tomahawkMoc ${tomahawkHeaders} )
|
||||
|
@@ -6,7 +6,7 @@ ADD_DEFINITIONS( -fPIC )
|
||||
|
||||
SET( GLOOX_LIBS ${GLOOX_LIBS} resolv gloox )
|
||||
|
||||
SET( OS_SPECIFIC_LINK_LIBRARIES
|
||||
SET( OS_SPECIFIC_LINK_LIBRARIES
|
||||
${LIBLASTFM_LIBRARY}
|
||||
${GLOOX_LIBS}
|
||||
qxtweb-standalone
|
||||
|
@@ -120,7 +120,7 @@ DatabaseCommand_Resolve::exec( DatabaseImpl* lib )
|
||||
}
|
||||
else
|
||||
{
|
||||
source_ptr s = APP->sourcelist().lookup( files_query.value( 13 ).toUInt() );
|
||||
source_ptr s = APP->sourcelist().get( files_query.value( 13 ).toUInt() );
|
||||
if( s.isNull() )
|
||||
{
|
||||
//qDebug() << "Skipping result for offline sourceid:" << files_query.value(13).toUInt();
|
||||
|
@@ -1,115 +0,0 @@
|
||||
#ifndef JABBER_H
|
||||
#define JABBER_H
|
||||
|
||||
/*
|
||||
Pimpl of jabber_p, which inherits from a gazillion gloox classes
|
||||
and it littered with public methods.
|
||||
*/
|
||||
|
||||
#include "jabber_p.h"
|
||||
|
||||
class Jabber : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
Jabber( const QString &jid, const QString password, const QString server = "", const int port=-1 )
|
||||
: p( jid, password, server, port )
|
||||
{
|
||||
}
|
||||
|
||||
~Jabber()
|
||||
{
|
||||
// p.disconnect();
|
||||
}
|
||||
|
||||
void setProxy( QNetworkProxy* proxy )
|
||||
{
|
||||
p.setProxy( proxy );
|
||||
}
|
||||
|
||||
public slots:
|
||||
|
||||
void start()
|
||||
{
|
||||
//connect( &p, SIGNAL( finished() ),
|
||||
// this, SIGNAL( finished() ) );
|
||||
|
||||
connect( &p, SIGNAL( msgReceived( QString, QString ) ),
|
||||
this, SIGNAL( msgReceived( QString, QString ) ) );
|
||||
|
||||
connect( &p, SIGNAL( peerOnline( QString ) ),
|
||||
this, SIGNAL( peerOnline( QString ) ) );
|
||||
|
||||
connect( &p, SIGNAL( peerOffline( QString ) ),
|
||||
this, SIGNAL( peerOffline( QString ) ) );
|
||||
|
||||
connect( &p, SIGNAL( connected() ),
|
||||
this, SIGNAL( connected() ) );
|
||||
|
||||
connect( &p, SIGNAL( disconnected() ),
|
||||
this, SIGNAL( disconnected() ) );
|
||||
|
||||
connect( &p, SIGNAL( jidChanged( QString ) ),
|
||||
this, SIGNAL( jidChanged( QString ) ) );
|
||||
|
||||
connect( &p, SIGNAL( authError( int, const QString& ) ),
|
||||
this, SIGNAL( authError( int, const QString& ) ) );
|
||||
|
||||
p.go();
|
||||
}
|
||||
|
||||
void disconnect()
|
||||
{
|
||||
QMetaObject::invokeMethod( &p,
|
||||
"disconnect",
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
}
|
||||
|
||||
void sendMsg( const QString& to, const QString& msg )
|
||||
{
|
||||
QMetaObject::invokeMethod( &p,
|
||||
"sendMsg",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(const QString, to),
|
||||
Q_ARG(const QString, msg)
|
||||
);
|
||||
}
|
||||
|
||||
void broadcastMsg( const QString &msg )
|
||||
{
|
||||
QMetaObject::invokeMethod( &p,
|
||||
"broadcastMsg",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(const QString, msg)
|
||||
);
|
||||
}
|
||||
|
||||
void addContact( const QString &jid, const QString& msg = QString() )
|
||||
{
|
||||
QMetaObject::invokeMethod( &p,
|
||||
"addContact",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(const QString, jid),
|
||||
Q_ARG(const QString, msg)
|
||||
);
|
||||
}
|
||||
|
||||
signals:
|
||||
//void finished();
|
||||
|
||||
void msgReceived( const QString&, const QString& );
|
||||
void peerOnline( const QString& );
|
||||
void peerOffline( const QString& );
|
||||
void connected();
|
||||
void disconnected();
|
||||
void jidChanged( const QString& );
|
||||
void authError( int, const QString& );
|
||||
|
||||
private:
|
||||
Jabber_p p;
|
||||
};
|
||||
|
||||
#endif
|
@@ -572,7 +572,7 @@ Servent::remoteIODeviceFactory( const result_ptr& result )
|
||||
QStringList parts = result->url().mid( QString( "servent://" ).length()).split( "\t" );
|
||||
const QString& sourceName = parts.at( 0 );
|
||||
const QString& fileId = parts.at( 1 );
|
||||
const source_ptr& s = TomahawkApp::instance()->sourcelist().lookup( sourceName );
|
||||
const source_ptr& s = TomahawkApp::instance()->sourcelist().get( sourceName );
|
||||
if ( s.isNull() )
|
||||
return sp;
|
||||
|
||||
|
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QDebug>
|
||||
#include <QDesktopServices>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkProxy>
|
||||
@@ -16,7 +17,7 @@
|
||||
#include "tomahawk/tomahawkapp.h"
|
||||
#include "musicscanner.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include <QDesktopServices>
|
||||
#include "sip/SipHandler.h"
|
||||
|
||||
|
||||
static QString
|
||||
@@ -121,7 +122,8 @@ SettingsDialog::~SettingsDialog()
|
||||
|
||||
if( rejabber )
|
||||
{
|
||||
APP->reconnectJabber();
|
||||
APP->sipHandler()->disconnect();
|
||||
APP->sipHandler()->connect();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
198
src/sip/SipHandler.cpp
Normal file
198
src/sip/SipHandler.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
#include "SipHandler.h"
|
||||
#include "sip/SipPlugin.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QPluginLoader>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "tomahawk/tomahawkapp.h"
|
||||
#include "controlconnection.h"
|
||||
|
||||
|
||||
SipHandler::SipHandler( QObject* parent )
|
||||
: QObject( parent )
|
||||
{
|
||||
loadPlugins();
|
||||
}
|
||||
|
||||
|
||||
SipHandler::~SipHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::loadPlugins()
|
||||
{
|
||||
qDebug() << TomahawkApp::instance();
|
||||
qDebug() << TomahawkApp::instance()->applicationDirPath();
|
||||
QDir pluginsDir( TomahawkApp::instance()->applicationDirPath() );
|
||||
|
||||
foreach ( QString fileName, pluginsDir.entryList( QDir::Files ) )
|
||||
{
|
||||
QPluginLoader loader( pluginsDir.absoluteFilePath( fileName ) );
|
||||
QObject* plugin = loader.instance();
|
||||
if ( plugin )
|
||||
{
|
||||
// Connect via that plugin
|
||||
qDebug() << "Trying to load plugin:" << loader.fileName();
|
||||
loadPlugin( plugin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::loadPlugin( QObject* plugin )
|
||||
{
|
||||
SipPlugin* sip = qobject_cast<SipPlugin*>(plugin);
|
||||
if ( sip )
|
||||
{
|
||||
qDebug() << "Loaded plugin!";
|
||||
|
||||
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( connected() ), SIGNAL( connected() ) );
|
||||
QObject::connect( sip, SIGNAL( disconnected() ), SIGNAL( disconnected() ) );
|
||||
QObject::connect( sip, SIGNAL( error( int, QString ) ), SLOT( onError( int, QString ) ) );
|
||||
|
||||
m_plugins << sip;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::connect()
|
||||
{
|
||||
foreach( SipPlugin* sip, m_plugins )
|
||||
sip->connect();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::disconnect()
|
||||
{
|
||||
foreach( SipPlugin* sip, m_plugins )
|
||||
sip->disconnect();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::onPeerOnline( const QString& jid )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << "Jabber online:" << jid;
|
||||
|
||||
SipPlugin* sip = qobject_cast<SipPlugin*>(sender());
|
||||
|
||||
QVariantMap m;
|
||||
if( APP->servent().visibleExternally() )
|
||||
{
|
||||
QString key = uuid();
|
||||
ControlConnection* conn = new ControlConnection( &APP->servent() );
|
||||
|
||||
const QString& nodeid = APP->nodeID();
|
||||
conn->setName( jid.left( jid.indexOf( "/" ) ) );
|
||||
conn->setId( nodeid );
|
||||
|
||||
// FIXME strip /resource, but we should use a UID per database install
|
||||
//QString uniqname = jid.left( jid.indexOf("/") );
|
||||
//conn->setName( uniqname ); //FIXME
|
||||
|
||||
// FIXME:
|
||||
//QString ouruniqname = m_settings->value( "jabber/username" ).toString()
|
||||
// .left( m_settings->value( "jabber/username" ).toString().indexOf("/") );
|
||||
|
||||
APP->servent().registerOffer( key, conn );
|
||||
m["visible"] = true;
|
||||
m["ip"] = APP->servent().externalAddress().toString();
|
||||
m["port"] = APP->servent().externalPort();
|
||||
m["key"] = key;
|
||||
m["uniqname"] = nodeid;
|
||||
|
||||
qDebug() << "Asking them to connect to us:" << m;
|
||||
}
|
||||
else
|
||||
{
|
||||
m["visible"] = false;
|
||||
qDebug() << "We are not visible externally:" << m;
|
||||
}
|
||||
|
||||
QJson::Serializer ser;
|
||||
QByteArray ba = ser.serialize( m );
|
||||
|
||||
sip->sendMsg( jid, QString::fromAscii( ba ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::onPeerOffline( const QString& jid )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << "Jabber offline:" << jid;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::onMessage( const QString& from, const QString& msg )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << "Jabber Message:" << from << msg;
|
||||
|
||||
QJson::Parser parser;
|
||||
bool ok;
|
||||
QVariant v = parser.parse( msg.toAscii(), &ok );
|
||||
if ( !ok || v.type() != QVariant::Map )
|
||||
{
|
||||
qDebug() << "Invalid JSON in XMPP msg";
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap m = v.toMap();
|
||||
/*
|
||||
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 ( m.value( "visible" ).toBool() )
|
||||
{
|
||||
if( !APP->servent().visibleExternally() ||
|
||||
APP->servent().externalAddress().toString() <= m.value( "ip" ).toString() )
|
||||
{
|
||||
qDebug() << "Initiate connection to" << from;
|
||||
APP->servent().connectToPeer( m.value( "ip" ).toString(),
|
||||
m.value( "port" ).toInt(),
|
||||
m.value( "key" ).toString(),
|
||||
from,
|
||||
m.value( "uniqname" ).toString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "They should be conecting to us...";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "They are not visible, doing nothing atm";
|
||||
// if ( m_servent.visibleExternally() )
|
||||
// jabberPeerOnline( from ); // HACK FIXME
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SipHandler::onError( int code, const QString& msg )
|
||||
{
|
||||
qWarning() << "Failed to connect to SIP:" << code << msg;
|
||||
|
||||
if ( code == SipPlugin::AuthError )
|
||||
{
|
||||
emit authError();
|
||||
}
|
||||
else
|
||||
{
|
||||
// QTimer::singleShot( 10000, this, SLOT( reconnectJabber() ) );
|
||||
}
|
||||
}
|
43
src/sip/SipHandler.h
Normal file
43
src/sip/SipHandler.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef SIPHANDLER_H
|
||||
#define SIPHANDLER_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
|
||||
class SipPlugin;
|
||||
|
||||
class SipHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// static SipHandler* instance() { return s_instance ? s_instance : new SipHandler(); }
|
||||
|
||||
SipHandler( QObject* parent );
|
||||
~SipHandler();
|
||||
|
||||
public slots:
|
||||
void addContact( const QString& id ) { qDebug() << Q_FUNC_INFO << id; }
|
||||
|
||||
void connect();
|
||||
void disconnect();
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
void authError();
|
||||
|
||||
private slots:
|
||||
void onMessage( const QString&, const QString& );
|
||||
void onPeerOffline( const QString& );
|
||||
void onPeerOnline( const QString& );
|
||||
void onError( int code, const QString& msg );
|
||||
|
||||
private:
|
||||
void loadPlugins();
|
||||
void loadPlugin( QObject* plugin );
|
||||
|
||||
QList< SipPlugin* > m_plugins;
|
||||
};
|
||||
|
||||
#endif
|
2
src/sip/SipPlugin.cpp
Normal file
2
src/sip/SipPlugin.cpp
Normal file
@@ -0,0 +1,2 @@
|
||||
#include <sip/SipPlugin.h>
|
||||
|
34
src/sip/SipPlugin.h
Normal file
34
src/sip/SipPlugin.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef SIPPLUGIN_H
|
||||
#define SIPPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class SipPlugin : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum SipErrorCode { AuthError, ConnectionError }; // Placeholder for errors, to be defined
|
||||
|
||||
virtual ~SipPlugin() {}
|
||||
|
||||
virtual bool connect() = 0;
|
||||
virtual void disconnect() = 0;
|
||||
|
||||
virtual void addContact( const QString &jid, const QString& msg = QString() ) = 0;
|
||||
virtual void sendMsg( const QString& to, const QString& msg ) = 0;
|
||||
|
||||
signals:
|
||||
void error( int, const QString& );
|
||||
void connected();
|
||||
void disconnected();
|
||||
|
||||
void peerOnline( const QString& );
|
||||
void peerOffline( const QString& );
|
||||
void msgReceived( const QString&, const QString& );
|
||||
};
|
||||
|
||||
Q_DECLARE_INTERFACE( SipPlugin, "tomahawk.Sip/1.0" )
|
||||
|
||||
#endif
|
30
src/sip/jabber/CMakeLists.txt
Normal file
30
src/sip/jabber/CMakeLists.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
project( tomahawk )
|
||||
|
||||
include( ${QT_USE_FILE} )
|
||||
add_definitions( ${QT_DEFINITIONS} )
|
||||
add_definitions( -DQT_PLUGIN )
|
||||
add_definitions( -DQT_SHARED )
|
||||
|
||||
set( jabberSources
|
||||
jabber.cpp
|
||||
jabber_p.cpp
|
||||
)
|
||||
|
||||
set( jabberHeaders
|
||||
jabber.h
|
||||
jabber_p.h
|
||||
)
|
||||
|
||||
include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ..
|
||||
${QT_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
qt4_wrap_cpp( jabberMoc ${jabberHeaders} )
|
||||
add_library( sip_jabber SHARED ${jabberSources} ${jabberMoc} )
|
||||
|
||||
target_link_libraries( sip_jabber
|
||||
${QT_LIBRARIES}
|
||||
${GLOOX_LIBS}
|
||||
)
|
||||
|
||||
install( TARGETS sip_jabber DESTINATION . )
|
63
src/sip/jabber/jabber.cpp
Normal file
63
src/sip/jabber/jabber.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "jabber.h"
|
||||
|
||||
#include "tomahawk/tomahawkapp.h"
|
||||
#include "tomahawksettings.h"
|
||||
|
||||
|
||||
void
|
||||
JabberPlugin::setProxy( QNetworkProxy* proxy )
|
||||
{
|
||||
p->setProxy( proxy );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
JabberPlugin::connect()
|
||||
{
|
||||
if ( !APP->settings()->value( "jabber/autoconnect", true ).toBool() )
|
||||
return false;
|
||||
|
||||
QString jid = APP->settings()->value( "jabber/username" ).toString();
|
||||
QString server = APP->settings()->value( "jabber/server" ).toString();
|
||||
QString password = APP->settings()->value( "jabber/password" ).toString();
|
||||
unsigned int port = APP->settings()->value( "jabber/port", 5222 ).toUInt();
|
||||
|
||||
// gtalk check
|
||||
if( server.isEmpty() && ( jid.contains( "@gmail.com" ) || jid.contains( "@googlemail.com" ) ) )
|
||||
{
|
||||
qDebug() << "Setting jabber server to talk.google.com";
|
||||
server = "talk.google.com";
|
||||
}
|
||||
|
||||
if ( port < 1 || port > 65535 || jid.isEmpty() || password.isEmpty() )
|
||||
{
|
||||
qDebug() << "Jabber credentials look wrong, not connecting";
|
||||
return false;
|
||||
}
|
||||
|
||||
p = new Jabber_p( jid, password, server, port );
|
||||
|
||||
QObject::connect( p, SIGNAL( peerOnline( QString ) ), SIGNAL( peerOnline( QString ) ) );
|
||||
QObject::connect( p, SIGNAL( peerOffline( QString ) ), SIGNAL( peerOffline( QString ) ) );
|
||||
QObject::connect( p, SIGNAL( msgReceived( QString, QString ) ), SIGNAL( msgReceived( QString, QString ) ) );
|
||||
|
||||
QObject::connect( p, SIGNAL( connected() ), SIGNAL( connected() ) );
|
||||
QObject::connect( p, SIGNAL( disconnected() ), SIGNAL( disconnected() ) );
|
||||
QObject::connect( p, SIGNAL( authError( int, QString ) ), SLOT( onAuthError( int, QString ) ) );
|
||||
|
||||
p->go();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberPlugin::onAuthError( int code, const QString& message )
|
||||
{
|
||||
if ( code == gloox::ConnAuthenticationFailed )
|
||||
emit error( SipPlugin::AuthError, message );
|
||||
else
|
||||
emit error( SipPlugin::ConnectionError, message );
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN2( sip, JabberPlugin )
|
68
src/sip/jabber/jabber.h
Normal file
68
src/sip/jabber/jabber.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifndef JABBER_H
|
||||
#define JABBER_H
|
||||
|
||||
#include "SipPlugin.h"
|
||||
#include "jabber_p.h"
|
||||
|
||||
class JabberPlugin : public SipPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES( SipPlugin )
|
||||
|
||||
public:
|
||||
JabberPlugin()
|
||||
: p( 0 )
|
||||
{}
|
||||
|
||||
virtual ~JabberPlugin() { delete p; }
|
||||
|
||||
void setProxy( QNetworkProxy* proxy );
|
||||
|
||||
virtual bool connect();
|
||||
|
||||
public slots:
|
||||
void disconnect()
|
||||
{
|
||||
QMetaObject::invokeMethod( p,
|
||||
"disconnect",
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
}
|
||||
|
||||
void sendMsg( const QString& to, const QString& msg )
|
||||
{
|
||||
QMetaObject::invokeMethod( p,
|
||||
"sendMsg",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(const QString, to),
|
||||
Q_ARG(const QString, msg)
|
||||
);
|
||||
}
|
||||
|
||||
void broadcastMsg( const QString &msg )
|
||||
{
|
||||
QMetaObject::invokeMethod( p,
|
||||
"broadcastMsg",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(const QString, msg)
|
||||
);
|
||||
}
|
||||
|
||||
void addContact( const QString &jid, const QString& msg = QString() )
|
||||
{
|
||||
QMetaObject::invokeMethod( p,
|
||||
"addContact",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(const QString, jid),
|
||||
Q_ARG(const QString, msg)
|
||||
);
|
||||
}
|
||||
|
||||
private slots:
|
||||
void onAuthError( int, const QString& );
|
||||
|
||||
private:
|
||||
Jabber_p* p;
|
||||
};
|
||||
|
||||
#endif
|
@@ -79,7 +79,7 @@ SourceList::sources() const
|
||||
|
||||
|
||||
source_ptr
|
||||
SourceList::lookup( unsigned int id ) const
|
||||
SourceList::get( unsigned int id ) const
|
||||
{
|
||||
QMutexLocker lock( &m_mut );
|
||||
return m_sources.value( m_sources_id2name.value( id ) );
|
||||
@@ -87,7 +87,7 @@ SourceList::lookup( unsigned int id ) const
|
||||
|
||||
|
||||
source_ptr
|
||||
SourceList::lookup( const QString& username ) const
|
||||
SourceList::get( const QString& username ) const
|
||||
{
|
||||
QMutexLocker lock( &m_mut );
|
||||
return m_sources.value( username );
|
||||
|
@@ -14,14 +14,13 @@
|
||||
#include "database/databasecollection.h"
|
||||
#include "database/databasecommand_collectionstats.h"
|
||||
#include "database/databaseresolver.h"
|
||||
#include "jabber/jabber.h"
|
||||
#include "sip/SipHandler.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "xmppbot/xmppbot.h"
|
||||
#include "web/api_v1.h"
|
||||
#include "scriptresolver.h"
|
||||
|
||||
#include "audioengine.h"
|
||||
#include "controlconnection.h"
|
||||
#include "tomahawkzeroconf.h"
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
@@ -154,16 +153,6 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
||||
m_nam = new QNetworkAccessManager;
|
||||
#endif
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
if ( !m_headless )
|
||||
{
|
||||
m_mainwindow = new TomahawkWindow();
|
||||
m_mainwindow->setWindowTitle( "Tomahawk" );
|
||||
m_mainwindow->show();
|
||||
connect( m_mainwindow, SIGNAL( settingsChanged() ), SIGNAL( settingsChanged() ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set up proxy
|
||||
if( m_settings->proxyType() != QNetworkProxy::NoProxy && !m_settings->proxyHost().isEmpty() )
|
||||
{
|
||||
@@ -185,6 +174,22 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
||||
boost::bind( &TomahawkApp::httpIODeviceFactory, this, _1 );
|
||||
this->registerIODeviceFactory( "http", fac );
|
||||
|
||||
if( !arguments().contains("--nojabber") )
|
||||
{
|
||||
setupSIP();
|
||||
m_xmppBot = new XMPPBot( this );
|
||||
}
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
if ( !m_headless )
|
||||
{
|
||||
m_mainwindow = new TomahawkWindow();
|
||||
m_mainwindow->setWindowTitle( "Tomahawk" );
|
||||
m_mainwindow->show();
|
||||
connect( m_mainwindow, SIGNAL( settingsChanged() ), SIGNAL( settingsChanged() ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
setupPipeline();
|
||||
initLocalCollection();
|
||||
startServent();
|
||||
@@ -193,9 +198,6 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
||||
if( arguments().contains( "--http" ) || settings()->value( "network/http", true ).toBool() )
|
||||
startHTTP();
|
||||
|
||||
if( !arguments().contains("--nojabber") ) setupJabber();
|
||||
m_xmppBot = new XMPPBot( this );
|
||||
|
||||
if ( !arguments().contains( "--nozeroconf" ) )
|
||||
{
|
||||
// advertise our servent on the LAN
|
||||
@@ -205,12 +207,14 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
||||
m_zeroconf->advertise();
|
||||
}
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
m_sipHandler->connect();
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
if ( !m_settings->hasScannerPath() )
|
||||
{
|
||||
m_mainwindow->showSettingsDialog();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -218,10 +222,7 @@ TomahawkApp::~TomahawkApp()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if ( !m_jabber.isNull() )
|
||||
{
|
||||
m_jabber.clear();
|
||||
}
|
||||
delete m_sipHandler;
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
delete m_mainwindow;
|
||||
@@ -432,218 +433,13 @@ TomahawkApp::loadPlugins()
|
||||
|
||||
|
||||
void
|
||||
TomahawkApp::setupJabber()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( !m_jabber.isNull() )
|
||||
return;
|
||||
if ( !m_settings->value( "jabber/autoconnect", true ).toBool() )
|
||||
return;
|
||||
|
||||
QString jid = m_settings->value( "jabber/username" ).toString();
|
||||
QString server = m_settings->value( "jabber/server" ).toString();
|
||||
QString password = m_settings->value( "jabber/password" ).toString();
|
||||
unsigned int port = m_settings->value( "jabber/port", 5222 ).toUInt();
|
||||
|
||||
// gtalk check
|
||||
if( server.isEmpty() && ( jid.contains("@gmail.com") || jid.contains("@googlemail.com") ) )
|
||||
{
|
||||
qDebug() << "Setting jabber server to talk.google.com";
|
||||
server = "talk.google.com";
|
||||
}
|
||||
|
||||
if ( port < 1 || port > 65535 || jid.isEmpty() || password.isEmpty() )
|
||||
{
|
||||
qDebug() << "Jabber credentials look wrong, not connecting";
|
||||
return;
|
||||
}
|
||||
|
||||
m_jabber = QSharedPointer<Jabber>( new Jabber( jid, password, server, port ) );
|
||||
|
||||
connect( m_jabber.data(), SIGNAL( peerOnline( QString ) ), SLOT( jabberPeerOnline( QString ) ) );
|
||||
connect( m_jabber.data(), SIGNAL( peerOffline( QString ) ), SLOT( jabberPeerOffline( QString ) ) );
|
||||
connect( m_jabber.data(), SIGNAL( msgReceived( QString, QString ) ), SLOT( jabberMessage( QString, QString ) ) );
|
||||
|
||||
connect( m_jabber.data(), SIGNAL( connected() ), SLOT( jabberConnected() ) );
|
||||
connect( m_jabber.data(), SIGNAL( disconnected() ), SLOT( jabberDisconnected() ) );
|
||||
connect( m_jabber.data(), SIGNAL( authError( int, QString ) ), SLOT( jabberAuthError( int, QString ) ) );
|
||||
|
||||
m_jabber->setProxy( m_proxy );
|
||||
m_jabber->start();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkApp::reconnectJabber()
|
||||
{
|
||||
m_jabber.clear();
|
||||
setupJabber();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkApp::jabberAddContact( const QString& jid )
|
||||
{
|
||||
m_jabber->addContact( jid );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkApp::jabberAuthError( int code, const QString& msg )
|
||||
{
|
||||
qWarning() << "Failed to connect to jabber" << code << msg;
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
if( m_mainwindow )
|
||||
{
|
||||
m_mainwindow->setWindowTitle( QString("Tomahawk [jabber: %1, portfwd: %2]")
|
||||
.arg( "AUTH_ERROR" )
|
||||
.arg( (servent().externalPort() > 0) ? QString( "YES:%1" ).arg(servent().externalPort()) :"NO" ) );
|
||||
|
||||
if ( code == gloox::ConnAuthenticationFailed )
|
||||
{
|
||||
QMessageBox::warning( m_mainwindow,
|
||||
"Jabber Auth Error",
|
||||
QString("Error connecting to Jabber (%1) %2").arg(code).arg(msg),
|
||||
QMessageBox::Ok );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( code != gloox::ConnAuthenticationFailed )
|
||||
QTimer::singleShot( 10000, this, SLOT( reconnectJabber() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkApp::jabberConnected()
|
||||
TomahawkApp::setupSIP()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
if( m_mainwindow )
|
||||
{
|
||||
m_mainwindow->setWindowTitle( QString("Tomahawk [jabber: %1, portfwd: %2]")
|
||||
.arg( "CONNECTED" )
|
||||
.arg( (servent().externalPort() > 0) ? QString( "YES:%1" ).arg(servent().externalPort()):"NO" ) );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
m_sipHandler = new SipHandler( this );
|
||||
|
||||
|
||||
void
|
||||
TomahawkApp::jabberDisconnected()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
if( m_mainwindow )
|
||||
{
|
||||
m_mainwindow->setWindowTitle( QString("Tomahawk [jabber: %1, portfwd: %2]")
|
||||
.arg( "DISCONNECTED" )
|
||||
.arg( (servent().externalPort() > 0) ? QString( "YES:%1" ).arg(servent().externalPort()):"NO" ) );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkApp::jabberPeerOnline( const QString& jid )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO;
|
||||
// qDebug() << "Jabber Peer online:" << jid;
|
||||
|
||||
QVariantMap m;
|
||||
if( m_servent.visibleExternally() )
|
||||
{
|
||||
QString key = uuid();
|
||||
ControlConnection* conn = new ControlConnection( &m_servent );
|
||||
|
||||
const QString& nodeid = APP->nodeID();
|
||||
conn->setName( jid.left( jid.indexOf( "/" ) ) );
|
||||
conn->setId( nodeid );
|
||||
|
||||
// FIXME strip /resource, but we should use a UID per database install
|
||||
//QString uniqname = jid.left( jid.indexOf("/") );
|
||||
//conn->setName( uniqname ); //FIXME
|
||||
|
||||
// FIXME:
|
||||
//QString ouruniqname = m_settings->value( "jabber/username" ).toString()
|
||||
// .left( m_settings->value( "jabber/username" ).toString().indexOf("/") );
|
||||
|
||||
m_servent.registerOffer( key, conn );
|
||||
m["visible"] = true;
|
||||
m["ip"] = m_servent.externalAddress().toString();
|
||||
m["port"] = m_servent.externalPort();
|
||||
m["key"] = key;
|
||||
m["uniqname"] = nodeid;
|
||||
|
||||
qDebug() << "Asking them to connect to us:" << m;
|
||||
}
|
||||
else
|
||||
{
|
||||
m["visible"] = false;
|
||||
qDebug() << "We are not visible externally:" << m;
|
||||
}
|
||||
|
||||
QJson::Serializer ser;
|
||||
QByteArray ba = ser.serialize( m );
|
||||
m_jabber->sendMsg( jid, QString::fromAscii( ba ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkApp::jabberPeerOffline( const QString& jid )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO;
|
||||
// qDebug() << "Jabber Peer offline:" << jid;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkApp::jabberMessage( const QString& from, const QString& msg )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << "Jabber Message:" << from << msg;
|
||||
|
||||
QJson::Parser parser;
|
||||
bool ok;
|
||||
QVariant v = parser.parse( msg.toAscii(), &ok );
|
||||
if ( !ok || v.type() != QVariant::Map )
|
||||
{
|
||||
qDebug() << "Invalid JSON in XMPP msg";
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap m = v.toMap();
|
||||
/*
|
||||
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 ( m.value( "visible" ).toBool() )
|
||||
{
|
||||
if( !m_servent.visibleExternally() ||
|
||||
m_servent.externalAddress().toString() <= m.value( "ip" ).toString() )
|
||||
{
|
||||
qDebug() << "Initiate connection to" << from;
|
||||
m_servent.connectToPeer( m.value( "ip" ).toString(),
|
||||
m.value( "port" ).toInt(),
|
||||
m.value( "key" ).toString(),
|
||||
from,
|
||||
m.value( "uniqname" ).toString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "They should be conecting to us...";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "They are not visible, doing nothing atm";
|
||||
// if ( m_servent.visibleExternally() )
|
||||
// jabberPeerOnline( from ); // HACK FIXME
|
||||
}
|
||||
// m_sipHandler->setProxy( m_proxy );
|
||||
}
|
||||
|
||||
|
||||
|
@@ -20,6 +20,8 @@
|
||||
#include "database/databasecommand_collectionstats.h"
|
||||
#include "topbar/topbar.h"
|
||||
|
||||
#include "sip/SipHandler.h"
|
||||
|
||||
#include "audiocontrols.h"
|
||||
#include "controlconnection.h"
|
||||
#include "database.h"
|
||||
@@ -168,6 +170,11 @@ TomahawkWindow::setupSignals()
|
||||
connect( ui->actionCreatePlaylist, SIGNAL( triggered() ), SLOT( createPlaylist() ));
|
||||
connect( ui->actionAboutTomahawk, SIGNAL( triggered() ), SLOT( showAboutTomahawk() ) );
|
||||
connect( ui->actionExit, SIGNAL( triggered() ), APP, SLOT( quit() ) );
|
||||
|
||||
// <SipHandler>
|
||||
connect( APP->sipHandler(), SIGNAL( connected() ), SLOT( onSipConnected() ) );
|
||||
connect( APP->sipHandler(), SIGNAL( disconnected() ), SLOT( onSipDisconnected() ) );
|
||||
connect( APP->sipHandler(), SIGNAL( authError() ), SLOT( onSipError() ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -293,7 +300,7 @@ TomahawkWindow::addFriendManually()
|
||||
return;
|
||||
|
||||
qDebug() << "Attempting to add jabber contact to roster:" << id;
|
||||
APP->jabberAddContact( id );
|
||||
APP->sipHandler()->addContact( id );
|
||||
}
|
||||
|
||||
|
||||
@@ -338,6 +345,32 @@ TomahawkWindow::onPlaybackLoading( const Tomahawk::result_ptr& result )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkWindow::onSipConnected()
|
||||
{
|
||||
ui->statusButton->setText( tr( "Online" ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkWindow::onSipDisconnected()
|
||||
{
|
||||
ui->statusButton->setText( tr( "Offline" ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkWindow::onSipError()
|
||||
{
|
||||
onSipDisconnected();
|
||||
|
||||
QMessageBox::warning( this,
|
||||
tr( "Authentication Error" ),
|
||||
QString( "Error connecting to SIP: Authentication failed!" ),
|
||||
QMessageBox::Ok );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkWindow::setWindowTitle( const QString& title )
|
||||
{
|
||||
|
@@ -50,6 +50,11 @@ public slots:
|
||||
private slots:
|
||||
void scanFinished();
|
||||
void rescanCollectionManually();
|
||||
|
||||
void onSipConnected();
|
||||
void onSipDisconnected();
|
||||
void onSipError();
|
||||
|
||||
void addPeerManually();
|
||||
void addFriendManually();
|
||||
|
||||
|
@@ -23,9 +23,9 @@
|
||||
<widget class="QWidget" name="">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<widget class="QPushButton" name="statusButton">
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
<string></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
Reference in New Issue
Block a user