/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. #ifndef TOMAHAWKZCONF
  19. #define TOMAHAWKZCONF
  20. #define ZCONF_PORT 50210
  21. #include <QList>
  22. #include <QHostAddress>
  23. #include <QHostInfo>
  24. #include <QNetworkProxy>
  25. #include <QUdpSocket>
  26. #include <QTimer>
  27. #include "database/database.h"
  28. #include "network/servent.h"
  29. #include "../sipdllmacro.h"
  30. class SIPDLLEXPORT Node : public QObject
  31. {
  32. Q_OBJECT
  33. public:
  34. Node( const QString& i, const QString& n, int p )
  35. : ip( i ), nid( n ), port( p )
  36. {
  37. qDebug() << Q_FUNC_INFO;
  38. }
  39. ~Node()
  40. {
  41. qDebug() << Q_FUNC_INFO;
  42. }
  43. signals:
  44. void tomahawkHostFound( const QString&, int, const QString&, const QString& );
  45. public slots:
  46. void resolved( QHostInfo i )
  47. {
  48. emit tomahawkHostFound( ip, port, i.hostName(), nid );
  49. this->deleteLater();
  50. }
  51. void resolve()
  52. {
  53. QHostInfo::lookupHost( ip, this, SLOT( resolved( QHostInfo ) ) );
  54. }
  55. private:
  56. QString ip;
  57. QString nid;
  58. int port;
  59. };
  60. class SIPDLLEXPORT TomahawkZeroconf : public QObject
  61. {
  62. Q_OBJECT
  63. public:
  64. TomahawkZeroconf( int port, QObject* parent = 0 )
  65. : QObject( parent ), m_sock( this ), m_port( port )
  66. {
  67. qDebug() << Q_FUNC_INFO;
  68. m_sock.setProxy( QNetworkProxy::NoProxy );
  69. m_sock.bind( ZCONF_PORT, QUdpSocket::ShareAddress );
  70. connect( &m_sock, SIGNAL( readyRead() ), this, SLOT( readPacket() ) );
  71. }
  72. virtual ~TomahawkZeroconf()
  73. {
  74. qDebug() << Q_FUNC_INFO;
  75. }
  76. public slots:
  77. void advertise()
  78. {
  79. qDebug() << "Advertising us on the LAN";
  80. QByteArray advert = QString( "TOMAHAWKADVERT:%1:%2" )
  81. .arg( m_port )
  82. .arg( Database::instance()->dbid() )
  83. .toAscii();
  84. m_sock.writeDatagram( advert.data(), advert.size(),
  85. QHostAddress::Broadcast, ZCONF_PORT );
  86. }
  87. signals:
  88. // IP, port, name, session
  89. void tomahawkHostFound( const QString&, int, const QString&, const QString& );
  90. private slots:
  91. void readPacket()
  92. {
  93. if ( !m_sock.hasPendingDatagrams() )
  94. return;
  95. QByteArray datagram;
  96. datagram.resize( m_sock.pendingDatagramSize() );
  97. QHostAddress sender;
  98. quint16 senderPort;
  99. m_sock.readDatagram( datagram.data(), datagram.size(), &sender, &senderPort );
  100. qDebug() << "DATAGRAM RCVD" << QString::fromAscii( datagram ) << sender;
  101. // only process msgs originating on the LAN:
  102. if ( datagram.startsWith( "TOMAHAWKADVERT:" ) &&
  103. Servent::isIPWhitelisted( sender ) )
  104. {
  105. QStringList parts = QString::fromAscii( datagram ).split( ':' );
  106. if ( parts.length() == 3 )
  107. {
  108. bool ok;
  109. int port = parts.at(1).toInt( &ok );
  110. if(ok && Database::instance()->dbid() != parts.at( 2 ) )
  111. {
  112. qDebug() << "ADVERT received:" << sender << port;
  113. Node *n = new Node( sender.toString(), parts.at( 2 ), port );
  114. connect( n, SIGNAL( tomahawkHostFound( QString, int, QString, QString ) ),
  115. this, SIGNAL( tomahawkHostFound( QString, int, QString, QString ) ) );
  116. n->resolve();
  117. }
  118. }
  119. }
  120. if ( m_sock.hasPendingDatagrams() )
  121. QTimer::singleShot( 0, this, SLOT( readPacket() ) );
  122. }
  123. private:
  124. QUdpSocket m_sock;
  125. int m_port;
  126. };
  127. #endif