PageRenderTime 93ms CodeModel.GetById 40ms app.highlight 11ms RepoModel.GetById 39ms app.codeStats 1ms

/src/sip/zeroconf/tomahawkzeroconf.h

http://github.com/tomahawk-player/tomahawk
C++ Header | 152 lines | 108 code | 25 blank | 19 comment | 8 complexity | 3ca62578c756080ede63ea2fe03882da 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 *
  5 *   Tomahawk is free software: you can redistribute it and/or modify
  6 *   it under the terms of the GNU General Public License as published by
  7 *   the Free Software Foundation, either version 3 of the License, or
  8 *   (at your option) any later version.
  9 *
 10 *   Tomahawk is distributed in the hope that it will be useful,
 11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 13 *   GNU General Public License for more details.
 14 *
 15 *   You should have received a copy of the GNU General Public License
 16 *   along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 17 */
 18
 19#ifndef TOMAHAWKZCONF
 20#define TOMAHAWKZCONF
 21
 22#define ZCONF_PORT 50210
 23
 24#include <QList>
 25#include <QHostAddress>
 26#include <QHostInfo>
 27#include <QNetworkProxy>
 28#include <QUdpSocket>
 29#include <QTimer>
 30
 31#include "database/database.h"
 32#include "network/servent.h"
 33
 34#include "../sipdllmacro.h"
 35
 36class SIPDLLEXPORT Node : public QObject
 37{
 38Q_OBJECT
 39
 40public:
 41    Node( const QString& i, const QString& n, int p )
 42        : ip( i ), nid( n ), port( p )
 43    {
 44        qDebug() << Q_FUNC_INFO;
 45    }
 46
 47    ~Node()
 48    {
 49        qDebug() << Q_FUNC_INFO;
 50    }
 51
 52signals:
 53    void tomahawkHostFound( const QString&, int, const QString&, const QString& );
 54
 55public slots:
 56    void resolved( QHostInfo i )
 57    {
 58        emit tomahawkHostFound( ip, port, i.hostName(), nid );
 59        this->deleteLater();
 60    }
 61
 62    void resolve()
 63    {
 64        QHostInfo::lookupHost( ip, this, SLOT( resolved( QHostInfo ) ) );
 65    }
 66
 67private:
 68    QString ip;
 69    QString nid;
 70    int port;
 71};
 72
 73
 74class SIPDLLEXPORT TomahawkZeroconf : public QObject
 75{
 76Q_OBJECT
 77
 78public:
 79    TomahawkZeroconf( int port, QObject* parent = 0 )
 80        : QObject( parent ), m_sock( this ), m_port( port )
 81    {
 82        qDebug() << Q_FUNC_INFO;
 83        m_sock.setProxy( QNetworkProxy::NoProxy );
 84        m_sock.bind( ZCONF_PORT, QUdpSocket::ShareAddress );
 85        connect( &m_sock, SIGNAL( readyRead() ), this, SLOT( readPacket() ) );
 86    }
 87
 88    virtual ~TomahawkZeroconf()
 89    {
 90        qDebug() << Q_FUNC_INFO;
 91    }
 92
 93public slots:
 94    void advertise()
 95    {
 96        qDebug() << "Advertising us on the LAN";
 97        QByteArray advert = QString( "TOMAHAWKADVERT:%1:%2" )
 98                            .arg( m_port )
 99                            .arg( Database::instance()->dbid() )
100                            .toAscii();
101        m_sock.writeDatagram( advert.data(), advert.size(),
102                              QHostAddress::Broadcast, ZCONF_PORT );
103    }
104
105signals:
106    // IP, port, name, session
107    void tomahawkHostFound( const QString&, int, const QString&, const QString& );
108
109private slots:
110    void readPacket()
111    {
112        if ( !m_sock.hasPendingDatagrams() )
113            return;
114
115        QByteArray datagram;
116        datagram.resize( m_sock.pendingDatagramSize() );
117        QHostAddress sender;
118        quint16 senderPort;
119        m_sock.readDatagram( datagram.data(), datagram.size(), &sender, &senderPort );
120        qDebug() << "DATAGRAM RCVD" << QString::fromAscii( datagram ) << sender;
121
122        // only process msgs originating on the LAN:
123        if ( datagram.startsWith( "TOMAHAWKADVERT:" ) &&
124            Servent::isIPWhitelisted( sender ) )
125        {
126            QStringList parts = QString::fromAscii( datagram ).split( ':' );
127            if ( parts.length() == 3 )
128            {
129                bool ok;
130                int port = parts.at(1).toInt( &ok );
131                if(ok && Database::instance()->dbid() != parts.at( 2 ) )
132                {
133                    qDebug() << "ADVERT received:" << sender << port;
134                    Node *n = new Node( sender.toString(), parts.at( 2 ), port );
135                    connect( n,    SIGNAL( tomahawkHostFound( QString, int, QString, QString ) ),
136                             this, SIGNAL( tomahawkHostFound( QString, int, QString, QString ) ) );
137                    n->resolve();
138                }
139            }
140        }
141
142        if ( m_sock.hasPendingDatagrams() )
143            QTimer::singleShot( 0, this, SLOT( readPacket() ) );
144    }
145
146private:
147    QUdpSocket m_sock;
148    int m_port;
149};
150
151#endif
152