summaryrefslogtreecommitdiffstats
path: root/src/net/mcast/McastReceiver.cpp
diff options
context:
space:
mode:
authorSebastien Braun2010-10-06 00:04:49 +0200
committerSebastien Braun2010-10-06 00:04:49 +0200
commitf07fc3b426815e28fde23313242fbbb998a08d45 (patch)
treeba9eda1a83135a1727d2d35661d6facabee53b95 /src/net/mcast/McastReceiver.cpp
parentFix recognition of letters in keyboard handler (diff)
parentMerge remote branch 'openslx/master' into mcastft (diff)
downloadpvs-f07fc3b426815e28fde23313242fbbb998a08d45.tar.gz
pvs-f07fc3b426815e28fde23313242fbbb998a08d45.tar.xz
pvs-f07fc3b426815e28fde23313242fbbb998a08d45.zip
Merge remote branch 'openslx/mcastft' into input
Conflicts: CMakeLists.txt i18n/pvs_ar_JO.ts i18n/pvs_de_DE.ts i18n/pvs_es_MX.ts i18n/pvs_fr_FR.ts i18n/pvs_pl_PL.ts i18n/pvsmgr_ar_JO.ts i18n/pvsmgr_de_DE.ts i18n/pvsmgr_es_MX.ts i18n/pvsmgr_fr_FR.ts i18n/pvsmgr_pl_PL.ts icons/README pvsmgr.qrc src/gui/mainWindow.cpp src/pvs.cpp src/pvs.h src/pvsDaemon.cpp src/util/clientGUIUtils.h
Diffstat (limited to 'src/net/mcast/McastReceiver.cpp')
-rw-r--r--src/net/mcast/McastReceiver.cpp179
1 files changed, 179 insertions, 0 deletions
diff --git a/src/net/mcast/McastReceiver.cpp b/src/net/mcast/McastReceiver.cpp
new file mode 100644
index 0000000..1f27127
--- /dev/null
+++ b/src/net/mcast/McastReceiver.cpp
@@ -0,0 +1,179 @@
+/*
+# 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 <QDataStream>
+#include <QtDebug>
+#include <QtGlobal>
+
+#include <pgm/pgm.h>
+// OpenPGM #defines bool. This is bad in C++.
+#undef bool
+
+#include "McastConstants.h"
+#include "McastReceiver.h"
+
+McastReceiver::McastReceiver(QIODevice* iodev, McastConfiguration* config, QObject* parent) :
+ QObject(parent),
+ _config(config ? new McastConfiguration(*config) : 0),
+ _socket(0),
+ _curoffs(0),
+ _closed(false),
+ _hash(QCryptographicHash::Md5),
+ _iodev(iodev)
+{
+ _config->setParent(this);
+}
+
+McastReceiver::~McastReceiver()
+{
+ if (_config)
+ delete _config;
+}
+
+void McastReceiver::config(McastConfiguration const* config)
+{
+ if (_config)
+ delete _config;
+ _config = new McastConfiguration(*config, this);
+}
+
+bool McastReceiver::start()
+{
+ McastConfiguration *config = _config;
+ if (!config)
+ config = new McastConfiguration();
+
+ if (_socket)
+ {
+ delete _socket;
+ }
+ _socket = new McastPGMSocket(this);
+
+ connect(_socket, SIGNAL(receivedPacket(QByteArray)), SLOT(receivedPacket(QByteArray)));
+ connect(_socket, SIGNAL(connectionReset()), SLOT(connectionReset()));
+ // connect(_socket, SIGNAL(connectionFinished()), this, SLOT(connectionFinished()));
+ if (_socket->open(_config, McastPGMSocket::PSOCK_READ))
+ {
+ return true;
+ }
+ else
+ {
+ disconnect(_socket, SIGNAL(receivedPacket(QByteArray)), this, SLOT(receivedPacket(QByteArray)));
+ disconnect(_socket, SIGNAL(connectionReset()), this, SLOT(connectionReset()));
+ return false;
+ }
+}
+
+void McastReceiver::abort()
+{
+ if (_socket)
+ {
+ delete _socket;
+ _socket = 0;
+ }
+
+ if (_iodev)
+ {
+ _iodev->close();
+ }
+}
+
+void McastReceiver::receivedPacket(QByteArray const& bytes)
+{
+ if(_closed)
+ return;
+
+ quint16 checksum_should = qChecksum(bytes.constData(), bytes.size() - 2);
+
+ QDataStream strm(bytes);
+ strm.setByteOrder(QDataStream::BigEndian);
+
+ // read the packet
+ quint64 magic;
+ quint64 offset;
+ quint16 checksum;
+
+
+ strm >> magic;
+ if(magic != MCASTFT_MAGIC)
+ {
+ qCritical() << "Received packet whose magic number does not match. Ignoring.";
+ return;
+ }
+
+ strm >> offset;
+ qDebug() << " Received packet for offset" << offset;
+
+ if (offset == UINT64_C(0xffffffffffffffff))
+ {
+ // this is the end of the data stream.
+ QByteArray md5;
+ strm >> md5;
+
+ quint16 fchecksum;
+ strm >> fchecksum;
+
+ // compare the hash value
+ if ((fchecksum != checksum_should) || (md5 != _hash.result()))
+ {
+ _close(RES_MD5_MISMATCH);
+ }
+ else
+ {
+ _close(RES_OK);
+ }
+
+ return;
+ }
+ else if (offset != _curoffs)
+ {
+ qCritical() << "Packet loss or double delivery. PGM should have prevented this. Bailing out.";
+ _close(RES_OFFSET_MISMATCH);
+ return;
+ }
+
+ QByteArray contents;
+ strm >> contents;
+ _curoffs += contents.size();
+
+ strm >> checksum;
+ if(checksum != checksum_should)
+ {
+ qCritical() << "Checksum does not match. Bailing out.";
+ _close(RES_CHECKSUM_MISMATCH);
+ return;
+ }
+
+ _hash.addData(contents);
+
+ _iodev->write(contents);
+
+ emit progress(_curoffs);
+}
+
+void McastReceiver::connectionReset()
+{
+ _close(RES_CONNECTION_RESET);
+}
+
+void McastReceiver::_close(Result result)
+{
+ _iodev->close();
+ _socket->finish();
+
+ _closed = true;
+ emit finished(result);
+}