PageRenderTime 310ms CodeModel.GetById 100ms app.highlight 73ms RepoModel.GetById 133ms app.codeStats 1ms

/src/libtomahawk/sip/SipHandler.cpp

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