/*
# 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/pcsIncomingMulticastTransfer.h
# - wrap McastReceiver functionality in PVS daemon
# -----------------------------------------------------------------------------
*/
#include <QDir>
#include <QTemporaryFile>
#include <QTimer>
#include "pvsIncomingMulticastTransfer.h"
#include <src/net/mcast/McastReceiver.h>
PVSIncomingMulticastTransfer::PVSIncomingMulticastTransfer(QString const& sender, qulonglong transferID, qulonglong size, QString const& filename,
ushort port, McastConfiguration const* configTemplate, QObject* parent) :
QObject(parent),
_sender(sender),
_transferID(transferID),
_bytes(0),
_size(size),
_port(port),
_file(new QFile(filename, this)),
_receiver(0),
_config(configTemplate ?
new McastConfiguration(*configTemplate) :
new McastConfiguration()),
_progressTimer(new QTimer(this))
{
_file->open(QIODevice::WriteOnly);
_config->multicastUDPPortBase(port);
// _config->multicastDPort(port+1);
// _config->multicastSPort(port+2);
connect(_progressTimer, SIGNAL(timeout()), SLOT(updateProgress()));
connect(this, SIGNAL(failed(qulonglong, QString const&)), SLOT(removeFile()));
}
PVSIncomingMulticastTransfer::~PVSIncomingMulticastTransfer()
{
// TODO Auto-generated destructor stub
}
bool PVSIncomingMulticastTransfer::start()
{
_file->open(QIODevice::WriteOnly);
_receiver = new McastReceiver(_file, new McastConfiguration(*_config), this);
connect(_receiver, SIGNAL(finished(int)), SLOT(receiverFinished(int)));
connect(_receiver, SIGNAL(progress(quint64)), SLOT(receiverProgressed(quint64)));
if (!_receiver->start())
{
emit retry(_sender, _transferID);
return false;
}
else
{
_progressTimer->start(333);
return true;
}
}
void PVSIncomingMulticastTransfer::abort()
{
delete _receiver;
_receiver = 0;
delete _progressTimer;
_progressTimer = 0;
if(_file)
delete _file;
}
void PVSIncomingMulticastTransfer::updatePort(ushort port)
{
_config->multicastUDPPortBase(port);
_config->multicastSPort(port);
_config->multicastDPort(port);
}
void PVSIncomingMulticastTransfer::receiverProgressed(quint64 bytes)
{
_bytes = bytes;
}
void PVSIncomingMulticastTransfer::receiverFinished(int how)
{
switch(how)
{
case McastReceiver::RES_OK:
emit finished(_transferID);
break;
case McastReceiver::RES_ABORTED:
emit failed(_transferID, tr("Aborted"));
break;
case McastReceiver::RES_MD5_MISMATCH:
case McastReceiver::RES_CHECKSUM_MISMATCH:
emit failed(_transferID, tr("Unrecoverable data corruption"));
break;
case McastReceiver::RES_CONNECTION_RESET:
emit failed(_transferID, tr("Connection was reset"));
break;
case McastReceiver::RES_OFFSET_MISMATCH:
emit failed(_transferID, tr("Unrecoverable data loss. Try a lower transfer rate"));
break;
}
}
void PVSIncomingMulticastTransfer::removeFile()
{
if(_file)
_file->remove();
}
void PVSIncomingMulticastTransfer::updateProgress()
{
if (!_started)
{
emit started(_transferID);
}
emit progress(_transferID, _bytes, _size);
}