summaryrefslogblamecommitdiffstats
path: root/src/net/mcast/McastSender.cpp
blob: 294fc55a77f140ddc7fd409dc89e6b01320833ab (plain) (tree)






























































                                                                                                  

                                                                                     


                         
                        

                       
     





                                                                      
 
                                    
 


                                                             
 



                                                                          
 
                                     
 
                                         

                                        
     





                          





                                  
/*
# Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg
#
# This program is free software distributed under the GPL version 2.
# See http://openslx.org/COPYING
#
# If you have any feedback please consult http://openslx.org/feedback and
# send your suggestions, praise, or complaints to feedback@openslx.org
#
# General information about OpenSLX can be found at http://openslx.org/
# -----------------------------------------------------------------------------
# src/net/mcast/McastReceiver.h
#    - implement the receiver-side multicast file transfer protocol -- implementation
# -----------------------------------------------------------------------------
*/

#include "McastSender.h"
#include "McastConstants.h"

#include <QDataStream>

#include <pgm/pgm.h>
// OpenPGM #defines bool. This is bad in C++.
#undef bool

McastSender::McastSender(QIODevice* iodev, McastConfiguration const* config, QObject* parent) :
    QObject(parent),
    _config(config ? new McastConfiguration(*config) : new McastConfiguration()),
    _socket(0),
    _iodev(iodev),
    _curoffs(0),
    _hash(QCryptographicHash::Md5),
    _finished(false)
{
}

McastSender::~McastSender()
{
	delete _config;
}

void McastSender::start()
{
    _socket = new McastPGMSocket(this);
    connect(_socket, SIGNAL(readyToSend()), this, SLOT(readyToSend()));
    _socket->open(_config, McastPGMSocket::PSOCK_WRITE);
}

void McastSender::readyToSend()
{
	if(_finished)
		return;

    if(_iodev->atEnd())
    {
        QByteArray fpdu;
        QDataStream strm(&fpdu, QIODevice::WriteOnly);
        strm.setByteOrder(QDataStream::BigEndian);

        strm << (quint64)MCASTFT_MAGIC << (quint64)UINT64_C(0xffffffffffffffff) << _hash.result();
        strm << qChecksum(fpdu.constData(), fpdu.size());

        _socket->sendPacket(fpdu);
        connect(_socket, SIGNAL(connectionFinished()), this, SLOT(socketFinished()));
        _socket->shutdown();

        _finished = true;

        _iodev->close();

        emit allSent();
    }
    else
    {
		QByteArray barr(DEFAULT_MULTICAST_APDU, '\0');
		qint64 len_read;
		len_read = _iodev->read(barr.data(), barr.capacity());
		barr.resize((int)len_read);

		_hash.addData(barr);

		QByteArray pdu;
		QDataStream strm(&pdu, QIODevice::WriteOnly);
		strm.setByteOrder(QDataStream::BigEndian);

		strm << (quint64)MCASTFT_MAGIC << _curoffs;
		strm << barr;
		quint16 checksum = qChecksum(pdu.constData(), pdu.size());
		strm << checksum;

		_curoffs += len_read;

		_socket->sendPacket(pdu);

		emit progress(_curoffs);
    }
}

void McastSender::close()
{
	_socket->finish();
}

void McastSender::socketFinished()
{
	delete _socket;
	emit finished();
}