summaryrefslogtreecommitdiffstats
path: root/src/net/mcast/McastSender.cpp
diff options
context:
space:
mode:
authorFabian Schillinger2010-11-01 17:35:27 +0100
committerFabian Schillinger2010-11-01 17:35:27 +0100
commitea3fb17345e5f82db9f2e98a8062e95797700ace (patch)
tree1da0d1a8ec9455364386af78762d0f6fed187824 /src/net/mcast/McastSender.cpp
parentProcess start/stop/view functionality (diff)
parent[PVSGUI] No X required for --help and --version (diff)
downloadpvs-ea3fb17345e5f82db9f2e98a8062e95797700ace.tar.gz
pvs-ea3fb17345e5f82db9f2e98a8062e95797700ace.tar.xz
pvs-ea3fb17345e5f82db9f2e98a8062e95797700ace.zip
Merge branch 'master' of openslx.org:pvs
Conflicts: CMakeLists.txt src/core/pvsConnectionManager.cpp src/pvs.cpp src/pvs.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();
+}