mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-03-22 16:59:58 +01:00
Unpimple sipjreen
This commit is contained in:
parent
e863324c40
commit
eba947854b
@ -8,7 +8,6 @@ add_definitions( -DSIPDLLEXPORT_PRO )
|
||||
|
||||
set( jabberSources
|
||||
jabber.cpp
|
||||
jabber_p.cpp
|
||||
tomahawksipmessage.cpp
|
||||
tomahawksipmessagefactory.cpp
|
||||
avatarmanager.cpp
|
||||
@ -16,7 +15,6 @@ set( jabberSources
|
||||
|
||||
set( jabberHeaders
|
||||
jabber.h
|
||||
jabber_p.h
|
||||
tomahawksipmessage.h
|
||||
tomahawksipmessagefactory.h
|
||||
avatarmanager.h
|
||||
|
@ -19,30 +19,94 @@
|
||||
|
||||
#include "jabber.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "tomahawksettings.h"
|
||||
#include "tomahawksipmessage.h"
|
||||
#include "tomahawksipmessagefactory.h"
|
||||
|
||||
#include <jreen/jid.h>
|
||||
#include <jreen/capabilities.h>
|
||||
#include <jreen/vcardupdate.h>
|
||||
#include <jreen/vcard.h>
|
||||
|
||||
#include <qjson/parser.h>
|
||||
#include <qjson/serializer.h>
|
||||
|
||||
#include <QtPlugin>
|
||||
#include <QStringList>
|
||||
#include <QInputDialog>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QDateTime>
|
||||
#include <QTimer>
|
||||
|
||||
JabberPlugin::JabberPlugin()
|
||||
: p( 0 )
|
||||
, m_menu( 0 )
|
||||
: m_menu( 0 )
|
||||
, m_addFriendAction( 0 )
|
||||
, m_connected(false)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
qsrand(QDateTime::currentDateTime().toTime_t());
|
||||
|
||||
// load settings
|
||||
m_currentUsername = TomahawkSettings::instance()->jabberUsername();
|
||||
m_currentServer = TomahawkSettings::instance()->jabberServer();
|
||||
m_currentPassword = TomahawkSettings::instance()->jabberPassword();
|
||||
m_currentPort = TomahawkSettings::instance()->jabberPort();
|
||||
|
||||
// setup JID object
|
||||
Jreen::JID jid = Jreen::JID( accountName() );
|
||||
|
||||
// general client setup
|
||||
m_client = new Jreen::Client( jid, m_currentPassword );
|
||||
m_client->registerStanzaExtension(new TomahawkSipMessageFactory);
|
||||
m_currentResource = QString::fromAscii( "tomahawk%1" ).arg( QString::number( qrand() % 10000 ) );
|
||||
m_client->setResource( m_currentResource );
|
||||
|
||||
// add VCardUpdate extension to own presence
|
||||
m_client->presence().addExtension( new Jreen::VCardUpdate() );
|
||||
|
||||
// initialize the AvatarManager
|
||||
m_avatarManager = new AvatarManager( m_client );
|
||||
|
||||
// setup disco
|
||||
m_client->disco()->setSoftwareVersion( "Tomahawk Player", TOMAHAWK_VERSION, CMAKE_SYSTEM );
|
||||
m_client->disco()->addIdentity( Jreen::Disco::Identity( "client", "type", "tomahawk", "en" ) );
|
||||
m_client->disco()->addFeature( TOMAHAWK_FEATURE );
|
||||
|
||||
// setup caps node, legacy peer detection - used before 0.1
|
||||
Jreen::Capabilities::Ptr caps = m_client->presence().findExtension<Jreen::Capabilities>();
|
||||
caps->setNode( TOMAHAWK_CAP_NODE_NAME );
|
||||
//FIXME: caps->setVersion( TOMAHAWK_VERSION );
|
||||
|
||||
// print connection parameters
|
||||
qDebug() << "Our JID set to:" << m_client->jid().full();
|
||||
qDebug() << "Our Server set to:" << m_client->server();
|
||||
qDebug() << "Our Port set to" << m_client->port();
|
||||
|
||||
// setup slots
|
||||
connect(m_client->connection(), SIGNAL(error(SocketError)), SLOT(onError(SocketError)));
|
||||
connect(m_client, SIGNAL(serverFeaturesReceived(QSet<QString>)), SLOT(onConnect()));
|
||||
connect(m_client, SIGNAL(disconnected(Jreen::Client::DisconnectReason)), SLOT(onDisconnect(Jreen::Client::DisconnectReason)));
|
||||
connect(m_client, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroy()));
|
||||
connect(m_client, SIGNAL(newMessage(Jreen::Message)), SLOT(onNewMessage(Jreen::Message)));
|
||||
connect(m_client, SIGNAL(newPresence(Jreen::Presence)), SLOT(onNewPresence(Jreen::Presence)));
|
||||
connect(m_client, SIGNAL(newIQ(Jreen::IQ)), SLOT(onNewIq(Jreen::IQ)));
|
||||
|
||||
connect(m_avatarManager, SIGNAL(newAvatar(QString)), SLOT(onNewAvatar(QString)));
|
||||
}
|
||||
|
||||
JabberPlugin::~JabberPlugin()
|
||||
{
|
||||
delete p;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
JabberPlugin::setProxy( QNetworkProxy* proxy )
|
||||
{
|
||||
p->setProxy( proxy );
|
||||
qDebug() << Q_FUNC_INFO << "Not implemented";
|
||||
}
|
||||
|
||||
|
||||
@ -78,37 +142,13 @@ JabberPlugin::connectPlugin( bool startup )
|
||||
if ( startup && !TomahawkSettings::instance()->jabberAutoConnect() )
|
||||
return false;
|
||||
|
||||
QString jid = m_currentUsername = TomahawkSettings::instance()->jabberUsername();
|
||||
QString server = m_currentServer = TomahawkSettings::instance()->jabberServer();
|
||||
QString password = m_currentPassword = TomahawkSettings::instance()->jabberPassword();
|
||||
unsigned int port = m_currentPort = TomahawkSettings::instance()->jabberPort();
|
||||
qDebug() << "Connecting to the XMPP server..." << m_connected;
|
||||
qDebug() << m_client->jid().full();
|
||||
//m_client->setServer( m_client->jid().domain() );
|
||||
qDebug() << m_client->server() << m_client->port();
|
||||
|
||||
QStringList splitJid = jid.split( '@', QString::SkipEmptyParts );
|
||||
if ( splitJid.size() < 2 )
|
||||
{
|
||||
qDebug() << "JID did not have an @ in it, could not find a server part";
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( port < 1 || port > 65535 || jid.isEmpty() || password.isEmpty() )
|
||||
{
|
||||
qDebug() << "Jabber credentials look wrong, not connecting";
|
||||
return false;
|
||||
}
|
||||
|
||||
delete p;
|
||||
p = new Jabber_p( jid, password, ( server.isEmpty() ? QString() : 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() ), SLOT( onConnected() ) );
|
||||
QObject::connect( p, SIGNAL( disconnected() ), SLOT( onDisconnected() ) );
|
||||
|
||||
QObject::connect( p, SIGNAL( authError( int, QString ) ), SLOT( onAuthError( int, QString ) ) );
|
||||
QObject::connect( p, SIGNAL( avatarReceived( QString, QPixmap ) ), SIGNAL( avatarReceived( QString, QPixmap ) ) );
|
||||
QObject::connect( p, SIGNAL( avatarReceived( QPixmap ) ), SIGNAL( avatarReceived( QPixmap) ) );
|
||||
QTimer::singleShot(1000, m_client, SLOT( connectToServer() ) );
|
||||
//m_client->connectToServer();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -116,54 +156,130 @@ JabberPlugin::connectPlugin( bool startup )
|
||||
void
|
||||
JabberPlugin::disconnectPlugin()
|
||||
{
|
||||
onDisconnected();
|
||||
qDebug() << Q_FUNC_INFO << m_connected;
|
||||
|
||||
if ( p )
|
||||
p->disconnect();
|
||||
if(!m_connected)
|
||||
return;
|
||||
|
||||
delete p;
|
||||
p = 0;
|
||||
foreach(const Jreen::JID &peer, m_peers.keys())
|
||||
{
|
||||
handlePeerStatus(peer, Jreen::Presence::Unavailable);
|
||||
}
|
||||
|
||||
|
||||
//m_roster->deleteLater();
|
||||
//m_roster = 0;
|
||||
//m_room->deleteLater();
|
||||
//m_room = 0;
|
||||
|
||||
m_peers.clear();
|
||||
m_legacy_peers.clear();
|
||||
|
||||
m_client->disconnectFromServer(true);
|
||||
}
|
||||
|
||||
void
|
||||
JabberPlugin::onConnected()
|
||||
JabberPlugin::onConnect()
|
||||
{
|
||||
if( !m_menu ) {
|
||||
m_menu = new QMenu( QString( "JREEN (" ).append( accountName() ).append(")" ) );
|
||||
m_addFriendAction = m_menu->addAction( "Add Friend..." );
|
||||
QAction *connectAction = m_menu->addAction( "Connect" );
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
connect( m_addFriendAction, SIGNAL(triggered() ),
|
||||
this, SLOT( showAddFriendDialog() ) );
|
||||
connect( connectAction, SIGNAL( triggered() ), SLOT( connectPlugin() ) );
|
||||
|
||||
emit addMenu( m_menu );
|
||||
// update jid resource, servers like gtalk use resource binding and may
|
||||
// have changed our requested /resource
|
||||
if ( m_client->jid().resource() != m_currentResource )
|
||||
{
|
||||
m_currentResource = m_client->jid().resource();
|
||||
emit jidChanged( m_client->jid().full() );
|
||||
}
|
||||
|
||||
emit connected();
|
||||
|
||||
qDebug() << "Connected as:" << m_client->jid().full();
|
||||
|
||||
// set presence to least valid value
|
||||
m_client->setPresence(Jreen::Presence::XA, "Got Tomahawk? http://gettomahawk.com", -127);
|
||||
|
||||
// set ping timeout to 15 secs (TODO: verify if this works)
|
||||
m_client->setPingInterval(1000);
|
||||
|
||||
// load roster
|
||||
m_roster = new Jreen::SimpleRoster( m_client );
|
||||
m_roster->load();
|
||||
|
||||
//FIXME: this implementation is totally broken atm, so it's disabled to avoid harm :P
|
||||
// join MUC with bare jid as nickname
|
||||
//TODO: make the room a list of rooms and make that configurable
|
||||
QString mucNickname = QString( "tomahawk@conference.qutim.org/" ).append( QString( m_client->jid().bare() ).replace( "@", "-" ) );
|
||||
//m_room = new Jreen::MUCRoom(m_client, Jreen::JID( mucNickname ) );
|
||||
//m_room->setHistorySeconds(0);
|
||||
//m_room->join();
|
||||
|
||||
// treat muc participiants like contacts
|
||||
//connect( m_room, SIGNAL( messageReceived( Jreen::Message, bool ) ), this, SLOT( onNewMessage( Jreen::Message ) ) );
|
||||
//connect( m_room, SIGNAL( presenceReceived( Jreen::Presence, const Jreen::MUCRoom::Participant* ) ), this, SLOT( onNewPresence( Jreen::Presence ) ) );
|
||||
|
||||
m_connected = true;
|
||||
}
|
||||
|
||||
void
|
||||
JabberPlugin::onDisconnected()
|
||||
JabberPlugin::onDisconnect( Jreen::Client::DisconnectReason reason )
|
||||
{
|
||||
if( m_menu && m_addFriendAction ) {
|
||||
emit removeMenu( m_menu );
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
delete m_menu;
|
||||
m_menu = 0;
|
||||
m_addFriendAction = 0; // deleted by menu
|
||||
QString errorMessage;
|
||||
bool reconnect = false;
|
||||
int reconnectInSeconds = 0;
|
||||
|
||||
switch( reason )
|
||||
{
|
||||
case Jreen::Client::User:
|
||||
errorMessage = "User Interaction";
|
||||
break;
|
||||
case Jreen::Client::HostUnknown:
|
||||
errorMessage = "Host is unknown";
|
||||
break;
|
||||
case Jreen::Client::ItemNotFound:
|
||||
errorMessage = "Item not found";
|
||||
break;
|
||||
case Jreen::Client::AuthorizationError:
|
||||
errorMessage = "Authorization Error";
|
||||
break;
|
||||
case Jreen::Client::RemoteStreamError:
|
||||
errorMessage = "Remote Stream Error";
|
||||
reconnect = true;
|
||||
break;
|
||||
case Jreen::Client::RemoteConnectionFailed:
|
||||
errorMessage = "Remote Connection failed";
|
||||
break;
|
||||
case Jreen::Client::InternalServerError:
|
||||
errorMessage = "Internal Server Error";
|
||||
reconnect = true;
|
||||
break;
|
||||
case Jreen::Client::SystemShutdown:
|
||||
errorMessage = "System shutdown";
|
||||
reconnect = true;
|
||||
reconnectInSeconds = 60;
|
||||
break;
|
||||
case Jreen::Client::Conflict:
|
||||
errorMessage = "Conflict";
|
||||
break;
|
||||
|
||||
case Jreen::Client::Unknown:
|
||||
errorMessage = "Unknown";
|
||||
break;
|
||||
|
||||
default:
|
||||
qDebug() << "Not all Client::DisconnectReasons checked";
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
emit disconnected();
|
||||
}
|
||||
|
||||
void
|
||||
JabberPlugin::onAuthError( int code, const QString& msg )
|
||||
{
|
||||
switch( code )
|
||||
switch( reason )
|
||||
{
|
||||
case Jreen::Client::User:
|
||||
break;
|
||||
|
||||
case Jreen::Client::AuthorizationError:
|
||||
emit error( SipPlugin::AuthError, msg );
|
||||
emit error( SipPlugin::AuthError, errorMessage );
|
||||
break;
|
||||
|
||||
case Jreen::Client::HostUnknown:
|
||||
@ -174,7 +290,7 @@ JabberPlugin::onAuthError( int code, const QString& msg )
|
||||
case Jreen::Client::SystemShutdown:
|
||||
case Jreen::Client::Conflict:
|
||||
case Jreen::Client::Unknown:
|
||||
emit error( SipPlugin::ConnectionError, msg );
|
||||
emit error( SipPlugin::ConnectionError, errorMessage );
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -182,27 +298,99 @@ JabberPlugin::onAuthError( int code, const QString& msg )
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
emit disconnected();
|
||||
removeMenuHelper();
|
||||
|
||||
if(reconnect)
|
||||
QTimer::singleShot(reconnectInSeconds*1000, this, SLOT(connectPlugin()));
|
||||
|
||||
m_connected = false;
|
||||
}
|
||||
|
||||
void
|
||||
JabberPlugin::onAuthError( int code, const QString& msg )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
JabberPlugin::sendMsg(const QString& to, const QString& msg)
|
||||
{
|
||||
if ( p )
|
||||
p->sendMsg( to, msg );
|
||||
qDebug() << Q_FUNC_INFO << to << msg;
|
||||
|
||||
if ( !m_client ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_legacy_peers.contains( to ) )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << to << "Send legacy message" << msg;
|
||||
Jreen::Message m( Jreen::Message::Chat, Jreen::JID(to), msg);
|
||||
m_client->send( m );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************
|
||||
* Obsolete this by a SipMessage class
|
||||
*/
|
||||
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();
|
||||
/*******************************************************/
|
||||
|
||||
TomahawkSipMessage *sipMessage;
|
||||
if(m["visible"].toBool())
|
||||
{
|
||||
sipMessage = new TomahawkSipMessage(m["ip"].toString(),
|
||||
m["port"].toInt(),
|
||||
m["uniqname"].toString(),
|
||||
m["key"].toString(),
|
||||
m["visible"].toBool()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
sipMessage = new TomahawkSipMessage();
|
||||
}
|
||||
|
||||
|
||||
qDebug() << "Send sip messsage to " << to;
|
||||
Jreen::IQ iq( Jreen::IQ::Set, to );
|
||||
iq.addExtension( sipMessage );
|
||||
|
||||
m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), SipMessageSent );
|
||||
}
|
||||
|
||||
void
|
||||
JabberPlugin::broadcastMsg(const QString& msg)
|
||||
{
|
||||
if ( p )
|
||||
p->broadcastMsg( msg );
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if ( !m_client )
|
||||
return;
|
||||
|
||||
foreach( const Jreen::JID& jid, m_peers.keys() )
|
||||
{
|
||||
sendMsg( jid.full(), msg );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
JabberPlugin::addContact(const QString& jid, const QString& msg)
|
||||
{
|
||||
if ( p )
|
||||
p->addContact( jid, msg );
|
||||
// Add contact to the Tomahawk group on the roster
|
||||
m_roster->add( jid, jid, QStringList() << "Tomahawk" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
@ -232,16 +420,299 @@ JabberPlugin::checkSettings()
|
||||
if ( m_currentPort != TomahawkSettings::instance()->jabberPort() )
|
||||
reconnect = true;
|
||||
|
||||
m_currentUsername = TomahawkSettings::instance()->jabberUsername();
|
||||
m_currentPassword = TomahawkSettings::instance()->jabberPassword();
|
||||
m_currentServer = TomahawkSettings::instance()->jabberServer();
|
||||
m_currentPort = TomahawkSettings::instance()->jabberPort();
|
||||
|
||||
if ( reconnect && ( p || TomahawkSettings::instance()->jabberAutoConnect() ) )
|
||||
if ( reconnect )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Reconnecting jreen plugin...";
|
||||
disconnectPlugin();
|
||||
|
||||
m_currentUsername = TomahawkSettings::instance()->jabberUsername();
|
||||
m_currentPassword = TomahawkSettings::instance()->jabberPassword();
|
||||
m_currentServer = TomahawkSettings::instance()->jabberServer();
|
||||
m_currentPort = TomahawkSettings::instance()->jabberPort();
|
||||
|
||||
Jreen::JID jid = Jreen::JID( accountName() );
|
||||
m_client->setJID( jid );
|
||||
m_client->setPassword( m_currentPassword );
|
||||
m_client->setServer( m_currentServer );
|
||||
m_client->setPort( m_currentPort );
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Updated settings";
|
||||
connectPlugin( false );
|
||||
}
|
||||
}
|
||||
|
||||
void JabberPlugin::addMenuHelper()
|
||||
{
|
||||
if( !m_menu )
|
||||
{
|
||||
m_menu = new QMenu( QString( "JREEN (" ).append( accountName() ).append(")" ) );
|
||||
m_addFriendAction = m_menu->addAction( "Add Friend..." );
|
||||
|
||||
connect( m_addFriendAction, SIGNAL( triggered() ), this, SLOT( showAddFriendDialog() ) );
|
||||
|
||||
emit addMenu( m_menu );
|
||||
}
|
||||
}
|
||||
|
||||
void JabberPlugin::removeMenuHelper()
|
||||
{
|
||||
if( m_menu && m_addFriendAction )
|
||||
{
|
||||
emit removeMenu( m_menu );
|
||||
|
||||
delete m_menu;
|
||||
m_menu = 0;
|
||||
m_addFriendAction = 0; // deleted by menu
|
||||
}
|
||||
}
|
||||
|
||||
void JabberPlugin::onNewMessage(const Jreen::Message& message)
|
||||
{
|
||||
QString from = message.from().full();
|
||||
QString msg = message.body();
|
||||
|
||||
if ( msg.isEmpty() )
|
||||
return;
|
||||
|
||||
QJson::Parser parser;
|
||||
bool ok;
|
||||
QVariant v = parser.parse( msg.toAscii(), &ok );
|
||||
if ( !ok || v.type() != QVariant::Map )
|
||||
{
|
||||
QString to = from;
|
||||
QString response = QString( tr("I'm sorry -- I'm just an automatic presence used by Tomahawk Player"
|
||||
" (http://gettomahawk.com). If you are getting this message, the person you"
|
||||
" are trying to reach is probably not signed on, so please try again later!") );
|
||||
|
||||
// this is not a sip message, so we send it directly through the client
|
||||
m_client->send( Jreen::Message ( Jreen::Message::Chat, Jreen::JID(to), response) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "From:" << message.from().full() << ":" << message.body();
|
||||
emit msgReceived( from, msg );
|
||||
}
|
||||
|
||||
|
||||
void JabberPlugin::onNewPresence( const Jreen::Presence& presence)
|
||||
{
|
||||
Jreen::JID jid = presence.from();
|
||||
QString fulljid( jid.full() );
|
||||
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "* New presence: " << fulljid << presence.subtype();
|
||||
|
||||
if( jid == m_client->jid() )
|
||||
return;
|
||||
|
||||
if ( presence.error() ) {
|
||||
//qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: no" << "presence error";
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore anyone not Running tomahawk:
|
||||
Jreen::Capabilities::Ptr caps = presence.findExtension<Jreen::Capabilities>();
|
||||
if ( caps && ( caps->node() == TOMAHAWK_CAP_NODE_NAME ) )
|
||||
{
|
||||
// must be a jreen resource, implementation in gloox was broken
|
||||
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: yes" << "caps " << caps->node();
|
||||
handlePeerStatus( jid, presence.subtype() );
|
||||
}
|
||||
else if( caps )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: maybe" << "caps " << caps->node()
|
||||
<< "requesting disco..";
|
||||
|
||||
// request disco features
|
||||
QString node = caps->node() + '#' + caps->ver();
|
||||
|
||||
Jreen::IQ iq( Jreen::IQ::Get, jid );
|
||||
iq.addExtension( new Jreen::Disco::Info( node ) );
|
||||
|
||||
m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), RequestDisco );
|
||||
}
|
||||
else if( !caps )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Running tomahawk: no" << "no caps";
|
||||
}
|
||||
}
|
||||
|
||||
void JabberPlugin::onNewIq(const Jreen::IQ& iq, int context)
|
||||
{
|
||||
if( context == RequestDisco )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Received disco IQ...";
|
||||
Jreen::Disco::Info *discoInfo = iq.findExtension<Jreen::Disco::Info>().data();
|
||||
if(!discoInfo)
|
||||
return;
|
||||
iq.accept();
|
||||
|
||||
Jreen::JID jid = iq.from();
|
||||
|
||||
Jreen::DataForm::Ptr form = discoInfo->form();
|
||||
|
||||
if(discoInfo->features().contains( TOMAHAWK_FEATURE ))
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << jid.full() << "Running tomahawk/feature enabled: yes";
|
||||
|
||||
// the actual presence doesn't matter, it just needs to be "online"
|
||||
handlePeerStatus( jid, Jreen::Presence::Available );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << jid.full() << "Running tomahawk/feature enabled: no";
|
||||
|
||||
//LEGACY: accept resources starting with tomahawk too
|
||||
if( jid.resource().startsWith("tomahawk") )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << jid.full() << "Detected legacy tomahawk..";
|
||||
|
||||
// add to legacy peers, so we can send text messages instead of iqs
|
||||
m_legacy_peers.append( jid );
|
||||
|
||||
handlePeerStatus( jid, Jreen::Presence::Available );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(context == RequestedDisco)
|
||||
{
|
||||
qDebug() << "Sent IQ(Set), what should be happening here?";
|
||||
}
|
||||
else if(context == SipMessageSent )
|
||||
{
|
||||
qDebug() << "Sent SipMessage... what now?!";
|
||||
}
|
||||
/*else if(context == RequestedVCard )
|
||||
{
|
||||
qDebug() << "Requested VCard... what now?!";
|
||||
}*/
|
||||
else
|
||||
{
|
||||
|
||||
TomahawkSipMessage *sipMessage = iq.findExtension<TomahawkSipMessage>().data();
|
||||
if(sipMessage)
|
||||
{
|
||||
iq.accept();
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Got SipMessage ...";
|
||||
qDebug() << "ip" << sipMessage->ip();
|
||||
qDebug() << "port" << sipMessage->port();
|
||||
qDebug() << "uniqname" << sipMessage->uniqname();
|
||||
qDebug() << "key" << sipMessage->key();
|
||||
qDebug() << "visible" << sipMessage->visible();
|
||||
|
||||
|
||||
QVariantMap m;
|
||||
if( sipMessage->visible() )
|
||||
{
|
||||
m["visible"] = true;
|
||||
m["ip"] = sipMessage->ip();
|
||||
m["port"] = sipMessage->port();
|
||||
m["key"] = sipMessage->key();
|
||||
m["uniqname"] = sipMessage->uniqname();
|
||||
}
|
||||
else
|
||||
{
|
||||
m["visible"] = false;
|
||||
}
|
||||
|
||||
|
||||
QJson::Serializer ser;
|
||||
QByteArray ba = ser.serialize( m );
|
||||
QString msg = QString::fromAscii( ba );
|
||||
|
||||
QString from = iq.from().full();
|
||||
qDebug() << Q_FUNC_INFO << "From:" << from << ":" << msg;
|
||||
emit msgReceived( from, msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool JabberPlugin::presenceMeansOnline(Jreen::Presence::Type p)
|
||||
{
|
||||
switch(p)
|
||||
{
|
||||
case Jreen::Presence::Invalid:
|
||||
case Jreen::Presence::Unavailable:
|
||||
case Jreen::Presence::Error:
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void JabberPlugin::handlePeerStatus(const Jreen::JID& jid, Jreen::Presence::Type presenceType)
|
||||
{
|
||||
QString fulljid = jid.full();
|
||||
|
||||
// "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;
|
||||
|
||||
// remove peer from legacy peers
|
||||
if( m_legacy_peers.contains( jid ) )
|
||||
{
|
||||
m_legacy_peers.removeAll( jid );
|
||||
}
|
||||
|
||||
emit peerOffline( fulljid );
|
||||
return;
|
||||
}
|
||||
|
||||
// "coming online" event
|
||||
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 );
|
||||
|
||||
if(!m_avatarManager->avatar(jid.bare()).isNull())
|
||||
onNewAvatar( jid.bare() );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//qDebug() << "Updating presence data for" << fulljid;
|
||||
m_peers[ jid ] = presenceType;
|
||||
}
|
||||
|
||||
void JabberPlugin::onNewAvatar(const QString& jid)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << jid;
|
||||
Q_ASSERT(!m_avatarManager->avatar( jid ).isNull());
|
||||
|
||||
// find peers for the jid
|
||||
QList<Jreen::JID> peers = m_peers.keys();
|
||||
foreach(const Jreen::JID &peer, peers)
|
||||
{
|
||||
if( peer.bare() == jid )
|
||||
{
|
||||
emit avatarReceived ( peer.full(), 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 ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
Q_EXPORT_PLUGIN2( sip, JabberPlugin )
|
||||
|
@ -21,11 +21,29 @@
|
||||
#define JABBER_H
|
||||
|
||||
#include "sip/SipPlugin.h"
|
||||
#include "jabber_p.h"
|
||||
|
||||
#include "../sipdllmacro.h"
|
||||
#include "avatarmanager.h"
|
||||
|
||||
#include <jreen/client.h>
|
||||
#include <jreen/disco.h>
|
||||
#include <jreen/message.h>
|
||||
#include <jreen/messagesession.h>
|
||||
#include <jreen/stanza.h>
|
||||
#include <jreen/jreen.h>
|
||||
#include <jreen/error.h>
|
||||
#include <jreen/presence.h>
|
||||
#include <jreen/vcard.h>
|
||||
#include <jreen/abstractroster.h>
|
||||
#include <jreen/connection.h>
|
||||
#include <jreen/mucroom.h>
|
||||
|
||||
#include <QNetworkProxy>
|
||||
|
||||
#define MYNAME "SIPJREEN"
|
||||
#define TOMAHAWK_FEATURE QLatin1String( "tomahawk:sip:v1" )
|
||||
#define TOMAHAWK_CAP_NODE_NAME QLatin1String( "http://tomahawk-player.org/" )
|
||||
|
||||
#include "../sipdllmacro.h"
|
||||
|
||||
class SIPDLLEXPORT JabberPlugin : public SipPlugin
|
||||
{
|
||||
@ -44,6 +62,8 @@ public:
|
||||
virtual QMenu* menu();
|
||||
|
||||
void setProxy( QNetworkProxy* proxy );
|
||||
signals:
|
||||
void jidChanged( const QString& );
|
||||
|
||||
public slots:
|
||||
virtual bool connectPlugin( bool startup );
|
||||
@ -55,12 +75,28 @@ public slots:
|
||||
|
||||
private slots:
|
||||
void showAddFriendDialog();
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
void onConnect();
|
||||
void onDisconnect(Jreen::Client::DisconnectReason reason);
|
||||
void onAuthError(int code, const QString &msg);
|
||||
|
||||
void onNewPresence( const Jreen::Presence& presence );
|
||||
void onNewMessage( const Jreen::Message& message );
|
||||
void onError( const Jreen::Connection::SocketError& e )
|
||||
{
|
||||
qDebug() << e;
|
||||
}
|
||||
void onNewIq( const Jreen::IQ &iq, int context = NoContext );
|
||||
void onNewAvatar( const QString &jid );
|
||||
|
||||
private:
|
||||
Jabber_p* p;
|
||||
void addMenuHelper();
|
||||
void removeMenuHelper();
|
||||
|
||||
bool presenceMeansOnline( Jreen::Presence::Type p );
|
||||
void handlePeerStatus( const Jreen::JID &jid, Jreen::Presence::Type presenceType );
|
||||
|
||||
bool m_connected;
|
||||
|
||||
QMenu* m_menu;
|
||||
QAction* m_addFriendAction;
|
||||
|
||||
@ -68,6 +104,17 @@ private:
|
||||
QString m_currentPassword;
|
||||
QString m_currentServer;
|
||||
unsigned int m_currentPort;
|
||||
QString m_currentResource;
|
||||
|
||||
// sort out
|
||||
Jreen::Client *m_client;
|
||||
|
||||
Jreen::MUCRoom *m_room;
|
||||
Jreen::SimpleRoster *m_roster;
|
||||
QHash<Jreen::JID, Jreen::Presence::Type> m_peers;
|
||||
enum IqContext { NoContext, RequestDisco, RequestedDisco, SipMessageSent, RequestedVCard };
|
||||
QStringList m_legacy_peers;
|
||||
AvatarManager *m_avatarManager;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,576 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Dominik Schmidt <dev@dominik-schmidt.de>
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@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 "jabber_p.h"
|
||||
#include "tomahawksipmessage.h"
|
||||
#include "tomahawksipmessagefactory.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
|
||||
#include <jreen/capabilities.h>
|
||||
#include <jreen/tcpconnection.h>
|
||||
#include <jreen/vcardupdate.h>
|
||||
#include <jreen/vcard.h>
|
||||
|
||||
#include <qjson/parser.h>
|
||||
#include <qjson/serializer.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTime>
|
||||
#include <QTimer>
|
||||
#include <QString>
|
||||
#include <QRegExp>
|
||||
#include <QThread>
|
||||
#include <QVariant>
|
||||
#include <QMap>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QPixmap>
|
||||
|
||||
//remove
|
||||
#include <QLabel>
|
||||
#include <QtGui/QLabel>
|
||||
|
||||
#define TOMAHAWK_FEATURE QLatin1String( "tomahawk:sip:v1" )
|
||||
|
||||
#define TOMAHAWK_CAP_NODE_NAME QLatin1String( "http://tomahawk-player.org/" )
|
||||
|
||||
Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& server, const int port )
|
||||
: QObject()
|
||||
, m_server()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qsrand(QDateTime::currentDateTime().toTime_t());
|
||||
|
||||
// setup JID object
|
||||
m_jid = Jreen::JID( jid );
|
||||
|
||||
// general client setup
|
||||
m_client = new Jreen::Client( jid, password );
|
||||
if ( !server.isEmpty() )
|
||||
{
|
||||
m_client->setServer( server );
|
||||
m_client->setPort( port );
|
||||
}
|
||||
m_client->registerStanzaExtension(new TomahawkSipMessageFactory);
|
||||
m_client->setResource( QString( "tomahawk%1" ).arg( QString::number( qrand() % 10000 ) ) );
|
||||
|
||||
// add VCardUpdate extension to own presence
|
||||
m_client->presence().addExtension( new Jreen::VCardUpdate() );
|
||||
|
||||
// initialize the AvatarManager
|
||||
m_avatarManager = new AvatarManager(m_client);
|
||||
|
||||
// setup disco
|
||||
m_client->disco()->setSoftwareVersion( "Tomahawk Player", TOMAHAWK_VERSION, CMAKE_SYSTEM );
|
||||
m_client->disco()->addIdentity( Jreen::Disco::Identity( "client", "type", "tomahawk", "en" ) );
|
||||
m_client->disco()->addFeature( TOMAHAWK_FEATURE );
|
||||
|
||||
// setup caps node, legacy peer detection - used before 0.1
|
||||
Jreen::Capabilities::Ptr caps = m_client->presence().findExtension<Jreen::Capabilities>();
|
||||
caps->setNode( TOMAHAWK_CAP_NODE_NAME );
|
||||
|
||||
// print connection parameters
|
||||
qDebug() << "Our JID set to:" << m_client->jid().full();
|
||||
qDebug() << "Our Server set to:" << m_client->server();
|
||||
qDebug() << "Our Port set to" << m_client->port();
|
||||
|
||||
m_client->setConnectionImpl( new Jreen::TcpConnection( m_client->server(), m_client->port() ) );
|
||||
|
||||
// setup slots
|
||||
connect(qobject_cast<Jreen::Connection*>(m_client->connection()), SIGNAL(error(const Jreen::Connection::SocketError&)), SLOT(onError(const Jreen::Connection::SocketError&)));
|
||||
connect(m_client, SIGNAL(serverFeaturesReceived(QSet<QString>)), SLOT(onConnect()));
|
||||
connect(m_client, SIGNAL(disconnected(Jreen::Client::DisconnectReason)), SLOT(onDisconnect(Jreen::Client::DisconnectReason)));
|
||||
connect(m_client, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroy(QObject*)));
|
||||
connect(m_client, SIGNAL(newMessage(Jreen::Message)), SLOT(onNewMessage(Jreen::Message)));
|
||||
connect(m_client, SIGNAL(newPresence(Jreen::Presence)), SLOT(onNewPresence(Jreen::Presence)));
|
||||
connect(m_client, SIGNAL(newIQ(Jreen::IQ)), SLOT(onNewIq(Jreen::IQ)));
|
||||
|
||||
connect(m_avatarManager, SIGNAL(newAvatar(QString)), SLOT(onNewAvatar(QString)));
|
||||
|
||||
|
||||
// connect
|
||||
qDebug() << "Connecting to the XMPP server...";
|
||||
m_client->connectToServer();
|
||||
}
|
||||
|
||||
|
||||
Jabber_p::~Jabber_p()
|
||||
{
|
||||
delete m_client;
|
||||
}
|
||||
|
||||
void
|
||||
Jabber_p::setProxy( QNetworkProxy* proxy )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "NOT IMPLEMENTED";
|
||||
}
|
||||
|
||||
void
|
||||
Jabber_p::disconnect()
|
||||
{
|
||||
if ( m_client )
|
||||
{
|
||||
m_client->disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Jabber_p::sendMsg( const QString& to, const QString& msg )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << to << msg;
|
||||
|
||||
if ( !m_client ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_legacy_peers.contains( to ) )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << to << "Send legacy message" << msg;
|
||||
Jreen::Message m( Jreen::Message::Chat, Jreen::JID(to), msg);
|
||||
m_client->send( m );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************
|
||||
* Obsolete this by a SipMessage class
|
||||
*/
|
||||
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();
|
||||
/*******************************************************/
|
||||
|
||||
TomahawkSipMessage *sipMessage;
|
||||
if(m["visible"].toBool())
|
||||
{
|
||||
sipMessage = new TomahawkSipMessage(m["ip"].toString(),
|
||||
m["port"].toInt(),
|
||||
m["uniqname"].toString(),
|
||||
m["key"].toString(),
|
||||
m["visible"].toBool()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
sipMessage = new TomahawkSipMessage();
|
||||
}
|
||||
|
||||
|
||||
qDebug() << "Send sip messsage to " << to;
|
||||
Jreen::IQ iq( Jreen::IQ::Set, to );
|
||||
iq.addExtension( sipMessage );
|
||||
|
||||
m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), SipMessageSent );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Jabber_p::broadcastMsg( const QString &msg )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if ( !m_client )
|
||||
return;
|
||||
|
||||
foreach( const QString& jidstr, m_peers.keys() )
|
||||
{
|
||||
sendMsg( jidstr, msg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Jabber_p::addContact( const QString& jid, const QString& msg )
|
||||
{
|
||||
// Add contact to the Tomahawk group on the roster
|
||||
m_roster->add( jid, jid, QStringList() << "Tomahawk" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
Jabber_p::onConnect()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
// update jid resource, servers like gtalk use resource binding and may
|
||||
// have changed our requested /resource
|
||||
if ( m_client->jid().resource() != m_jid.resource() )
|
||||
{
|
||||
// TODO: check if this is still neccessary with jreen
|
||||
m_jid.setResource( m_client->jid().resource() );
|
||||
QString jidstr( m_jid.full() );
|
||||
emit jidChanged( jidstr );
|
||||
}
|
||||
|
||||
emit connected();
|
||||
qDebug() << "Connected as:" << m_jid.full();
|
||||
|
||||
// set presence to least valid value
|
||||
m_client->setPresence(Jreen::Presence::XA, "Got Tomahawk? http://gettomahawk.com", -127);
|
||||
|
||||
// set ping timeout to 15 secs (TODO: verify if this works)
|
||||
m_client->setPingInterval(15000);
|
||||
|
||||
// load roster
|
||||
m_roster = new Jreen::SimpleRoster( m_client );
|
||||
m_roster->load();
|
||||
|
||||
//FIXME: this implementation is totally broken atm, so it's disabled to avoid harm :P
|
||||
// join MUC with bare jid as nickname
|
||||
//TODO: make the room a list of rooms and make that configurable
|
||||
QString mucNickname = QString( "tomahawk@conference.qutim.org/" ).append( QString( m_jid.bare() ).replace( "@", "-" ) );
|
||||
m_room = new Jreen::MUCRoom(m_client, Jreen::JID( mucNickname ) );
|
||||
//m_room->setHistorySeconds(0);
|
||||
//m_room->join();
|
||||
|
||||
// treat muc participiants like contacts
|
||||
connect( m_room, SIGNAL( messageReceived( Jreen::Message, bool ) ), this, SLOT( onNewMessage( Jreen::Message ) ) );
|
||||
connect( m_room, SIGNAL( presenceReceived( Jreen::Presence, const Jreen::MUCRoom::Participant* ) ), this, SLOT( onNewPresence( Jreen::Presence ) ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Jabber_p::onDisconnect( Jreen::Client::DisconnectReason reason )
|
||||
{
|
||||
QString error;
|
||||
bool reconnect = false;
|
||||
int reconnectInSeconds = 0;
|
||||
|
||||
switch( reason )
|
||||
{
|
||||
case Jreen::Client::User:
|
||||
error = "User Interaction";
|
||||
break;
|
||||
case Jreen::Client::HostUnknown:
|
||||
error = "Host is unknown";
|
||||
break;
|
||||
case Jreen::Client::ItemNotFound:
|
||||
error = "Item not found";
|
||||
break;
|
||||
case Jreen::Client::AuthorizationError:
|
||||
error = "Authorization Error";
|
||||
break;
|
||||
case Jreen::Client::RemoteStreamError:
|
||||
error = "Remote Stream Error";
|
||||
reconnect = true;
|
||||
break;
|
||||
case Jreen::Client::RemoteConnectionFailed:
|
||||
error = "Remote Connection failed";
|
||||
break;
|
||||
case Jreen::Client::InternalServerError:
|
||||
error = "Internal Server Error";
|
||||
reconnect = true;
|
||||
break;
|
||||
case Jreen::Client::SystemShutdown:
|
||||
error = "System shutdown";
|
||||
reconnect = true;
|
||||
reconnectInSeconds = 60;
|
||||
break;
|
||||
case Jreen::Client::Conflict:
|
||||
error = "Conflict";
|
||||
break;
|
||||
|
||||
case Jreen::Client::Unknown:
|
||||
error = "Unknown";
|
||||
break;
|
||||
|
||||
default:
|
||||
qDebug() << "Not all Client::DisconnectReasons checked";
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
qDebug() << "Disconnected from server:" << error;
|
||||
if( reason != Jreen::Client::User )
|
||||
{
|
||||
emit authError( reason, error );
|
||||
}
|
||||
|
||||
if(reconnect)
|
||||
QTimer::singleShot(reconnectInSeconds*1000, m_client, SLOT(connectToServer()));
|
||||
|
||||
emit disconnected();
|
||||
}
|
||||
|
||||
void
|
||||
Jabber_p::onNewMessage( const Jreen::Message& m )
|
||||
{
|
||||
QString from = m.from().full();
|
||||
QString msg = m.body();
|
||||
|
||||
if ( msg.isEmpty() )
|
||||
return;
|
||||
|
||||
QJson::Parser parser;
|
||||
bool ok;
|
||||
QVariant v = parser.parse( msg.toAscii(), &ok );
|
||||
if ( !ok || v.type() != QVariant::Map )
|
||||
{
|
||||
if ( m.from().domain().contains( "googlemail." )
|
||||
|| m.from().domain().contains( "gmail." )
|
||||
|| m.from().domain().contains( "gtalk." )
|
||||
)
|
||||
return;
|
||||
|
||||
QString to = from;
|
||||
QString response = QString( tr("I'm sorry -- I'm just an automatic presence used by Tomahawk Player"
|
||||
" (http://gettomahawk.com). If you are getting this message, the person you"
|
||||
" are trying to reach is probably not signed on, so please try again later!") );
|
||||
|
||||
// this is not a sip message, so we send it directly through the client
|
||||
m_client->send( Jreen::Message ( Jreen::Message::Chat, Jreen::JID(to), response) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "From:" << m.from().full() << ":" << m.body();
|
||||
emit msgReceived( from, msg );
|
||||
}
|
||||
|
||||
|
||||
void Jabber_p::onNewPresence( const Jreen::Presence& presence)
|
||||
{
|
||||
Jreen::JID jid = presence.from();
|
||||
QString fulljid( jid.full() );
|
||||
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "* New presence: " << fulljid << presence.subtype();
|
||||
|
||||
if( jid == m_jid )
|
||||
return;
|
||||
|
||||
if ( presence.error() ) {
|
||||
//qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: no" << "presence error";
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore anyone not Running tomahawk:
|
||||
Jreen::Capabilities::Ptr caps = presence.findExtension<Jreen::Capabilities>();
|
||||
if ( caps && ( caps->node() == TOMAHAWK_CAP_NODE_NAME ) )
|
||||
{
|
||||
// must be a jreen resource, implementation in gloox was broken
|
||||
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: yes" << "caps " << caps->node();
|
||||
handlePeerStatus( fulljid, presence.subtype() );
|
||||
}
|
||||
else if( caps )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: maybe" << "caps " << caps->node()
|
||||
<< "requesting disco..";
|
||||
|
||||
// request disco features
|
||||
QString node = caps->node() + '#' + caps->ver();
|
||||
|
||||
Jreen::IQ iq( Jreen::IQ::Get, jid );
|
||||
iq.addExtension( new Jreen::Disco::Info( node ) );
|
||||
|
||||
m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), RequestDisco );
|
||||
}
|
||||
else if( !caps )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Running tomahawk: no" << "no caps";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Jabber_p::onNewIq( const Jreen::IQ &iq, int context )
|
||||
{
|
||||
if( context == RequestDisco )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Received disco IQ...";
|
||||
Jreen::Disco::Info *discoInfo = iq.findExtension<Jreen::Disco::Info>().data();
|
||||
if(!discoInfo)
|
||||
return;
|
||||
iq.accept();
|
||||
|
||||
QString fulljid = iq.from().full();
|
||||
Jreen::DataForm::Ptr form = discoInfo->form();
|
||||
|
||||
if(discoInfo->features().contains( TOMAHAWK_FEATURE ))
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk/feature enabled: yes";
|
||||
|
||||
// the actual presence doesn't matter, it just needs to be "online"
|
||||
handlePeerStatus( fulljid, Jreen::Presence::Available );
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk/feature enabled: no";
|
||||
|
||||
//LEGACY: accept resources starting with tomahawk too
|
||||
if( iq.from().resource().startsWith("tomahawk") )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << fulljid << "Detected legacy tomahawk..";
|
||||
|
||||
// add to legacy peers, so we can send text messages instead of iqs
|
||||
m_legacy_peers.append( fulljid );
|
||||
|
||||
handlePeerStatus( fulljid, Jreen::Presence::Available );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(context == RequestedDisco)
|
||||
{
|
||||
qDebug() << "Sent IQ(Set), what should be happening here?";
|
||||
}
|
||||
else if(context == SipMessageSent )
|
||||
{
|
||||
qDebug() << "Sent SipMessage... what now?!";
|
||||
}
|
||||
/*else if(context == RequestedVCard )
|
||||
{
|
||||
qDebug() << "Requested VCard... what now?!";
|
||||
}*/
|
||||
else
|
||||
{
|
||||
|
||||
TomahawkSipMessage *sipMessage = iq.findExtension<TomahawkSipMessage>().data();
|
||||
if(sipMessage)
|
||||
{
|
||||
iq.accept();
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Got SipMessage ...";
|
||||
qDebug() << "ip" << sipMessage->ip();
|
||||
qDebug() << "port" << sipMessage->port();
|
||||
qDebug() << "uniqname" << sipMessage->uniqname();
|
||||
qDebug() << "key" << sipMessage->key();
|
||||
qDebug() << "visible" << sipMessage->visible();
|
||||
|
||||
|
||||
QVariantMap m;
|
||||
if( sipMessage->visible() )
|
||||
{
|
||||
m["visible"] = true;
|
||||
m["ip"] = sipMessage->ip();
|
||||
m["port"] = sipMessage->port();
|
||||
m["key"] = sipMessage->key();
|
||||
m["uniqname"] = sipMessage->uniqname();
|
||||
}
|
||||
else
|
||||
{
|
||||
m["visible"] = false;
|
||||
}
|
||||
|
||||
|
||||
QJson::Serializer ser;
|
||||
QByteArray ba = ser.serialize( m );
|
||||
QString msg = QString::fromAscii( ba );
|
||||
|
||||
QString from = iq.from().full();
|
||||
qDebug() << Q_FUNC_INFO << "From:" << from << ":" << msg;
|
||||
emit msgReceived( from, msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Jabber_p::presenceMeansOnline( Jreen::Presence::Type p )
|
||||
{
|
||||
switch(p)
|
||||
{
|
||||
case Jreen::Presence::Invalid:
|
||||
case Jreen::Presence::Unavailable:
|
||||
case Jreen::Presence::Error:
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Jabber_p::handlePeerStatus( const Jreen::JID& jid, Jreen::Presence::Type presenceType )
|
||||
{
|
||||
QString fulljid = jid.full();
|
||||
|
||||
// "going offline" event
|
||||
if ( !presenceMeansOnline( presenceType ) &&
|
||||
( !m_peers.contains( fulljid ) ||
|
||||
presenceMeansOnline( m_peers.value( fulljid ) )
|
||||
)
|
||||
)
|
||||
{
|
||||
m_peers[ fulljid ] = presenceType;
|
||||
qDebug() << Q_FUNC_INFO << "* Peer goes offline:" << fulljid;
|
||||
|
||||
// remove peer from legacy peers
|
||||
if( m_legacy_peers.contains( fulljid ) )
|
||||
{
|
||||
m_legacy_peers.removeAll( fulljid );
|
||||
}
|
||||
|
||||
emit peerOffline( fulljid );
|
||||
return;
|
||||
}
|
||||
|
||||
// "coming online" event
|
||||
if( presenceMeansOnline( presenceType ) &&
|
||||
( !m_peers.contains( fulljid ) ||
|
||||
!presenceMeansOnline( m_peers.value( fulljid ) )
|
||||
)
|
||||
)
|
||||
{
|
||||
m_peers[ fulljid ] = presenceType;
|
||||
qDebug() << Q_FUNC_INFO << "* Peer goes online:" << fulljid;
|
||||
|
||||
emit peerOnline( fulljid );
|
||||
|
||||
if(!m_avatarManager->avatar(jid.bare()).isNull())
|
||||
onNewAvatar( jid.bare() );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//qDebug() << "Updating presence data for" << fulljid;
|
||||
m_peers[ fulljid ] = presenceType;
|
||||
}
|
||||
|
||||
void Jabber_p::onNewAvatar(const QString& jid)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << jid;
|
||||
Q_ASSERT(!m_avatarManager->avatar( jid ).isNull());
|
||||
|
||||
// find peers for the jid
|
||||
QStringList peers = m_peers.keys();
|
||||
foreach(const QString &peer, peers)
|
||||
{
|
||||
if( peer.startsWith(jid) )
|
||||
{
|
||||
emit avatarReceived ( peer, 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 ) );
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Dominik Schmidt <dev@dominik-schmidt.de>
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@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 JABBER_P_H
|
||||
#define JABBER_P_H
|
||||
|
||||
#include "../sipdllmacro.h"
|
||||
|
||||
#include "avatarmanager.h"
|
||||
|
||||
#include <jreen/client.h>
|
||||
#include <jreen/disco.h>
|
||||
#include <jreen/message.h>
|
||||
#include <jreen/messagesession.h>
|
||||
#include <jreen/stanza.h>
|
||||
#include <jreen/jreen.h>
|
||||
#include <jreen/error.h>
|
||||
#include <jreen/presence.h>
|
||||
#include <jreen/vcard.h>
|
||||
#include <jreen/abstractroster.h>
|
||||
#include <jreen/connection.h>
|
||||
#include <jreen/mucroom.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
#include <QMap>
|
||||
#include <QNetworkProxy>
|
||||
|
||||
|
||||
#if defined( WIN32 ) || defined( _WIN32 )
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
class SIPDLLEXPORT Jabber_p :
|
||||
public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Jabber_p( const QString& jid, const QString& password, const QString& server = "", const int port = -1 );
|
||||
virtual ~Jabber_p();
|
||||
|
||||
void setProxy( QNetworkProxy* proxy );
|
||||
|
||||
signals:
|
||||
void msgReceived( const QString&, const QString& ); //from, msg
|
||||
void peerOnline( const QString& );
|
||||
void peerOffline( const QString& );
|
||||
void connected();
|
||||
void disconnected();
|
||||
void jidChanged( const QString& );
|
||||
void avatarReceived( const QPixmap& avatar );
|
||||
void avatarReceived( const QString&, const QPixmap& avatar );
|
||||
void authError( int, const QString& );
|
||||
|
||||
public slots:
|
||||
void sendMsg( const QString& to, const QString& msg );
|
||||
void broadcastMsg( const QString& msg );
|
||||
void addContact( const QString& jid, const QString& msg = QString() );
|
||||
void disconnect();
|
||||
|
||||
void onDisconnect(Jreen::Client::DisconnectReason reason);
|
||||
void onConnect();
|
||||
|
||||
private slots:
|
||||
virtual void onNewPresence( const Jreen::Presence& presence );
|
||||
virtual void onNewMessage( const Jreen::Message& msg );
|
||||
virtual void onError( const Jreen::Connection::SocketError& e )
|
||||
{
|
||||
qDebug() << e;
|
||||
}
|
||||
virtual void onDestroy( QObject */*object*/ )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
virtual void onNewIq( const Jreen::IQ &iq, int context = NoContext );
|
||||
virtual void onNewAvatar( const QString &jid );
|
||||
|
||||
private:
|
||||
bool presenceMeansOnline( Jreen::Presence::Type p );
|
||||
void handlePeerStatus( const Jreen::JID &jid, Jreen::Presence::Type presenceType );
|
||||
|
||||
Jreen::Client *m_client;
|
||||
Jreen::MUCRoom *m_room;
|
||||
Jreen::SimpleRoster *m_roster;
|
||||
Jreen::JID m_jid;
|
||||
QMap<Jreen::Presence::Type, QString> m_presences;
|
||||
QMap<QString, Jreen::Presence::Type> m_peers;
|
||||
QString m_server;
|
||||
|
||||
enum IqContext { NoContext, RequestDisco, RequestedDisco, SipMessageSent, RequestedVCard };
|
||||
|
||||
QStringList m_legacy_peers;
|
||||
|
||||
AvatarManager *m_avatarManager;
|
||||
};
|
||||
|
||||
#endif // JABBER_H
|
Loading…
x
Reference in New Issue
Block a user