summaryrefslogtreecommitdiffstats
path: root/src/pvs.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/pvs.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/pvs.cpp')
-rwxr-xr-xsrc/pvs.cpp261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/pvs.cpp b/src/pvs.cpp
index b343f29..bda16f8 100755
--- a/src/pvs.cpp
+++ b/src/pvs.cpp
@@ -10,11 +10,21 @@
# General information about OpenSLX can be found at http://openslx.org/
*/
+#include <QCryptographicHash>
+#include <QDataStream>
+#include <QDateTime>
+
#include "pvs.h"
#include "src/util/dispatcher.h"
#include "src/net/pvsMsg.h"
#include "src/net/pvsServiceDiscovery.h"
#include "src/net/pvsDiscoveredServer.h"
+#include "src/input/inputEvent.h"
+#include "src/input/inputHandlerChain.h"
+#include "src/input/x11InputUtils.h"
+#include "src/net/mcast/McastConfiguration.h"
+#include "src/net/pvsOutgoingMulticastTransfer.h"
+#include "src/net/pvsIncomingMulticastTransfer.h"
// D-Bus
#include "pvsadaptor.h"
@@ -41,6 +51,9 @@ PVS::PVS() :
/*#endif*/
_vncPort = -1;
+ _masterMcastConfig = new McastConfiguration(this);
+ _masterMcastConfig->loadFrom(&_settings, "multicast");
+
// add a notify to the allow file, so we get informed when the file is changed
QString watchPath(getPolicyDir());
watchPath.append(QString(".allow"));
@@ -80,6 +93,8 @@ PVS::PVS() :
sigaction(SIGHUP, &act, 0);
sigaction(SIGINT, &act, 0);
sigaction(SIGQUIT, &act, 0);
+
+ initializeInputEventHandling();
#endif /*__WIN32__*/
}
@@ -181,6 +196,67 @@ void PVS::onCommand(PVSMsg cmdMessage)
unlock();
return;
}
+ if (ident.compare("INPUTEVENT") == 0)
+ {
+ InputEvent evt;
+ eventFromString(message, evt);
+ handleInputEvent(evt);
+ }
+ if (ident.compare("MCASTFTRETRY") == 0)
+ {
+ QStringList fields = message.split(':');
+ if (fields[0].compare(getUserName()) == 0)
+ {
+ quint64 id = fields[1].toULongLong();
+ PVSOutgoingMulticastTransfer* transfer = _outgoingTransfers.value(id, 0);
+ if (transfer)
+ transfer->retry();
+ }
+ }
+ if (ident.compare("MCASTFTANNOUNCE") == 0)
+ {
+ QStringList fields = message.split(':');
+ bool ok;
+ QString sender;
+ qulonglong transferID;
+ QString basename;
+ qulonglong size;
+ ushort port;
+
+ if (!fields.size() == 5)
+ {
+ goto malformedAnnounce;
+ }
+ sender = fields[0];
+ transferID = fields[1].toULongLong(&ok);
+ if (!ok)
+ {
+ goto malformedAnnounce;
+ }
+ basename = fields[2];
+ size = fields[3].toULongLong(&ok);
+ if (!ok)
+ {
+ goto malformedAnnounce;
+ }
+ port = fields[4].toUShort(&ok);
+ if (!ok)
+ {
+ goto malformedAnnounce;
+ }
+
+ onIncomingMulticastTransfer(sender, transferID, basename, size, port);
+ return;
+
+ malformedAnnounce:
+ qDebug() << "Ignoring malformed MCASTFTANNOUNCE command: " << message;
+ return;
+ }
+ if (ident.compare("MCASTFTCONFIG") == 0)
+ {
+ loadMcastConfig(message);
+ return;
+ }
if (ident.compare("SHOWPROCESSES") == 0)
{
_pvsServerConnection->sendMessage(PVSMsg(PVSCOMMAND, "PROCESSES", "SHOW clear")); //tell the client that we want to clear his process-list
@@ -652,6 +728,191 @@ void PVS::signalHandler(int signal)
}
+bool PVS::createMulticastTransfer(QString const& objectPath, quint64& transferID, QString& errorReason)
+{
+ transferID = generateMcastTransferID();
+
+ PVSOutgoingMulticastTransfer* transfer = new PVSOutgoingMulticastTransfer(getUserName(), transferID, objectPath, this);
+ if (transfer->isError())
+ {
+ errorReason = transfer->reason();
+ delete transfer;
+ return false;
+ }
+
+ _outgoingTransfers.insert(transferID, transfer);
+ connect(transfer, SIGNAL(started(qulonglong)), SIGNAL(outgoingMulticastTransferStarted(qulonglong)));
+ connect(transfer, SIGNAL(finished(qulonglong)), SIGNAL(outgoingMulticastTransferFinished(qulonglong)));
+ connect(transfer, SIGNAL(failed(qulonglong, QString const)), SIGNAL(outgoingMulticastTransferFailed(qulonglong, QString const)));
+ connect(transfer, SIGNAL(progress(qulonglong, qulonglong, qulonglong)), SIGNAL(outgoingMulticastTransferProgress(qulonglong, qulonglong, qulonglong)));
+ connect(transfer, SIGNAL(announce(PVSMsg)), _pvsServerConnection, SLOT(sendMessage(PVSMsg)));
+ connect(transfer, SIGNAL(finished(qulonglong)), SLOT(outgoingMulticastTransferDelete(qulonglong)));
+ connect(transfer, SIGNAL(failed(qulonglong, QString const)), SLOT(outgoingMulticastTransferDelete(qulonglong)));
+ QTimer::singleShot(0, transfer, SLOT(start()));
+ errorReason = "";
+ return true;
+}
+
+// Input handling
+
+void PVS::handleInputEvent(InputEvent const& evt)
+{
+ std::string s = evt.toString();
+ ConsoleLog writeLine(QString("Received input event: %1").arg(s.c_str()));
+ _inputEventHandlers.handle(evt);
+}
+
+void PVS::initializeInputEventHandling()
+{
+ X11InputUtils::setDisplay(X11Info::display());
+ _inputEventHandlers.initialize();
+}
+
+void PVS::cancelOutgoingMulticastTransfer(quint64 transferID)
+{
+ PVSOutgoingMulticastTransfer* transfer = _outgoingTransfers.value(transferID, 0);
+
+ if (transfer)
+ {
+ _outgoingTransfers.remove(transferID);
+ delete transfer;
+ }
+}
+
+void PVS::cancelIncomingMulticastTransfer(qulonglong transferID)
+{
+ PVSIncomingMulticastTransfer* transfer = _incomingTransfers.value(transferID, 0);
+
+ if(transfer)
+ {
+ _incomingTransfers.remove(transferID);
+ delete transfer;
+ }
+}
+
+void PVS::onIncomingMulticastTransfer(QString const& sender, qulonglong transferID,
+ QString const& basename, qulonglong size, ushort port)
+{
+ if (_outgoingTransfers.contains(transferID))
+ return;
+
+ PVSIncomingMulticastTransfer* transfer;
+ if (transfer = _incomingTransfers.value(transferID, 0))
+ {
+ transfer->updatePort(port);
+ QTimer::singleShot(0, transfer, SLOT(start()));
+ }
+ else
+ {
+ QString filename = QFileInfo(QDir::home(), QString("%1.part.%2").arg(basename).arg(transferID, 0, 16)).absoluteFilePath();
+ transfer = new PVSIncomingMulticastTransfer(sender, transferID, size, filename, port, _masterMcastConfig, this);
+ _incomingTransfers.insert(transferID, transfer);
+
+ connect(transfer, SIGNAL(retry(QString const&, qulonglong)), SLOT(onIncomingMulticastTransferRetry(QString const&, qulonglong)));
+ connect(transfer, SIGNAL(started(qulonglong)), SIGNAL(incomingMulticastTransferStarted(qulonglong)));
+ connect(transfer, SIGNAL(progress(qulonglong, qulonglong, qulonglong)), SIGNAL(incomingMulticastTransferProgress(qulonglong, qulonglong, qulonglong)));
+ connect(transfer, SIGNAL(finished(qulonglong)), SIGNAL(incomingMulticastTransferFinished(qulonglong)));
+ connect(transfer, SIGNAL(failed(qulonglong, QString const&)), SIGNAL(incomingMulticastTransferFailed(qulonglong, QString)));
+ connect(transfer, SIGNAL(finished(qulonglong)), SLOT(incomingMulticastTransferDelete(qulonglong)));
+ connect(transfer, SIGNAL(failed(qulonglong, QString const&)), SLOT(incomingMulticastTransferDelete(qulonglong)));
+
+ emit incomingMulticastTransferNew(transferID, sender, filename, size);
+ QTimer::singleShot(0, transfer, SLOT(start()));
+ }
+}
+
+void PVS::onIncomingMulticastTransferRetry(QString const& sender, qulonglong transferID)
+{
+ PVSMsg retryMessage(PVSCOMMAND, "MCASTFTRETRY", QString("%1:%2").arg(sender).arg(transferID));
+ _pvsServerConnection->sendMessage(retryMessage);
+}
+
+quint64 PVS::generateMcastTransferID()
+{
+ static quint64 nodeID = 0;
+ static quint16 counter = 0;
+
+ if (!nodeID)
+ {
+ QDateTime t = QDateTime::currentDateTime();
+ QCryptographicHash h(QCryptographicHash::Md5);
+ h.addData(getUserName().toLocal8Bit());
+ h.addData(t.toString().toLocal8Bit());
+ QDataStream(h.result()) >> nodeID;
+ }
+
+ return (nodeID & Q_UINT64_C(0xffffffffffff0000)) | (quint64)(++counter);
+}
+
+void PVS::outgoingMulticastTransferDelete(qulonglong transferID)
+{
+ PVSOutgoingMulticastTransfer* transfer = _outgoingTransfers.value(transferID, 0);
+ if (!transfer)
+ return;
+
+ _outgoingTransfers.remove(transferID);
+ transfer->deleteLater();
+}
+
+void PVS::incomingMulticastTransferDelete(qulonglong transferID)
+{
+ PVSIncomingMulticastTransfer* transfer = _incomingTransfers.value(transferID, 0);
+ if (!transfer)
+ {
+ return;
+ }
+
+ _incomingTransfers.remove(transferID);
+ transfer->deleteLater();
+}
+
+void PVS::loadMcastConfig(QString const& message)
+{
+ QByteArray ba = QByteArray::fromBase64(message.toAscii());
+ QDataStream d(&ba, QIODevice::ReadOnly);
+ quint16 ver, udpp, dp, sp, mtu, wsz;
+ quint32 rate;
+ QString addr;
+ bool useudp;
+
+ d >> ver;
+ if(ver != 1)
+ {
+ ConsoleLog writeLine(QString("Unable to decode multicast configuration message: Unknown version %1").arg(ver));
+ return;
+ }
+
+ d >> addr
+ >> udpp
+ >> dp
+ >> sp
+ >> mtu
+ >> wsz
+ >> rate
+ >> useudp;
+ if(d.status() != QDataStream::Ok)
+ {
+ ConsoleLog writeLine(QString("Unable to decode multicast configuration message: There was an error reading"));
+ return;
+ }
+
+ _masterMcastConfig->multicastUDPPortBase(udpp);
+ _masterMcastConfig->multicastDPort(dp);
+ _masterMcastConfig->multicastSPort(sp);
+ _masterMcastConfig->multicastMTU(mtu);
+ _masterMcastConfig->multicastWinSize(wsz);
+ _masterMcastConfig->multicastRate(rate);
+ _masterMcastConfig->multicastAddress(addr);
+ _masterMcastConfig->multicastUseUDP(useudp);
+
+ QSettings settings;
+ _masterMcastConfig->writeTo(&settings, "multicast");
+ settings.sync();
+
+ ConsoleLog writeLine(QString("Reconfigured multicast filetransfer to IP %1, UDP port base %2, destination port %3, source port %4, MTU %5, Window Size %6, rate %7, %8using UDP")
+ .arg(addr).arg(udpp).arg(dp).arg(sp).arg(mtu).arg(wsz).arg(rate).arg(useudp ? "" : "not "));
+}
+
void PVS::setConfigValue(QString key, QString value)
{
_settings.setValue(key, value);