summaryrefslogtreecommitdiffstats
path: root/src/net/mcast/McastSender.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/McastSender.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/McastSender.cpp')
-rw-r--r--src/net/mcast/McastSender.cpp127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/net/mcast/McastSender.cpp b/src/net/mcast/McastSender.cpp
new file mode 100644
index 0000000..3fec6a4
--- /dev/null
+++ b/src/net/mcast/McastSender.cpp
@@ -0,0 +1,127 @@
+/*
+# 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 <QTimer>
+
+#include <pgm/pgm.h>
+// OpenPGM #defines bool. This is bad in C++.
+#undef bool
+
+#define MCASTFT_START_DEFER_TIME 2000 /* msec */
+
+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(deferredStart()));
+ _socket->open(_config, McastPGMSocket::PSOCK_WRITE);
+}
+
+void McastSender::start(McastPGMSocket* socket)
+{
+ _socket = socket;
+ Q_ASSERT(_socket->isOpen());
+ deferredStart();
+}
+
+void McastSender::deferredStart()
+{
+ // Wait some time, to give the PGM library the chance to generate some
+ // undisturbed SPM messages:
+ QTimer::singleShot(MCASTFT_START_DEFER_TIME, this, SLOT(readyToSend()));
+ disconnect(_socket, SIGNAL(readyToSend()), this, SLOT(deferredStart()));
+ connect(_socket, SIGNAL(readyToSend()), this, SLOT(readyToSend()));
+}
+
+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()
+{
+ _socket->deleteLater();
+ emit finished();
+}