Logo Search packages:      
Sourcecode: kmess version File versions

ssdpconnection.cpp

/***************************************************************************
                          ssdpconnection.cpp -  description
                             -------------------
    begin                : Fri Jul 29 2005
    copyright            : (C) 2005 by Diederik van der Boor
    email                : vdboor --at-- codingdomain.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "ssdpconnection.h"

#include "../../kmessdebug.h"

#include <QHostAddress>
#include <QUdpSocket>
#include <QByteArray>

#include <KUrl>


#ifdef KMESSDEBUG_UPNP
#define KMESSDEBUG_UPNP_GENERAL
#endif



namespace UPnP
{


// The constructor
SsdpConnection::SsdpConnection()
: QObject()
, socket_(new QUdpSocket)
{
  connect(socket_, SIGNAL(        readyRead() ) ,
          this,      SLOT( slotDataReceived() ) );
}


// The destructor
SsdpConnection::~SsdpConnection()
{
  if(socket_ != 0)
  {
    socket_->close();
    delete socket_;
  }
}



// Data was received by the socket
void SsdpConnection::slotDataReceived()
{
#ifdef KMESSDEBUG_UPNP_GENERAL
  kDebug() << "received " << socket_->bytesAvailable() << " bytes.";
#endif

/*
  Response from my Alcatel router:

  HTTP/1.1 200 OK
  CACHE-CONTROL:max-age=1800
  EXT:
  LOCATION:http://10.0.0.138:80/IGD.xml
  SERVER:SpeedTouch 510 4.0.2.0.0 UPnP/1.0 (0313QZ6S2)
  ST:upnp:rootdevice
  USN:uuid:UPnP-SpeedTouch510-1_00-90-D0-8E-A1-6F::upnp:rootdevice
*/

  QByteArray datagram;

  while( socket_->hasPendingDatagrams() )
  {
    datagram.clear();
    datagram.resize( (int)socket_->pendingDatagramSize() );

    // Get the HTTP-like content
    socket_->readDatagram( datagram.data(), datagram.size() );
    QString sspdResponse( datagram );

    // Find the location field manually, MimeMessage is not required
    int locationStart = sspdResponse.indexOf( "LOCATION:", 0, Qt::CaseInsensitive );
    int locationEnd   = sspdResponse.indexOf( "\r\n", locationStart );

    locationStart    += 9;  // length of field name
    QString location( sspdResponse.mid( locationStart, locationEnd - locationStart ) );

    // Parse the URL syntax using KUrl
    KUrl url(location);

    // Emit success
    // TODO: How to handle multiple packets arriving from different devices?
    emit deviceFound(url.host(), url.port(), url.path());
  }
}


// Send a broadcast to detect all devices
void SsdpConnection::queryDevices( quint16 bindPort )
{
#ifdef KMESSDEBUG_UPNP_GENERAL
  kDebug() << "Sending broadcast packet.";
#endif

  // Send a packet to a broadcast address
  QHostAddress address;
  address.setAddress("239.255.255.250");

  QString data( "M-SEARCH * HTTP/1.1\r\n"
                "Host:239.255.255.250:1900\r\n"
                "Man:\"ssdp:discover\"\r\n"
                "MX:3\r\n"
                "ST:urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n"
//                 "ST:urn:schemas-upnp-org:device:WANIPConnection:1\r\n"
//                 "ST:urn:schemas-upnp-org:device:WANPPPConnection:1\r\n"
//                 "ST:upnp:rootdevice\r\n"
                "\r\n" );

  // Bind the socket to a certain port
  bool success = socket_->bind( QHostAddress(), bindPort );
  if(! success)
  {
    kWarning() << "Failed to bind to port " << bindPort << ".";
  }

  // Send the data
  qint64 bytesWritten = socket_->writeDatagram( data.toAscii(), address, 1900 );

  if(bytesWritten == -1)
  {
    kWarning() << "Failed to send the UPnP broadcast packet.";
  }
}



}  // end of namespace

#include "ssdpconnection.moc"

Generated by  Doxygen 1.6.0   Back to index