summaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/core/pvsConnectionManager.cpp19
-rw-r--r--src/gui/clientChatDialog.cpp2
-rw-r--r--src/gui/clientConfigDialog.cpp104
-rw-r--r--src/gui/clientConfigDialog.h5
-rw-r--r--src/gui/clientFileReceiveDialog.cpp95
-rw-r--r--src/gui/clientFileReceiveDialog.h14
-rw-r--r--src/gui/clientFileSendDialog.cpp203
-rw-r--r--src/gui/clientFileSendDialog.h21
-rw-r--r--src/gui/clientVNCViewer.cpp2
-rw-r--r--src/gui/mainWindow.cpp1320
-rw-r--r--src/gui/mainWindow.h4
-rw-r--r--src/gui/multicastConfigDialog.cpp170
-rw-r--r--src/gui/multicastConfigDialog.h38
-rw-r--r--src/gui/ui/clientConfigDialog.ui64
-rw-r--r--src/gui/ui/clientFileReceiveDialog.ui11
-rw-r--r--src/gui/ui/clientFileSendDialog.ui15
-rw-r--r--src/gui/ui/clientNicklistDialog.ui7
-rw-r--r--src/gui/ui/clientToolbar.ui42
-rw-r--r--src/gui/ui/mainwindow.ui34
-rw-r--r--src/gui/ui/mainwindowtouch.ui28
-rw-r--r--src/gui/ui/multicastConfigDialog.ui156
-rw-r--r--src/net/SslServer.cpp4
-rw-r--r--src/net/mcast/CMakeLists.txt61
-rw-r--r--src/net/mcast/McastConfiguration.cpp57
-rw-r--r--src/net/mcast/McastConfiguration.h204
-rw-r--r--src/net/mcast/McastConstants.h36
-rw-r--r--src/net/mcast/McastPGMSocket.cpp666
-rw-r--r--src/net/mcast/McastPGMSocket.h81
-rw-r--r--src/net/mcast/McastReceiver.cpp179
-rw-r--r--src/net/mcast/McastReceiver.h80
-rw-r--r--src/net/mcast/McastSender.cpp127
-rw-r--r--src/net/mcast/McastSender.h73
-rw-r--r--src/net/mcast/trial_programs/CMakeLists.txt38
-rw-r--r--src/net/mcast/trial_programs/McastConfigArgParser.cpp165
-rw-r--r--src/net/mcast/trial_programs/McastConfigArgParser.h26
-rw-r--r--src/net/mcast/trial_programs/mcastreceive.cpp150
-rw-r--r--src/net/mcast/trial_programs/mcastreceive.h44
-rw-r--r--src/net/mcast/trial_programs/mcastsend.cpp122
-rw-r--r--src/net/mcast/trial_programs/mcastsend.h42
-rw-r--r--src/net/pvsClientConnection.cpp2
-rw-r--r--src/net/pvsDiscoveredServer.cpp22
-rw-r--r--src/net/pvsIncomingMulticastTransfer.cpp133
-rw-r--r--src/net/pvsIncomingMulticastTransfer.h71
-rw-r--r--src/net/pvsListenServer.cpp67
-rw-r--r--src/net/pvsListenServer.h12
-rw-r--r--src/net/pvsLocalhostCommunicator.cpp6
-rw-r--r--src/net/pvsNetworkInterfaceListModel.cpp81
-rw-r--r--src/net/pvsNetworkInterfaceListModel.h35
-rw-r--r--src/net/pvsOutgoingMulticastTransfer.cpp209
-rw-r--r--src/net/pvsOutgoingMulticastTransfer.h92
-rw-r--r--src/net/pvsServerConnection.cpp2
-rw-r--r--src/net/pvsServerConnection.h7
-rw-r--r--src/net/pvsServiceBroadcast.cpp18
-rw-r--r--src/net/pvsServiceBroadcast.h2
-rw-r--r--src/net/pvsServiceDiscovery.cpp2
-rwxr-xr-x[-rw-r--r--]src/pvs.cpp323
-rwxr-xr-x[-rw-r--r--]src/pvs.h55
-rw-r--r--src/pvsDaemon.cpp234
-rw-r--r--src/pvsgui.cpp269
-rw-r--r--src/pvsgui.h12
-rw-r--r--src/pvsmgr.cpp2
-rw-r--r--src/pvsmgrtouch.cpp3
-rw-r--r--src/util/clientGUIUtils.cpp10
-rwxr-xr-x[-rw-r--r--]src/util/clientGUIUtils.h27
-rwxr-xr-xsrc/util/clientGUIUtils_Win32.cpp46
-rwxr-xr-xsrc/util/clientGUIUtils_X11.cpp179
-rwxr-xr-x[-rw-r--r--]src/util/consoleLogger.cpp10
-rw-r--r--src/util/consoleLogger.h2
-rw-r--r--src/util/pvsSettingsManager.cpp185
-rw-r--r--src/util/pvsSettingsManager.h50
-rwxr-xr-x[-rw-r--r--]src/util/util.cpp64
-rwxr-xr-x[-rw-r--r--]src/util/util.h6
-rw-r--r--src/version.h4
73 files changed, 5370 insertions, 1381 deletions
diff --git a/src/core/pvsConnectionManager.cpp b/src/core/pvsConnectionManager.cpp
index 8a35ca9..5bf6418 100644
--- a/src/core/pvsConnectionManager.cpp
+++ b/src/core/pvsConnectionManager.cpp
@@ -218,6 +218,25 @@ void PVSConnectionManager::onCommand(PVSMsg command)
break;
}
}
+ else if (ident == "MCASTFTANNOUNCE")
+ {
+ _pvsServer.sendToAll(command);
+ }
+ else if (ident == "MCASTFTRETRY")
+ {
+ QStringList fields = message.split(':');
+ if (!fields.size() == 2)
+ {
+ qDebug() << "Malformed MCASTFTRETRY message:" << message;
+ return;
+ }
+
+ PVSClient* client = getClientFromUsername(fields[0]);
+ if (client)
+ {
+ client->sendMessage(command);
+ }
+ }
}
void PVSConnectionManager::onChat(PVSMsg chatMsg)
{
diff --git a/src/gui/clientChatDialog.cpp b/src/gui/clientChatDialog.cpp
index 7c32790..163ac92 100644
--- a/src/gui/clientChatDialog.cpp
+++ b/src/gui/clientChatDialog.cpp
@@ -29,8 +29,6 @@ ClientChatDialog::ClientChatDialog(QWidget *parent) :
// connect to D-Bus and get interface
QDBusConnection dbus = QDBusConnection::sessionBus();
- dbus.registerObject("/chat", this);
- dbus.registerService("org.openslx.pvsgui");
_ifaceDBus = new OrgOpenslxPvsInterface("org.openslx.pvs", "/", dbus, this);
connect(_ifaceDBus, SIGNAL(chat_receive(QString, QString, QString)), this,
SLOT(receive(QString, QString, QString)));
diff --git a/src/gui/clientConfigDialog.cpp b/src/gui/clientConfigDialog.cpp
index 76b4f5e..b7ba407 100644
--- a/src/gui/clientConfigDialog.cpp
+++ b/src/gui/clientConfigDialog.cpp
@@ -16,16 +16,33 @@
# -----------------------------------------------------------------------------
*/
+#include <QtDebug>
+#include <QNetworkInterface>
+#include <QStandardItemModel>
#include "clientConfigDialog.h"
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+#include <src/net/pvsNetworkInterfaceListModel.h>
+
+using namespace std;
ClientConfigDialog::ClientConfigDialog(QWidget *parent) :
- QDialog(parent)
+ QDialog(parent),
+ _interfaceListModel(0)
{
setupUi(this);
connect(this, SIGNAL(accepted()), this, SLOT(writeSettings()));
connect(radioButtonOtherRO, SIGNAL(clicked()), this,
SLOT(checkPermissions()));
+ _interfaceListModel = new PVSNetworkInterfaceListModel(this);
+ interfaceList->setModel(_interfaceListModel);
+ interfaceList->setModelColumn(0);
+ connect(reloadInterfaceListButton, SIGNAL(clicked()), _interfaceListModel, SLOT(reloadInterfaceList()));
+ // connect to D-Bus and get interface
+ QDBusConnection dbus = QDBusConnection::sessionBus();
+ _ifaceDBus = new OrgOpenslxPvsInterface("org.openslx.pvs", "/", dbus, this);
}
ClientConfigDialog::~ClientConfigDialog()
@@ -49,50 +66,73 @@ void ClientConfigDialog::readSettings()
else
comboBox->setCurrentIndex(_settings.value("Display/location").toInt());
- if (_settings.value("Permissions/vnc_lecturer").toString() == "rw")
- radioButtonLecturerRW->setChecked(true);
- else if (_settings.value("Permissions/vnc_lecturer").toString() == "ro")
- radioButtonLecturerRO->setChecked(true);
- else
- radioButtonLecturerNO->setChecked(true);
- if (_settings.value("Permissions/vnc_other").toString() == "rw")
- radioButtonOtherRW->setChecked(true);
- else if (_settings.value("Permissions/vnc_other").toString() == "ro")
- radioButtonOtherRO->setChecked(true);
- else
- radioButtonOtherNO->setChecked(true);
- checkBoxAllowChat->setChecked(
- _settings.value("Permissions/allow_chat").toBool());
- checkBoxAllowFiletransfer->setChecked(_settings.value(
- "Permissions/allow_filetransfer").toBool());
-
- qDebug("[%s] Setting read from: '%s'", metaObject()->className(),
- qPrintable(_settings.fileName()));
+ QDBusPendingReply<QString> reply = _ifaceDBus->getConfigValue("multicast/interface");
+ reply.waitForFinished();
+ if (reply.isValid())
+ {
+ interfaceList->setEditText(reply.value());
+ }
+
+ reply = _ifaceDBus->getConfigValue("Permissions/vnc_lecturer");
+ reply.waitForFinished();
+ if (reply.isValid())
+ {
+ if (reply.value() == "rw")
+ radioButtonLecturerRW->setChecked(true);
+ else if (reply.value() == "ro")
+ radioButtonLecturerRO->setChecked(true);
+ else
+ radioButtonLecturerNO->setChecked(true);
+ }
+
+ reply = _ifaceDBus->getConfigValue("Permissions/vnc_other");
+ reply.waitForFinished();
+ if (reply.isValid())
+ {
+ if (reply.value() == "rw")
+ radioButtonOtherRW->setChecked(true);
+ else if (reply.value() == "ro")
+ radioButtonOtherRO->setChecked(true);
+ else
+ radioButtonOtherNO->setChecked(true);
+ }
+
+ reply = _ifaceDBus->getConfigValue("Permissions/allow_chat");
+ reply.waitForFinished();
+ if (reply.isValid())
+ checkBoxAllowChat->setChecked(reply.value() == "T");
+
+ reply = _ifaceDBus->getConfigValue("Permissions/allow_filetransfer");
+ reply.waitForFinished();
+ if (reply.isValid())
+ checkBoxAllowFiletransfer->setChecked(reply.value() == "T");
}
void ClientConfigDialog::writeSettings()
{
_settings.setValue("Display/location", comboBox->currentIndex());
+
if (radioButtonLecturerRW->isChecked())
- _settings.setValue("Permissions/vnc_lecturer", "rw");
+ _ifaceDBus->setConfigValue("Permissions/vnc_lecturer", "rw");
else if (radioButtonLecturerRO->isChecked())
- _settings.setValue("Permissions/vnc_lecturer", "ro");
+ _ifaceDBus->setConfigValue("Permissions/vnc_lecturer", "ro");
else
- _settings.setValue("Permissions/vnc_lecturer", "no");
+ _ifaceDBus->setConfigValue("Permissions/vnc_lecturer", "no");
if (radioButtonOtherRW->isChecked())
- _settings.setValue("Permissions/vnc_other", "rw");
+ _ifaceDBus->setConfigValue("Permissions/vnc_other", "rw");
else if (radioButtonOtherRO->isChecked())
- _settings.setValue("Permissions/vnc_other", "ro");
+ _ifaceDBus->setConfigValue("Permissions/vnc_other", "ro");
else
- _settings.setValue("Permissions/vnc_other", "no");
- _settings.setValue("Permissions/allow_chat", checkBoxAllowChat->isChecked());
- _settings.setValue("Permissions/allow_filetransfer",
- checkBoxAllowFiletransfer->isChecked());
+ _ifaceDBus->setConfigValue("Permissions/vnc_other", "no");
+
+ _ifaceDBus->setConfigValue("Permissions/allow_chat",
+ QString(checkBoxAllowChat->isChecked() ? "T" : "F"));
+ _ifaceDBus->setConfigValue("Permissions/allow_filetransfer",
+ QString(checkBoxAllowFiletransfer->isChecked() ? "T" : "F"));
+ _ifaceDBus->setConfigValue("multicast/interface", interfaceList->currentText());
+
_settings.sync();
emit configChanged();
-
- qDebug("[%s] Settings written to: '%s'.", metaObject()->className(),
- qPrintable(_settings.fileName()));
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gui/clientConfigDialog.h b/src/gui/clientConfigDialog.h
index 706bd8a..fd7529e 100644
--- a/src/gui/clientConfigDialog.h
+++ b/src/gui/clientConfigDialog.h
@@ -15,8 +15,11 @@
#define CLIENTCONFIGDIALOG_H_
#include <QtGui>
+#include "pvsinterface.h"
#include "ui_clientConfigDialog.h"
+class QAbstractItemModel;
+
class ClientConfigDialog: public QDialog, private Ui::ClientConfigDialogClass
{
Q_OBJECT
@@ -37,7 +40,9 @@ private Q_SLOTS:
void checkPermissions();
private:
+ OrgOpenslxPvsInterface *_ifaceDBus;
QSettings _settings;
+ QAbstractItemModel* _interfaceListModel;
};
diff --git a/src/gui/clientFileReceiveDialog.cpp b/src/gui/clientFileReceiveDialog.cpp
index 669ca81..fc6a1a3 100644
--- a/src/gui/clientFileReceiveDialog.cpp
+++ b/src/gui/clientFileReceiveDialog.cpp
@@ -16,6 +16,9 @@
*/
#include "clientFileReceiveDialog.h"
+#include <pvsinterface.h>
+#include <QFileInfo>
+#include <limits.h>
ClientFileReceiveDialog::ClientFileReceiveDialog(QTcpSocket *socket, QWidget *parent) :
QDialog(parent)
@@ -37,9 +40,44 @@ ClientFileReceiveDialog::ClientFileReceiveDialog(QTcpSocket *socket, QWidget *pa
connect(this, SIGNAL(finished(int)), this, SLOT(deleteLater()));
}
+ClientFileReceiveDialog::ClientFileReceiveDialog(QString const& sender, qulonglong transferID,
+ QString const& filename, qulonglong size, OrgOpenslxPvsInterface* ifaceDBus, QWidget* parent)
+{
+ setupUi(this);
+
+ _transferID = transferID;
+ _filename = filename;
+ _ifaceDBus = ifaceDBus;
+ _bytesToRead = size;
+ _socket = 0;
+ _file = 0;
+ div = 1;
+ while((size / div) > INT_MAX)
+ {
+ div <<= 1;
+ }
+
+ connect(ifaceDBus, SIGNAL(incomingMulticastTransferStarted(qulonglong)), SLOT(mcastTransferStarted(qulonglong)));
+ connect(ifaceDBus, SIGNAL(incomingMulticastTransferProgress(qulonglong, qulonglong, qulonglong)),
+ SLOT(mcastTransferProgress(qulonglong, qulonglong, qulonglong)));
+ connect(ifaceDBus, SIGNAL(incomingMulticastTransferFinished(qulonglong)), SLOT(mcastTransferFinished(qulonglong)));
+ connect(ifaceDBus, SIGNAL(incomingMulticastTransferFailed(qulonglong, QString)), SLOT(mcastTransferFailed(qulonglong, QString)));
+ connect(cancelButton, SIGNAL(clicked()), SLOT(cancelTransfer()));
+
+ qDebug("[%s] New multicast incoming transfer: %s from %s", metaObject()->className(),
+ filename.toLocal8Bit().constData(), sender.toLocal8Bit().constData());
+
+
+ filenameLabel->setText(QFileInfo(filename).baseName());
+ labelNick->setText(sender);
+ progressBar->setRange(0, 0);
+}
+
+
ClientFileReceiveDialog::~ClientFileReceiveDialog()
{
- _socket->deleteLater();
+ if(_socket)
+ _socket->deleteLater();
qDebug("[%s] Deleted!", metaObject()->className());
}
@@ -168,6 +206,61 @@ void ClientFileReceiveDialog::error(QAbstractSocket::SocketError error)
close();
}
+void ClientFileReceiveDialog::mcastTransferStarted(qulonglong transferID)
+{
+ if(transferID != _transferID)
+ return;
+}
+
+void ClientFileReceiveDialog::mcastTransferProgress(qulonglong transferID, qulonglong bytes, qulonglong of)
+{
+ if(transferID != _transferID)
+ return;
+
+ progressBar->setRange(0, of);
+ progressBar->setValue(bytes);
+
+ labelA->setText(formatSize(bytes));
+ labelB->setText(formatSize(of));
+}
+
+void ClientFileReceiveDialog::mcastTransferFinished(qulonglong transferID)
+{
+ if(transferID != _transferID)
+ return;
+
+ QString filename = QFileDialog::getSaveFileName(this, tr("Where should I save %1?").arg(_filename), _filename);
+ QFile* file = new QFile(_filename);
+ if(filename.isNull() || filename.isEmpty())
+ {
+ file->remove();
+ }
+ else
+ {
+ if(!file->rename(filename))
+ {
+ QMessageBox::warning(this, tr("Could not rename file"), tr("Failed to rename %1 to %2").arg(_filename).arg(filename));
+ }
+ }
+ accept();
+ deleteLater();
+}
+
+void ClientFileReceiveDialog::mcastTransferFailed(qulonglong transferID, QString reason)
+{
+ if(transferID != _transferID)
+ return;
+
+ QMessageBox::warning(this, tr("File transfer failed"), tr("File transfer failed for the following reason:\n%1").arg(reason));
+ reject();
+ deleteLater();
+}
+
+void ClientFileReceiveDialog::cancelTransfer()
+{
+ _ifaceDBus->cancelIncomingMulticastTransfer(_transferID);
+}
+
QString ClientFileReceiveDialog::formatSize(qint64 size)
{
if (size >= 1000000000) // GB
diff --git a/src/gui/clientFileReceiveDialog.h b/src/gui/clientFileReceiveDialog.h
index c13d7b7..c9ed220 100644
--- a/src/gui/clientFileReceiveDialog.h
+++ b/src/gui/clientFileReceiveDialog.h
@@ -18,6 +18,8 @@
#include <QtNetwork>
#include "ui_clientFileReceiveDialog.h"
+class OrgOpenslxPvsInterface;
+
class ClientFileReceiveDialog: public QDialog,
private Ui::ClientFileReceiveDialogClass
{
@@ -25,6 +27,7 @@ Q_OBJECT
public:
ClientFileReceiveDialog(QTcpSocket *socket, QWidget *parent = 0);
+ ClientFileReceiveDialog(QString const& sender, qulonglong transferID, QString const& basename, qulonglong size, OrgOpenslxPvsInterface* ifaceDBus, QWidget* parent = 0);
~ClientFileReceiveDialog();
private Q_SLOTS:
@@ -33,6 +36,13 @@ private Q_SLOTS:
void close();
void error(QAbstractSocket::SocketError error);
+ // multicast:
+ void mcastTransferStarted(qulonglong transferID);
+ void mcastTransferProgress(qulonglong transferID, qulonglong bytes, qulonglong of);
+ void mcastTransferFinished(qulonglong transferID);
+ void mcastTransferFailed(qulonglong transferID, QString reason);
+ void cancelTransfer();
+
private:
void sendAck(bool b);
QString formatSize(qint64 size);
@@ -42,6 +52,10 @@ private:
qint64 _bytesToRead;
int div;
+ // multicast:
+ OrgOpenslxPvsInterface* _ifaceDBus;
+ QString _filename;
+ qulonglong _transferID;
};
#endif /* CLIENTFILERECEIVEDIALOG_H_ */
diff --git a/src/gui/clientFileSendDialog.cpp b/src/gui/clientFileSendDialog.cpp
index ccb44b3..93da725 100644
--- a/src/gui/clientFileSendDialog.cpp
+++ b/src/gui/clientFileSendDialog.cpp
@@ -22,14 +22,16 @@ ClientFileSendDialog::ClientFileSendDialog(QWidget *parent) :
{
setupUi(this);
+ _transferID = 0;
+ _error = false;
+ _isMulticast = false;
+
_file = NULL;
_socket = NULL;
_clientNicklistDialog = new ClientNicklistDialog(this);
// connect to D-Bus and get interface
QDBusConnection dbus = QDBusConnection::sessionBus();
- dbus.registerObject("/filesend", this);
- dbus.registerService("org.openslx.pvsgui");
_ifaceDBus = new OrgOpenslxPvsInterface("org.openslx.pvs", "/", dbus, this);
// get current users name from backend
@@ -60,7 +62,15 @@ void ClientFileSendDialog::open()
reject();
return;
}
- open(_clientNicklistDialog->getNick());
+
+ if (_clientNicklistDialog->isSendToAll())
+ {
+ sendToAll();
+ }
+ else
+ {
+ open(_clientNicklistDialog->getNick());
+ }
}
void ClientFileSendDialog::open(QString nick)
@@ -75,6 +85,70 @@ void ClientFileSendDialog::open(QString nick)
open(nick, filename);
}
+void ClientFileSendDialog::sendToAll()
+{
+ QString filename = QFileDialog::getOpenFileName(this, tr("Send File"), QDir::homePath(), "");
+ if (filename == "")
+ {
+ reject();
+ return;
+ }
+ sendToAll(filename);
+}
+
+void ClientFileSendDialog::sendToAll(QString filename)
+{
+ _isMulticast = true;
+
+ connect(_ifaceDBus, SIGNAL(outgoingMulticastTransferStarted(qulonglong)), SLOT(multicastTransferStarted(qulonglong)));
+ connect(_ifaceDBus, SIGNAL(outgoingMulticastTransferProgress(qulonglong,qulonglong,qulonglong)), SLOT(multicastTransferProgress(qulonglong, qulonglong, qulonglong)));
+ connect(_ifaceDBus, SIGNAL(outgoingMulticastTransferFinished(qulonglong)), SLOT(multicastTransferFinished(qulonglong)));
+ connect(_ifaceDBus, SIGNAL(outgoingMulticastTransferFailed(qulonglong, QString const&)), SLOT(multicastTransferFailed(qulonglong, QString const&)));
+
+ filenameLabel->setText(filename);
+ progressBar->setRange(0, 0);
+ labelNick->setText(tr("all"));
+ labelStatus->setText(tr("Waiting to start"));
+
+ QString errorMessage("Backend error");
+
+ // We need to jump through a lot of hoops because this call is prone to time out, and
+ // QtDBus does not support specifying timeouts in generated interfaces.
+ QDBusMessage call = QDBusMessage::createMethodCall("org.openslx.pvs", "/", "org.openslx.pvs", "createMulticastTransfer");
+ call << filename;
+
+ QDBusMessage reply = _ifaceDBus->connection().call(call, QDBus::Block, 5000);
+ if (reply.type() == QDBusMessage::ErrorMessage)
+ {
+ QMessageBox::critical(this, tr("File Send error"), tr("Error communicating with backend: %1: %2").arg(reply.errorName()).arg(reply.errorMessage()));
+ reject();
+ return;
+ }
+ else if (reply.type() == QDBusMessage::InvalidMessage)
+ {
+ QMessageBox::critical(this, tr("File Send error"), tr("Something went wrong while communicating with backend, but I don't know what."));
+ reject();
+ return;
+ }
+ else if (reply.type() == QDBusMessage::ReplyMessage)
+ {
+ QList<QVariant> args = reply.arguments();
+ bool created = args.at(0).toBool();
+ _transferID = args.at(1).toULongLong();
+ QString errorMessage = args.at(2).toString();
+ if (!created)
+ {
+ QMessageBox::critical(this, tr("File Send error"), tr("Could not create a multicast transfer: %1").arg(errorMessage));
+ reject();
+ return;
+ }
+ }
+
+ connect(cancelButton, SIGNAL(clicked()), SLOT(canceled()));
+
+ show();
+}
+
void ClientFileSendDialog::open(QString nick, QString filename)
{
// open file
@@ -129,6 +203,8 @@ void ClientFileSendDialog::receiveAck()
QString ack = QString::fromUtf8(_socket->readLine());
if (ack != "ok\n")
{
+ _error = true;
+ _reason = tr("Receiver declined");
qDebug("[%s] Received nack!", metaObject()->className());
close();
return;
@@ -160,27 +236,30 @@ void ClientFileSendDialog::sendFile()
void ClientFileSendDialog::close()
{
- if (_file && _file->isOpen())
+ if (!_isMulticast)
{
- _file->close();
- qDebug("[%s] File closed.", metaObject()->className());
+ if (_file && _file->isOpen())
+ {
+ _file->close();
+ qDebug("[%s] File closed.", metaObject()->className());
+ }
+
+ if (_socket && _socket->isOpen())
+ {
+ disconnect(_socket, SIGNAL(readyRead()), this, SLOT(receiveAck()));
+ disconnect(_socket, SIGNAL(bytesWritten(qint64)), this, SLOT(sendFile()));
+ disconnect(_socket, SIGNAL(disconnected()), this, SLOT(close()));
+ disconnect(_socket, SIGNAL(connected()), this, SLOT(sendHeader()));
+ disconnect(_socket, SIGNAL(error(QAbstractSocket::SocketError)),
+ this, SLOT(error(QAbstractSocket::SocketError)));
+ _socket->disconnectFromHost();
+ qDebug("[%s] Connection closed.", metaObject()->className());
+ }
}
- if (_socket && _socket->isOpen())
- {
- disconnect(_socket, SIGNAL(readyRead()), this, SLOT(receiveAck()));
- disconnect(_socket, SIGNAL(bytesWritten(qint64)), this, SLOT(sendFile()));
- disconnect(_socket, SIGNAL(disconnected()), this, SLOT(close()));
- disconnect(_socket, SIGNAL(connected()), this, SLOT(sendHeader()));
- disconnect(_socket, SIGNAL(error(QAbstractSocket::SocketError)),
- this, SLOT(error(QAbstractSocket::SocketError)));
- _socket->disconnectFromHost();
- qDebug("[%s] Connection closed.", metaObject()->className());
- }
-
- disconnect(cancelButton, SIGNAL(clicked()), this, SLOT(close()));
+ disconnect(cancelButton, SIGNAL(clicked()), this, SLOT(canceled()));
- if (_bytesToWrite == 0)
+ if (!_error)
{
accept();
QMessageBox::information(0, tr("PVS - File Transfer"),
@@ -190,12 +269,26 @@ void ClientFileSendDialog::close()
{
reject();
QMessageBox::warning(0, tr("PVS - File Transfer"),
- tr("File Transfer canceled!"));
+ tr("File Transfer canceled: %1").arg(_reason));
+ }
+}
+
+void ClientFileSendDialog::canceled()
+{
+ if(_isMulticast)
+ {
+ _ifaceDBus->cancelOutgoingMulticastTransfer(_transferID);
}
+
+ _error = true;
+ _reason = tr("You clicked 'Cancel'");
+ close();
}
void ClientFileSendDialog::error(QAbstractSocket::SocketError error)
{
+ _error = true;
+ _reason = tr("Socket Error");
qDebug("[%s] Socket error: %i", metaObject()->className(), error);
close();
}
@@ -212,6 +305,55 @@ QString ClientFileSendDialog::formatSize(qint64 size)
return QString("%1B").arg((qreal)size, 0, 'f',1);
}
+void ClientFileSendDialog::multicastTransferStarted(qulonglong transferID)
+{
+ qDebug() << "multicastTransferStarted(" << transferID << ")";
+ if (transferID != _transferID)
+ {
+ return;
+ }
+ labelStatus->setText("Started");
+}
+
+void ClientFileSendDialog::multicastTransferProgress(qulonglong transferID, qulonglong bytes, qulonglong of)
+{
+ qDebug() << "multicastTransferProgress(" << transferID << bytes << of << ")";
+ if (transferID != _transferID)
+ {
+ return;
+ }
+
+ if(bytes < of)
+ {
+ labelStatus->setText("Transferring");
+ progressBar->setRange(0, of);
+ progressBar->setValue(bytes);
+ }
+ else
+ {
+ labelStatus->setText("Waiting to finish");
+ progressBar->setRange(0, 0);
+ }
+
+ labelA->setText(formatSize(bytes));
+ labelB->setText(formatSize(of));
+}
+
+void ClientFileSendDialog::multicastTransferFinished(quint64 transferID)
+{
+ qDebug() << "multicastTransferFinished(" << transferID << ")";
+ qDebug("[%s] MulticastTransfer finished", metaObject()->className());
+ close();
+}
+
+void ClientFileSendDialog::multicastTransferFailed(quint64 transferID, QString const& reason)
+{
+ qDebug() << "multicastTransferFailed(" << transferID << reason << ")";
+ _error = true;
+ _reason = reason;
+ close();
+}
+
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@@ -235,6 +377,25 @@ ClientNicklistDialog::ClientNicklistDialog(QWidget *parent) :
listWidget->addItems(nicknames);
listWidget->setCurrentRow(0);
+
+ connect(sendToAllCheckBox, SIGNAL(stateChanged(int)), SLOT(sendToAllStateChanged(int)));
+
+ sendToAllCheckBox->setCheckState(Qt::Unchecked);
+ _isSendToAll = false;
+}
+
+void ClientNicklistDialog::sendToAllStateChanged(int state)
+{
+ if (state)
+ {
+ listWidget->setEnabled(false);
+ _isSendToAll = true;
+ }
+ else
+ {
+ listWidget->setEnabled(true);
+ _isSendToAll = false;
+ }
}
ClientNicklistDialog::~ClientNicklistDialog()
diff --git a/src/gui/clientFileSendDialog.h b/src/gui/clientFileSendDialog.h
index d8afc3a..7abdcc7 100644
--- a/src/gui/clientFileSendDialog.h
+++ b/src/gui/clientFileSendDialog.h
@@ -30,9 +30,17 @@ public:
~ClientNicklistDialog();
QString getNick();
+ bool isSendToAll() const
+ {
+ return _isSendToAll;
+ }
+
+private Q_SLOTS:
+ void sendToAllStateChanged(int state);
private:
OrgOpenslxPvsInterface *_ifaceDBus;
+ bool _isSendToAll;
};
@@ -51,14 +59,22 @@ public:
void open();
void open(QString nick);
void open(QString nick, QString filename);
+ void sendToAll();
+ void sendToAll(QString filename);
private Q_SLOTS:
void sendHeader();
void receiveAck();
void sendFile();
void close();
+ void canceled();
void error(QAbstractSocket::SocketError error);
+ void multicastTransferStarted(qulonglong transferID);
+ void multicastTransferProgress(qulonglong transferID, qulonglong bytes, qulonglong of);
+ void multicastTransferFinished(qulonglong transferID);
+ void multicastTransferFailed(qulonglong transferID, QString const& reason);
+
private:
QString formatSize(qint64 size);
@@ -71,6 +87,11 @@ private:
OrgOpenslxPvsInterface *_ifaceDBus;
QString _nickname;
+ quint64 _transferID;
+ bool _error;
+ QString _reason;
+ bool _isMulticast;
+
};
#endif /* CLIENTFILESENDDIALOG_H_ */
diff --git a/src/gui/clientVNCViewer.cpp b/src/gui/clientVNCViewer.cpp
index d6a218b..d794b0b 100644
--- a/src/gui/clientVNCViewer.cpp
+++ b/src/gui/clientVNCViewer.cpp
@@ -22,8 +22,6 @@ ClientVNCViewer::ClientVNCViewer(QWidget *parent) :
{
// connect to D-Bus and get interface
QDBusConnection dbus = QDBusConnection::sessionBus();
- dbus.registerObject("/vnc", this);
- dbus.registerService("org.openslx.pvsgui");
_ifaceDBus = new OrgOpenslxPvsInterface("org.openslx.pvs", "/", dbus, this);
connect(_ifaceDBus, SIGNAL(project(QString, int, QString, bool, bool, int)),
this, SLOT(open(QString, int, QString, bool, bool, int)));
diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp
index 8a2b512..0f2fd0e 100644
--- a/src/gui/mainWindow.cpp
+++ b/src/gui/mainWindow.cpp
@@ -10,13 +10,16 @@
# General information about OpenSLX can be found at http://openslx.org/
# -----------------------------------------------------------------------------
# mainWindow.cpp
- This is the Main class for the pvsManager. The GUI is contructed here.
+ This is the Main class for the pvsManager. The GUI is contructed here.
# -----------------------------------------------------------------------------
*/
#include <QtGui>
#include <QFileDialog>
+#include <QBuffer>
+#include <QDataStream>
#include <src/gui/mainWindow.h>
+#include <src/net/mcast/McastConfiguration.h>
using namespace std;
// setting the IF-DEF Block for the touchgui and the normal gui, for later use
@@ -34,134 +37,138 @@ using namespace std;
#include <src/gui/profileDialog.h>
//#include <src/gui/dialog.h>
#include <src/core/pvsConnectionManager.h>
+#include <src/gui/multicastConfigDialog.h>
#include <iostream>
MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent), ui(new Ui::MainWindow)
+ QMainWindow(parent), ui(new Ui::MainWindow)
{
+ ui->setupUi(this);
- ui->setupUi(this);
+ if (!QFile::exists(_settings.fileName()))
+ {
+ QDir::root().mkpath(QFileInfo(_settings.fileName()).path());
+ QFile::copy("/etc/openslx/pvsmgr.conf", _settings.fileName());
+ }
- ui->horizontalSlider->setValue(100);
- ui->label_2->setText("100");
+ ui->horizontalSlider->setValue(100);
+ ui->label_2->setText("100");
- ui->separator->setVisible(false);
+ ui->separator->setVisible(false);
- myself = this;
- conWin = new ConnectionWindow(ui->widget);
- ui->VconWinLayout->addWidget(conWin);
- conList = new ConnectionList(ui->ClWidget);
- ui->ClientGLayout->addWidget(conList);
+ myself = this;
+ conWin = new ConnectionWindow(ui->widget);
+ ui->VconWinLayout->addWidget(conWin);
+ conList = new ConnectionList(ui->ClWidget);
+ ui->ClientGLayout->addWidget(conList);
- bgimage = false;
+ bgimage = false;
- _aboutDialog = new AboutDialog(this);
+ _aboutDialog = new AboutDialog(this);
- PVSConnectionManager::getManager();
+ PVSConnectionManager::getManager();
- //set the maximum width for list content
- ui->ClWidget->setMaximumWidth(160);
+ //set the maximum width for list content
+ ui->ClWidget->setMaximumWidth(160);
- ui->pvsLog->setReadOnly(true);
- ui->pvsLog->hide();
+ ui->pvsLog->setReadOnly(true);
+ ui->pvsLog->hide();
- onToggleLog(false);
- // add ourself to the log listeners, so we can output them too
- ConsoleLog addListener(this, &MainWindow::on_log_line);
+ onToggleLog(false);
+ // add ourself to the log listeners, so we can output them too
+ ConsoleLog addListener(this, &MainWindow::on_log_line);
- _firstResize = 1;
- _oldRatio = "100";
- _isThumbnailrate = false;
- is_closeup = false;
- is_fullscreen = false;
- _isLockAll = false;
- locked = false;
+ _firstResize = 1;
+ _oldRatio = "100";
+ _isThumbnailrate = false;
+ is_closeup = false;
+ is_fullscreen = false;
+ _isLockAll = false;
+ locked = false;
- /*
- * _sessionName: The session name for this Connection
- * _pwdCon: Password needed to connect to the session with the name _sessionName
- */
- _pwdCon = PVSConnectionManager::getManager()->setNeedPassword(false);
- _sessionName = PVSConnectionManager::getManager()->getSessionName();
+ /*
+ * _sessionName: The session name for this Connection
+ * _pwdCon: Password needed to connect to the session with the name _sessionName
+ */
+ _pwdCon = PVSConnectionManager::getManager()->setNeedPassword(false);
+ _sessionName = PVSConnectionManager::getManager()->getSessionName();
- ui->setPassword->setCheckState(Qt::Checked);
+ ui->setPassword->setCheckState(Qt::Checked);
#ifdef MAINWINDOW_USE_TOUCHGUI //only used for the touchgui
+ // define the slots we want to use
+ connect(ui->comboBox_touch1, SIGNAL(currentIndexChanged(int)), this, SLOT(combobox1(int))); // Combobox 1 verknüpfen mit IndexChangend Signal
+ connect(ui->comboBox_touch1, SIGNAL(currentIndexChanged(int)), this, SLOT(setindexback()));
- // define the slots we want to use
- connect(ui->comboBox_touch1, SIGNAL(currentIndexChanged(int)), this, SLOT(combobox1(int))); // Combobox 1 verknüpfen mit IndexChangend Signal
- connect(ui->comboBox_touch1, SIGNAL(currentIndexChanged(int)), this, SLOT(setindexback()));
-
-
- connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(createProfile())); // profile button
- connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(clientlisthide())); // clienlist button
-
- // toolbar slots
- connect(ui->actionresetall, SIGNAL(triggered()), this, SLOT(resetall()));
- connect(ui->actionLocksingle, SIGNAL(triggered()), this, SLOT(locksingle()));
- connect(ui->actionUnlocksingle, SIGNAL(triggered()), this, SLOT(unlocksingle()));
- connect(ui->actionProjection, SIGNAL(triggered()), this, SLOT(projecttoolbar()));
- connect(ui->actionUnprojection, SIGNAL(triggered()), this, SLOT(unprojecttoolbar()));
- connect(ui->actionDozent, SIGNAL(triggered()), this, SLOT(setdozenttoolbar()));
+ connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(createProfile())); // profile button
+ connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(clientlisthide())); // clienlist button
- // Ui specific settings
+ // toolbar slots
+ connect(ui->actionresetall, SIGNAL(triggered()), this, SLOT(resetall()));
+ connect(ui->actionLocksingle, SIGNAL(triggered()), this, SLOT(locksingle()));
+ connect(ui->actionUnlocksingle, SIGNAL(triggered()), this, SLOT(unlocksingle()));
+ connect(ui->actionProjection, SIGNAL(triggered()), this, SLOT(projecttoolbar()));
+ connect(ui->actionUnprojection, SIGNAL(triggered()), this, SLOT(unprojecttoolbar()));
+ connect(ui->actionDozent, SIGNAL(triggered()), this, SLOT(setdozenttoolbar()));
+ connect(ui->actionShowProcesses, SIGNAL(triggered()), this, SLOT(showProcesses()));
- ui->ClWidget->hide();
- ui->progressBar->hide();
- ui->pvsLog->hide();
+ // Ui specific settings
+ ui->ClWidget->hide();
+ ui->progressBar->hide();
+ ui->pvsLog->hide();
#endif
-
- // toolbar and actions in pvsmgr
- connect(ui->action_Exit, SIGNAL(triggered()), this, SLOT(close()));
- ui->action_Exit->setStatusTip(tr("Exit"));
- connect(ui->action_Disconnect, SIGNAL(triggered()), this, SLOT(disconnect()));
- ui->action_Disconnect->setStatusTip(tr("Remove the vnc-Connection for the selected client(s)"));
- ui->action_Disconnect->setVisible(false);//we need it only for debug
- connect(ui->actionView, SIGNAL(triggered()), this, SLOT(closeUp()));
- ui->actionView->setStatusTip(tr("Show the selected client in the whole window"));
- connect(ui->actionFoto, SIGNAL(triggered()), this, SLOT(foto()));
- connect(ui->actionLock, SIGNAL(triggered()), this, SLOT(lockalltoolbar()));
- connect(ui->actionChat, SIGNAL(triggered()), this, SLOT(startChatDialog()));
- ui->actionFoto->setStatusTip(tr("Make a screenshot for the selected client(s)"));
- ui->actionLock->setStatusTip(tr("Lock or Unlock all Clients"));
- connect(ui->actionCreate_profile, SIGNAL(triggered()), this, SLOT(createProfile()));
-
- connect(ui->actionShow_Username, SIGNAL(triggered()), this, SLOT(showusername()));
- connect(ui->actionShow_Hostname_IP, SIGNAL(triggered()), this, SLOT(showip()));
- connect(ui->actionShow_Fullname, SIGNAL(triggered()), this, SLOT(showname()));
- connect(ui->horizontalSlider, SIGNAL(valueChanged (int)), this, SLOT(changeRatio(int)));
- connect(ui->setPassword, SIGNAL(stateChanged (int)), this, SLOT(setPasswordForConnection(int)));
- connect(ui->vncQuality, SIGNAL(currentIndexChanged (int)), this, SLOT(setVNCQuality(int)));
- connect(ui->thumbStatus, SIGNAL(currentIndexChanged(int)), this, SLOT(changeStatus(int)));
- connect(ui->actionShow_Log, SIGNAL(toggled(bool)), this, SLOT(setLogConsoleDisabled(bool)));
- connect(ui->actionShow_Network, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool)));
- connect(ui->actionShow_Chat, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool)));
- connect(ui->actionShow_Terminal, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool)));
- connect(ui->actionShow_Normal, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool)));
- connect(ui->actionShow_Error, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool)));
- connect(ui->actionAbout_pvs, SIGNAL(triggered()), _aboutDialog, SLOT(open()));
-
- loadSettings(); //we load the appliocation settings
-
- setUnifiedTitleAndToolBarOnMac(true);
- statusBar()->showMessage(tr("The pvs manager"));
- this->showMaximized(); // show the Mainwindow maximized
-
- // listen on port 29481 for incoming file transfers
+ // toolbar and actions in pvsmgr
+ connect(ui->action_Exit, SIGNAL(triggered()), this, SLOT(close()));
+ ui->action_Exit->setStatusTip(tr("Exit"));
+ connect(ui->action_Disconnect, SIGNAL(triggered()), this, SLOT(disconnect()));
+ ui->action_Disconnect->setStatusTip(tr("Remove the vnc-Connection for the selected client(s)"));
+ ui->action_Disconnect->setVisible(false);//we need it only for debug
+ connect(ui->actionView, SIGNAL(triggered()), this, SLOT(closeUp()));
+ ui->actionView->setStatusTip(tr("Show the selected client in the whole window"));
+ connect(ui->actionFoto, SIGNAL(triggered()), this, SLOT(foto()));
+ connect(ui->actionLock, SIGNAL(triggered()), this, SLOT(lockalltoolbar()));
+ connect(ui->actionChat, SIGNAL(triggered()), this, SLOT(startChatDialog()));
+ ui->actionFoto->setStatusTip(tr("Make a screenshot for the selected client(s)"));
+ ui->actionLock->setStatusTip(tr("Lock or Unlock all Clients"));
+ connect(ui->actionCreate_profile, SIGNAL(triggered()), this, SLOT(createProfile()));
+ connect(ui->actionConfigure_Network, SIGNAL(triggered()), this, SLOT(configureNetwork()));
+ connect(ui->actionShowProcesses, SIGNAL(triggered()), this, SLOT(showProcesses()));
+ ui->actionShowProcesses->setStatusTip(tr("Show Processes of the selected Client"));
+
+ connect(ui->actionShow_Username, SIGNAL(triggered()), this, SLOT(showusername()));
+ connect(ui->actionShow_Hostname_IP, SIGNAL(triggered()), this, SLOT(showip()));
+ connect(ui->actionShow_Fullname, SIGNAL(triggered()), this, SLOT(showname()));
+ connect(ui->horizontalSlider, SIGNAL(valueChanged (int)), this, SLOT(changeRatio(int)));
+ connect(ui->setPassword, SIGNAL(stateChanged (int)), this, SLOT(setPasswordForConnection(int)));
+ connect(ui->vncQuality, SIGNAL(currentIndexChanged (int)), this, SLOT(setVNCQuality(int)));
+ connect(ui->thumbStatus, SIGNAL(currentIndexChanged(int)), this, SLOT(changeStatus(int)));
+ connect(ui->actionShow_Log, SIGNAL(toggled(bool)), this, SLOT(setLogConsoleDisabled(bool)));
+ connect(ui->actionShow_Network, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool)));
+ connect(ui->actionShow_Chat, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool)));
+ connect(ui->actionShow_Terminal, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool)));
+ connect(ui->actionShow_Normal, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool)));
+ connect(ui->actionShow_Error, SIGNAL(toggled(bool)), this, SLOT(onToggleLog(bool)));
+ connect(ui->actionAbout_pvs, SIGNAL(triggered()), _aboutDialog, SLOT(open()));
+
+ loadSettings(); //we load the appliocation settings
+
+ setUnifiedTitleAndToolBarOnMac(true);
+ statusBar()->showMessage(tr("The pvs manager"));
+ this->showMaximized(); // show the Mainwindow maximized
+
+ // listen on port 29481 for incoming file transfers
_serverSocket = new QTcpServer();
_serverSocket->listen(QHostAddress::Any, 29481);
connect(_serverSocket, SIGNAL(newConnection()), this, SLOT(incomingFile()));
-
-
}
MainWindow::~MainWindow()
{
- delete ui;
+ delete ui;
}
/*
@@ -180,38 +187,38 @@ void MainWindow::closeEvent(QCloseEvent *e)
MainWindow* MainWindow::getWindow() // catches the window
{
- if (myself)
- {
- return myself;
- }
- else
- {
- return myself = new MainWindow;
- }
+ if (myself)
+ {
+ return myself;
+ }
+ else
+ {
+ return myself = new MainWindow;
+ }
}
ConnectionWindow* MainWindow::getConnectionWindow() // catches the ConnectionWindow
{
- if (conWin)
- {
- return conWin;
- }
- else
- {
- conWin = new ConnectionWindow;
- return conWin;
- }
+ if (conWin)
+ {
+ return conWin;
+ }
+ else
+ {
+ conWin = new ConnectionWindow;
+ return conWin;
+ }
}
ConnectionList* MainWindow::getConnectionList() // catches the ConnectionList
{
- if (conList)
- return conList;
- else
- {
- conList = new ConnectionList;
- return conList;
- }
+ if (conList)
+ return conList;
+ else
+ {
+ conList = new ConnectionList;
+ return conList;
+ }
}
int MainWindow::getConnectionWindowWidth() // returns the width of the ConnectionWindow
@@ -226,9 +233,9 @@ int MainWindow::getConnectionWindowHeight() // returns the height of the Coonect
QStringList MainWindow::getProfilList() // loads the profile list
{
- QSettings settings("openslx", "pvsmgr");
- profilList = settings.childGroups();
- return profilList;
+ QSettings settings("openslx", "pvsmgr");
+ profilList = settings.childGroups();
+ return profilList;
}
#ifdef MAINWINDOW_USE_NORMALGUI
@@ -254,70 +261,63 @@ void MainWindow::removeProfileInMenu(QString name)
#endif
void MainWindow::loadSettings()
{
- QSettings settings("openslx", "pvsmgr");
- QString current = settings.value("current", "default").toString();
- currentProfi = current;
- _profilName = current;
+ QSettings settings("openslx", "pvsmgr");
+ QString current = settings.value("current", "default").toString();
+ currentProfi = current;
+ _profilName = current;
- //When no profile is available, we define a default one whith 9 dummy screens
- if (current.compare("default") == 0)
- {
- setWindowTitle("PVSmgr - Default");
- QPoint pos1 = settings.value("default/1", QPoint(0, 0)).toPoint();
- MainWindow::getConnectionWindow()->addFrameBySettings("1", pos1);
- QPoint pos2 =
- settings.value("default/2", QPoint(194, 0)).toPoint();
- MainWindow::getConnectionWindow()->addFrameBySettings("2", pos2);
- QPoint pos3 =
- settings.value("default/3", QPoint(388, 0)).toPoint();
- MainWindow::getConnectionWindow()->addFrameBySettings("3", pos3);
- QPoint pos4 =
- settings.value("default/4", QPoint(582, 0)).toPoint();
- MainWindow::getConnectionWindow()->addFrameBySettings("4", pos4);
- QPoint pos5 =
- settings.value("default/5", QPoint(0, 173)).toPoint();
- MainWindow::getConnectionWindow()->addFrameBySettings("5", pos5);
- QPoint pos6 =
- settings.value("default/6", QPoint(194, 173)).toPoint();
- MainWindow::getConnectionWindow()->addFrameBySettings("6", pos6);
- QPoint pos7 =
- settings.value("default/7", QPoint(388, 173)).toPoint();
- MainWindow::getConnectionWindow()->addFrameBySettings("7", pos7);
- QPoint pos8 =
- settings.value("default/8", QPoint(582, 173)).toPoint();
- MainWindow::getConnectionWindow()->addFrameBySettings("8", pos8);
- QPoint pos9 =
- settings.value("default/9", QPoint(293, 346)).toPoint();
- MainWindow::getConnectionWindow()->addFrameBySettings("9", pos9);
-
- QString title = "PVSmgr - ";
+ //When no profile is available, we define a default one whith 9 dummy screens
+ if (current.compare("default") == 0)
+ {
+ setWindowTitle("PVSmgr - Default");
+ QPoint pos1 = settings.value("default/1", QPoint(0, 0)).toPoint();
+ MainWindow::getConnectionWindow()->addFrameBySettings("1", pos1);
+ QPoint pos2 = settings.value("default/2", QPoint(194, 0)).toPoint();
+ MainWindow::getConnectionWindow()->addFrameBySettings("2", pos2);
+ QPoint pos3 = settings.value("default/3", QPoint(388, 0)).toPoint();
+ MainWindow::getConnectionWindow()->addFrameBySettings("3", pos3);
+ QPoint pos4 = settings.value("default/4", QPoint(582, 0)).toPoint();
+ MainWindow::getConnectionWindow()->addFrameBySettings("4", pos4);
+ QPoint pos5 = settings.value("default/5", QPoint(0, 173)).toPoint();
+ MainWindow::getConnectionWindow()->addFrameBySettings("5", pos5);
+ QPoint pos6 = settings.value("default/6", QPoint(194, 173)).toPoint();
+ MainWindow::getConnectionWindow()->addFrameBySettings("6", pos6);
+ QPoint pos7 = settings.value("default/7", QPoint(388, 173)).toPoint();
+ MainWindow::getConnectionWindow()->addFrameBySettings("7", pos7);
+ QPoint pos8 = settings.value("default/8", QPoint(582, 173)).toPoint();
+ MainWindow::getConnectionWindow()->addFrameBySettings("8", pos8);
+ QPoint pos9 = settings.value("default/9", QPoint(293, 346)).toPoint();
+ MainWindow::getConnectionWindow()->addFrameBySettings("9", pos9);
+
+ QString title = "PVSmgr - ";
title.append(_profilName);
- title.append(" ["+_sessionName + " : ");
- title.append(_pwdCon+"]");
+ title.append(" [" + _sessionName + " : ");
+ title.append(_pwdCon + "]");
setWindowTitle(title);
- }
- else
- {
- QString title = "PVSmgr - ";
+ }
+ else
+ {
+ QString title = "PVSmgr - ";
title.append(_profilName);
- title.append(" ["+_sessionName + " : ");
- title.append(_pwdCon+"]");
+ title.append(" [" + _sessionName + " : ");
+ title.append(_pwdCon + "]");
setWindowTitle(title);
- settings.beginGroup(current);
- QStringList keys = settings.childKeys();
- for (int i=0; i<keys.size(); i++)
- {
- QString profil = current;
- profil = profil.append("/").append(keys.at(i));
- QPoint pos = settings.value(keys.at(i)).toPoint();
- MainWindow::getConnectionWindow()->addFrameBySettings(keys.at(i), pos);
- }
- }
+ settings.beginGroup(current);
+ QStringList keys = settings.childKeys();
+ for (int i = 0; i < keys.size(); i++)
+ {
+ QString profil = current;
+ profil = profil.append("/").append(keys.at(i));
+ QPoint pos = settings.value(keys.at(i)).toPoint();
+ MainWindow::getConnectionWindow()->addFrameBySettings(keys.at(i),
+ pos);
+ }
+ }
- MainWindow::getConnectionWindow()->showFrameFromSettings();
+ MainWindow::getConnectionWindow()->showFrameFromSettings();
#ifdef MAINWINDOW_USE_NORMALGUI
- foreach (QString profile, getProfilList())
- addProfileInMenu(profile);
+ foreach (QString profile, getProfilList())
+ addProfileInMenu(profile);
#endif
}
@@ -329,17 +329,17 @@ void MainWindow::loadProfile(QAction* actiontriggered)
void MainWindow::loadSettings(QString profilname) // loads the current profile
{
- QList<ConnectionFrame*> AllFrameOnWindow =
- MainWindow::getConnectionWindow()->getAllFrameOnWindow();
+ QList<ConnectionFrame*> AllFrameOnWindow =
+ MainWindow::getConnectionWindow()->getAllFrameOnWindow();
- if (AllFrameOnWindow.size() > 0)
- {
- _profilName = profilname;
- MainWindow::getConnectionWindow()->ClientLocationList.clear();
- QSettings settings("openslx", "pvsmgr");
- settings.setValue("current", _profilName);
- ConnectionFrame* cFrame;
- foreach (cFrame, AllFrameOnWindow)
+ if (AllFrameOnWindow.size() > 0)
+ {
+ _profilName = profilname;
+ MainWindow::getConnectionWindow()->ClientLocationList.clear();
+ QSettings settings("openslx", "pvsmgr");
+ settings.setValue("current", _profilName);
+ ConnectionFrame* cFrame;
+ foreach (cFrame, AllFrameOnWindow)
{
if (cFrame->isDummy())
{
@@ -348,90 +348,91 @@ void MainWindow::loadSettings(QString profilname) // loads the current profile
cFrame->deleteLater();
}
}
- settings.beginGroup(_profilName);
- QStringList keys = settings.childKeys();
- int rest = AllFrameOnWindow.size();
- int init = 1;
- for (int i = 0; i < keys.size(); i++)
- {
- if (init <= rest)
- {
- ConnectionFrame* cF = AllFrameOnWindow.at(i);
- QString profil = _profilName;
- profil = profil.append("/").append(cF->getTaskbarTitle());
- if (!cF->isDummy())
- cF->move(settings.value(keys.at(i)).toPoint());
- else
- cF->move(settings.value(profil, QPoint(10,(10+(5*i)))).toPoint());
-
- init += 1;
- }
- else
- {
- MainWindow::getConnectionWindow()->addFrameBySettings(
- keys.at(i), settings.value(keys.at(i)).toPoint());
- }
- }
-
- MainWindow::getConnectionWindow()->showFrameFromSettings();
-
- QString title = "PVSmgr - ";
- title.append(_profilName);
- title.append(" ["+_sessionName + " : ");
- title.append(_pwdCon+"]");
- setWindowTitle(title);
- }
+ settings.beginGroup(_profilName);
+ QStringList keys = settings.childKeys();
+ int rest = AllFrameOnWindow.size();
+ int init = 1;
+ for (int i = 0; i < keys.size(); i++)
+ {
+ if (init <= rest)
+ {
+ ConnectionFrame* cF = AllFrameOnWindow.at(i);
+ QString profil = _profilName;
+ profil = profil.append("/").append(cF->getTaskbarTitle());
+ if (!cF->isDummy())
+ cF->move(settings.value(keys.at(i)).toPoint());
+ else
+ cF->move(
+ settings.value(profil, QPoint(10, (10 + (5 * i)))).toPoint());
+
+ init += 1;
+ }
+ else
+ {
+ MainWindow::getConnectionWindow()->addFrameBySettings(
+ keys.at(i), settings.value(keys.at(i)).toPoint());
+ }
+ }
+
+ MainWindow::getConnectionWindow()->showFrameFromSettings();
+
+ QString title = "PVSmgr - ";
+ title.append(_profilName);
+ title.append(" [" + _sessionName + " : ");
+ title.append(_pwdCon + "]");
+ setWindowTitle(title);
+ }
}
void MainWindow::saveSettings(QString profilname)
{
- QList<ConnectionFrame*> AllFrameOnWindow =
- MainWindow::getConnectionWindow()->getAllFrameOnWindow();
- QSettings settings("openslx", "pvsmgr");
- settings.setValue("current", profilname);
- settings.setValue("size", QString("%1").arg(AllFrameOnWindow.size()));
+ QList<ConnectionFrame*> AllFrameOnWindow =
+ MainWindow::getConnectionWindow()->getAllFrameOnWindow();
+ QSettings settings("openslx", "pvsmgr");
+ settings.setValue("current", profilname);
+ settings.setValue("size", QString("%1").arg(AllFrameOnWindow.size()));
- for (int i = 0; i < AllFrameOnWindow.size(); i++)
- {
- ConnectionFrame* current = AllFrameOnWindow.at(i);
- QString profil = "";
- profil = settings.value("current").toString().append("/");
- if (!current->isDummy())
- profil.append(QString(current->getTaskbarTitle()));
- else
- profil.append(QString("%1").arg(i + 1));
- settings.setValue(profil, current->pos());
- }
+ for (int i = 0; i < AllFrameOnWindow.size(); i++)
+ {
+ ConnectionFrame* current = AllFrameOnWindow.at(i);
+ QString profil = "";
+ profil = settings.value("current").toString().append("/");
+ if (!current->isDummy())
+ profil.append(QString(current->getTaskbarTitle()));
+ else
+ profil.append(QString("%1").arg(i + 1));
+ settings.setValue(profil, current->pos());
+ }
#ifdef MAINWINDOW_USE_NORMALGUI
-addProfileInMenu(profilname);
+ addProfileInMenu(profilname);
#endif
}
void MainWindow::removeProfil(QString profilname)
{
- QSettings settings("openslx", "pvsmgr");
- settings.remove(profilname);
+ QSettings settings("openslx", "pvsmgr");
+ settings.remove(profilname);
#ifdef MAINWINDOW_USE_NORMALGUI
-removeProfileInMenu(profilname);
+ removeProfileInMenu(profilname);
#endif
}
void MainWindow::addConnection(PVSClient* newCon)
{
- conWin->addConnection(newCon);
- if (!_chatListClients.contains(newCon->getUserName()))
- {
- _chatListClients.append(newCon->getUserName());
- sChatDialog.chat_client_add(newCon->getUserName());
- sChatDialog.chat_nicklist_update();
- }
- // sChatDialog->chat_nicklist_update(newCon->getUserName());
+ conWin->addConnection(newCon);
+ if (!_chatListClients.contains(newCon->getUserName()))
+ {
+ _chatListClients.append(newCon->getUserName());
+ sChatDialog.chat_client_add(newCon->getUserName());
+ sChatDialog.chat_nicklist_update();
+ }
+ // sChatDialog->chat_nicklist_update(newCon->getUserName());
}
void MainWindow::removeConnection(PVSClient* newCon)
{
- conWin->removeConnection(newCon);
- if (_chatListClients.contains(newCon->getUserName()))
+ conWin->removeConnection(newCon);
+ if (_chatListClients.contains(newCon->getUserName()))
{
_chatListClients.removeOne(newCon->getUserName());
sChatDialog.chat_client_remove(newCon->getUserName());
@@ -442,87 +443,87 @@ void MainWindow::removeConnection(PVSClient* newCon)
void MainWindow::onConnectionFailed(QString host)
{
#ifdef never
- // code is voided because the info-management will be overhauled sometime
+ // code is voided because the info-management will be overhauled sometime
- if (pwDiag) // assume this thing failed after the pw-question... so a wrong password, ey?
+ if (pwDiag) // assume this thing failed after the pw-question... so a wrong password, ey?
- {
- onPasswordFailed(host);
- return;
- }
+ {
+ onPasswordFailed(host);
+ return;
+ }
- QString caption, secondary;
- if (host != "")
- {
- caption = ("PVSConnection with hostname \"");
- caption.append(host);
- caption.append("\" failed.");
- secondary = "PVSConnection attempt for this hostname failed.Maybe the host is not prepared to accept vnc connections. Please make sure hostname and (if needed) password are correct.";
- }
- else
- {
- caption = "No IP given";
- secondary = "PVSConnection attempt for this host failed. There was either no or an errorous Hostname given.";
- }
- QMessageBox::information(*this, caption, secondary);
- /* Gtk::MessageDialog dialog(*this, Glib::ustring(caption));
- dialog.set_secondary_text(secondary);
- dialog.run();*/
+ QString caption, secondary;
+ if (host != "")
+ {
+ caption = ("PVSConnection with hostname \"");
+ caption.append(host);
+ caption.append("\" failed.");
+ secondary = "PVSConnection attempt for this hostname failed.Maybe the host is not prepared to accept vnc connections. Please make sure hostname and (if needed) password are correct.";
+ }
+ else
+ {
+ caption = "No IP given";
+ secondary = "PVSConnection attempt for this host failed. There was either no or an errorous Hostname given.";
+ }
+ QMessageBox::information(*this, caption, secondary);
+ /* Gtk::MessageDialog dialog(*this, Glib::ustring(caption));
+ dialog.set_secondary_text(secondary);
+ dialog.run();*/
#endif
}
void MainWindow::onConnectionTerminated(PVSClient* newConnection)
{
#ifdef never
- // code is voided because the info-management will be overhauled sometime
+ // code is voided because the info-management will be overhauled sometime
- QString host;
- if (newConnection)
- {
- host = newConnection->getIp(); // copy hostname for message
- }
- else
- host = "spooky unknown";
+ QString host;
+ if (newConnection)
+ {
+ host = newConnection->getIp(); // copy hostname for message
+ }
+ else
+ host = "spooky unknown";
- // now inform
- QString caption, secondary;
+ // now inform
+ QString caption, secondary;
- caption = "Hostname \"";
- caption.append(host);
- caption.append("\" terminated connection.");
- secondary = "The server has closed the connection to your client.";
+ caption = "Hostname \"";
+ caption.append(host);
+ caption.append("\" terminated connection.");
+ secondary = "The server has closed the connection to your client.";
- QMessageBox::information(*this, caption, secondary);
- /*Gtk::MessageDialog dialog(*this, Glib::ustring(caption));
- dialog.set_secondary_text(secondary);
- dialog.run();*/
+ QMessageBox::information(*this, caption, secondary);
+ /*Gtk::MessageDialog dialog(*this, Glib::ustring(caption));
+ dialog.set_secondary_text(secondary);
+ dialog.run();*/
#endif
}
void MainWindow::onConnectionRemoved(PVSClient* newConnection)
{
- // TODO this would be the place to handle the rest of the fullscreen issue
- conWin->onConnectionRemoved(newConnection);
+ // TODO this would be the place to handle the rest of the fullscreen issue
+ conWin->onConnectionRemoved(newConnection);
}
void MainWindow::onPasswordFailed(QString Qhost)
{
#ifdef never
- // code is voided because the info-management will be overhauled sometime
- QString caption, secondary;
- if (Qhost != "")
- {
- caption = "Hostname \"";
- caption.append(Qhost);
- caption.append("\" refused password.");
- secondary = "You have entered no or a wrong password.";
- }
- else
- return; // unknown connection was terminated? too spooky
- QMessageBox::information(*this, caption, secondary);
- /* Gtk::MessageDialog dialog(*this, Glib::ustring(caption));
- dialog.set_secondary_text(secondary);
- Gtk::Main::run(dialog);*/
+ // code is voided because the info-management will be overhauled sometime
+ QString caption, secondary;
+ if (Qhost != "")
+ {
+ caption = "Hostname \"";
+ caption.append(Qhost);
+ caption.append("\" refused password.");
+ secondary = "You have entered no or a wrong password.";
+ }
+ else
+ return; // unknown connection was terminated? too spooky
+ QMessageBox::information(*this, caption, secondary);
+ /* Gtk::MessageDialog dialog(*this, Glib::ustring(caption));
+ dialog.set_secondary_text(secondary);
+ Gtk::Main::run(dialog);*/
#endif
}
@@ -538,41 +539,41 @@ void MainWindow::receiveChatMsg(QString nick_from, QString nick_to, QString msg)
int MainWindow::getPrevWidth() // PVSConnectionManager::getManager()->getPrevWidth()
{
- return prev_width;
+ return prev_width;
}
void MainWindow::setPrevWidth(int newWidth)
{
- if (newWidth > 100)
- prev_width = newWidth;
- else
- prev_width = 100;
+ if (newWidth > 100)
+ prev_width = newWidth;
+ else
+ prev_width = 100;
}
int MainWindow::getPrevHeight()
{
- return prev_height;
+ return prev_height;
}
void MainWindow::setPrevHeight(int newHeight)
{
- if (newHeight > 100)
- prev_height = newHeight;
- else
- prev_height = 100;
+ if (newHeight > 100)
+ prev_height = newHeight;
+ else
+ prev_height = 100;
}
void MainWindow::changeEvent(QEvent *e)
{
- QMainWindow::changeEvent(e);
- switch (e->type())
- {
- case QEvent::LanguageChange:
- ui->retranslateUi(this);
- break;
- default:
- break;
- }
+ QMainWindow::changeEvent(e);
+ switch (e->type())
+ {
+ case QEvent::LanguageChange:
+ ui->retranslateUi(this);
+ break;
+ default:
+ break;
+ }
}
/*
@@ -586,107 +587,108 @@ void MainWindow::changeEvent(QEvent *e)
void MainWindow::resizeEvent(QResizeEvent *event)
{
- if (bgimage == true){
- repaintbackgroundpicture(); // repaint the backgroundpicture scaled to the window size
+ if (bgimage == true)
+ {
+ repaintbackgroundpicture(); // repaint the backgroundpicture scaled to the window size
}
if (_firstResize == 3)
{
QSize oldSize = event->oldSize();
- _initW = ui->widget->width();
- _initH = ui->widget->height();
+ _initW = ui->widget->width();
+ _initH = ui->widget->height();
_firstResize++;
}
- std::list<QString>* selectedClients =
- MainWindow::getConnectionList()->getSelectedClients();
- if (is_closeup && selectedClients->size() == 1)
- {
- PVSClient* pvsClient =
- PVSConnectionManager::getManager()->getClientFromIp(
- selectedClients->front().toStdString().c_str());
- pvsClient->getConnectionFrame()->paintCloseUp(ui->widget->width(),
- ui->widget->height());
- }
- else if (!is_closeup && _firstResize > 3)
- {
- int ratio_w = (ui->widget->width()*100)/_initW;
- int ratio_h = (ui->widget->height()*100)/_initH;
- foreach (ConnectionFrame* cf, getConnectionWindow()->getFrameList())
- {
- /*int margin = ui->widget->style()->pixelMetric(QStyle::PM_DefaultTopLevelMargin);
- int x = ui->widget->width() - margin;
- int y = ui->widget->height() - margin;
- updatePos(cf, x, y);*/
- int w = (cf->init_w * ratio_w) / 100;
- int h = (cf->init_h * ratio_h) / 100;
- cf->paintCloseUp(w,h);
- }
- }
+ std::list<QString>* selectedClients =
+ MainWindow::getConnectionList()->getSelectedClients();
+ if (is_closeup && selectedClients->size() == 1)
+ {
+ PVSClient* pvsClient =
+ PVSConnectionManager::getManager()->getClientFromIp(
+ selectedClients->front().toStdString().c_str());
+ pvsClient->getConnectionFrame()->paintCloseUp(ui->widget->width(),
+ ui->widget->height());
+ }
+ else if (!is_closeup && _firstResize > 3)
+ {
+ int ratio_w = (ui->widget->width() * 100) / _initW;
+ int ratio_h = (ui->widget->height() * 100) / _initH;
+foreach (ConnectionFrame* cf, getConnectionWindow()->getFrameList())
+ {
+ /*int margin = ui->widget->style()->pixelMetric(QStyle::PM_DefaultTopLevelMargin);
+ int x = ui->widget->width() - margin;
+ int y = ui->widget->height() - margin;
+ updatePos(cf, x, y);*/
+ int w = (cf->init_w * ratio_w) / 100;
+ int h = (cf->init_h * ratio_h) / 100;
+ cf->paintCloseUp(w,h);
+ }
+}
- if (_firstResize < 3)
- _firstResize++;
+if (_firstResize < 3)
+_firstResize++;
}
void MainWindow::updatePos(ConnectionFrame* cf, int x, int y)
{
- int posx = (x*cf->pos().x())/_initW;
- int posy = (y*cf->pos().y())/_initH;
+ int posx = (x * cf->pos().x()) / _initW;
+ int posy = (y * cf->pos().y()) / _initH;
cf->move(posx, posy);
/*QSize size = cf->sizeHint();
- cf->setGeometry(x - size.rwidth(), y - size.rheight(),
- size.rwidth(), size.rheight());*/
+ cf->setGeometry(x - size.rwidth(), y - size.rheight(),
+ size.rwidth(), size.rheight());*/
}
void MainWindow::on_log_line(LogEntry consoleEntry)
{
- ConsoleLogger::LOG_LEVEL level = consoleEntry.getLevel();
- if (level == ConsoleLogger::LOG_ERROR && !showError)
- return;
- if (level == ConsoleLogger::LOG_NORMAL && !showNormal)
- return;
- if (level == ConsoleLogger::LOG_NETWORK && !showNetwork)
- return;
- if (level == ConsoleLogger::LOG_TERMINAL && !showTerminal)
- return;
- if (level == ConsoleLogger::LOG_CHAT && !showChat)
- return;
-
- ui->pvsLog->insertPlainText(consoleEntry.getLine());
+ ConsoleLogger::LOG_LEVEL level = consoleEntry.getLevel();
+ if (level == ConsoleLogger::LOG_ERROR && !showError)
+ return;
+ if (level == ConsoleLogger::LOG_NORMAL && !showNormal)
+ return;
+ if (level == ConsoleLogger::LOG_NETWORK && !showNetwork)
+ return;
+ if (level == ConsoleLogger::LOG_TERMINAL && !showTerminal)
+ return;
+ if (level == ConsoleLogger::LOG_CHAT && !showChat)
+ return;
+
+ ui->pvsLog->insertPlainText(consoleEntry.getLine());
}
void MainWindow::onToggleLog(bool showtime)
{
- if (showtime)
- ;//to kill the system warning due "unused variable"
- showError = ui->actionShow_Error->isChecked();
- showTerminal = ui->actionShow_Terminal->isChecked();
- showNetwork = ui->actionShow_Network->isChecked();
- showChat = ui->actionShow_Chat->isChecked();
- showNormal = ui->actionShow_Normal->isChecked();
- //showAtAll = ui->logAtAllAction->get_active();
+ if (showtime)
+ ;//to kill the system warning due "unused variable"
+ showError = ui->actionShow_Error->isChecked();
+ showTerminal = ui->actionShow_Terminal->isChecked();
+ showNetwork = ui->actionShow_Network->isChecked();
+ showChat = ui->actionShow_Chat->isChecked();
+ showNormal = ui->actionShow_Normal->isChecked();
+ //showAtAll = ui->logAtAllAction->get_active();
- ConsoleLog dump2Listener(this, &MainWindow::on_log_line);
+ ConsoleLog dump2Listener(this, &MainWindow::on_log_line);
}
void MainWindow::setLogConsoleDisabled(bool visible)
{
- if (!visible)
- ui->pvsLog->hide();
- else
- ui->pvsLog->show();
+ if (!visible)
+ ui->pvsLog->hide();
+ else
+ ui->pvsLog->show();
}
/*void MainWindow::close()
-{
- //sChatDialog.close();
- QApplication::closeAllWindows();
-}*/
+ {
+ //sChatDialog.close();
+ QApplication::closeAllWindows();
+ }*/
void MainWindow::disconnect()
{
- conWin->removeVNC();
+ conWin->removeVNC();
}
void MainWindow::lockUnlockAll()
@@ -707,122 +709,153 @@ void MainWindow::lockUnlockAll()
void MainWindow::closeUp()
{
- std::list<QString>* selectedClients =
- MainWindow::getConnectionList()->getSelectedClients();
- if (!is_closeup)
- {
- if (selectedClients->size() == 1)
- {
- PVSClient
- * pvsClient =
- PVSConnectionManager::getManager()->getClientFromIp(
- selectedClients->front().toStdString().c_str());
- _framePosOnCloseUp = pvsClient->getConnectionFrame()->pos();//get the actualy position before run closeup
- if (pvsClient->getVNCConnection())
- {
- conWin->setCloseupFrame(pvsClient->getConnectionFrame());
- _updatefreq = pvsClient->getConnectionFrame()->getFrame()->getVNCClientThread()->getUpdatefreq();
- pvsClient->getConnectionFrame()->getFrame()->getVNCClientThread()->setUpdatefreq(50);
- pvsClient->getConnectionFrame()->move(5,5);
- pvsClient->getConnectionFrame()->setWindowFlags(Qt::WindowStaysOnTopHint);
+ std::list<QString>* selectedClients =
+ MainWindow::getConnectionList()->getSelectedClients();
+ if (!is_closeup)
+ {
+ if (selectedClients->size() == 1)
+ {
+ PVSClient * pvsClient =
+ PVSConnectionManager::getManager()->getClientFromIp(
+ selectedClients->front().toStdString().c_str());
+ _framePosOnCloseUp = pvsClient->getConnectionFrame()->pos();//get the actualy position before run closeup
+ if (pvsClient->getVNCConnection())
+ {
+ conWin->setCloseupFrame(pvsClient->getConnectionFrame());
+ _updatefreq
+ = pvsClient->getConnectionFrame()->getFrame()->getVNCClientThread()->getUpdatefreq();
+ pvsClient->getConnectionFrame()->getFrame()->getVNCClientThread()->setUpdatefreq(
+ 50);
+ pvsClient->getConnectionFrame()->move(5, 5);
+ pvsClient->getConnectionFrame()->setWindowFlags(
+ Qt::WindowStaysOnTopHint);
pvsClient->getConnectionFrame()->raise();
- pvsClient->getConnectionFrame()->paintCloseUp(ui->widget->width(),ui->widget->height());
+ pvsClient->getConnectionFrame()->paintCloseUp(
+ ui->widget->width(), ui->widget->height());
is_closeup = true;
conWin->setCloseupFrame(pvsClient->getConnectionFrame());
}
- }
- else
- {
- QString
- message =
- QString(
- tr(
- "This operation can only be performed for one selected Client!"));
- QMessageBox::information(this, "PVS", message);
- }
- }
- else
- {
- if (conWin->getCloseupFrame())
- {
- /*PVSClient* pvsClient =
- PVSConnectionManager::getManager()->getClientFromIp(
- selectedClients->front().toStdString().c_str());*/
- conWin->getCloseupFrame()->setWindowFlags(Qt::Widget);
- conWin->getCloseupFrame()->paintCloseUp(conWin->getCloseupFrame()->getPrevWidth(), conWin->getCloseupFrame()->getPrevHeight());
- conWin->getCloseupFrame()->move(_framePosOnCloseUp);//back to the position before the closeup
- if (conWin->getCloseupFrame()->getConnection()->getVNCConnection())
- conWin->getCloseupFrame()->getFrame()->getVNCClientThread()->setUpdatefreq(_updatefreq);
- conWin->setCloseupFrame(NULL);
- }
-
- is_closeup = false;
- }
+ }
+ else
+ {
+ QString
+ message =
+ QString(
+ tr(
+ "This operation can only be performed for one selected Client!"));
+ QMessageBox::information(this, "PVS", message);
+ }
+ }
+ else if (conWin->getCloseupFrame())
+ {
+ /*PVSClient* pvsClient =
+ PVSConnectionManager::getManager()->getClientFromIp(
+ selectedClients->front().toStdString().c_str());*/
+ conWin->getCloseupFrame()->setWindowFlags(Qt::Widget);
+ conWin->getCloseupFrame()->paintCloseUp(
+ conWin->getCloseupFrame()->getPrevWidth(),
+ conWin->getCloseupFrame()->getPrevHeight());
+ conWin->getCloseupFrame()->move(_framePosOnCloseUp);//back to the position before the closeup
+ if (conWin->getCloseupFrame()->getConnection()->getVNCConnection())
+ conWin->getCloseupFrame()->getFrame()->getVNCClientThread()->setUpdatefreq(
+ _updatefreq);
+
+ is_closeup = false;
+ conWin->setCloseupFrame(NULL);
+ }
+}
+
+/* Perform some action if actionShowProcesses button was pressed
+ *
+ */
+void MainWindow::showProcesses()
+{
+ std::list<QString>* selectedClients =
+ MainWindow::getConnectionList()->getSelectedClients();
+ if (selectedClients->size() == 1)
+ {
+ // do stuff
+ PVSClient * pvsClient =
+ PVSConnectionManager::getManager()->getClientFromIp(
+ selectedClients->front().toStdString().c_str());
+ pvsClient->sendMessage(PVSCOMMAND, "SHOWPROCESSES", "");
+ }
+ else
+ {
+ QString
+ message =
+ QString(
+ tr(
+ "This operation can only be performed if you have selected a Client!"));
+ QMessageBox::information(this, "PVS", message);
+ }
}
void MainWindow::foto() // makes a screenshot of the selected client
{
- std::list<QString>* selectedClients =
- MainWindow::getConnectionList()->getSelectedClients();
- if (selectedClients->size() > 0)
- {
- QString format = "png";
- for (std::list<QString>::iterator tmpIt = selectedClients->begin(); tmpIt
- != selectedClients->end(); tmpIt++)
- {
-
- QString path = QDir::homePath().append("/").append(*tmpIt).append(
- ".png");
- PVSClient
- * pvsClient =
- PVSConnectionManager::getManager()->getClientFromIp(
- (*tmpIt).toUtf8().data());
- if (pvsClient->getVNCConnection())
- {
- const QImage img = pvsClient->getConnectionFrame()->getFrame()->getImageForFoto();
- if (!img.isNull())
- img.save(path, format.toAscii());
- }
- else printf("Cannot save screen: Image is null.\n");
- }
- }
- else
- {
- QString
- message =
- QString(
- tr(
- "This operation can only be performed for at least one selected Client!"));
- QMessageBox::information(this, "PVS", message);
- }
+ std::list<QString>* selectedClients =
+ MainWindow::getConnectionList()->getSelectedClients();
+ if (selectedClients->size() > 0)
+ {
+ QString format = "png";
+ for (std::list<QString>::iterator tmpIt = selectedClients->begin(); tmpIt
+ != selectedClients->end(); tmpIt++)
+ {
+
+ QString path = QDir::homePath().append("/").append(*tmpIt).append(
+ ".png");
+ PVSClient * pvsClient =
+ PVSConnectionManager::getManager()->getClientFromIp(
+ (*tmpIt).toUtf8().data());
+ if (pvsClient->getVNCConnection())
+ {
+ const QImage
+ img =
+ pvsClient->getConnectionFrame()->getFrame()->getImageForFoto();
+ if (!img.isNull())
+ img.save(path, format.toAscii());
+ }
+ else
+ qDebug("Cannot save screen: Image is null.");
+ }
+ }
+ else
+ {
+ QString
+ message =
+ QString(
+ tr(
+ "This operation can only be performed for at least one selected Client!"));
+ QMessageBox::information(this, "PVS", message);
+ }
}
void MainWindow::createProfile()
{
- profileDialog proDiag;
- proDiag.exec();
+ profileDialog proDiag;
+ proDiag.exec();
}
void MainWindow::showusername()
{
- MainWindow::getConnectionList()->setColumnHidden(2, false);
- MainWindow::getConnectionList()->setColumnHidden(0, true);
- MainWindow::getConnectionList()->setColumnHidden(1, true);
+ MainWindow::getConnectionList()->setColumnHidden(2, false);
+ MainWindow::getConnectionList()->setColumnHidden(0, true);
+ MainWindow::getConnectionList()->setColumnHidden(1, true);
}
void MainWindow::showname()
{
- MainWindow::getConnectionList()->setColumnHidden(0, false);
- MainWindow::getConnectionList()->setColumnHidden(1, true);
- MainWindow::getConnectionList()->setColumnHidden(2, true);
+ MainWindow::getConnectionList()->setColumnHidden(0, false);
+ MainWindow::getConnectionList()->setColumnHidden(1, true);
+ MainWindow::getConnectionList()->setColumnHidden(2, true);
}
void MainWindow::showip()
{
- MainWindow::getConnectionList()->setColumnHidden(1, false);
- MainWindow::getConnectionList()->setColumnHidden(2, true);
- MainWindow::getConnectionList()->setColumnHidden(0, true);
+ MainWindow::getConnectionList()->setColumnHidden(1, false);
+ MainWindow::getConnectionList()->setColumnHidden(2, true);
+ MainWindow::getConnectionList()->setColumnHidden(0, true);
}
void MainWindow::incomingFile()
@@ -841,15 +874,16 @@ void MainWindow::changeRatio(int ratio) // needed the change the size of the vnc
str.append(QString("%1").arg(ratio));
ui->label_2->setText(str);
- std::list<QString>* selClients = getConnectionList()->getSelectedClients();
+ std::list<QString>* selClients =
+ getConnectionList()->getSelectedClients();
if (selClients->size() > 0)
{
for (std::list<QString>::iterator client = selClients->begin(); client
!= selClients->end(); client++)
{
PVSClient* pvsClient =
- PVSConnectionManager::getManager()->getClientFromIp(
- (*client).toUtf8().data());
+ PVSConnectionManager::getManager()->getClientFromIp(
+ (*client).toUtf8().data());
ConnectionFrame *frame = pvsClient->getConnectionFrame();
int w = (frame->init_w * ratio) / 100;
int h = (frame->init_h * ratio) / 100;
@@ -864,46 +898,46 @@ void MainWindow::changeRatio(int ratio) // needed the change the size of the vnc
QList<ConnectionFrame *> frameList =
MainWindow::getConnectionWindow()->getFrameList();
ConnectionFrame *frame;
- foreach(frame, frameList)
- {
- int w = (frame->init_w * ratio) / 100;
- int h = (frame->init_h * ratio) / 100;
- frame->setPrevWidth(w);
- frame->setPrevHeight(h);
- frame->paintCloseUp(w, h);
- }
+foreach (frame, frameList)
+ {
+ int w = (frame->init_w * ratio) / 100;
+ int h = (frame->init_h * ratio) / 100;
+ frame->setPrevWidth(w);
+ frame->setPrevHeight(h);
+ frame->paintCloseUp(w, h);
}
}
- else
+}
+else
+{
+ int updatefreq = (ratio*500)/100;
+ QString str;
+ str.append(QString("%1").arg(updatefreq));
+ ui->label_2->setText(str);
+ std::list<QString>* selClients = getConnectionList()->getSelectedClients();
+ if (selClients->size() > 0)
{
- int updatefreq = (ratio*500)/100;
- QString str;
- str.append(QString("%1").arg(updatefreq));
- ui->label_2->setText(str);
- std::list<QString>* selClients = getConnectionList()->getSelectedClients();
- if (selClients->size() > 0)
+ for (std::list<QString>::iterator client = selClients->begin(); client
+ != selClients->end(); client++)
{
- for (std::list<QString>::iterator client = selClients->begin(); client
- != selClients->end(); client++)
- {
- PVSClient* pvsClient =
- PVSConnectionManager::getManager()->getClientFromIp(
- (*client).toUtf8().data());
- if (pvsClient->getVNCConnection())
- pvsClient->getConnectionFrame()->getFrame()->getVNCClientThread()->setUpdatefreq(updatefreq);
- }
+ PVSClient* pvsClient =
+ PVSConnectionManager::getManager()->getClientFromIp(
+ (*client).toUtf8().data());
+ if (pvsClient->getVNCConnection())
+ pvsClient->getConnectionFrame()->getFrame()->getVNCClientThread()->setUpdatefreq(updatefreq);
}
- else
+ }
+ else
+ {
+ std::list<PVSClient*> clients = PVSConnectionManager::getManager()->getConnections();
+ foreach (PVSClient* client, clients)
{
- std::list<PVSClient*> clients = PVSConnectionManager::getManager()->getConnections();
- foreach (PVSClient* client, clients)
- {
- if (client->getVNCConnection())
- client->getConnectionFrame()->getFrame()->getVNCClientThread()->setUpdatefreq(updatefreq);
- }
+ if (client->getVNCConnection())
+ client->getConnectionFrame()->getFrame()->getVNCClientThread()->setUpdatefreq(updatefreq);
}
-
}
+
+}
}
/*
@@ -917,18 +951,19 @@ void MainWindow::changeRatio(int ratio) // needed the change the size of the vnc
*/
void MainWindow::changeStatus(int index)
{
- QString status = ui->thumbStatus->currentText ();
+ QString status = ui->thumbStatus->currentText();
if (status == "Thumbnailratio")
{
_isThumbnailrate = false;
ui->label_3->setText("%");
- std::list<QString>* selClients = getConnectionList()->getSelectedClients();
+ std::list<QString>* selClients =
+ getConnectionList()->getSelectedClients();
if (selClients->size() == 1)
{
PVSClient* pvsClient =
- PVSConnectionManager::getManager()->getClientFromIp(
- selClients->front().toStdString().c_str());
+ PVSConnectionManager::getManager()->getClientFromIp(
+ selClients->front().toStdString().c_str());
int ratio = pvsClient->getConnectionFrame()->getRatio();
ui->label_2->setText(QString::number(ratio));
ui->horizontalSlider->setValue(ratio);
@@ -944,16 +979,19 @@ void MainWindow::changeStatus(int index)
{
_isThumbnailrate = true;
ui->label_3->setText("ms");
- std::list<QString>* selClients = getConnectionList()->getSelectedClients();
+ std::list<QString>* selClients =
+ getConnectionList()->getSelectedClients();
if (selClients->size() == 1)
{
PVSClient* pvsClient =
- PVSConnectionManager::getManager()->getClientFromIp(
- selClients->front().toStdString().c_str());
+ PVSConnectionManager::getManager()->getClientFromIp(
+ selClients->front().toStdString().c_str());
if (pvsClient->getVNCConnection())
{
- int updatefreq = pvsClient->getConnectionFrame()->getFrame()->getVNCClientThread()->getUpdatefreq();
- int showfreq = (updatefreq*100)/500;
+ int
+ updatefreq =
+ pvsClient->getConnectionFrame()->getFrame()->getVNCClientThread()->getUpdatefreq();
+ int showfreq = (updatefreq * 100) / 500;
ui->label_2->setText(QString::number(updatefreq));
ui->horizontalSlider->setValue(showfreq);
}
@@ -966,7 +1004,6 @@ void MainWindow::changeStatus(int index)
}
}
-
/*
* Going to run a new vncthread with quality: quality
*/
@@ -976,47 +1013,48 @@ void MainWindow::setVNCQuality(int quality)
if (selClients->size() > 0)
{
for (std::list<QString>::iterator client = selClients->begin(); client
- != selClients->end(); client++)
+ != selClients->end(); client++)
{
PVSClient* pvsClient =
- PVSConnectionManager::getManager()->getClientFromIp(
- (*client).toUtf8().data());
+ PVSConnectionManager::getManager()->getClientFromIp(
+ (*client).toUtf8().data());
pvsClient->getConnectionFrame()->resetConnectionWithQuality(quality);
pvsClient->getConnectionFrame()->update();
}
}
else
{
- QList<ConnectionFrame*> FrameList = MainWindow::getConnectionWindow()->getFrameList();
- foreach(ConnectionFrame* frame, FrameList)
- {
- frame->resetConnectionWithQuality(quality);
- frame->update();
- }
+ QList<ConnectionFrame*> FrameList =
+ MainWindow::getConnectionWindow()->getFrameList();
+foreach (ConnectionFrame* frame, FrameList)
+ {
+ frame->resetConnectionWithQuality(quality);
+ frame->update();
}
-
}
+}
void MainWindow::setPasswordForConnection(int enabled)
{
- if(enabled == 0)//the checkbox isn't checked, so no passowrd needed, we remove it in the titlebar
+ if (enabled == 0)//the checkbox isn't checked, so no passowrd needed, we remove it in the titlebar
{
- QString dummy = PVSConnectionManager::getManager()->setNeedPassword(false);
- _sessionName = PVSConnectionManager::getManager()->getSessionName();
+ QString dummy = PVSConnectionManager::getManager()->setNeedPassword(
+ false);
+ _sessionName = PVSConnectionManager::getManager()->getSessionName();
QString title = "PVSmgr - ";
title.append(_profilName);
- title.append(" ["+_sessionName + " : ]");
+ title.append(" [" + _sessionName + " : ]");
setWindowTitle(title);
}
else if (enabled == 2) //password is needed, we show it in the titlebar
{
- _pwdCon = PVSConnectionManager::getManager()->setNeedPassword(true);
+ _pwdCon = PVSConnectionManager::getManager()->setNeedPassword(true);
_sessionName = PVSConnectionManager::getManager()->getSessionName();
QString title = "PVSmgr - ";
title.append(_profilName);
- title.append(" ["+_sessionName + " : ");
- title.append(_pwdCon+"]");
+ title.append(" [" + _sessionName + " : ");
+ title.append(_pwdCon + "]");
setWindowTitle(title);
}
}
@@ -1026,153 +1064,155 @@ void MainWindow::setPasswordForConnection(int enabled)
void MainWindow::setindexback() //sets the index of the combobox back
{
#ifdef MAINWINDOW_USE_TOUCHGUI
- ui->comboBox_touch1->setCurrentIndex(0);
+ ui->comboBox_touch1->setCurrentIndex(0);
#endif
}
void MainWindow::clientlisthide() // hide or show the clientlist
{
- if (locked1 == false)
- {
- ui->ClWidget->show();
- locked1 = true;
- }
+ if (locked1 == false)
+ {
+ ui->ClWidget->show();
+ locked1 = true;
+ }
- else
- {
- ui->ClWidget->hide();
- locked1 = false;
- }
+ else
+ {
+ ui->ClWidget->hide();
+ locked1 = false;
+ }
}
-
void MainWindow::lockalltoolbar() // locks all if a dozent is set
{
+ if (locked == false)
+ {
+ if (MainWindow::getConnectionWindow()->hasDozent)
+ {
+ MainWindow::getConnectionList()->on_lock_all();
+ locked = true;
+ }
+ else
+ {
+ QString
+ message =
+ QString(
+ tr(
+ "You have to set a Superclient-machine before performing this action."));
+ QMessageBox::information(this, "PVS", message);
+ }
+ }
- if (locked == false)
- {
- if (MainWindow::getConnectionWindow()->hasDozent)
- {
- MainWindow::getConnectionList()->on_lock_all();
- locked = true;
- }
- else
- {
- QString message = QString(tr("You have to set a Superclient-machine before performing this action."));
- QMessageBox::information(this, "PVS", message);
- }
- }
-
- else
- {
- MainWindow::getConnectionList()->on_unlock_all();
- locked = false;
- }
+ else
+ {
+ MainWindow::getConnectionList()->on_unlock_all();
+ locked = false;
+ }
}
void MainWindow::locksingle() // locks a single client
{
- MainWindow::getConnectionList()->on_lock();
+ MainWindow::getConnectionList()->on_lock();
}
void MainWindow::unlocksingle() // unlocks a single client
{
- MainWindow::getConnectionList()->on_unlock();
+ MainWindow::getConnectionList()->on_unlock();
}
-
void MainWindow::combobox1(int menuindex1) // defines the functions to call from the combobox
{
- switch (menuindex1)
- // index comes from the slot definition
- {
- case 1:
- // Lock all
- MainWindow::getConnectionList()->on_lock_all();
- break;
-
- case 2:
- // UnLock all
- MainWindow::getConnectionList()->on_unlock_all();
- break;
-
- case 3:
- // UnProject all
- MainWindow::getConnectionList()->on_unproject_all();
- break;
-
- case 4:
- //Background Picture
- backgroundpicture();
- break;
- }
+ switch (menuindex1)
+ // index comes from the slot definition
+ {
+ case 1:
+ // Lock all
+ MainWindow::getConnectionList()->on_lock_all();
+ break;
+
+ case 2:
+ // UnLock all
+ MainWindow::getConnectionList()->on_unlock_all();
+ break;
+
+ case 3:
+ // UnProject all
+ MainWindow::getConnectionList()->on_unproject_all();
+ break;
+
+ case 4:
+ //Background Picture
+ backgroundpicture();
+ break;
+ }
}
void MainWindow::resetall() // unlock and unproject all in toolbar
- {
+{
MainWindow::getConnectionList()->on_unlock_all();
MainWindow::getConnectionList()->on_unproject_all();
- }
-
+}
void MainWindow::projecttoolbar() // projection from toolbar button
- {
+{
MainWindow::getConnectionList()->on_projection();
- }
+}
void MainWindow::unprojecttoolbar() // unproject all in toolbar
- {
+{
MainWindow::getConnectionList()->on_unprojection();
- }
+}
void MainWindow::backgroundpicture()
- {
-
+{
- fileName = QFileDialog::getOpenFileName(this,
- tr("Open Image"), "/home", tr("Image Files (*.png *.jpg *.svg)")); // user chooses a file
+ fileName = QFileDialog::getOpenFileName(this, tr("Open Image"), "/home",
+ tr("Image Files (*.png *.jpg *.svg)")); // user chooses a file
- QImage img(""+fileName+""); // set image
+ QImage img("" + fileName + ""); // set image
QString test("/tmp/test.png"); // set path for saving the scaled picture
- QImage img2 = img.scaled(ui->widget->size(),Qt::IgnoreAspectRatio,Qt::FastTransformation); // scale it
+ QImage img2 = img.scaled(ui->widget->size(), Qt::IgnoreAspectRatio,
+ Qt::FastTransformation); // scale it
- img2.save(""+test+""); // save it
+ img2.save("" + test + ""); // save it
- ui->widget->setStyleSheet("background-image: url(/tmp/test.png);background-repeat:no-repeat; background-position:center;"); //set the picture as background
+ ui->widget->setStyleSheet(
+ "background-image: url(/tmp/test.png);background-repeat:no-repeat; background-position:center;"); //set the picture as background
foreach (ConnectionFrame* cf, MainWindow::getConnectionWindow()->getAllFrameOnWindow())
{
cf->setStyleSheet(QString::fromUtf8("background-color: rgb(150, 150, 168);"));
}
- bgimage=true; // for the resize event, set background true
+ bgimage = true; // for the resize event, set background true
- }
+}
void MainWindow::repaintbackgroundpicture() // same as backgroundpicture but called when mainwindow is resized
- {
+{
QImage img("/tmp/test.png");
QString test("/tmp/test.png");
- QImage img2 = img.scaled(ui->widget->size(),Qt::IgnoreAspectRatio,Qt::FastTransformation);
+ QImage img2 = img.scaled(ui->widget->size(), Qt::IgnoreAspectRatio,
+ Qt::FastTransformation);
- img2.save(""+test+"");
+ img2.save("" + test + "");
- ui->widget->setStyleSheet("background-image: url(/tmp/test.png);background-repeat:no-repeat; background-position:center;");
+ ui->widget->setStyleSheet(
+ "background-image: url(/tmp/test.png);background-repeat:no-repeat; background-position:center;");
-
- }
+}
void MainWindow::setdozenttoolbar() // set the dozents pc which is not locked with lockedall
{
@@ -1184,8 +1224,8 @@ void MainWindow::setdozenttoolbar() // set the dozents pc which is not locked wi
{
PVSClient* pvsClient =
- PVSConnectionManager::getManager()->getClientFromIp(
- selectedClients->front().toStdString().c_str());
+ PVSConnectionManager::getManager()->getClientFromIp(
+ selectedClients->front().toStdString().c_str());
if (pvsClient->getVNCConnection())
pvsClient->getConnectionFrame()->getFrame()->setDozent();
}
@@ -1200,9 +1240,19 @@ void MainWindow::startChatDialog()
sChatDialog.raise();//show the chat dialog on top level
}
+void MainWindow::configureNetwork()
+{
+ PVSServer* server = PVSConnectionManager::getManager()->getServer();
+ McastConfiguration mc(*(server->getMulticastConfiguration()));
+ MulticastConfigDialog* mcd = new MulticastConfigDialog(&mc, this);
+ int result = mcd->exec();
+ if(result == QDialog::Accepted)
+ {
+ server->multicastReconfigure(&mc);
+ }
+}
-
-MainWindow* MainWindow::myself = NULL;
-ConnectionList* MainWindow::conList = NULL;
-ConnectionWindow* MainWindow::conWin = NULL;
-bool MainWindow::_isLockAll = false;
+MainWindow* MainWindow::myself = NULL;
+ConnectionList* MainWindow::conList = NULL;
+ConnectionWindow* MainWindow::conWin = NULL;
+bool MainWindow::_isLockAll = false;
diff --git a/src/gui/mainWindow.h b/src/gui/mainWindow.h
index 00bd927..88756fd 100644
--- a/src/gui/mainWindow.h
+++ b/src/gui/mainWindow.h
@@ -159,6 +159,8 @@ private:
QMenu* _profileMenuList;
QMap<QString, QAction*> _mapProfileToAction;
+ QSettings _settings;
+
public slots:
void loadProfile(QAction* actiontriggered);
void setindexback();
@@ -176,6 +178,7 @@ public slots:
void repaintbackgroundpicture();
void setdozenttoolbar();
void startChatDialog();
+ void showProcesses();
private slots:
void onToggleLog(bool showtime);
@@ -194,6 +197,7 @@ private slots:
void setPasswordForConnection(int enabled);
void combobox1(int menuindex1); // Funktion um index der combobox auszulesen und weiterzuverarbeiten s. Ticker 671
//void combobox2(int menuindex2); // Funktion um index der combobox auszulesen und weiterzuverarbeiten
+ void configureNetwork();
};
diff --git a/src/gui/multicastConfigDialog.cpp b/src/gui/multicastConfigDialog.cpp
new file mode 100644
index 0000000..ff370c7
--- /dev/null
+++ b/src/gui/multicastConfigDialog.cpp
@@ -0,0 +1,170 @@
+#include <QValidator>
+#include <QIntValidator>
+#include <QHostAddress>
+#include <QPushButton>
+#include "multicastConfigDialog.h"
+#include <src/net/mcast/McastConfiguration.h>
+// #include "multicastValidators.h"
+
+MulticastConfigDialog::MulticastConfigDialog(QWidget* parent) :
+ QDialog(parent)
+{
+ setupUi();
+}
+
+MulticastConfigDialog::MulticastConfigDialog(McastConfiguration* config,
+ QWidget *parent) :
+ QDialog(parent)
+{
+ setupUi();
+ _config = config;
+
+ _ui.groupAddressEdit->setText(config->multicastAddress());
+ _ui.dataPortEdit->setText(QString::number(config->multicastUDPPortBase()));
+
+ connect(_ui.buttonBox, SIGNAL(accepted()), this, SLOT(dialogAccepted()));
+ connect(_ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+}
+
+void MulticastConfigDialog::setupUi()
+{
+ _ui.setupUi(this);
+
+ QIntValidator* portValidator = new QIntValidator(1024, 65535, this);
+ _ui.dataPortEdit->setValidator(portValidator);
+
+ connect(_ui.groupAddressEdit, SIGNAL(textChanged(QString const&)), this,
+ SLOT(validateGroupAddress(QString const&)));
+ connect(_ui.dataPortEdit, SIGNAL(textChanged(QString const&)), this,
+ SLOT(validateDataPort(QString const&)));
+
+ connect(_ui.buttonBox, SIGNAL(accepted()), this, SLOT(dialogAccepted()));
+ connect(_ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+
+ validateGroupAddress(_ui.groupAddressEdit->text());
+ validateDataPort(_ui.dataPortEdit->text());
+}
+
+MulticastConfigDialog::~MulticastConfigDialog()
+{
+}
+
+void MulticastConfigDialog::dialogAccepted()
+{
+ QHostAddress addr;
+ bool addressParses = addr.setAddress(_ui.groupAddressEdit->text());
+ _config->multicastAddress(_ui.groupAddressEdit->text());
+ quint16 port = _ui.dataPortEdit->text().toInt();
+ _config->multicastUDPPortBase(port);
+ _config->multicastDPort(port + 1);
+ _config->multicastSPort(port + 2);
+ _config->multicastRate(_ui.rateSpinbox->value() * 1024);
+ accept();
+}
+
+void MulticastConfigDialog::setError(QWidget* widget,
+ QLabel* errorMessageLabel, QString text)
+{
+ if (errorMessageLabel)
+ errorMessageLabel->setText(QString(
+ "<span style=\"font-weight: 600; color: #880000;\">") + text
+ + "</span>");
+ if (widget)
+ widget->setStyleSheet("background-color: #ffcccc;");
+}
+
+void MulticastConfigDialog::setOK(QWidget* widget, QLabel* errorMessageLabel)
+{
+ if (errorMessageLabel)
+ errorMessageLabel->setText(QString(
+ "<span style=\"font-weight: 600; color: #008800;\">")
+ + tr("OK") + "</span>");
+ if (widget)
+ widget->setStyleSheet("background-color: #ccffcc;");
+}
+
+void MulticastConfigDialog::validateGroupAddress(QString const& input)
+{
+ QHostAddress a;
+
+ _isAddressValid = false;
+
+ if (!a.setAddress(input))
+ {
+ setError(_ui.groupAddressEdit, _ui.groupAddressMessage, tr(
+ "Not a valid IP Address"));
+ revalidateButtons();
+ return;
+ }
+
+ // check if it is IPv4
+ if (a.protocol() != QAbstractSocket::IPv4Protocol)
+ {
+ setError(_ui.groupAddressEdit, _ui.groupAddressMessage, tr(
+ "Not a valid IPv4 Address"));
+ revalidateButtons();
+ return;
+ }
+
+ // check if it is a valid multicast address
+ quint32 addr = a.toIPv4Address();
+ if ((addr & 0xf0000000) != 0xe0000000)
+ {
+ setError(_ui.groupAddressEdit, _ui.groupAddressMessage, tr(
+ "Not an IPv4 multicast address"));
+ revalidateButtons();
+ return;
+ }
+
+ _isAddressValid = true;
+ setOK(_ui.groupAddressEdit, _ui.groupAddressMessage);
+ revalidateButtons();
+}
+
+void MulticastConfigDialog::validateDataPort(QString const& input)
+{
+ bool ok;
+ int p = input.toInt(&ok, 0);
+
+ _isPortValid = false;
+
+ if (!ok)
+ {
+ setError(_ui.dataPortEdit, _ui.dataPortMessage, tr("Not a number"));
+ revalidateButtons();
+ return;
+ }
+
+ if (p < 0)
+ {
+ setError(_ui.dataPortEdit, _ui.dataPortMessage, tr("Must be positive"));
+ revalidateButtons();
+ return;
+ }
+
+ if (p < 1024)
+ {
+ setError(_ui.dataPortEdit, _ui.dataPortMessage, tr(
+ "Must not be a privileged port"));
+ revalidateButtons();
+ return;
+ }
+
+ if (p > 65535)
+ {
+ setError(_ui.dataPortEdit, _ui.dataPortMessage, tr(
+ "Port number too large"));
+ revalidateButtons();
+ return;
+ }
+
+ _isPortValid = true;
+ setOK(_ui.dataPortEdit, _ui.dataPortMessage);
+ revalidateButtons();
+}
+
+void MulticastConfigDialog::revalidateButtons()
+{
+ _ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(_isAddressValid
+ && _isPortValid);
+}
diff --git a/src/gui/multicastConfigDialog.h b/src/gui/multicastConfigDialog.h
new file mode 100644
index 0000000..6421813
--- /dev/null
+++ b/src/gui/multicastConfigDialog.h
@@ -0,0 +1,38 @@
+#ifndef MULTICASTCONFIGDIALOG_H
+#define MULTICASTCONFIGDIALOG_H
+
+#include <QtGui/QDialog>
+#include <QPointer>
+#include "ui_multicastConfigDialog.h"
+#include <pvsinterface.h>
+
+class McastConfiguration;
+
+class MulticastConfigDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ MulticastConfigDialog(QWidget* parent = 0);
+ MulticastConfigDialog(McastConfiguration* dbusIface, QWidget *parent = 0);
+ ~MulticastConfigDialog();
+
+private:
+ Ui::MulticastConfigDialogClass _ui;
+ McastConfiguration* _config;
+ bool _isAddressValid;
+ bool _isPortValid;
+
+ void setupUi();
+
+ void setError(QWidget* input, QLabel* messageLabel, QString text);
+ void setOK(QWidget* input, QLabel* messageLabel);
+ void revalidateButtons();
+
+private slots:
+ void dialogAccepted();
+ void validateGroupAddress(QString const&);
+ void validateDataPort(QString const&);
+};
+
+#endif // MULTICASTCONFIGDIALOG_H
diff --git a/src/gui/ui/clientConfigDialog.ui b/src/gui/ui/clientConfigDialog.ui
index 3262b6b..bb4bdc9 100644
--- a/src/gui/ui/clientConfigDialog.ui
+++ b/src/gui/ui/clientConfigDialog.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>438</width>
- <height>257</height>
+ <width>445</width>
+ <height>266</height>
</rect>
</property>
<property name="windowTitle">
@@ -27,7 +27,7 @@
<enum>QTabWidget::North</enum>
</property>
<property name="currentIndex">
- <number>0</number>
+ <number>2</number>
</property>
<widget class="QWidget" name="tabPermissions">
<attribute name="title">
@@ -197,6 +197,64 @@
</item>
</layout>
</widget>
+ <widget class="QWidget" name="networkTab">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <attribute name="title">
+ <string>Network</string>
+ </attribute>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="2" column="1">
+ <widget class="QComboBox" name="interfaceList">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ <property name="insertPolicy">
+ <enum>QComboBox::NoInsert</enum>
+ </property>
+ <property name="frame">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Network Interface</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QPushButton" name="reloadInterfaceListButton">
+ <property name="text">
+ <string>Reload List</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
<item>
diff --git a/src/gui/ui/clientFileReceiveDialog.ui b/src/gui/ui/clientFileReceiveDialog.ui
index af3a135..a137def 100644
--- a/src/gui/ui/clientFileReceiveDialog.ui
+++ b/src/gui/ui/clientFileReceiveDialog.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>208</width>
- <height>108</height>
+ <width>528</width>
+ <height>117</height>
</rect>
</property>
<property name="windowTitle">
@@ -61,6 +61,13 @@
</property>
</spacer>
</item>
+ <item>
+ <widget class="QLabel" name="labelStatus">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
<item>
diff --git a/src/gui/ui/clientFileSendDialog.ui b/src/gui/ui/clientFileSendDialog.ui
index d2d9c75..85462ba 100644
--- a/src/gui/ui/clientFileSendDialog.ui
+++ b/src/gui/ui/clientFileSendDialog.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>186</width>
- <height>108</height>
+ <width>528</width>
+ <height>144</height>
</rect>
</property>
<property name="windowTitle">
@@ -33,7 +33,7 @@
</widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
@@ -61,10 +61,17 @@
</property>
</spacer>
</item>
+ <item>
+ <widget class="QLabel" name="labelStatus">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="labelA">
<property name="text">
diff --git a/src/gui/ui/clientNicklistDialog.ui b/src/gui/ui/clientNicklistDialog.ui
index afd84f1..3679b55 100644
--- a/src/gui/ui/clientNicklistDialog.ui
+++ b/src/gui/ui/clientNicklistDialog.ui
@@ -29,6 +29,13 @@
<widget class="QListWidget" name="listWidget"/>
</item>
<item>
+ <widget class="QCheckBox" name="sendToAllCheckBox">
+ <property name="text">
+ <string>Send to &amp;all</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
diff --git a/src/gui/ui/clientToolbar.ui b/src/gui/ui/clientToolbar.ui
index 5a59c5f..d70857a 100644
--- a/src/gui/ui/clientToolbar.ui
+++ b/src/gui/ui/clientToolbar.ui
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>577</width>
+ <width>328</width>
<height>28</height>
</rect>
</property>
@@ -144,46 +144,6 @@ p, li { white-space: pre-wrap; }
</spacer>
</item>
<item>
- <widget class="QCheckBox" name="vncCheckBox">
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Enable/Disable VNC only for this session</string>
- </property>
- <property name="text">
- <string>Allow VNC</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
-&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
-p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt; font-weight:600; font-style:italic; color:#0055ff;&quot;&gt;Pool Video Switch&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item>
<widget class="QLabel" name="label_3">
<property name="maximumSize">
<size>
diff --git a/src/gui/ui/mainwindow.ui b/src/gui/ui/mainwindow.ui
index eb49d1b..7913e38 100644
--- a/src/gui/ui/mainwindow.ui
+++ b/src/gui/ui/mainwindow.ui
@@ -28,8 +28,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>776</width>
- <height>534</height>
+ <width>778</width>
+ <height>542</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
@@ -195,7 +195,7 @@
<x>0</x>
<y>0</y>
<width>838</width>
- <height>28</height>
+ <height>23</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
@@ -243,9 +243,16 @@
</property>
<addaction name="actionAbout_pvs"/>
</widget>
+ <widget class="QMenu" name="menuNetwork">
+ <property name="title">
+ <string>Network</string>
+ </property>
+ <addaction name="actionConfigure_Network"/>
+ </widget>
<addaction name="menu_File"/>
<addaction name="menuClients"/>
<addaction name="menuLogging"/>
+ <addaction name="menuNetwork"/>
<addaction name="menu_Help"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
@@ -286,6 +293,7 @@
<addaction name="actionView"/>
<addaction name="actionLock"/>
<addaction name="actionChat"/>
+ <addaction name="actionShowProcesses"/>
</widget>
<action name="actionShow_Username">
<property name="checkable">
@@ -531,6 +539,26 @@
<string>-</string>
</property>
</action>
+ <action name="actionConfigure_Network">
+ <property name="text">
+ <string>&amp;Configure...</string>
+ </property>
+ <property name="toolTip">
+ <string>Configure Network Parameters</string>
+ </property>
+ </action>
+ <action name="actionShowProcesses">
+ <property name="icon">
+ <iconset resource="../../../pvsmgr.qrc">
+ <normaloff>:/icons/gears.png</normaloff>:/icons/gears.png</iconset>
+ </property>
+ <property name="text">
+ <string>showProcesses</string>
+ </property>
+ <property name="toolTip">
+ <string>Show Processes of the selected Client</string>
+ </property>
+ </action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
diff --git a/src/gui/ui/mainwindowtouch.ui b/src/gui/ui/mainwindowtouch.ui
index 9030b17..24f40b6 100644
--- a/src/gui/ui/mainwindowtouch.ui
+++ b/src/gui/ui/mainwindowtouch.ui
@@ -28,8 +28,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>1327</width>
- <height>658</height>
+ <width>1329</width>
+ <height>660</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
@@ -365,6 +365,9 @@
<addaction name="actionresetall"/>
<addaction name="separator"/>
<addaction name="actionDozent"/>
+ <addaction name="separator"/>
+ <addaction name="actionConfigure_Network"/>
+ <addaction name="actionShowProcesses"/>
</widget>
<action name="actionShow_Username">
<property name="checkable">
@@ -636,6 +639,27 @@
<string>Ctrl+D</string>
</property>
</action>
+ <action name="actionConfigure_Network">
+ <property name="icon">
+ <iconset resource="../../../pvsmgr.qrc">
+ <normaloff>:/netconf</normaloff>:/netconf</iconset>
+ </property>
+ <property name="text">
+ <string>Configure Network...</string>
+ </property>
+ </action>
+ <action name="actionShowProcesses">
+ <property name="icon">
+ <iconset resource="../../../pvsmgr.qrc">
+ <normaloff>:/icons/gears.png</normaloff>:/icons/gears.png</iconset>
+ </property>
+ <property name="text">
+ <string>showProcesses</string>
+ </property>
+ <property name="toolTip">
+ <string>Show Processes of the selected Client</string>
+ </property>
+ </action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
diff --git a/src/gui/ui/multicastConfigDialog.ui b/src/gui/ui/multicastConfigDialog.ui
new file mode 100644
index 0000000..1ddf02c
--- /dev/null
+++ b/src/gui/ui/multicastConfigDialog.ui
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MulticastConfigDialogClass</class>
+ <widget class="QDialog" name="MulticastConfigDialogClass">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>331</width>
+ <height>314</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>PVS - Multicast Configuration</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;table style=&quot;-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;&quot;&gt;
+&lt;tr&gt;
+&lt;td style=&quot;border: none;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;You need to specify connection parameters for multicast messaging on your network. These parameters will automatically be distributed to client computers, so you need to assign them only once.&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;You will probably want to assign an address from the &lt;span style=&quot; text-decoration: underline;&quot;&gt;239.0.0.0/8&lt;/span&gt; &amp;quot;Administratively Scoped&amp;quot; range.&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Do not assign arbitrary numbers without checking with your network administrator!&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Multicast Group Address</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="groupAddressEdit">
+ <property name="inputMask">
+ <string notr="true">009.009.009.009; </string>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="groupAddressMessage">
+ <property name="text">
+ <string>&lt;span style=&quot; font-weight:600; color:#008800;&quot;&gt;OK&lt;/span&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Data Port (1024-65535)</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="dataPortEdit">
+ <property name="inputMask">
+ <string notr="true">00009; </string>
+ </property>
+ <property name="maxLength">
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QLabel" name="dataPortMessage">
+ <property name="text">
+ <string>&lt;span style=&quot; font-weight:600; color:#008800;&quot;&gt;OK&lt;/span&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Transmission Rate</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QSpinBox" name="rateSpinbox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix">
+ <string> KiB/s</string>
+ </property>
+ <property name="maximum">
+ <number>10240</number>
+ </property>
+ <property name="singleStep">
+ <number>10</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/net/SslServer.cpp b/src/net/SslServer.cpp
index e353e0a..9940a61 100644
--- a/src/net/SslServer.cpp
+++ b/src/net/SslServer.cpp
@@ -59,7 +59,7 @@ void SslServer::incomingConnection(int socketDescriptor)
void SslServer :: sslErrors ( const QList<QSslError> & errors )
{
- printf("FIXME: SSL ERRORS on SERVER: %s\n", errors.begin()->errorString().toUtf8().data());
+ qDebug("FIXME: SSL ERRORS on SERVER: %s", qPrintable(errors.begin()->errorString()));
}
void SslServer::timerEvent (QTimerEvent* event)
@@ -98,7 +98,7 @@ bool SslServer::hasPendingConnections()
{
for (QList<QSslSocket*>::iterator it = _pending.begin(); it != _pending.end(); it++)
{
- printf("State: %d - Encrypted: %d\n", (int)(*it)->state(), (*it)->isEncrypted());
+ qDebug("State: %d - Encrypted: %d", (int)(*it)->state(), (*it)->isEncrypted());
if ((*it)->state() == QAbstractSocket::ConnectedState && (*it)->isEncrypted()) return true;
}
return false;
diff --git a/src/net/mcast/CMakeLists.txt b/src/net/mcast/CMakeLists.txt
new file mode 100644
index 0000000..e92b090
--- /dev/null
+++ b/src/net/mcast/CMakeLists.txt
@@ -0,0 +1,61 @@
+INCLUDE(../../../OpenPGMConfig.cmake)
+
+ADD_DEFINITIONS(
+ ${LIBPGM_CXXFLAGS}
+ -D__STDC_CONSTANT_MACROS
+ -D__STDC_LIMIT_MACROS
+)
+
+# OpenPGM uses the C99 restrict keyword which g++ does not recognize:
+#IF(CMAKE_COMPILER_IS_GNUCXX)
+# ADD_DEFINITIONS(${LIBPGM_CXXFLAGS})
+#ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+
+INCLUDE(${QT_USE_FILE})
+
+SET(pvsmcast_MOC_HDRS
+ McastConfiguration.h
+ McastPGMSocket.h
+ McastReceiver.h
+ McastSender.h
+)
+
+SET(pvsmcast_HDRS
+ McastConfiguration.h
+ McastPGMSocket.h
+ McastReceiver.h
+ McastSender.h
+)
+
+SET(pvsmcast_SRCS
+ McastConfiguration.cpp
+ McastPGMSocket.cpp
+ McastReceiver.cpp
+ McastSender.cpp
+)
+
+QT4_WRAP_CPP(
+ pvsmcast_MOC_SRCS
+ ${pvsmcast_MOC_HDRS}
+)
+
+SET_SOURCE_FILES_PROPERTIES(${pvsmcast_SRCS} ${pvsmcast_MOC_SRCS}
+ PROPERTIES
+ OBJECT_DEPENDS "3rdparty/libpgm.a" # Make sure libpgm gets unpacked before building C++ files
+)
+
+ADD_LIBRARY(
+ pvsmcast
+ STATIC
+ ${pvsmcast_HDRS}
+ ${pvsmcast_SRCS}
+ ${pvsmcast_MOC_SRCS}
+)
+
+TARGET_LINK_LIBRARIES(
+ pvsmcast
+ pgm
+ ${QT_LIBRARIES}
+)
+
+ADD_SUBDIRECTORY(trial_programs)
diff --git a/src/net/mcast/McastConfiguration.cpp b/src/net/mcast/McastConfiguration.cpp
new file mode 100644
index 0000000..6c5e620
--- /dev/null
+++ b/src/net/mcast/McastConfiguration.cpp
@@ -0,0 +1,57 @@
+/*
+# 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/McastConfiguration.cpp
+# - hold Multicast protocol configuration data
+# -----------------------------------------------------------------------------
+*/
+
+#include <QSettings>
+
+#include "McastConfiguration.h"
+
+void McastConfiguration::loadFrom(QSettings* _settings, char const* group)
+{
+ if (group)
+ _settings->beginGroup(group);
+
+ _multicastAddress = _settings->value("groupAddress", DEFAULT_MULTICAST_ADDRESS).toString();
+ _multicastInterface = _settings->value("interface", DEFAULT_MULTICAST_INTERFACE).toString();
+ _multicastMTU = _settings->value("mtu", DEFAULT_MULTICAST_MTU).value<quint16>();
+ _multicastRate = _settings->value("rate", DEFAULT_MULTICAST_RATE).value<quint32>();
+ _multicastUseUDP = _settings->value("use-udp", DEFAULT_MULTICAST_USEUDP).toBool();
+ _multicastWinSize = _settings->value("winsize", DEFAULT_MULTICAST_WSIZ).value<quint16>();
+ _multicastUDPPortBase = _settings->value("portbase", DEFAULT_MULTICAST_UDPPORT).value<quint16>();
+ _multicastDPort = _settings->value("dport", DEFAULT_MULTICAST_DPORT).value<quint16>();
+ _multicastSPort = _settings->value("sport", DEFAULT_MULTICAST_SPORT).value<quint16>();
+
+ if (group)
+ _settings->endGroup();
+}
+
+void McastConfiguration::writeTo(QSettings* _settings, char const* group) const
+{
+ if (group)
+ _settings->beginGroup(group);
+
+ _settings->setValue("groupAddress", _multicastAddress);
+ _settings->setValue("interface", _multicastInterface);
+ _settings->setValue("mtu", _multicastMTU);
+ _settings->setValue("rate", _multicastRate);
+ _settings->setValue("use-udp", _multicastUseUDP);
+ _settings->setValue("winsize", _multicastWinSize);
+ _settings->setValue("portbase", _multicastUDPPortBase);
+ _settings->setValue("dport", _multicastDPort);
+ _settings->setValue("sport", _multicastSPort);
+
+ if (group)
+ _settings->endGroup();
+}
diff --git a/src/net/mcast/McastConfiguration.h b/src/net/mcast/McastConfiguration.h
new file mode 100644
index 0000000..53f7a54
--- /dev/null
+++ b/src/net/mcast/McastConfiguration.h
@@ -0,0 +1,204 @@
+/*
+# 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/McastConfiguration.h
+# - hold Multicast protocol configuration data
+# -----------------------------------------------------------------------------
+*/
+
+#ifndef MCASTCONFIGURATION_H_
+#define MCASTCONFIGURATION_H_
+
+#include <QObject>
+#include <QString>
+#include <QtGlobal>
+
+#include "McastConstants.h"
+
+class QSettings;
+
+class McastConfiguration: public QObject
+{
+ Q_OBJECT
+public:
+ McastConfiguration(QObject* parent = 0) :
+ QObject(parent),
+ _multicastInterface(DEFAULT_MULTICAST_INTERFACE),
+ _multicastAddress(DEFAULT_MULTICAST_ADDRESS),
+ _multicastRate(DEFAULT_MULTICAST_RATE),
+ _multicastSPort(DEFAULT_MULTICAST_SPORT),
+ _multicastDPort(DEFAULT_MULTICAST_DPORT),
+ _multicastWinSize(DEFAULT_MULTICAST_WSIZ),
+ _multicastMTU(DEFAULT_MULTICAST_MTU),
+ _multicastUDPPortBase(DEFAULT_MULTICAST_UDPPORT),
+ _multicastUseUDP(DEFAULT_MULTICAST_USEUDP)
+ {
+ }
+
+ McastConfiguration(McastConfiguration const& other, QObject* parent = 0) :
+ QObject(parent),
+ _multicastInterface(other._multicastInterface),
+ _multicastAddress(other._multicastAddress),
+ _multicastRate(other._multicastRate),
+ _multicastSPort(other._multicastSPort),
+ _multicastDPort(other._multicastDPort),
+ _multicastWinSize(other._multicastWinSize),
+ _multicastMTU(other._multicastMTU),
+ _multicastUDPPortBase(other._multicastUDPPortBase),
+ _multicastUseUDP(other._multicastUseUDP)
+ {
+ }
+
+ virtual ~McastConfiguration()
+ {
+ }
+
+ QString multicastAddress() const
+ {
+ return _multicastAddress;
+ }
+ McastConfiguration* multicastAddress(QString const& address)
+ {
+ _multicastAddress = address;
+ return this;
+ }
+
+ quint16 multicastSPort() const
+ {
+ return _multicastSPort;
+ }
+ McastConfiguration* multicastSPort(quint16 port)
+ {
+ _multicastSPort = port;
+ return this;
+ }
+
+ quint16 multicastDPort() const
+ {
+ return _multicastDPort;
+ }
+ McastConfiguration* multicastDPort(quint16 port)
+ {
+ _multicastDPort = port;
+ return this;
+ }
+
+ quint32 multicastRate() const
+ {
+ return _multicastRate;
+ }
+ McastConfiguration* multicastRate(quint32 rate)
+ {
+ _multicastRate = rate;
+ return this;
+ }
+
+ quint16 multicastWinSize() const
+ {
+ return _multicastWinSize;
+ }
+ McastConfiguration* multicastWinSize(quint16 size)
+ {
+ _multicastWinSize = size;
+ return this;
+ }
+
+ quint16 multicastMTU() const
+ {
+ return _multicastMTU;
+ }
+ McastConfiguration* multicastMTU(quint16 mtu)
+ {
+ _multicastMTU = mtu;
+ return this;
+ }
+
+ bool multicastUseUDP() const
+ {
+ return _multicastUseUDP;
+ }
+ McastConfiguration* multicastUseUDP(bool useUDP)
+ {
+ _multicastUseUDP = useUDP;
+ return this;
+ }
+
+ quint16 multicastUDPPortBase() const
+ {
+ return _multicastUDPPortBase;
+ }
+ McastConfiguration* multicastUDPPortBase(quint16 port)
+ {
+ _multicastUDPPortBase = port;
+ return this;
+ }
+
+ QString multicastInterface() const
+ {
+ return _multicastInterface;
+ }
+ McastConfiguration* multicastInterface(QString const& interface)
+ {
+ _multicastInterface = interface;
+ return this;
+ }
+
+ quint16 multicastUDPUPort() const
+ {
+ return _multicastUDPPortBase;
+ }
+
+ quint16 multicastUDPMPort() const
+ {
+ return _multicastUDPPortBase;
+ }
+
+ void commit()
+ {
+ emit changed();
+ }
+
+ McastConfiguration& operator=(McastConfiguration const& source)
+ {
+ if(this != &source)
+ {
+ _multicastInterface = source._multicastInterface;
+ _multicastAddress = source._multicastAddress;
+ _multicastRate = source._multicastRate;
+ _multicastSPort = source._multicastSPort;
+ _multicastDPort = source._multicastDPort;
+ _multicastWinSize = source._multicastWinSize;
+ _multicastMTU = source._multicastMTU;
+ _multicastUDPPortBase = source._multicastUDPPortBase;
+ _multicastUseUDP = source._multicastUseUDP;
+ }
+ return *this;
+ }
+
+ void loadFrom(QSettings* settings, char const* group = 0);
+ void writeTo(QSettings* settings, char const* group = 0) const;
+
+signals:
+ void changed();
+
+private:
+ QString _multicastInterface;
+ QString _multicastAddress;
+ quint32 _multicastRate;
+ quint16 _multicastSPort;
+ quint16 _multicastDPort;
+ quint16 _multicastWinSize;
+ quint16 _multicastMTU;
+ quint16 _multicastUDPPortBase;
+ bool _multicastUseUDP;
+};
+
+#endif /* MCASTCONFIGURATION_H_ */
diff --git a/src/net/mcast/McastConstants.h b/src/net/mcast/McastConstants.h
new file mode 100644
index 0000000..624e195
--- /dev/null
+++ b/src/net/mcast/McastConstants.h
@@ -0,0 +1,36 @@
+/*
+# 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/McastMagic.h
+# - Specify the magic numbers for the McastFT protocol
+# -----------------------------------------------------------------------------
+*/
+
+#ifndef MCASTMAGIC_H_
+#define MCASTMAGIC_H_
+
+#include <stdint.h>
+
+#define MCASTFT_MAGIC UINT64_C(0x6d60ad83825fb7f9)
+#define DEFAULT_MULTICAST_INTERFACE ""
+#define DEFAULT_MULTICAST_ADDRESS "239.255.220.207"
+#define DEFAULT_MULTICAST_SPORT 6964
+#define DEFAULT_MULTICAST_DPORT 6965
+#define DEFAULT_MULTICAST_USEUDP true
+#define DEFAULT_MULTICAST_UDPPORT 6966
+#define DEFAULT_MULTICAST_WSIZ 30
+#define DEFAULT_MULTICAST_RATE (100*1024)
+#define DEFAULT_MULTICAST_MTU 1400
+#define DEFAULT_MULTICAST_APDU 1200
+#define DEFAULT_MULTICAST_CHUNK 1024
+#define DEFAULT_MULTICAST_SHUTDOWN_TIMEOUT 10000
+
+#endif /* MCASTMAGIC_H_ */
diff --git a/src/net/mcast/McastPGMSocket.cpp b/src/net/mcast/McastPGMSocket.cpp
new file mode 100644
index 0000000..731fc13
--- /dev/null
+++ b/src/net/mcast/McastPGMSocket.cpp
@@ -0,0 +1,666 @@
+/*
+# 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/McastPGMSocket.cpp
+# - wrap OpenPGM Sockets in a nicer interface -- implementation
+# -----------------------------------------------------------------------------
+*/
+
+#include <cstdlib>
+
+#include <sys/poll.h>
+#include <sys/socket.h>
+
+#include <QByteArray>
+#include <QList>
+#include <QtDebug>
+#include <QPointer>
+#include <QSocketNotifier>
+#include <QTimer>
+
+#include <pgm/pgm.h>
+
+#include "McastPGMSocket.h"
+
+using namespace std;
+
+class McastPGMSocket_priv
+{
+public:
+ McastPGMSocket_priv() :
+ socket(0),
+ send_notif(0)
+ {
+ }
+ ~McastPGMSocket_priv()
+ {
+ if (socket)
+ pgm_close(socket, 0);
+ Q_FOREACH(QSocketNotifier* notif, _notifs)
+ {
+ delete notif;
+ }
+ if (send_notif)
+ delete send_notif;
+ }
+
+ pgm_sock_t* socket;
+ McastPGMSocket::Direction direction;
+ QSocketNotifier* send_notif;
+ QList<QSocketNotifier*> _notifs;
+
+ QSocketNotifier* notifier_for(int fd) {
+ Q_FOREACH(QSocketNotifier* notif, _notifs)
+ {
+ if(notif->socket() == fd)
+ {
+ return notif;
+ }
+ }
+ return 0;
+ }
+};
+
+static void _ensurePGMInited()
+{
+ if (!pgm_supported())
+ {
+ pgm_error_t* err;
+ int good = pgm_init(&err);
+ if (!good)
+ {
+ qCritical() << "Could not init OpenPGM library: PGM Error: " << (err->message ? err->message : "(null)");
+ std::exit(1);
+ }
+ }
+}
+
+McastPGMSocket::McastPGMSocket(QObject* parent) :
+ QObject(parent),
+ _priv(new McastPGMSocket_priv),
+ _opened(false),
+ _finished(false),
+ _nakTimeout(new QTimer()),
+ _dataTimeout(new QTimer()),
+ _sendTimeout(new QTimer()),
+ _shutdownTimer(0),
+ _shutdown_timeout(0)
+{
+ _ensurePGMInited();
+
+ _nakTimeout->setSingleShot(true);
+ _dataTimeout->setSingleShot(true);
+ _sendTimeout->setSingleShot(true);
+
+ connect(_nakTimeout, SIGNAL(timeout()), this, SLOT(handleNakTimeout()));
+ connect(_dataTimeout, SIGNAL(timeout()), this, SLOT(handleDataTimeout()));
+ connect(_sendTimeout, SIGNAL(timeout()), this, SLOT(canSend()));
+}
+
+McastPGMSocket::~McastPGMSocket()
+{
+ delete _priv;
+ delete _nakTimeout;
+ delete _dataTimeout;
+ delete _sendTimeout;
+}
+
+bool McastPGMSocket::open(McastConfiguration const* config, Direction direction)
+{
+ _priv->direction = direction;
+
+ pgm_error_t* err = 0;
+ int good;
+
+ pgm_addrinfo_t* addrinfo;
+ // parse the address string
+ good = pgm_getaddrinfo((config->multicastInterface() + ";" + config->multicastAddress()).toLatin1().constData(),
+ 0, &addrinfo, &err);
+ if (!good)
+ {
+ qCritical() << "Could not parse address info: PGM Error: "
+ << err->message;
+ return false;
+ }
+
+ sa_family_t family = addrinfo->ai_send_addrs[0].gsr_group.ss_family;
+
+ if(config->multicastUseUDP())
+ {
+ good = pgm_socket(&_priv->socket, family, SOCK_SEQPACKET, IPPROTO_UDP, &err);
+ }
+ else
+ {
+ good = pgm_socket(&_priv->socket, family, SOCK_SEQPACKET, IPPROTO_PGM, &err);
+ }
+
+ if (!good)
+ {
+ qCritical() << "Could not open socket: PGM Error: " << err->message;
+ pgm_error_free(err);
+ return false;
+ }
+
+ unsigned const ambient_spm = 2000 * 1000; // every one hundred milliseconds (approx.)
+
+ /* Options for sending data */
+ const int spm_heartbeat[] =
+ { 512 * 1000,
+ 1024 * 1000,
+ 2048 * 1000,
+ 4096 * 1000 },
+ max_rate = 0,
+ max_window = config->multicastWinSize() * config->multicastRate() / config->multicastMTU();
+ // const int max_window_sqns = 3000;
+ qDebug() << "Computed window size " << max_window << " packets";
+
+// pgm_setsockopt(_priv->socket, PGM_SEND_ONLY, &send_only,
+// sizeof(send_only));
+
+ // SPM messages
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_AMBIENT_SPM, &ambient_spm, sizeof(ambient_spm));
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_HEARTBEAT_SPM, &spm_heartbeat, sizeof(spm_heartbeat));
+
+ // Transmit window
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_TXW_MAX_RTE, &max_rate, sizeof(max_rate));
+// pgm_setsockopt(_priv->socket, PGM_TXW_SECS, &max_window, sizeof(max_window));
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_TXW_SQNS, &max_window, sizeof(max_window));
+
+ /* Options for receiving data */
+ const int passive = 0,
+ spmr_expiry = 500 * 1000,
+ nak_bo_ivl = 200 * 1000,
+ nak_rpt_ivl = 500 * 1000,
+ nak_rdata_ivl = 500 * 1000,
+ nak_data_retries = 50,
+ nak_ncf_retries = 50;
+ qDebug() << "Computed window size " << max_window << " packets";
+
+// pgm_setsockopt(_priv->socket, PGM_RECV_ONLY, &recv_only, sizeof(recv_only));
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_PASSIVE, &passive, sizeof(passive));
+// pgm_setsockopt(_priv->socket, PGM_RXW_MAX_RTE, &max_rate, sizeof(max_rate));
+// pgm_setsockopt(_priv->socket, PGM_RXW_SECS, &max_window, sizeof(max_window));
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_SPMR_EXPIRY, &spmr_expiry, sizeof(spmr_expiry));
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_NAK_BO_IVL, &nak_bo_ivl, sizeof(nak_bo_ivl));
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_NAK_RPT_IVL, &nak_rpt_ivl, sizeof(nak_rpt_ivl));
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_NAK_RDATA_IVL, &nak_rdata_ivl, sizeof(nak_rdata_ivl));
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_NAK_DATA_RETRIES, &nak_data_retries, sizeof(nak_data_retries));
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_NAK_NCF_RETRIES, &nak_ncf_retries, sizeof(nak_ncf_retries));
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_RXW_SQNS, &max_window, sizeof(max_window));
+
+ /* Try using PGMCC */
+ const struct pgm_pgmccinfo_t pgmccinfo = {
+ 100 /* usecs */ * 1000 /* msecs */,
+ 75 /* from OpenPGM examples */,
+ 500 /* from PGMCC internet-draft */
+ };
+ good = pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_USE_PGMCC, &pgmccinfo, sizeof(pgmccinfo));
+ if(!good)
+ {
+ qCritical() << "Could not enable PGMCC";
+ return false;
+ }
+
+// /* Forward Error Correction */
+// const struct pgm_fecinfo_t pgmfecinfo = {
+// 255 /* from OpenPGM examples */,
+// 2 /* send two proactive packets */,
+// 8 /* from OpenPGM examples */,
+// 1 /* enable on-demand parity */,
+// 1 /* enable variable packet length */
+// };
+// good = pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_USE_FEC, &pgmfecinfo, sizeof(pgmfecinfo));
+// if(!good)
+// {
+// qCritical() << "Could not enable FEC";
+// return false;
+// }
+
+ // Peer Expiry: We will give 1 minute.
+ int const peer_expiry = 60 /* seconds */ * 1000000 /* microseconds */;
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_PEER_EXPIRY, &peer_expiry, sizeof(peer_expiry));
+
+ // MTU
+ int const mtu = config->multicastMTU();
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_MTU, &mtu, sizeof(mtu));
+
+ pgm_sockaddr_t addr;
+ addr.sa_addr.sport = config->multicastSPort();
+ addr.sa_port = config->multicastDPort();
+ good = pgm_gsi_create_from_hostname(&addr.sa_addr.gsi, &err);
+ if (!good)
+ {
+ qCritical() << "Could not generate a GSI: PGM Error: " << err->message;
+ pgm_error_free(err);
+ return false;
+ }
+
+ struct pgm_interface_req_t ifreq;
+ ifreq.ir_interface = addrinfo->ai_send_addrs[0].gsr_interface;
+ ifreq.ir_scope_id = 0;
+ if (AF_INET6 == family)
+ {
+ ifreq.ir_scope_id = ((struct sockaddr_in6*)&addrinfo->ai_send_addrs[0])->sin6_scope_id;
+ }
+
+ // UDP Encapsulation
+ if(config->multicastUseUDP())
+ {
+ const int uport = config->multicastUDPUPort();
+ const int mport = config->multicastUDPMPort();
+
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_UDP_ENCAP_MCAST_PORT, &mport, sizeof(mport));
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_UDP_ENCAP_UCAST_PORT, &uport, sizeof(uport));
+ }
+
+ good = pgm_bind3(_priv->socket, &addr, sizeof(addr), &ifreq , sizeof(ifreq), &ifreq, sizeof(ifreq), &err);
+ if (!good)
+ {
+ qCritical() << "Could not bind socket: PGM Error: " << err->message;
+ pgm_error_free(err);
+ return false;
+ }
+
+ // qDebug() << "Max APDU is " << _priv->socket->max_apdu;
+ // qDebug() << "Max TPDU is " << _priv->socket->max_tpdu;
+ // qDebug() << "Max TSDU Fragment is " << _priv->socket->max_tsdu_fragment;
+ // qDebug() << "TXW_SQNS is " << _priv->socket->txw_sqns;
+
+ // join the group
+ for (unsigned i = 0; i < addrinfo->ai_recv_addrs_len; i++)
+ {
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_JOIN_GROUP,
+ &addrinfo->ai_recv_addrs[i], sizeof(struct group_req));
+ }
+
+ // set send address
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_SEND_GROUP, &addrinfo->ai_send_addrs[0],
+ sizeof(struct group_req));
+
+ // IP parameters
+ const int nonblocking = 1, multicast_loop = 0, multicast_hops = 16;
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_MULTICAST_LOOP, &multicast_loop,
+ sizeof(multicast_loop));
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_MULTICAST_HOPS, &multicast_hops,
+ sizeof(multicast_hops));
+ pgm_setsockopt(_priv->socket, IPPROTO_PGM, PGM_NOBLOCK, &nonblocking,
+ sizeof(nonblocking));
+
+ good = pgm_connect(_priv->socket, &err);
+ if (!good)
+ {
+ qCritical() << "Could not connect socket: PGM Error: " << err->message;
+ pgm_error_free(err);
+ return false;
+ }
+
+ _opened = true;
+
+ setupNotifiers();
+
+ pgm_freeaddrinfo(addrinfo);
+
+ /* Prime the generation of SPM packets during the waiting period */
+ if(_priv->direction == PSOCK_WRITE)
+ QTimer::singleShot(0, this, SLOT(handleNak()));
+
+ return true;
+}
+
+void McastPGMSocket::setupNotifiers()
+{
+ int recv_sock, repair_sock, pending_sock;
+ char const* slotname = (_priv->direction == PSOCK_WRITE) ? SLOT(handleNak(int)) : SLOT(handleData(int));
+
+ struct pollfd pollin[10];
+ int in_nfds = 10;
+ pgm_poll_info(_priv->socket, pollin, &in_nfds, POLLIN);
+ for(int i = 0; i < in_nfds; i++)
+ {
+ QSocketNotifier* notif = new QSocketNotifier(pollin[i].fd, QSocketNotifier::Read, this);
+ _priv->_notifs.append(notif);
+ connect(notif, SIGNAL(activated(int)), this, slotname);
+ }
+
+ if(_priv->direction == PSOCK_WRITE)
+ {
+ struct pollfd pfd;
+ int nfds = 1;
+ pgm_poll_info(_priv->socket, &pfd, &nfds, POLLOUT);
+ _priv->send_notif = new QSocketNotifier(pfd.fd, QSocketNotifier::Write, this);
+ connect(_priv->send_notif, SIGNAL(activated(int)), this, SLOT(canSend()));
+ }
+}
+
+void McastPGMSocket::handleNak(int fd)
+{
+ qDebug() << "handleNak(" << fd << ")";
+
+ QSocketNotifier* notif = _priv->notifier_for(fd);
+ notif->setEnabled(false);
+
+ if (_shutdownTimer)
+ {
+ _shutdownTimer->start(_shutdown_timeout);
+ qDebug() << "Started shutdown timer";
+ }
+
+ handleNak();
+
+ notif->setEnabled(true);
+}
+
+void McastPGMSocket::handleNak()
+{
+ if (_finished)
+ return;
+
+ // QTimer::singleShot(1000, this, SLOT(handleNakTimeout()));
+
+ // to handle NAKs in OpenPGM, we need to pgm_recv:
+ char buf[4096];
+ pgm_error_t* err = 0;
+
+ int status;
+ // while we don't block:
+ do
+ {
+ status = pgm_recv(_priv->socket, buf, sizeof(buf), MSG_DONTWAIT, 0, &err);
+
+ if(status == PGM_IO_STATUS_TIMER_PENDING)
+ {
+ struct timeval tv;
+ socklen_t size = sizeof(tv);
+ pgm_getsockopt(_priv->socket, IPPROTO_PGM, PGM_TIME_REMAIN, &tv, &size);
+ const long usecs = tv.tv_sec * 1000000 + tv.tv_usec;
+ int msecs = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
+ if(msecs == 0)
+ msecs = 1;
+ qDebug() << " timer pending: " << usecs << "us (rounded to " << msecs << "ms)";
+ _nakTimeout->start(msecs);
+ break;
+ }
+ else if(status == PGM_IO_STATUS_RATE_LIMITED)
+ {
+ struct timeval tv;
+ socklen_t size = sizeof(tv);
+ pgm_getsockopt(_priv->socket, IPPROTO_PGM, PGM_RATE_REMAIN, &tv, &size);
+ int msecs = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
+ if(msecs == 0)
+ msecs = 1;
+ qDebug() << " rate limited: " << msecs << "ms";
+ _nakTimeout->start(msecs);
+ break;
+ }
+ else if(status == PGM_IO_STATUS_WOULD_BLOCK)
+ {
+ qDebug() << " wouldblock";
+ break;
+ }
+ else
+ {
+ if(err)
+ {
+ qCritical() << "Could not handle NAKs: PGM Error: " << err->message;
+ pgm_error_free(err);
+ err = 0;
+ }
+ }
+ }
+ while (true);
+}
+
+void McastPGMSocket::handleNakTimeout()
+{
+ qDebug() << "handleNakTimeout()";
+
+ handleNak();
+}
+
+void McastPGMSocket::handleData(int fd)
+{
+ // need to guard against destruction in finish() via signals/slots
+ QPointer<QSocketNotifier> notif(_priv->notifier_for(fd));
+ notif->setEnabled(false);
+
+ handleData();
+
+ if (notif)
+ notif->setEnabled(true);
+}
+
+void McastPGMSocket::handleData()
+{
+ if (_finished) {
+ return;
+ }
+
+ int status;
+ do
+ {
+ char buf[4096];
+ size_t size;
+ pgm_error_t* err = 0;
+
+ status = pgm_recv(_priv->socket, buf, sizeof(buf), MSG_DONTWAIT, &size, &err);
+
+ if (status == PGM_IO_STATUS_NORMAL)
+ {
+ qDebug() << " normally received";
+ if(size > 0)
+ {
+ QByteArray bytes(buf, size);
+ emit receivedPacket(bytes);
+ }
+ }
+ else if (status == PGM_IO_STATUS_WOULD_BLOCK)
+ {
+ qDebug() << " would block";
+ // nothing more to do this time
+ break;
+ }
+ else if (status == PGM_IO_STATUS_TIMER_PENDING)
+ {
+ struct timeval tv;
+ socklen_t size = sizeof(tv);
+ pgm_getsockopt(_priv->socket, IPPROTO_PGM, PGM_TIME_REMAIN, &tv, &size);
+ const long usecs = tv.tv_sec * 1000000 + tv.tv_usec;
+ int msecs = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
+ if(msecs == 0)
+ msecs = 1;
+ qDebug() << " timer pending: " << usecs << "us (rounded to " << msecs << "ms)";
+ _dataTimeout->start(msecs);
+ break;
+ }
+ else if (status == PGM_IO_STATUS_RATE_LIMITED)
+ {
+ struct timeval tv;
+ socklen_t size = sizeof(tv);
+ pgm_getsockopt(_priv->socket, IPPROTO_PGM, PGM_RATE_REMAIN, &tv, &size);
+ int msecs = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
+ if(msecs == 0)
+ msecs = 1;
+ qDebug() << " rate limit pending: " << msecs << "ms";
+ _dataTimeout->start(msecs);
+ break;
+ }
+ else if (status == PGM_IO_STATUS_RESET)
+ {
+ qDebug() << " connection reset";
+ emit connectionReset();
+ qCritical() << "Connection Reset: PGM Error: " << (err ? err->message : "(null)");
+ pgm_error_free(err);
+ break;
+ }
+ else if (status == PGM_IO_STATUS_FIN)
+ {
+ qDebug() << " connection finished";
+ emit connectionFinished();
+ break;
+ }
+ else
+ {
+ if(err)
+ {
+ qCritical() << "Could not read packet: PGM Error: " << (err ? err->message: "(null)");
+ break;
+ }
+ }
+
+ // the socket might have been closed from under us
+ if (!_priv->socket)
+ break;
+ }
+ while (true);
+}
+
+void McastPGMSocket::handleDataTimeout()
+{
+ qDebug() << "handleDataTimeout()";
+
+ handleData();
+}
+
+void McastPGMSocket::canSend()
+{
+ if (_finished)
+ return;
+
+
+ if (_priv->send_notif)
+ {
+ _priv->send_notif->setEnabled(false);
+ }
+
+ if(_q.isEmpty())
+ {
+ emit readyToSend();
+ }
+ else
+ {
+ QByteArray const packet(_q.head());
+ int status;
+
+ status = pgm_send(_priv->socket, packet.constData(), packet.size(), 0);
+
+ if(status == PGM_IO_STATUS_NORMAL)
+ {
+ _q.dequeue();
+ if(!_q.isEmpty())
+ {
+ _priv->send_notif->setEnabled(true);
+ }
+ else
+ {
+ emit readyToSend();
+ }
+ }
+ else if(status == PGM_IO_STATUS_WOULD_BLOCK)
+ {
+ _priv->send_notif->setEnabled(true);
+ }
+ else if(status == PGM_IO_STATUS_CONGESTION)
+ {
+ qDebug() << " congested...";
+ // wait a short time (10ms?)
+ _sendTimeout->start(10);
+ }
+ else if(status == PGM_IO_STATUS_RATE_LIMITED)
+ {
+ struct timeval tv;
+ socklen_t size = sizeof(tv);
+ pgm_getsockopt(_priv->socket, IPPROTO_PGM, PGM_RATE_REMAIN, &tv, &size);
+ int msecs = (tv.tv_sec * 1000) + ((tv.tv_usec + 999) / 1000);
+ if(msecs == 0)
+ msecs = 1;
+ qDebug() << " rate_limited, waiting" << msecs << "ms";
+ _sendTimeout->start(msecs);
+ }
+ else
+ {
+ qCritical() << "Unhandled status in canSend():" << status;
+ }
+ }
+
+ if (_shutdownTimer)
+ _shutdownTimer->start(_shutdown_timeout);
+}
+
+void McastPGMSocket::sendPacket(QByteArray const& bytes)
+{
+ if(_shutdownTimer)
+ {
+ qCritical() << "Logic error: sendPacket() after shutdown()";
+ }
+
+ _q.enqueue(bytes);
+ _priv->send_notif->setEnabled(true);
+}
+
+void McastPGMSocket::finish()
+{
+ if (_finished)
+ {
+ return;
+ }
+
+ qDebug() << "finish()";
+
+ Q_FOREACH(QSocketNotifier* notif, _priv->_notifs)
+ {
+ notif->setEnabled(false);
+ delete notif;
+ }
+ _priv->_notifs.clear();
+
+ if(_priv->send_notif)
+ {
+ delete _priv->send_notif;
+ _priv->send_notif = 0;
+ }
+
+ if (_priv->socket)
+ {
+ pgm_close(_priv->socket, 1);
+ _priv->socket = 0;
+ }
+
+ _finished = true;
+
+ emit connectionFinished();
+
+ qDebug() << "Socket finished";
+}
+
+bool McastPGMSocket::finished() const
+{
+ return _finished;
+}
+
+bool McastPGMSocket::isOpen() const
+{
+ return _opened && !_finished;
+}
+
+void McastPGMSocket::shutdown(int interval)
+{
+ if(_priv->direction == PSOCK_READ)
+ return;
+
+ _shutdown_timeout = interval;
+ _shutdownTimer = new QTimer(this);
+ connect(_shutdownTimer, SIGNAL(timeout()), this, SLOT(finish()));
+ if (_q.isEmpty())
+ {
+ _shutdownTimer->start(_shutdown_timeout);
+ qDebug() << "Started shutdown timer";
+ }
+}
diff --git a/src/net/mcast/McastPGMSocket.h b/src/net/mcast/McastPGMSocket.h
new file mode 100644
index 0000000..4ccf931
--- /dev/null
+++ b/src/net/mcast/McastPGMSocket.h
@@ -0,0 +1,81 @@
+/*
+# 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/McastPGMSocket.h
+# - wrap OpenPGM Sockets in a nicer interface -- interface
+# -----------------------------------------------------------------------------
+*/
+
+#ifndef MCASTPGMSOCKET_H_
+#define MCASTPGMSOCKET_H_
+
+#include <QByteArray>
+#include <QObject>
+#include <QQueue>
+
+#include <src/net/mcast/McastConfiguration.h>
+#include <src/net/mcast/McastConstants.h>
+
+class McastPGMSocket_priv;
+class QTimer;
+
+class McastPGMSocket : public QObject
+{
+ Q_OBJECT
+public:
+ enum Direction {
+ PSOCK_READ,
+ PSOCK_WRITE
+ };
+
+ McastPGMSocket(QObject* parent = 0);
+ virtual ~McastPGMSocket();
+
+ bool open(McastConfiguration const* config, Direction direction);
+ bool finished() const;
+ bool isOpen() const;
+ void shutdown(int interval = DEFAULT_MULTICAST_SHUTDOWN_TIMEOUT);
+
+signals:
+ void readyToSend();
+ void receivedPacket(QByteArray const& bytes);
+ void connectionReset();
+ void connectionFinished();
+ void shutdownComplete();
+
+public slots:
+ void sendPacket(QByteArray const& bytes);
+ void finish();
+
+private slots:
+ void handleNak(int fd);
+ void handleData(int fd);
+ void handleNak();
+ void handleData();
+ void handleNakTimeout();
+ void handleDataTimeout();
+ void canSend();
+
+private:
+ McastPGMSocket_priv* _priv;
+ QQueue<QByteArray> _q;
+ bool _finished;
+ bool _opened;
+ QTimer* _nakTimeout;
+ QTimer* _dataTimeout;
+ QTimer* _sendTimeout;
+ QTimer* _shutdownTimer;
+ int _shutdown_timeout;
+
+ void setupNotifiers();
+};
+
+#endif /* MCASTPGMSOCKET_H_ */
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);
+}
diff --git a/src/net/mcast/McastReceiver.h b/src/net/mcast/McastReceiver.h
new file mode 100644
index 0000000..247733d
--- /dev/null
+++ b/src/net/mcast/McastReceiver.h
@@ -0,0 +1,80 @@
+/*
+# 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 -- interface
+# -----------------------------------------------------------------------------
+*/
+
+#ifndef MCASTRECEIVER_H_
+#define MCASTRECEIVER_H_
+
+#include <QByteArray>
+#include <QCryptographicHash>
+#include <QIODevice>
+#include <QObject>
+#include <QtGlobal>
+
+#include <src/net/mcast/McastConfiguration.h>
+#include <src/net/mcast/McastPGMSocket.h>
+
+class McastReceiver : public QObject
+{
+ Q_OBJECT
+public:
+ enum Result {
+ RES_OK,
+ RES_ABORTED,
+ RES_OFFSET_MISMATCH,
+ RES_CHECKSUM_MISMATCH,
+ RES_MD5_MISMATCH,
+ RES_CONNECTION_RESET
+ };
+
+ McastReceiver(QIODevice* iodev, McastConfiguration* config = 0, QObject* parent = 0);
+ virtual ~McastReceiver();
+
+ McastConfiguration* config()
+ {
+ return _config;
+ }
+
+ void config(McastConfiguration const* config);
+
+ static inline bool is_error(Result result)
+ {
+ return result != RES_OK;
+ }
+
+signals:
+ void finished(int result);
+ void progress(quint64 offset);
+
+public slots:
+ bool start();
+ void abort();
+
+private:
+ McastConfiguration* _config;
+ McastPGMSocket* _socket;
+ quint64 _curoffs;
+ bool _closed;
+ QCryptographicHash _hash;
+ QIODevice* _iodev;
+
+private slots:
+ void receivedPacket(QByteArray const& bytes);
+ void connectionReset();
+
+ void _close(Result result);
+};
+
+#endif /* MCASTRECEIVER_H_ */
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();
+}
diff --git a/src/net/mcast/McastSender.h b/src/net/mcast/McastSender.h
new file mode 100644
index 0000000..0c5e29f
--- /dev/null
+++ b/src/net/mcast/McastSender.h
@@ -0,0 +1,73 @@
+/*
+# 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 sender-side multicast file transfer protocol -- interface
+# -----------------------------------------------------------------------------
+*/
+
+#ifndef MCASTSENDER_H_
+#define MCASTSENDER_H_
+
+#include <QCryptographicHash>
+#include <QIODevice>
+#include <QObject>
+
+#include "McastConfiguration.h"
+#include "McastPGMSocket.h"
+
+class McastSender : public QObject
+{
+ Q_OBJECT
+public:
+ McastSender(QIODevice* iodev = 0, McastConfiguration const* config = 0, QObject* parent = 0);
+ virtual ~McastSender();
+
+ McastConfiguration* config()
+ {
+ return _config;
+ }
+
+ QIODevice* iodevice() const
+ {
+ return _iodev;
+ }
+
+ void setIODevice(QIODevice* iodevice)
+ {
+ _iodev = iodevice;
+ }
+
+signals:
+ void finished();
+ void progress(quint64 offset);
+ void allSent();
+
+public slots:
+ void start();
+ void start(McastPGMSocket* openSocket);
+ void close();
+
+private slots:
+ void deferredStart();
+ void readyToSend();
+ void socketFinished();
+
+private:
+ McastConfiguration* _config;
+ McastPGMSocket* _socket;
+ QIODevice* _iodev;
+ quint64 _curoffs;
+ QCryptographicHash _hash;
+ bool _finished;
+};
+
+#endif /* MCASTSENDER_H_ */
diff --git a/src/net/mcast/trial_programs/CMakeLists.txt b/src/net/mcast/trial_programs/CMakeLists.txt
new file mode 100644
index 0000000..d0f68fa
--- /dev/null
+++ b/src/net/mcast/trial_programs/CMakeLists.txt
@@ -0,0 +1,38 @@
+INCLUDE(${QT_USE_FILE})
+
+QT4_WRAP_CPP(
+ mcastsend_MOC
+ mcastsend.h
+)
+
+QT4_WRAP_CPP(
+ mcastreceive_MOC
+ mcastreceive.h
+)
+
+SET(argparser_SRC
+ McastConfigArgParser.h
+ McastConfigArgParser.cpp
+)
+
+ADD_EXECUTABLE(mcastsend
+ mcastsend.cpp
+ mcastsend.h
+ ${argparser_SRC}
+ ${mcastsend_MOC}
+)
+
+ADD_EXECUTABLE(mcastreceive
+ mcastreceive.cpp
+ mcastreceive.h
+ ${argparser_SRC}
+ ${mcastreceive_MOC}
+)
+
+TARGET_LINK_LIBRARIES(mcastsend
+ pvsmcast
+)
+
+TARGET_LINK_LIBRARIES(mcastreceive
+ pvsmcast
+) \ No newline at end of file
diff --git a/src/net/mcast/trial_programs/McastConfigArgParser.cpp b/src/net/mcast/trial_programs/McastConfigArgParser.cpp
new file mode 100644
index 0000000..881f728
--- /dev/null
+++ b/src/net/mcast/trial_programs/McastConfigArgParser.cpp
@@ -0,0 +1,165 @@
+/*
+# 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/trial_programs/McastConfigArgParser.cpp
+# - Parse common Multicast Configuration CLI arguments
+# -----------------------------------------------------------------------------
+*/
+
+#include <iostream>
+
+#include <QCoreApplication>
+
+#include "McastConfigArgParser.h"
+
+using namespace std;
+
+bool parseMcastConfigArg(QStringList::iterator& i, QStringList::iterator const& end, McastConfiguration* config)
+{
+ QString arg = *i;
+
+ if (arg == "-addr")
+ {
+ i++;
+ if(i == end)
+ {
+ cerr << "Option " << arg.toLatin1().constData() << " is missing argument" << endl;
+ return false;
+ }
+ config->multicastAddress(*i);
+ }
+ else if (arg == "-dport")
+ {
+ i++;
+ if(i == end)
+ {
+ cerr << "Option " << arg.toLatin1().constData() << " is missing argument" << endl;
+ return false;
+ }
+ bool ok;
+ quint16 dport = (quint16)i->toInt(&ok);
+ if (!ok)
+ {
+ cerr << "Error: dport is not an integer" << endl;
+ return false;
+ }
+ config->multicastDPort(dport);
+ }
+ else if (arg == "-sport")
+ {
+ i++;
+ if(i == end)
+ {
+ cerr << "Option " << arg.toLatin1().constData() << " is missing argument" << endl;
+ return false;
+ }
+ bool ok;
+ quint16 sport = (quint16)i->toInt(&ok);
+ if (!ok)
+ {
+ cerr << "Error: sport is not an integer" << endl;
+ return false;
+ }
+ config->multicastSPort(sport);
+ }
+ else if (arg == "-mtu")
+ {
+ i++;
+ if(i == end)
+ {
+ cerr << "Option " << arg.toLatin1().constData() << " is missing argument" << endl;
+ return false;
+ }
+ bool ok;
+ quint16 mtu = (quint16)i->toInt(&ok);
+ if (!ok)
+ {
+ cerr << "Error: MTU is not an integer" << endl;
+ return false;
+ }
+ config->multicastMTU(mtu);
+ }
+ else if (arg == "-rate")
+ {
+ i++;
+ if(i == end)
+ {
+ cerr << "Option " << arg.toLatin1().constData() << " is missing argument" << endl;
+ return false;
+ }
+ bool ok;
+ quint32 rate = i->toInt(&ok);
+ if (!ok)
+ {
+ cerr << "Error: Rate is not an integer" << endl;
+ return false;
+ }
+ config->multicastRate(rate);
+ }
+ else if (arg == "-winsize")
+ {
+ i++;
+ if(i == end)
+ {
+ cerr << "Option " << arg.toLatin1().constData() << " is missing argument" << endl;
+ return false;
+ }
+ bool ok;
+ quint16 winsize = (quint16)i->toInt(&ok);
+ if (!ok)
+ {
+ cerr << "Error: Winsize is not an integer" << endl;
+ return false;
+ }
+ config->multicastWinSize(winsize);
+ }
+ else if (arg == "-udp")
+ {
+ config->multicastUseUDP(true);
+ }
+ else if (arg == "-no-udp")
+ {
+ config->multicastUseUDP(false);
+ }
+ else if (arg == "-udp-port")
+ {
+ i++;
+ if(i == end)
+ {
+ cerr << "Option " << arg.toLatin1().constData() << " is missing argument" << endl;
+ return false;
+ }
+ bool ok;
+ quint16 udpport = (quint16)i->toInt(&ok);
+ if (!ok)
+ {
+ cerr << "Error: UDP-Port is not an integer" << endl;
+ return false;
+ }
+ config->multicastUDPPortBase(udpport);
+ }
+ else if (arg == "-intf")
+ {
+ i++;
+ if (i == end)
+ {
+ cerr << "Option " << arg.toLatin1().constData() << "is missing argument" << endl;
+ return false;
+ }
+ config->multicastInterface(*i);
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/net/mcast/trial_programs/McastConfigArgParser.h b/src/net/mcast/trial_programs/McastConfigArgParser.h
new file mode 100644
index 0000000..4fb18a7
--- /dev/null
+++ b/src/net/mcast/trial_programs/McastConfigArgParser.h
@@ -0,0 +1,26 @@
+/*
+# 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/trial_programs/McastConfigArgParser.h
+# - Parse common Multicast Configuration CLI arguments
+# -----------------------------------------------------------------------------
+*/
+
+#ifndef MCASTCONFIGARGPARSER_H_
+#define MCASTCONFIGARGPARSER_H_
+
+#include <QStringList>
+
+#include "../McastConfiguration.h"
+
+bool parseMcastConfigArg(QStringList::iterator& i, QStringList::iterator const& end, McastConfiguration* config);
+
+#endif /* MCASTCONFIGARGPARSER_H_ */
diff --git a/src/net/mcast/trial_programs/mcastreceive.cpp b/src/net/mcast/trial_programs/mcastreceive.cpp
new file mode 100644
index 0000000..48a0f10
--- /dev/null
+++ b/src/net/mcast/trial_programs/mcastreceive.cpp
@@ -0,0 +1,150 @@
+/*
+# 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/trial_programs/mcastsend.cpp
+# - Receive a file via the PVS Mcast protocol
+# -----------------------------------------------------------------------------
+*/
+
+#include <iostream>
+
+#include <QCoreApplication>
+#include <QFile>
+#include <QStringList>
+#include <QTimer>
+
+#include "mcastreceive.h"
+#include "McastConfigArgParser.h"
+#include "../McastConfiguration.h"
+#include "../McastReceiver.h"
+
+using namespace std;
+
+int main(int argc, char** argv)
+{
+ QCoreApplication app(argc, argv);
+ McastReceive me;
+
+ QTimer::singleShot(0, &me, SLOT(run()));
+
+ return app.exec();
+}
+
+void McastReceive::run()
+{
+ QStringList args = QCoreApplication::arguments();
+ QStringList::iterator i = args.begin();
+ QStringList::iterator const end = args.end();
+
+ QString filename("");
+
+ McastConfiguration config;
+
+ ++i;
+ while (i != end)
+ {
+ QString arg = *i;
+
+ cerr << "Arg: " << arg.toLatin1().constData() << endl;
+
+ if (arg == "-file")
+ {
+ ++i;
+ if (i == end)
+ {
+ cerr << "Option " << arg.toLatin1().constData() << " is missing its argument" << endl;
+ QCoreApplication::exit(1);
+ return;
+ }
+ filename = *i;
+ }
+ else if (arg == "-help")
+ {
+ cerr << "Options:" << endl << endl
+ << " -file <FILE> Receive to file FILE" << endl
+ << " -addr <ADDR> Use ADDR as address specification" << endl
+ << " -dport <PORT> Send to port PORT" << endl
+ << " -sport <PORT> Send from port PORT" << endl
+ << " -mtu <BYTES> Set MTU to BYTES" << endl
+ << " -rate <BYTES> Send BYTES per second" << endl
+ << " -winsize <SECONDS> Set Window Size to SECONDS" << endl
+ << " -udp Use UDP encapsulation" << endl
+ << " -udp-port PORT Use UDP port PORT" << endl;
+ QCoreApplication::quit();
+ return;
+ }
+ else
+ {
+ if (!parseMcastConfigArg(i, end, &config))
+ {
+ cerr << "Unknown argument: " << arg.toLatin1().constData() << endl;
+ QCoreApplication::exit(1);
+ return;
+ }
+ }
+
+ ++i;
+ }
+
+ if (filename == "")
+ {
+ cerr << "No Filename given" << endl;
+ QCoreApplication::exit(1);
+ return;
+ }
+
+ _target = new QFile(filename, this);
+ _target->open(QIODevice::WriteOnly);
+
+ McastReceiver* recv = new McastReceiver(_target, &config, this);
+
+ connect(recv, SIGNAL(finished(int)), this, SLOT(finished(int)));
+
+ QTimer::singleShot(0, recv, SLOT(start()));
+}
+
+void McastReceive::finished(int state)
+{
+ cerr << "finished: ";
+
+ switch(state)
+ {
+ case McastReceiver::RES_OK:
+ cerr << "OK." << endl;
+ break;
+ case McastReceiver::RES_ABORTED:
+ cerr << "Aborted." << endl;
+ goto failed;
+ case McastReceiver::RES_CHECKSUM_MISMATCH:
+ cerr << "Checksum mismatch." << endl;
+ goto failed;
+ case McastReceiver::RES_CONNECTION_RESET:
+ cerr << "Connection reset." << endl;
+ goto failed;
+ case McastReceiver::RES_MD5_MISMATCH:
+ cerr << "MD5 mismatch." << endl;
+ goto failed;
+ case McastReceiver::RES_OFFSET_MISMATCH:
+ cerr << "Offset mismatch. Undetected packet loss?" << endl;
+ goto failed;
+ default:
+ cerr << "Unknown error code!" << endl;
+ goto failed;
+ }
+
+ QCoreApplication::quit();
+ return;
+failed:
+ cerr << "Deleting file." << endl;
+ _target->remove();
+ QCoreApplication::exit(1);
+ return;
+}
diff --git a/src/net/mcast/trial_programs/mcastreceive.h b/src/net/mcast/trial_programs/mcastreceive.h
new file mode 100644
index 0000000..3e72d4c
--- /dev/null
+++ b/src/net/mcast/trial_programs/mcastreceive.h
@@ -0,0 +1,44 @@
+/*
+# 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/trial_programs/mcastsend.cpp
+# - Receive a file via the PVS Mcast protocol
+# -----------------------------------------------------------------------------
+*/
+
+#ifndef MCASTRECEIVE_H_
+#define MCASTRECEIVE_H_
+
+#include <QObject>
+
+class QFile;
+class McastReceiver;
+
+class McastReceive : public QObject
+{
+ Q_OBJECT
+public:
+ McastReceive() :
+ QObject(),
+ _receiver(0)
+ {
+ }
+
+public slots:
+ void run();
+ void finished(int state);
+
+private:
+ McastReceiver* _receiver;
+ QFile* _target;
+};
+
+#endif /* MCASTRECEIVE_H_ */
diff --git a/src/net/mcast/trial_programs/mcastsend.cpp b/src/net/mcast/trial_programs/mcastsend.cpp
new file mode 100644
index 0000000..f78a9ce
--- /dev/null
+++ b/src/net/mcast/trial_programs/mcastsend.cpp
@@ -0,0 +1,122 @@
+/*
+# 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/trial_programs/mcastsend.cpp
+# - Send a file via the PVS Mcast protocol
+# -----------------------------------------------------------------------------
+*/
+
+#include <iostream>
+
+#include <QCoreApplication>
+#include <QFile>
+#include <QStringList>
+#include <QTimer>
+
+#include <src/net/mcast/McastSender.h>
+#include "mcastsend.h"
+#include "McastConfigArgParser.h"
+#include "../McastConstants.h"
+#include "../McastConfiguration.h"
+
+using namespace std;
+
+int
+main(int argc, char**argv)
+{
+ QCoreApplication app(argc, argv);
+ McastSend me;
+
+ QTimer::singleShot(0, &me, SLOT(run()));
+
+ return app.exec();
+}
+
+void McastSend::run()
+{
+ QStringList args = QCoreApplication::arguments();
+ QStringList::iterator i = args.begin();
+ QStringList::iterator const end = args.end();
+ QString filename("");
+ McastConfiguration config;
+
+ ++i;
+ while(i != end)
+ {
+ // parse command line arguments
+
+ QString arg = *i;
+
+ cerr << "Arg: " << arg.toLatin1().constData() << endl;
+
+ if (arg == "-file")
+ {
+ i++;
+ if(i == end)
+ {
+ cerr << "Option " << arg.toLatin1().constData() << " is missing argument" << endl;
+ QCoreApplication::exit(1);
+ return;
+ }
+ filename = *i;
+ }
+ else if (arg == "-help")
+ {
+ cerr << "Options:" << endl << endl
+ << " -file <FILE> Send FILE to the listeners" << endl
+ << " -addr <ADDR> Use ADDR as address specification" << endl
+ << " -dport <PORT> Send to port PORT" << endl
+ << " -sport <PORT> Send from port PORT" << endl
+ << " -mtu <BYTES> Set MTU to BYTES" << endl
+ << " -rate <BYTES> Send BYTES per second" << endl
+ << " -winsize <SECONDS> Set Window Size to SECONDS" << endl
+ << " -udp Use UDP encapsulation" << endl
+ << " -udp-port PORT Use UDP port PORT" << endl;
+ QCoreApplication::quit();
+ return;
+ }
+ else
+ {
+ if (!parseMcastConfigArg(i, end, &config))
+ {
+ cerr << "Unknown command line argument: " << arg.toLatin1().constData() << endl;
+ QCoreApplication::exit(1);
+ return;
+ }
+ }
+
+ ++i;
+ }
+
+ if(filename == "")
+ {
+ cerr << "No filename given" << endl;
+ QCoreApplication::exit(1);
+ return;
+ }
+
+ // now, do it.
+ QFile* file = new QFile(filename);
+ file->open(QIODevice::ReadOnly);
+
+ McastSender* sender = new McastSender(file, &config, this);
+ file->setParent(sender);
+
+ connect(sender, SIGNAL(finished()), this, SLOT(finished()));
+
+ QTimer::singleShot(0, sender, SLOT(start()));
+}
+
+void McastSend::finished()
+{
+ cerr << "finished." << endl;
+ QCoreApplication::quit();
+}
diff --git a/src/net/mcast/trial_programs/mcastsend.h b/src/net/mcast/trial_programs/mcastsend.h
new file mode 100644
index 0000000..ae15eb4
--- /dev/null
+++ b/src/net/mcast/trial_programs/mcastsend.h
@@ -0,0 +1,42 @@
+/*
+# 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/trial_programs/mcastsend.cpp
+# - Send a file via the PVS Mcast protocol
+# -----------------------------------------------------------------------------
+*/
+
+#ifndef MCASTSEND_H_
+#define MCASTSEND_H_
+
+#include <QObject>
+
+#include "../McastSender.h"
+
+class McastSend : public QObject
+{
+ Q_OBJECT
+public:
+ McastSend() :
+ QObject(),
+ _sender(0)
+ {
+ }
+
+public slots:
+ void run();
+ void finished();
+
+private:
+ McastSender* _sender;
+};
+
+#endif /* MCASTSEND_H_ */
diff --git a/src/net/pvsClientConnection.cpp b/src/net/pvsClientConnection.cpp
index dff40d5..5354e95 100644
--- a/src/net/pvsClientConnection.cpp
+++ b/src/net/pvsClientConnection.cpp
@@ -134,7 +134,7 @@ bool PVSClientConnection::push_back_send(PVSMsg newMsg)
char *tmp = data;
if (!newMsg.getBinaryData(tmp, len))
{
- printf("Message empty. Ignored.\n");
+ qDebug("Message empty. Ignored.");
return false;
}
QByteArray ba;
diff --git a/src/net/pvsDiscoveredServer.cpp b/src/net/pvsDiscoveredServer.cpp
index dddb5a0..efa1506 100644
--- a/src/net/pvsDiscoveredServer.cpp
+++ b/src/net/pvsDiscoveredServer.cpp
@@ -48,7 +48,7 @@ void PVSDiscoveredServer::ssl_Error( const QList<QSslError> & errors )
}
//ConsoleLog writeNetwork(err.errorString().toUtf8().data());
//ConsoleLog writeNetwork("***** SSL ERROR, ABORTING *****");
- printf("Unhandled SSL Error in SD: %s\n", err.errorString().toUtf8().data());
+ qDebug("Unhandled SSL Error in SD: %s", qPrintable(err.errorString()));
return;
}
_socket->ignoreSslErrors();
@@ -70,30 +70,30 @@ void PVSDiscoveredServer::sock_connected()
QByteArray cert = _socket->peerCertificate().digest(QCryptographicHash::Sha1);
if (_socket->peerCertificate().isNull())
{
- printf("**** WARNING - PEER CERTIFICATE IS NULL ****\n");
+ qDebug("**** WARNING - PEER CERTIFICATE IS NULL ****");
}
else
{
- printf("%s\n", _socket->peerCertificate().subjectInfo(QSslCertificate::Organization).toUtf8().data());
- printf("%s\n", _socket->peerCertificate().subjectInfo(QSslCertificate::CommonName).toUtf8().data());
- printf("%s\n", _socket->peerCertificate().subjectInfo(QSslCertificate::LocalityName).toUtf8().data());
- printf("%s\n", _socket->peerCertificate().subjectInfo(QSslCertificate::OrganizationalUnitName ).toUtf8().data());
- printf("%s\n", _socket->peerCertificate().subjectInfo(QSslCertificate::CountryName ).toUtf8().data());
- printf("%s\n", _socket->peerCertificate().subjectInfo(QSslCertificate::StateOrProvinceName ).toUtf8().data());
+ qDebug("%s", qPrintable(_socket->peerCertificate().subjectInfo(QSslCertificate::Organization)));
+ qDebug("%s", qPrintable(_socket->peerCertificate().subjectInfo(QSslCertificate::CommonName)));
+ qDebug("%s", qPrintable(_socket->peerCertificate().subjectInfo(QSslCertificate::LocalityName)));
+ qDebug("%s", qPrintable(_socket->peerCertificate().subjectInfo(QSslCertificate::OrganizationalUnitName)));
+ qDebug("%s", qPrintable(_socket->peerCertificate().subjectInfo(QSslCertificate::CountryName)));
+ qDebug("%s", qPrintable(_socket->peerCertificate().subjectInfo(QSslCertificate::StateOrProvinceName)));
}
if (cert == _fingerprint && !_validated)
{
_validated = true;
emit validated(this);
- printf("Validated certificate of %s :)\n", _socket->peerAddress().toString().toUtf8().data());
+ qDebug("Validated certificate of %s :)", qPrintable(_socket->peerAddress().toString()));
}
else
{
- printf("Certificate of %s is invalid :(\n", _socket->peerAddress().toString().toUtf8().data());
+ qDebug("Certificate of %s is invalid :(", qPrintable(_socket->peerAddress().toString()));
QByteArray is, should;
is = cert.toBase64();
should = _fingerprint.toBase64();
- printf("Is %s and should be %s\n", is.data(), should.data());
+ qDebug("Is %s and should be %s", is.data(), should.data());
}
_socket->disconnectFromHost();
}
diff --git a/src/net/pvsIncomingMulticastTransfer.cpp b/src/net/pvsIncomingMulticastTransfer.cpp
new file mode 100644
index 0000000..10b5307
--- /dev/null
+++ b/src/net/pvsIncomingMulticastTransfer.cpp
@@ -0,0 +1,133 @@
+/*
+# 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);
+}
diff --git a/src/net/pvsIncomingMulticastTransfer.h b/src/net/pvsIncomingMulticastTransfer.h
new file mode 100644
index 0000000..f96e176
--- /dev/null
+++ b/src/net/pvsIncomingMulticastTransfer.h
@@ -0,0 +1,71 @@
+/*
+# 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
+# -----------------------------------------------------------------------------
+*/
+
+#ifndef PVSINCOMINGMULTICASTTRANSFER_H_
+#define PVSINCOMINGMULTICASTTRANSFER_H_
+
+#include <QObject>
+#include <QString>
+
+#include <src/net/pvsMsg.h>
+
+class McastConfiguration;
+class McastReceiver;
+class QFile;
+class QTimer;
+
+class PVSIncomingMulticastTransfer : public QObject
+{
+ Q_OBJECT
+public:
+ PVSIncomingMulticastTransfer(QString const& sender, qulonglong transferID, qulonglong size, QString const& filename, ushort port,
+ McastConfiguration const* configTemplate, QObject* parent = 0);
+ virtual ~PVSIncomingMulticastTransfer();
+
+ void setFinalFile(QString const& filename);
+
+signals:
+ void retry(QString const& sender, qulonglong transferID);
+ void started(qulonglong transferID);
+ void progress(qulonglong transferID, qulonglong bytes, qulonglong of);
+ void finished(qulonglong transferID);
+ void failed(qulonglong transferID, QString const& reason);
+
+public slots:
+ void updatePort(ushort port);
+ bool start();
+ void abort();
+
+private slots:
+ void receiverProgressed(quint64 bytes);
+ void receiverFinished(int reason);
+ void updateProgress();
+ void removeFile();
+
+private:
+ QString _sender;
+ qulonglong _transferID;
+ qulonglong _bytes;
+ qulonglong _size;
+ ushort _port;
+ QFile* _file;
+ McastReceiver* _receiver;
+ McastConfiguration* _config;
+ bool _started;
+ QTimer* _progressTimer;
+};
+
+#endif /* PVSINCOMINGMULTICASTTRANSFER_H_ */
diff --git a/src/net/pvsListenServer.cpp b/src/net/pvsListenServer.cpp
index f21303e..90c2dfb 100644
--- a/src/net/pvsListenServer.cpp
+++ b/src/net/pvsListenServer.cpp
@@ -21,9 +21,13 @@
#include "pvsClientConnection.h"
#include "src/util/consoleLogger.h"
#include <QtNetwork/QSslSocket>
+#include <QBuffer>
+#include <QByteArray>
+#include <QSettings>
#include "SslServer.h"
#include <cassert>
//#define verbose
+#include "mcast/McastConfiguration.h"
// Create listener
PVSListenServer::PVSListenServer(int port, int clients)
@@ -36,6 +40,7 @@ PVSListenServer::PVSListenServer(int port, int clients)
else
_clientsMax = clients;
_port = port;
+ _mcastConfig = 0;
init();
}
@@ -137,7 +142,7 @@ void PVSListenServer::timerEvent(QTimerEvent *event)
}
if (client->lastData() < refval)
{ // ping timeout
- printf("Ping timeout for client %s\n", client->getNameUser().toLocal8Bit().data());
+ qDebug("Ping timeout for client %s", qPrintable(client->getNameUser()));
if (disconnectClient(client))
break; // list was modified, iterator not valid anymore
}
@@ -178,6 +183,7 @@ void PVSListenServer::onClientConnected(PVSClientConnection* connected)
{
connected->setServerID(_id);
connected->setID(generateID());
+ connected->push_back_send(mcastConfigMessage());
}
void PVSListenServer::onClientDisconnected(PVSClientConnection* disconnected)
@@ -227,6 +233,11 @@ PVSClientConnection* PVSListenServer::getConnectionFromID(int id)
// Initialize listening socket
bool PVSListenServer::init()
{
+ if (_mcastConfig)
+ delete _mcastConfig;
+ _mcastConfig = new McastConfiguration(this);
+ loadMcastConfig();
+
if (_listenSocket != NULL)
shutdown();
@@ -283,9 +294,8 @@ void PVSListenServer::server_connectionRequest()
void PVSListenServer::handleClientMsg(unsigned int clientID, PVSMsg msg)
{
- printf("Got Message for client %ud: [%c][%s][%s]\n", clientID,
- (char) msg.getType(), msg.getIdent().toUtf8().data(),
- msg.getMessage().toUtf8().data());
+ qDebug("Got Message for client %ud: [%c][%s][%s]", clientID,
+ (char) msg.getType(), qPrintable(msg.getIdent()), qPrintable(msg.getMessage()));
msg.setSndID(clientID);
if (msg.getType() == PVSCOMMAND)
_commandDispatcher.fire(msg.getIdent(), msg);
@@ -306,3 +316,52 @@ bool PVSListenServer::isListening()
{
return _listenSocket != NULL && _listenSocket->isListening();
}
+
+void PVSListenServer::loadMcastConfig()
+{
+ QSettings settings;
+ _mcastConfig->loadFrom(&settings, "multicast-filetransfer");
+}
+
+void PVSListenServer::saveMcastConfig()
+{
+ QSettings settings;
+ _mcastConfig->writeTo(&settings, "multicast-filetransfer");
+ settings.sync();
+}
+
+PVSMsg PVSListenServer::mcastConfigMessage()
+{
+ // If anything is changed here, do not forget to
+ // 1. assign a new version number
+ // 2. adapt PVS::onCommand(PVSMsg) in pvs.cpp
+ QByteArray ba;
+ QDataStream strm(&ba, QIODevice::WriteOnly);
+ strm << (quint16)1 // version
+ << _mcastConfig->multicastAddress()
+ << _mcastConfig->multicastUDPPortBase()
+ << _mcastConfig->multicastDPort()
+ << _mcastConfig->multicastSPort()
+ << _mcastConfig->multicastMTU()
+ << _mcastConfig->multicastWinSize()
+ << _mcastConfig->multicastRate()
+ << _mcastConfig->multicastUseUDP();
+
+ QByteArray b64 = ba.toBase64();
+ QString message = QString::fromAscii(b64.constData(), b64.length());
+ PVSMsg msg(PVSCOMMAND, "MCASTFTCONFIG", message);
+ return msg;
+}
+
+void PVSListenServer::multicastReconfigure(McastConfiguration const* source)
+{
+ _mcastConfig->multicastAddress(source->multicastAddress());
+ *_mcastConfig = *source;
+ saveMcastConfig();
+ sendToAll(mcastConfigMessage());
+}
+
+McastConfiguration const* PVSListenServer::getMulticastConfiguration()
+{
+ return _mcastConfig;
+}
diff --git a/src/net/pvsListenServer.h b/src/net/pvsListenServer.h
index ab021c7..ca9977c 100644
--- a/src/net/pvsListenServer.h
+++ b/src/net/pvsListenServer.h
@@ -10,6 +10,7 @@ class SslServer;
class PVSClientConnection;
class PVSMsg;
+class McastConfiguration;
class PVSListenServer : public QObject
{
@@ -40,6 +41,12 @@ private:
bool init();
unsigned int generateID();
+ McastConfiguration* _mcastConfig;
+
+ void loadMcastConfig();
+ void saveMcastConfig();
+ PVSMsg mcastConfigMessage();
+
protected:
void timerEvent(QTimerEvent *event);
@@ -60,6 +67,9 @@ public:
bool disconnectClient(PVSClientConnection* delinquent);
void onConnectionRemoved(PVSClientConnection* delinquent);
+ void multicastReconfigure(McastConfiguration const* source);
+ McastConfiguration const* getMulticastConfiguration();
+
std::list<PVSClientConnection*>* getClientListPtr()
{
return &_clients;
@@ -73,7 +83,7 @@ public:
template<class T> void addLoginHandler(QString ident, T* who, void (T :: *func)(PVSMsg))
{
- printf("Listener got added to LoginHandler\n");
+ qDebug("Listener got added to LoginHandler");
_loginDispatcher.addListener(ident, who, func);
};
template<class T> void removeLoginHandler(QString ident, T* who, void (T :: *func)(PVSMsg))
diff --git a/src/net/pvsLocalhostCommunicator.cpp b/src/net/pvsLocalhostCommunicator.cpp
index 199b39c..20783bb 100644
--- a/src/net/pvsLocalhostCommunicator.cpp
+++ b/src/net/pvsLocalhostCommunicator.cpp
@@ -83,7 +83,7 @@ void PVSLocalhostCommunicator::sendCommand(QString ident, QString cmd)
int len;
sender.getBinaryData(data, len);
QByteArray qba(data, len);
- printf("Sending %d bytes to daemon...\n", qba.length());
+ qDebug("Sending %d bytes to daemon...", qba.length());
qint64 result = _sock->writeDatagram(qba, localhost, localport);
_sock->waitForBytesWritten(100);
@@ -92,11 +92,11 @@ void PVSLocalhostCommunicator::sendCommand(QString ident, QString cmd)
{
if (result == -1)
{
- printf("Error sending PVSMsg to daemon: %s\n", _sock->errorString().toUtf8().data());
+ qDebug("Error sending PVSMsg to daemon: %s", qPrintable(_sock->errorString()));
}
else
{
- printf("Sent PVSMsg was incomplete.\n");
+ qDebug("Sent PVSMsg was incomplete.");
}
stop();
}
diff --git a/src/net/pvsNetworkInterfaceListModel.cpp b/src/net/pvsNetworkInterfaceListModel.cpp
new file mode 100644
index 0000000..67d0c0a
--- /dev/null
+++ b/src/net/pvsNetworkInterfaceListModel.cpp
@@ -0,0 +1,81 @@
+/*
+ * pvsNetworkInterfaceListModel.cpp
+ *
+ * Created on: 04.08.2010
+ * Author: brs
+ */
+
+#include "pvsNetworkInterfaceListModel.h"
+#include <QStringList>
+
+PVSNetworkInterfaceListModel::PVSNetworkInterfaceListModel(QObject* parent) :
+ QAbstractListModel(parent)
+{
+ reloadInterfaceList();
+}
+
+PVSNetworkInterfaceListModel::~PVSNetworkInterfaceListModel()
+{
+}
+
+void PVSNetworkInterfaceListModel::reloadInterfaceList()
+{
+ _interfaces = QNetworkInterface::allInterfaces();
+ reset();
+}
+
+QVariant PVSNetworkInterfaceListModel::data(QModelIndex const& index, int role) const
+{
+ int i = index.row();
+ if(0 > i || i >= _interfaces.size())
+ {
+ return QVariant();
+ }
+ QNetworkInterface intf = _interfaces.at(i);
+
+ switch(role)
+ {
+ case Qt::DisplayRole:
+ {
+ QString name = intf.humanReadableName();
+ QList<QNetworkAddressEntry> addresses = intf.addressEntries();
+ QStringList l;
+
+ foreach(QNetworkAddressEntry addr, addresses)
+ {
+ l.append(addr.ip().toString());
+ }
+
+ return QString("%1 (%2)").arg(name).arg(l.join(", "));
+ }
+ case Qt::EditRole:
+ case Qt::UserRole:
+ return intf.name();
+ default:
+ return QVariant();
+ }
+}
+
+QVariant PVSNetworkInterfaceListModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if(section == 0 && orientation == Qt::Vertical && role == Qt::DisplayRole)
+ {
+ return tr("Interface");
+ }
+ else
+ {
+ return QVariant();
+ }
+}
+
+int PVSNetworkInterfaceListModel::rowCount(QModelIndex const& parent) const
+{
+ if(parent.isValid())
+ {
+ return 0;
+ }
+ else
+ {
+ return _interfaces.size();
+ }
+}
diff --git a/src/net/pvsNetworkInterfaceListModel.h b/src/net/pvsNetworkInterfaceListModel.h
new file mode 100644
index 0000000..3a9b95d
--- /dev/null
+++ b/src/net/pvsNetworkInterfaceListModel.h
@@ -0,0 +1,35 @@
+/*
+ * pvsNetworkInterfaceListModel.h
+ *
+ * Created on: 04.08.2010
+ * Author: brs
+ */
+
+#ifndef PVSNETWORKINTERFACELISTMODEL_H_
+#define PVSNETWORKINTERFACELISTMODEL_H_
+
+#include <QAbstractListModel>
+#include <QList>
+#include <QNetworkInterface>
+#include <QVariant>
+
+class PVSNetworkInterfaceListModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+public:
+ PVSNetworkInterfaceListModel(QObject* parent = 0);
+ virtual ~PVSNetworkInterfaceListModel();
+
+ QVariant data(QModelIndex const& index, int role = Qt::DisplayRole) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ int rowCount(QModelIndex const&) const;
+
+private:
+ QList<QNetworkInterface> _interfaces;
+
+public slots:
+ void reloadInterfaceList();
+};
+
+#endif /* PVSNETWORKINTERFACELISTMODEL_H_ */
diff --git a/src/net/pvsOutgoingMulticastTransfer.cpp b/src/net/pvsOutgoingMulticastTransfer.cpp
new file mode 100644
index 0000000..4df4986
--- /dev/null
+++ b/src/net/pvsOutgoingMulticastTransfer.cpp
@@ -0,0 +1,209 @@
+/*
+# 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/pvsOutgoingMulticastTransfer.cpp
+# - wrap McastSender functionality in PVS daemon
+# -----------------------------------------------------------------------------
+*/
+
+#include "pvsOutgoingMulticastTransfer.h"
+
+#include <QDataStream>
+#include <QFile>
+#include <QFileInfo>
+#include <QHostInfo>
+#include <QSettings>
+#include <QTimer>
+
+#include <src/net/pvsMsg.h>
+#include <src/net/mcast/McastConfiguration.h>
+#include <src/net/mcast/McastPGMSocket.h>
+#include <src/net/mcast/McastSender.h>
+#include <src/util/consoleLogger.h>
+
+PVSOutgoingMulticastTransfer::PVSOutgoingMulticastTransfer(QString senderName, quint64 id, QString filename, QObject* parent) :
+ QObject(parent),
+ _file(0),
+ _progress(0),
+ _config(0),
+ _socket(0),
+ _progressTimer(0),
+ _prepareTimer(0),
+ _senderName(senderName),
+ _id(id),
+ _error(false)
+{
+ QFileInfo finfo(filename);
+ if(!finfo.exists())
+ {
+ error("File does not exist");
+ }
+
+ if(!finfo.isReadable())
+ {
+ error("File is not readable");
+ }
+
+ _file = new QFile(filename, this);
+ _length = _file->size();
+}
+
+PVSOutgoingMulticastTransfer::~PVSOutgoingMulticastTransfer()
+{
+ if(_file)
+ delete _file;
+ if(_config)
+ delete _config;
+}
+
+void PVSOutgoingMulticastTransfer::prepare()
+{
+ if (_socket && !_socketInacceptable)
+ {
+ _prepareTimer->stop();
+ delete _prepareTimer;
+ _prepareTimer = 0;
+
+ QTimer::singleShot(0, this, SLOT(doStart()));
+ return;
+ }
+ else if (_socket)
+ {
+ delete _socket;
+ _socket = 0;
+ }
+
+ QSettings settings;
+ quint16 portbase = settings.value("multicast/port-base", "6966").value<quint16>();
+ quint16 portlimit = settings.value("multicast/port-limit", "7966").value<quint16>();
+
+ int tries_remaining = 5;
+ while(tries_remaining > 0)
+ {
+ quint16 port = portbase + (qrand() % (portlimit - portbase + 1));
+
+ if (!_config)
+ {
+ _config = new McastConfiguration();
+ }
+ _config->loadFrom(&settings, "multicast");
+ _config->multicastUDPPortBase(port);
+
+ _socket = new McastPGMSocket(this);
+ if(_socket->open(_config, McastPGMSocket::PSOCK_WRITE))
+ {
+ break;
+ }
+ else
+ {
+ delete _socket;
+ _socket = 0;
+ }
+ }
+
+ if (!_socket)
+ {
+ emit failed(_id, "Could not open socket");
+ delete _prepareTimer;
+ _prepareTimer = 0;
+ return;
+ }
+ else
+ {
+ _socketInacceptable = false;
+ // announce the transfer:
+ QFileInfo info(*_file);
+ QString message = QString("%1:%2:%3:%4:%5").arg(_senderName).arg(_id).arg(info.fileName()).arg(info.size()).arg(_config->multicastUDPPortBase());
+ PVSMsg msg(PVSCOMMAND, "MCASTFTANNOUNCE", message);
+ emit announce(msg);
+ _prepareTimer->start(5000);
+ }
+}
+
+void PVSOutgoingMulticastTransfer::doStart()
+{
+ ConsoleLog writeLine(QString("Starting multicast transfer %1").arg(_id));
+
+ _file->open(QIODevice::ReadOnly);
+
+ _sender = new McastSender(_file, _config, this);
+ connect(_sender, SIGNAL(finished()), SLOT(senderFinished()));
+ connect(_sender, SIGNAL(progress(quint64)), SLOT(senderProgress(quint64)));
+ // connect(_sender, SIGNAL(allSent()), SIGNAL(allSent()));
+ _socket->setParent(_sender);
+ _sender->start(_socket);
+
+ emit started(_id);
+
+ _progressTimer = new QTimer(this);
+ connect(_progressTimer, SIGNAL(timeout()), SLOT(reportTimeout()));
+ _progressTimer->setInterval(333);
+ _progressTimer->start();
+}
+
+void PVSOutgoingMulticastTransfer::senderProgress(quint64 bytes)
+
+{
+ _progress = bytes;
+}
+
+void PVSOutgoingMulticastTransfer::senderFinished()
+{
+ if(_progressTimer)
+ {
+ _progressTimer->stop();
+ delete _progressTimer;
+ _progressTimer = 0;
+ }
+ emit finished(_id);
+ _sender->close();
+ delete _sender;
+}
+
+void PVSOutgoingMulticastTransfer::reportTimeout()
+{
+ emit progress(_id, _progress, _length);
+}
+
+void PVSOutgoingMulticastTransfer::retry()
+{
+ bool first = !_socketInacceptable;
+ _socketInacceptable = true;
+
+ if(first)
+ {
+ _prepareTimer->setInterval(1000);
+ }
+}
+
+void PVSOutgoingMulticastTransfer::start()
+{
+ if (!_prepareTimer)
+ {
+ _prepareTimer = new QTimer(this);
+ _prepareTimer->setSingleShot(true);
+ connect(_prepareTimer, SIGNAL(timeout()), SLOT(prepare()));
+ }
+ QTimer::singleShot(0, this, SLOT(prepare()));
+}
+
+void PVSOutgoingMulticastTransfer::abort()
+{
+ if (_sender)
+ _sender->close();
+}
+
+void PVSOutgoingMulticastTransfer::error(QString const& reason)
+{
+ qCritical() << "Could not create an outgoing mcast transfer: " << reason;
+ _error = true;
+ _reason = reason;
+}
diff --git a/src/net/pvsOutgoingMulticastTransfer.h b/src/net/pvsOutgoingMulticastTransfer.h
new file mode 100644
index 0000000..5fd6a3d
--- /dev/null
+++ b/src/net/pvsOutgoingMulticastTransfer.h
@@ -0,0 +1,92 @@
+/*
+# 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/pvsOutgoingMulticastTransfer.h
+# - wrap McastSender functionality in PVS daemon
+# -----------------------------------------------------------------------------
+*/
+
+#ifndef PVSOUTGOINGMULTICASTTRANSFER_H_
+#define PVSOUTGOINGMULTICASTTRANSFER_H_
+
+#include <QtGlobal>
+#include <QObject>
+#include <QString>
+
+#include <src/net/pvsMsg.h>
+
+class QFile;
+class QTimer;
+class McastConfiguration;
+class McastPGMSocket;
+class McastSender;
+
+class PVSOutgoingMulticastTransfer : public QObject
+{
+ Q_OBJECT
+public:
+ PVSOutgoingMulticastTransfer(QString senderName, quint64 id, QString filename, QObject* parent = 0);
+ virtual ~PVSOutgoingMulticastTransfer();
+
+ quint64 id() const
+ {
+ return _id;
+ }
+
+ bool isError() const
+ {
+ return _error;
+ }
+
+ QString reason() const
+ {
+ return _reason;
+ }
+
+signals:
+ void started(qulonglong id);
+ void progress(qulonglong id, qulonglong bytes, qulonglong of);
+ void allSent(qulonglong id);
+ void finished(qulonglong id);
+ void failed(qulonglong id, QString const reason);
+ void announce(PVSMsg announcement);
+
+private slots:
+ void senderProgress(quint64 bytes);
+ void senderFinished();
+ void reportTimeout();
+ void doStart();
+ void prepare();
+
+public slots:
+ void start();
+ void abort();
+ void retry();
+
+private:
+ QFile* _file;
+ quint64 _length;
+ quint64 _progress;
+ McastConfiguration* _config;
+ McastPGMSocket* _socket;
+ McastSender* _sender;
+ QTimer* _progressTimer;
+ QTimer* _prepareTimer;
+ QString _senderName;
+ quint64 _id;
+ bool _error;
+ QString _reason;
+ bool _socketInacceptable;
+
+ void error(QString const& reason);
+};
+
+#endif /* PVSOUTGOINGMULTICASTTRANSFER_H_ */
diff --git a/src/net/pvsServerConnection.cpp b/src/net/pvsServerConnection.cpp
index 04a1ef6..d187ce3 100644
--- a/src/net/pvsServerConnection.cpp
+++ b/src/net/pvsServerConnection.cpp
@@ -70,7 +70,7 @@ void PVSServerConnection::sslErrors ( const QList<QSslError> & errors )
for (QList<QSslError>::const_iterator it = errors.begin(); it != errors.end(); it++)
{
QSslError err = *it;
- printf("Connect SSL: %s\n", err.errorString().toUtf8().data());
+ qDebug("Connect SSL: %s", qPrintable(err.errorString()));
if (err.error() == QSslError::HostNameMismatch) continue; // We don't pay attention to hostnames for validation
if (err.error() == QSslError::SelfSignedCertificate) continue; // Also, this will always be the case; we check the fingerprint later
ConsoleLog writeNetwork(err.errorString().toUtf8().data());
diff --git a/src/net/pvsServerConnection.h b/src/net/pvsServerConnection.h
index 0669d88..c6ef015 100644
--- a/src/net/pvsServerConnection.h
+++ b/src/net/pvsServerConnection.h
@@ -11,9 +11,9 @@
#define _PVSSERVERCONNECTION_H_
#include "src/util/dispatcher.h"
+#include "src/net/pvsMsg.h"
#include <QtNetwork/QSslSocket>
-class PVSMsg;
class PVS;
class PVSDiscoveredServer;
@@ -30,8 +30,6 @@ public:
return _socket != NULL && _socket->state() == QAbstractSocket::ConnectedState;
}
- void sendMessage(PVSMsg newMessage);
-
void ping();
QString getServerName();
@@ -63,6 +61,9 @@ public:
_commandDispatcher.removeListener(ident, who, func);
};
+public Q_SLOTS:
+ void sendMessage(PVSMsg newMessage);
+
protected:
void timerEvent(QTimerEvent *event);
diff --git a/src/net/pvsServiceBroadcast.cpp b/src/net/pvsServiceBroadcast.cpp
index cf15b5b..a861456 100644
--- a/src/net/pvsServiceBroadcast.cpp
+++ b/src/net/pvsServiceBroadcast.cpp
@@ -20,12 +20,22 @@
#include <cassert>
#include "src/util/serviceDiscoveryUtil.h"
+#include <QNetworkInterface>
+#include <QNetworkAddressEntry>
+
PVSServiceBroadcast::PVSServiceBroadcast()
{
_announce = NULL;
_timer = 0;
_broadcaster.bind(SD_PORT_CONSOLE);
- _everyone = QHostAddress(QHostAddress::Broadcast);
+
+ foreach (QNetworkInterface interface, QNetworkInterface::allInterfaces())
+ foreach (QNetworkAddressEntry entry, interface.addressEntries())
+ if (!entry.broadcast().isNull() && entry.broadcast().toString() != "127.255.255.255")
+ _everyone.append(entry.broadcast());
+
+ if (_everyone.isEmpty())
+ qDebug("ERROR: No broadcast address found");
}
PVSServiceBroadcast::~PVSServiceBroadcast()
@@ -47,5 +57,9 @@ void PVSServiceBroadcast::setFingerprint(QByteArray sha1)
void PVSServiceBroadcast::timerEvent(QTimerEvent *event)
{
if (_announce == NULL) return;
- _broadcaster.writeDatagram(*_announce, _everyone, SD_PORT_CLIENT);
+ foreach (QHostAddress bcast, _everyone)
+ {
+ qDebug("DEBUG: Broadcasting to %s:%i", qPrintable(bcast.toString()),SD_PORT_CLIENT);
+ _broadcaster.writeDatagram(*_announce, bcast, SD_PORT_CLIENT);
+ }
}
diff --git a/src/net/pvsServiceBroadcast.h b/src/net/pvsServiceBroadcast.h
index cf3f63d..a23370f 100644
--- a/src/net/pvsServiceBroadcast.h
+++ b/src/net/pvsServiceBroadcast.h
@@ -39,7 +39,7 @@ protected:
private:
QByteArray *_announce;
QUdpSocket _broadcaster;
- QHostAddress _everyone;
+ QList<QHostAddress> _everyone;
int _timer;
};
diff --git a/src/net/pvsServiceDiscovery.cpp b/src/net/pvsServiceDiscovery.cpp
index 0a99802..dd6b500 100644
--- a/src/net/pvsServiceDiscovery.cpp
+++ b/src/net/pvsServiceDiscovery.cpp
@@ -30,7 +30,7 @@ PVSServiceDiscovery::PVSServiceDiscovery(PVS* client)
bool ret = _sock.bind(SD_PORT_CLIENT);
if (!ret)
{
- printf("Could not open SERVICE DISCOVERY port\n");
+ qDebug("Could not open SERVICE DISCOVERY port");
exit(1);
}
connect(&_sock, SIGNAL(readyRead()), this, SLOT(sock_dataArrival()));
diff --git a/src/pvs.cpp b/src/pvs.cpp
index 911ed0d..eda63f5 100644..100755
--- a/src/pvs.cpp
+++ b/src/pvs.cpp
@@ -10,6 +10,10 @@
# 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"
@@ -18,6 +22,9 @@
#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"
@@ -39,12 +46,17 @@ PVS::PVS() :
_vncRequested = false;
readPolicyFiles();
loadCommands();
- _blankScreen = NULL;
+ /*#ifndef __WIN32__*/
+ _blankScreen = NULL;
+ /*#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("/home/");
- watchPath.append(getUserName().append(QString("/.pvs/.allow")));
+ QString watchPath(getPolicyDir());
+ watchPath.append(QString(".allow"));
_notify = new QFileSystemWatcher(this);
_notify->addPath(QString(watchPath.toUtf8().data()));
@@ -54,8 +66,10 @@ PVS::PVS() :
// connect to D-Bus
new PvsAdaptor(this);
QDBusConnection dbus = QDBusConnection::sessionBus();
- dbus.registerObject("/", this);
- dbus.registerService("org.openslx.pvs");
+ if (!dbus.registerObject("/", this))
+ qDebug("[ERROR] DBus: Could not register object");
+ if (!dbus.registerService("org.openslx.pvs"))
+ qDebug("[ERROR] DBus: Could not register service");
_sdClient = new PVSServiceDiscovery(this);
@@ -67,6 +81,7 @@ PVS::PVS() :
_timerLockTest = 0;
_timerLockDelay = 0;
+ #ifndef __WIN32__
//add signalhandling for sigterm signals
struct sigaction act;
act.sa_handler = &PVS::signalHandler;
@@ -80,6 +95,7 @@ PVS::PVS() :
sigaction(SIGQUIT, &act, 0);
initializeInputEventHandling();
+ #endif /*__WIN32__*/
}
PVS::~PVS()
@@ -186,6 +202,74 @@ void PVS::onCommand(PVSMsg cmdMessage)
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)
+ {
+ // do stuff to show processes
+ // to test if SHOWPROCESSES command is submitted correct uncomment following lines
+ // a messagebox will appear on the client
+ // emit showMessage("Show Processes", "", true);
+ return;
+ }
+ if (ident.compare("KILLPROCESS") == 0)
+ {
+ // do stuff to kill a process
+ return;
+ }
#ifdef never
// prototype
@@ -327,24 +411,9 @@ bool PVS::allowExists()
*/
bool PVS::getVNCAllow()
{
- if (allowExists())
- {
- if (getAllowed())
- {
- _vncAllowed = true;
- }
- else
- {
- _vncAllowed = false;
- }
- }
- else
- {
- ConsoleLog writeError("No .allow file found.");
- _vncAllowed = false;
- //make sure the vncsever is off
- ConsoleLog writeError("Shutting down vnc-server because we have no .allow file.");
- }
+
+ QString value = getConfigValue("Permissions/vnc_lecturer");
+ _vncAllowed = (value == "rw" || value == "ro");
if (_vncAllowed && _vncRequested)
{
@@ -459,12 +528,13 @@ void PVS::setScriptPath(QString path)
bool PVS::gotVNCScript()
{
- if (fileExists(_vncScriptPath))
+ if (!_vncScriptPath.isEmpty() && fileExists(_vncScriptPath))
return true;
- if (policyFileExists(_vncScriptName))
+
+ if (!_vncScriptName.isEmpty() && policyFileExists(_vncScriptName))
return true;
- return false;
+ return false;
}
/**
* setup password and port
@@ -510,14 +580,19 @@ int PVS::startVNCScript(int port, QString pass, QString rwpass)
commandLine.append(rwpass);
if (!system(NULL))
ConsoleLog writeError("No Command processor available");
-
int result = system(commandLine.toUtf8().data());
+ #ifndef __WIN32__
+//TODO Win32
result = WEXITSTATUS(result);
if (result != 0)
ConsoleLog writeError(QString("VNC-Server is not running, code: ") + int2String(result));
else
ConsoleLog writeLine("VNC-Server should be running");
return result;
+ #else
+ /*Code fuer VNC-Aufruf unter Windows einfuegen*/
+ return 0;
+ #endif /*__WIN32__*/
}
else
{
@@ -533,6 +608,7 @@ int PVS::stopVNCScript()
{
if (gotVNCScript())
{
+ #ifndef __WIN32__
ConsoleLog writeLine("Stopping VNC-Script");
QString commandLine(_vncScriptPath);
commandLine.append(" ");
@@ -544,6 +620,10 @@ int PVS::stopVNCScript()
ConsoleLog writeLine("VNC-Server should be stopped");
int result = system(commandLine.toUtf8().data());
return WEXITSTATUS(result);
+ #else
+ /*Code fuer VNC-Server stoppen unter Windows einfuegen*/
+ return 0;
+ #endif /*__WIN32__*/
}
else
{
@@ -551,9 +631,10 @@ int PVS::stopVNCScript()
}
}
-void PVS::start()
+bool PVS::start()
{
_pvsServerConnection->sendMessage(PVSMsg(PVSCOMMAND, "PROJECTING", "YES"));
+ return true;
}
void PVS::onConnected(QString name)
@@ -620,6 +701,7 @@ QString PVS::getIpByNick(QString nick)
void PVS::signalHandler(int signal)
{
ConsoleLog writeLine(QString("Received Signal ").append (int2String(signal)));
+ #ifndef __WIN32__
switch (signal) {
case SIGHUP:
mainClient->quit();
@@ -634,9 +716,37 @@ void PVS::signalHandler(int signal)
mainClient->quit();
break;
}
+ #else
+ ConsoleLog writeLine("Abfang nicht definiert fuer Windows");
+ #endif /*__WIN32__*/
}
+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)
@@ -651,3 +761,160 @@ 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);
+ _settings.sync();
+ getVNCAllow();
+}
+
+QString PVS::getConfigValue(QString key)
+{
+ return _settings.value(key).toString();
+}
diff --git a/src/pvs.h b/src/pvs.h
index f4e53c0..c18e9a3 100644..100755
--- a/src/pvs.h
+++ b/src/pvs.h
@@ -13,8 +13,10 @@
#define PVSCLIENT_H_
#include <QtCore>
-#include <X11/Xlib.h>
-#include <X11/cursorfont.h>
+#ifndef __WIN32__
+ #include <X11/Xlib.h>
+ #include <X11/cursorfont.h>
+#endif
#include <signal.h>
#include "setup.h"
@@ -26,10 +28,12 @@
#include "src/util/clientGUIUtils.h"
#include "src/input/inputHandlerChain.h"
-
class PVSServiceDiscovery;
class PVSDiscoveredServer;
class InputEvent;
+class McastConfiguration;
+class PVSOutgoingMulticastTransfer;
+class PVSIncomingMulticastTransfer;
/**
* PVSClient
@@ -70,7 +74,7 @@ public:
void guiDelHost(QString host);
public Q_SLOTS:
- void start();
+ bool start();
void quit();
void chat_send(QString nick_to, QString nick_from, QString msg);
QString chat_getNickname();
@@ -82,6 +86,14 @@ public Q_SLOTS:
QStringList getAvailableHosts();
QString getIpByNick(QString nick);
+ // Multicast File Transfer
+ bool createMulticastTransfer(QString const& objectPath, quint64& transferID, QString& errorReason);
+ void cancelOutgoingMulticastTransfer(quint64 transferID);
+ void cancelIncomingMulticastTransfer(qulonglong transferID);
+
+ void setConfigValue(QString key, QString value);
+ QString getConfigValue(QString key);
+
Q_SIGNALS:
void project(QString host, int port, QString passwd, bool fullscreen,
bool smoothTransformation, int quality);
@@ -95,6 +107,17 @@ Q_SIGNALS:
void addHost(QString host);
void delHost(QString host);
+ // Multicast File Transfer
+ void outgoingMulticastTransferStarted(qulonglong transferID);
+ void outgoingMulticastTransferProgress(qulonglong transferID, qulonglong bytes, qulonglong of);
+ void outgoingMulticastTransferFinished(qulonglong transferID);
+ void outgoingMulticastTransferFailed(qulonglong transferID, QString reason);
+ void incomingMulticastTransferNew(qulonglong transferID, QString sender, QString filename, qulonglong size);
+ void incomingMulticastTransferStarted(qulonglong transferID);
+ void incomingMulticastTransferProgress(qulonglong transferID, qulonglong bytes, qulonglong of);
+ void incomingMulticastTransferFinished(qulonglong transferID);
+ void incomingMulticastTransferFailed(qulonglong transferID, QString reason);
+
protected:
void timerEvent(QTimerEvent *event);
@@ -115,7 +138,9 @@ private:
bool _locked; ///< are we locked?
QString _lockMsg; ///< message to display while we're locked
bool _vncAllowed; ///< whether vncConnections to this client are allowed (dup?)
- BlankScreen *_blankScreen;///< obhject to blank the screen
+ /*#ifndef __WIN32__*/
+ BlankScreen *_blankScreen;///< object to blank the screen
+ /*#endif*/
QFileSystemWatcher* _notify; ///< used to get notifies about file changes
//vnc-server
@@ -133,8 +158,6 @@ private:
PVSServerConnection* _pvsServerConnection; ///< our tcp connection object to the pvsserver
- QSettings _settings;
-
PVSServiceDiscovery *_sdClient;
PVSChatClient *_chat;
@@ -148,5 +171,23 @@ private:
unprivileged_handler_chain _inputEventHandlers;
void handleInputEvent(InputEvent const& evt);
void initializeInputEventHandling();
+
+ // multicast transfer
+ McastConfiguration* _masterMcastConfig;
+ QHash<quint64, PVSOutgoingMulticastTransfer*> _outgoingTransfers;
+ QHash<quint64, PVSIncomingMulticastTransfer*> _incomingTransfers;
+
+ void loadMcastConfig(QString const& encoded);
+ void onIncomingMulticastTransfer(QString const& sender, qulonglong transferID, QString const& basename, qulonglong size, ushort port);
+ static quint64 generateMcastTransferID();
+
+private Q_SLOTS:
+ // housekeeping
+ void outgoingMulticastTransferDelete(qulonglong transferID);
+ void incomingMulticastTransferDelete(qulonglong transferID);
+ void onIncomingMulticastTransferRetry(QString const& sender, qulonglong transferID);
+
+private:
+ QSettings _settings;
};
#endif /* PVSCLIENT_H_ */
diff --git a/src/pvsDaemon.cpp b/src/pvsDaemon.cpp
index 591d43b..1784a14 100644
--- a/src/pvsDaemon.cpp
+++ b/src/pvsDaemon.cpp
@@ -3,21 +3,18 @@
#include <stdlib.h>
#include "pvs.h"
#include "src/net/pvsLocalhostCommunicator.h"
-#include "src/util/pvsSettingsManager.h"
#include "setup.h"
#include "src/net/pvsMsg.h"
#include "src/core/pvsChatClient.h"
PVS *mainClient = NULL;
-
-// This define works as a switch whether to run as deamon or regular app
-#define as_daemon
+QTextStream qout(stdout);
/// VERSION_STRING is defined in src/version.h
void printVersion(bool doExit)
{
-
- printf("Version:\t"VERSION_STRING"\n");
+ qout << "Version:\t"VERSION_STRING"\n";
+ qout.flush();
if (doExit)
exit(0);
}
@@ -25,58 +22,52 @@ void printVersion(bool doExit)
/// outputs the full help text
void printHelp()
{
- printf("**************************************************************\n");
- printf("\nPool Video Switch Client\n");
- printf("**************************************************************\n");
- printVersion(false);
- printf("**************************************************************\n");
- printf("Usage:\tpoolVSClient <<option> <value>, ... >\n\n");
- printf("Options:\n\n");
- printf("-vncScriptFile <fullpath\\filename>\n\tSpecifies a custom location for the vnc-start/stop-script.\n\tIf not specified, ~/.pvs/pvs-vncsrv is expected.\n\n");
- printf("-freq <seconds>\n\tSpecifies how long to wait until a reconnection attempt is made.\n\tDefault is 5.\n\n");
- printf("-port <port>\n\tSpecifies on which port to run.\n\tDefault is %d.\n\n", SERVER_PORT_INT);
- printf("-h or --help\n\t Shows this help text and exits.\n\n");
- printf("-v or --version\n\t Shows the current version and exits.\n");
- printf(
- "-c <string command>:<string value> \n\t Sends the command and the optional value to a running PVS-Client.\n\t Command and value may not contain spaces or colons.\n\t The dividing colon is mandatory.\n");
- printf("-commands: \n\tPrints out available commands to use with -c . \n ");
- printf("**************************************************************\n");
+ qout << "**************************************************************\n";
+ qout << "Pool Video Switch Client\n";
+ qout << "**************************************************************\n";
+ qout << QObject::tr("Version: ") << VERSION_STRING << "\n";
+ qout << "**************************************************************\n";
+ qout << QObject::tr("Usage:") << "\tpoolVSClient " << QObject::tr("<<option> <value>, ... >") << "\n\n";
+ qout << QObject::tr("Options:") << "\n\n";
+ qout << QObject::tr("-vncScriptFile <fullpath\\filename>") << "\n\t" << QObject::tr("Specifies a custom location for the vnc-start/stop-script.")<< "\n\t" << QObject::tr("If not specified, /usr/bin/pvs-vncsrv is expected.") << "\n\n";
+ qout << QObject::tr("-freq <seconds>") << "\n\t" << QObject::tr("Specifies how long to wait until a reconnection attempt is made.") << "\n\t" << QObject::tr("Default is 5.") << "\n\n";
+ qout << QObject::tr("-port <port>") << "\n\t" << QObject::tr("Specifies on which port to run.") << "\n\t" << QObject::tr("Default is ") << SERVER_PORT_INT << ".\n\n";
+ qout << QObject::tr("-h or --help") << "\n\t" << QObject::tr("Shows this help text and exits.") << "\n\n";
+ qout << QObject::tr("-v or --version") << "\n\t" << QObject::tr("Shows the current version and exits.") << "\n";
+ qout << QObject::tr("-d or --daemon") << "\n\t" << QObject::tr("Start as daemon.") << "\n";
+ qout << QObject::tr("-c <string command>:<string value>") << "\n\t" << QObject::tr("Sends the command and the optional value to a running PVS-Client.") << "\n\t" << QObject::tr("Command and value may not contain spaces or colons.") << "\n\t" << QObject::tr("The dividing colon is mandatory.") << "\n";
+ qout << "--commands: \n\t" << QObject::tr("Prints out available commands to use with -c.") << "\n";
+ qout << "**************************************************************\n";
+ qout.flush();
exit(0);
}
/// outputs a brief help text
void printNotice()
{
- printf(
- "Use -h or --help to get a listing of all options.\n-v or --version gives you the current version.\n\n");
+ qout << QObject::tr("Use -h or --help to get a listing of all options.\n-v or --version gives you the current version.\n\n");
+ qout.flush();
}
void printCommands()
{
- printf("**************************************************************\n");
- printf("chat:<on/ off/ 1/ 2/ 3>\n ");
- printf("on = turns that chat option on\n off = turns the chat option off\n 1 = bossmode\n 2 = community\n 3 = private\n");
- printf("stop \n\t Stops the running PVS-Client.\n");
- printf("**************************************************************\n");
+ qout << "**************************************************************\n";
+ qout << "stop \n\t Stops the running PVS-Client.\n";
+ qout << "**************************************************************\n";
+ qout.flush();
exit(0);
}
///
int main(int argc, char** argv)
{
+ bool _daemon = false;
int frequency = 5;
int port = -1;
#ifdef as_daemon
bool no_fork = false;
#endif
- QFileInfo script;
- script.setFile("/usr/bin/pvs-vncsrv");
- if (!script.exists())
- script.setFile("/usr/local/bin/pvs-vncsrv");
- if (!script.exists())
- script.setFile("/home/" + getUserName() + "/.pvs/pvs-vncsrv");
-
QCoreApplication app(argc, argv);
app.setOrganizationName("openslx");
app.setOrganizationDomain("openslx.org");
@@ -86,17 +77,37 @@ int main(int argc, char** argv)
translator.load(":pvs");
app.installTranslator(&translator);
+ QFileInfo script;
+#ifdef __WIN32__
+ //TODO Win32
+ if (!script.exists())
+ script.setFile(getHomeDir() + "/.pvs/pvs-vncsrv_win32.bat");
+#else
+ QSettings settings;
+ if (!QFile::exists(settings.fileName()))
+ {
+ QDir::root().mkpath(QFileInfo(settings.fileName()).path());
+ QFile::copy("/etc/openslx/pvs.conf", settings.fileName());
+ }
+ QString s = settings.value("VNC/script").toString();
+ script.setFile(s);
+ if (!script.exists())
+ script.setFile("/usr/bin/pvs-vncsrv");
+ if (!script.exists())
+ script.setFile("/usr/local/bin/pvs-vncsrv");
+ if (!script.exists())
+ script.setFile(getHomeDir() + "/.pvs/pvs-vncsrv");
+#endif //__WIN32__
PVSLocalhostCommunicator com(getPolicyFilePath(QString(
".comfile")));
com.run();
if (!(com.running()))
{
- printf("Error. UDS Communicator is not running. Exiting.\n");
+ qDebug("Error. UDS Communicator is not running. Exiting.");
exit(0);
}
- printf("UDS Communicator is running.\n");
int option_index = 0;
while (1)
@@ -106,6 +117,7 @@ int main(int argc, char** argv)
{ "help", no_argument, 0, 'h' },
{ "commands", no_argument, 0, 'o' },
{ "version", no_argument, 0, 'v' },
+ { "daemon", no_argument, 0, 'd' },
{ "port", required_argument, 0, 'p' },
{ "freq", required_argument, 0, 'f' },
{ "client", required_argument, 0, 'e' },
@@ -117,7 +129,7 @@ int main(int argc, char** argv)
};
/* getopt_long stores the option index here. */
- int c = getopt_long(argc, argv, "hvoFc:f:e:s:p:", long_options,
+ int c = getopt_long(argc, argv, "hvodc:f:e:s:p:", long_options,
&option_index);
option_index++;
if (c == -1)
@@ -134,6 +146,9 @@ int main(int argc, char** argv)
case 'v':
printVersion(true);
break;
+ case 'd':
+ _daemon = true;
+ break;
case 'c':
{
if (option_index + 1 < argc)
@@ -141,78 +156,22 @@ int main(int argc, char** argv)
if (com.server())
{
// wont work, no daemon running
- printf("Error. No running PVS-Client found. Exiting.\n");
+ qDebug("No running PVS-Client found. Exiting.");
com.stop();
}
else
{
- QStringList line = QString::fromLocal8Bit(argv[option_index
- + 1]).split(":");
- QString &ident = line[0];
- QString message;
- if (line.size() > 1)
- message = line[1];
- if (ident.size() > 0) // no use sending empty idents... not even sure if this COULD happen
- {
- bool flag = false;
- if (ident == "make")
- PVSSettingsManager::getManager()->setConfigs();
- else if (ident == "chat" && message == "boss")
- {
- PVSSettingsManager::getManager()->reWriteConfigs("chatmode", "bossmode");
- flag = true;
-
- }
- else if (ident == "chat" && message == "all")
- {
- PVSSettingsManager::getManager()->reWriteConfigs("chatmode", "community");
- flag = true;
- }
- else if (ident == "chat" && message == "private")
- {
- PVSSettingsManager::getManager()->reWriteConfigs("chatmode", "private");
- flag = true;
- }
- else if (ident == "chat" && message == "on")
- {
- PVSSettingsManager::getManager()->reWriteConfigs("chatstate", "on");
- flag = true;
- }
- else if (ident == "chat" && message == "off")
- {
- PVSSettingsManager::getManager()->reWriteConfigs("chatstate", "off");
- flag = true;
- }
- else if (ident == "room")
- {
- //PVSSettingsManager::getManager()->reWriteConfigs(ident, message);
- flag = true;
- }
- else if (ident == "stop" && message == NULL)
- flag = true;
- else
- printf("option %s doesn't exist\n", ident.toUtf8().data());
-
- if (flag)
- {
- qDebug("Will send i: %s, m: %s\n", ident.toUtf8().data(), message.toUtf8().data());
- com.sendCommand(ident, message);
- QCoreApplication::processEvents(QEventLoop::AllEvents);
- printf("Sent command. Exiting.\n");
- }
- }
-
- else
- printf("Something went horribly wrong, since the ident is empty.\n");
-
- }
+ qDebug("Will send i: %s, m: %s\n", argv[option_index + 1], "");
+ com.sendCommand(QString(argv[option_index + 1]), "");
+ QCoreApplication::processEvents(QEventLoop::AllEvents);
+ qDebug("Sent command. Exiting.");
+ }
}
else
{
- printf("Error. No command issued. Exiting.\n");
+ qDebug("Error. No command issued. Exiting.");
}
exit(0); // and gone
- break;
}
case 'f':
{
@@ -257,7 +216,7 @@ int main(int argc, char** argv)
{
if (option_index + 1 < argc)
{
- printf("WARNING: -e is deprecated\n");
+ qDebug("WARNING: -e is deprecated");
option_index++;
continue;
}
@@ -296,7 +255,7 @@ int main(int argc, char** argv)
if (!com.server())
{
- printf("Error. PoolVSClient already running. Exiting\n");
+ qDebug("Error. PoolVSClient already running. Exiting");
com.stop();
exit(0);
}
@@ -304,66 +263,14 @@ int main(int argc, char** argv)
ConsoleLog setLogName(QString("log.client"));
ConsoleLog writeLine(QString("PVS-Client started."));
-#ifdef as_daemon
-
- if (!no_fork)
+ if (_daemon)
{
- /* Our process ID and Session ID */
- pid_t pid, sid;
-
- /* Fork off the parent process */
- pid = fork();
- if (pid < 0)
- {
- exit(-1);
- }
- /* If we got a good PID, then
- we can exit the parent process. */
- if (pid > 0)
- {
- exit(0);
- }
-
- /* Change the file mode mask */
- umask(0);
-
- /* Open any logs here */
-
- /* Create a new SID for the child process */
- sid = setsid();
- if (sid < 0)
- {
- /* Log the failure */
- exit(-1);
- }
-
- /* Change the current working directory */
- if ((chdir("/")) < 0)
- {
- /* Log the failure */
- exit(-1);
- }
-
- /* Close out the standard file descriptors */
- close(STDIN_FILENO);
- freopen ((QString("/home/").append(getUserName().append(QString("/.pvs/dump")))).toUtf8().data(),"w",stdout);
- //close(STDOUT_FILENO);
- close(STDERR_FILENO);
-
- /* Daemon-specific initialization goes here */
-
- /* The Big Loop */
+ #ifndef __WIN32__
+ daemon(1, 1);
+ #endif /*__WIN32__*/
}
- else
- {
- /* just the umask(), please */
- umask(0);
- }
-
-#endif
mainClient = new PVS();
- PVSSettingsManager::getManager()->setConfigFile(getPolicyFilePath("clientconf"));
com.getDispatcher()->addListener("*", mainClient, &PVS::onDaemonCommand);
if (port <= 0)
@@ -374,11 +281,6 @@ int main(int argc, char** argv)
createPolicyDir();
createPolicyFiles();
- // long int gr = 0;
- mainClient->setScriptPath(script.filePath());
- app.exec();
- delete mainClient;
-
- return 0;
+ return app.exec();
}
diff --git a/src/pvsgui.cpp b/src/pvsgui.cpp
index 25f1cd6..eb1383b 100644
--- a/src/pvsgui.cpp
+++ b/src/pvsgui.cpp
@@ -17,13 +17,25 @@
# -----------------------------------------------------------------------------
*/
+#include <getopt.h>
#include "pvsgui.h"
+#include "version.h"
PVSGUI::PVSGUI(QWidget *parent) :
QWidget(parent)
{
setupUi(this);
+ if (!QFile::exists(_settings.fileName()))
+ {
+ QDir::root().mkpath(QFileInfo(_settings.fileName()).path());
+ QFile::copy("/etc/openslx/pvsgui.conf", _settings.fileName());
+ }
+
+ // stop running pvs
+ qDebug("[%s] Stopping pvs daemon.", metaObject()->className());
+ QProcess::execute("pvs -c stop");
+
_menu = new QMenu(this);
_hostMenu = new QMenu(tr("Connect"), this);
_hosts = new QHash<QString, QAction*> ();
@@ -38,62 +50,52 @@ PVSGUI::PVSGUI(QWidget *parent) :
setupMenu();
- if (QSystemTrayIcon::isSystemTrayAvailable())
- {
- qDebug("[%s] System tray available.", metaObject()->className());
- _trayIcon = new QSystemTrayIcon(QIcon(":cam_off32.svg"), this);
- _trayIcon->setContextMenu(_menu);
- _trayIcon->setVisible(true);
- _chatDialog->setTrayIcon(_trayIcon);
- }
- else
- _trayIcon = NULL;
+ _trayIcon = new QSystemTrayIcon(QIcon(":cam_off32.svg"), this);
+ _trayIcon->setContextMenu(_menu);
+ _trayIcon->setVisible(true);
+ _chatDialog->setTrayIcon(_trayIcon);
// connect to D-Bus and get interface
QDBusConnection dbus = QDBusConnection::sessionBus();
- dbus.registerObject("/", this);
- dbus.registerService("org.openslx.pvsgui");
_ifaceDBus = new OrgOpenslxPvsInterface("org.openslx.pvs", "/", dbus, this);
- _ifaceDBus->start(); // start pvs if not running
+ if (dbus.isConnected())
+ qDebug("[%s] Connection to DBus successful.", metaObject()->className());
+ else
+ qDebug("[%s] ERROR: Could not connect to DBus!", metaObject()->className());
- // get available hosts
- QDBusPendingReply<QStringList> reply0 = _ifaceDBus->getAvailableHosts();
+ // start pvs daemon
+ qDebug("[%s] Starting pvs daemon.", metaObject()->className());
+ QDBusPendingReply<bool> reply0 = _ifaceDBus->start();
reply0.waitForFinished();
- QStringList hosts = reply0.value();
- if (reply0.isValid() && !hosts.isEmpty())
+ if (reply0.isValid() && reply0.value())
+ qDebug("[%s] Connection to PVS daemon successful.", metaObject()->className());
+ else
+ qDebug("[%s] ERROR: Could not connect to PVS daemon!", metaObject()->className());
+
+ // get available hosts
+ QDBusPendingReply<QStringList> reply1 = _ifaceDBus->getAvailableHosts();
+ reply1.waitForFinished();
+ QStringList hosts = reply1.value();
+ if (reply1.isValid() && !hosts.isEmpty())
foreach (QString host, hosts)
addHost(host);
// already connected?
- QDBusPendingReply<QString> reply1 = _ifaceDBus->isConnected();
- reply1.waitForFinished();
- QString host = reply1.value();
- if (reply1.isValid() && host != "")
+ QDBusPendingReply<QString> reply2 = _ifaceDBus->isConnected();
+ reply2.waitForFinished();
+ QString host = reply2.value();
+ if (reply2.isValid() && host != "")
connected(host);
else
disconnected();
- if (dbus.isConnected())
- qDebug("[%s] Connection to DBus successful!", metaObject()->className());
-
- // TODO: perhaps this can go if fadi does his work
- // check if vnc is allowed and setup checkbox
- QFile file(QDir::toNativeSeparators(QDir::homePath() + "/.pvs/.allow"));
- if (file.open(QIODevice::ReadOnly | QIODevice::Text))
- {
- QTextStream in(&file);
- QString line = in.readLine();
- if (line == "1")
- vncCheckBox->setChecked(true);
- file.close();
- }
-
// listen on port 29481 for incoming file transfers
_serverSocket = new QTcpServer();
_serverSocket->listen(QHostAddress::Any, 29481);
connect(_serverSocket, SIGNAL(newConnection()), this, SLOT(receiveFile()));
// signals & slots - menu
+ connect(_showAction, SIGNAL(toggled(bool)), this, SLOT(setVisible(bool)));
connect(_disconnectAction, SIGNAL(triggered()), this, SLOT(pvsDisconnect()));
connect(_startChatAction, SIGNAL(triggered()), _chatDialog, SLOT(open()));
connect(_sendFileAction, SIGNAL(triggered()), this, SLOT(sendFile()));
@@ -108,8 +110,6 @@ PVSGUI::PVSGUI(QWidget *parent) :
connect(_hostMenu, SIGNAL(aboutToHide()), this, SLOT(hide()));
connect(_hostMenu, SIGNAL(triggered(QAction*)), this,
SLOT(pvsConnect(QAction*)));
- connect(vncCheckBox, SIGNAL(stateChanged(int)), this,
- SLOT(setVncAllow(int)));
// signals & slots - dbus
connect(_ifaceDBus, SIGNAL(showMessage(QString, QString, bool)), this,
@@ -119,13 +119,11 @@ PVSGUI::PVSGUI(QWidget *parent) :
connect(_ifaceDBus, SIGNAL(disconnected()), this, SLOT(disconnected()));
connect(_ifaceDBus, SIGNAL(addHost(QString)), this, SLOT(addHost(QString)));
connect(_ifaceDBus, SIGNAL(delHost(QString)), this, SLOT(delHost(QString)));
+ connect(_ifaceDBus, SIGNAL(incomingMulticastTransferNew(qulonglong, QString, QString, qulonglong)), SLOT(incomingMulticastFile(qulonglong, QString, QString, qulonglong)));
// show toolbar
- setWindowFlags(Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
+ setWindowFlags(Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint);
setAttribute(Qt::WA_AlwaysShowToolTips);
- updateConfig();
- setVisible(true);
- hide();
}
PVSGUI::~PVSGUI()
@@ -139,9 +137,52 @@ PVSGUI::~PVSGUI()
void PVSGUI::updateConfig()
{
if (_settings.value("Display/location").isNull())
- setLocation(POSITION_TOP_CENTER);
+ setPosition(POSITION_TOP_CENTER);
else
- setLocation(_settings.value("Display/location").toInt());
+ setPosition(_settings.value("Display/location").toInt());
+}
+
+
+void PVSGUI::setVisible(bool visible)
+{
+ QWidget::setVisible(visible);
+ _showAction->setChecked(isVisible());
+}
+
+void PVSGUI::setPosition(int position)
+{
+ _position = position;
+ switch (_position)
+ {
+ case POSITION_TOP_LEFT:
+ move(0, 0);
+ break;
+ case POSITION_TOP_CENTER:
+ move((QApplication::desktop()->width() - width()) / 2, 0);
+ break;
+ case POSITION_TOP_RIGHT:
+ move(QApplication::desktop()->width() - width(), 0);
+ break;
+ case POSITION_BOTTOM_LEFT:
+ move(0, QApplication::desktop()->height() - height());
+ break;
+ case POSITION_BOTTOM_CENTER:
+ move((QApplication::desktop()->width() - width()) / 2,
+ QApplication::desktop()->height() - height());
+ break;
+ case POSITION_BOTTOM_RIGHT:
+ move(QApplication::desktop()->width() - width(),
+ QApplication::desktop()->height() - height());
+ break;
+ default:
+ updateConfig();
+ }
+}
+
+void PVSGUI::hide()
+{
+ if (!_menu->isVisible() && !_hostMenu->isVisible())
+ hide(true);
}
////////////////////////////////////////////////////////////////////////////////
@@ -186,6 +227,8 @@ void PVSGUI::mouseMoveEvent(QMouseEvent *event)
void PVSGUI::setupMenu()
{
// setup actions
+ _showAction = new QAction(tr("Show &toolbar"), this);
+ _showAction->setCheckable(true);
_disconnectAction = new QAction(tr("&Disconnect"), this);
_startChatAction = new QAction(tr("C&hat"), this);
_sendFileAction = new QAction(tr("&Send File"), this);
@@ -195,6 +238,7 @@ void PVSGUI::setupMenu()
_quitAction = new QAction(tr("&Quit"), this);
// setup menu
+ _menu->addAction(_showAction);
_menu->addMenu(_hostMenu);
_menu->addAction(_disconnectAction);
_menu->addAction(_showInfoAction);
@@ -211,60 +255,24 @@ void PVSGUI::setupMenu()
hostButton->setMenu(_hostMenu);
}
-void PVSGUI::setLocation(int location)
-{
- _location = location;
- switch (_location)
- {
- case POSITION_TOP_LEFT:
- move(0, 0);
- break;
- case POSITION_TOP_CENTER:
- move((QApplication::desktop()->width() - width()) / 2, 0);
- break;
- case POSITION_TOP_RIGHT:
- move(QApplication::desktop()->width() - width(), 0);
- break;
- case POSITION_BOTTOM_LEFT:
- move(0, QApplication::desktop()->height() - height());
- break;
- case POSITION_BOTTOM_CENTER:
- move((QApplication::desktop()->width() - width()) / 2,
- QApplication::desktop()->height() - height());
- break;
- case POSITION_BOTTOM_RIGHT:
- move(QApplication::desktop()->width() - width(),
- QApplication::desktop()->height() - height());
- break;
- default:
- break;
- }
-}
-
void PVSGUI::hide(bool b)
{
if (b)
{
- if (_location <= POSITION_TOP_RIGHT)
+ if (_position <= POSITION_TOP_RIGHT)
move(x(), 2 - height());
else
move(x(), QApplication::desktop()->height() - 2);
}
else
{
- if (_location <= POSITION_TOP_RIGHT)
+ if (_position <= POSITION_TOP_RIGHT)
move(x(), 0);
else
move(x(), QApplication::desktop()->height() - height());
}
}
-void PVSGUI::hide()
-{
- if (!_menu->isVisible() && !_hostMenu->isVisible())
- hide(true);
-}
-
void PVSGUI::pvsConnect(QAction *action)
{
QString host = action->text();
@@ -392,22 +400,6 @@ void PVSGUI::delHost(QString host)
}
}
-// TODO: perhaps this can go if fadi does his work
-void PVSGUI::setVncAllow(int i)
-{
- QFile file(QDir::toNativeSeparators(QDir::homePath() + "/.pvs/.allow"));
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
- return;
-
- QTextStream out(&file);
- if (i == 0)
- out << 0;
- else
- out << 1;
-
- file.close();
-}
-
void PVSGUI::sendFile()
{
ClientFileSendDialog *d = new ClientFileSendDialog();
@@ -421,24 +413,103 @@ void PVSGUI::receiveFile()
d->open();
}
+void PVSGUI::incomingMulticastFile(qulonglong transferID, QString sender, QString basename, qulonglong size)
+{
+ ClientFileReceiveDialog *d = new ClientFileReceiveDialog(sender, transferID, basename, size, _ifaceDBus, this);
+ d->open();
+}
+
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Main
+void printHelp()
+{
+ QTextStream qout(stdout);
+ qout << QObject::tr("Usage: pvsgui [OPTIONS]...") << endl;
+ qout << QObject::tr("Start the Pool Video Switch GUI.") << endl;
+ qout << QObject::tr("Options:") << endl << endl;
+ qout << "-b or --toolbar" << "\t\t" << QObject::tr("Start with toolbar.") << endl;
+ qout << "-p or --position" << "\t" << QObject::tr("Set toolbar position (0-5)") << endl;
+ qout << "-h or --help" << "\t\t" << QObject::tr("Show this help text and quit.") << endl;
+ qout << "-v or --version" << "\t\t" << QObject::tr("Show version and quit.") << endl;
+ qout << endl;
+ qout.flush();
+ exit(0);
+}
+
+void printVersion()
+{
+ QTextStream qout(stdout);
+ qout << QObject::tr("Version: ") << VERSION_STRING << endl;
+ qout << endl;
+ qout.flush();
+ exit(0);
+}
+
int main(int argc, char *argv[])
{
- QApplication app(argc, argv);
+ QtSingleApplication app(argc, argv);
+ app.setQuitOnLastWindowClosed(false);
app.setOrganizationName("openslx");
app.setOrganizationDomain("openslx.org");
app.setApplicationName("pvsgui");
+ // only one instance should be allowed
+ if (app.sendMessage(""))
+ {
+ qDebug("[PVSGUI] ERROR: Already running. Exiting");
+ return 0;
+ }
+
// use system locale as language to translate gui
QTranslator translator;
translator.load(":pvsgui");
app.installTranslator(&translator);
+ bool visible = false;
+ int position = -1;
+
+ // parse command line arguments
+ int opt = 0;
+ int longIndex = 0;
+ static const char *optString = "hvp:b?";
+ static const struct option longOpts[] =
+ {
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ { "position", required_argument, NULL, 'p' },
+ { "toolbar", no_argument, NULL, 'b' }
+ };
+
+ opt = getopt_long( argc, argv, optString, longOpts, &longIndex );
+ while( opt != -1 )
+ {
+ switch( opt )
+ {
+ case 'h':
+ printHelp();
+ break;
+ case 'v':
+ printVersion();
+ break;
+ case 'p':
+ position = atoi(optarg);
+ break;
+ case 'b':
+ visible = true;
+ break;
+ case '?':
+ exit(1);
+ }
+ opt = getopt_long( argc, argv, optString, longOpts, &longIndex );
+ }
+
PVSGUI pvsgui;
+ pvsgui.setPosition(position);
+ pvsgui.setVisible(visible);
+ pvsgui.hide();
return app.exec();
}
diff --git a/src/pvsgui.h b/src/pvsgui.h
index f9a0ab8..b96d73c 100644
--- a/src/pvsgui.h
+++ b/src/pvsgui.h
@@ -16,6 +16,7 @@
#include <QtGui>
#include <QtNetwork>
+#include "3rdparty/qtsingleapplication/qtsingleapplication.h"
#include "ui_clientToolbar.h"
#include "src/gui/clientConfigDialog.h"
#include "src/gui/clientChatDialog.h"
@@ -30,7 +31,6 @@
class PVSGUI: public QWidget, private Ui_ClientToolbarClass
{
Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.openslx.pvsgui")
public:
PVSGUI(QWidget *parent = 0);
@@ -45,6 +45,9 @@ public:
public Q_SLOTS:
void updateConfig();
+ void setVisible(bool visible);
+ void setPosition(int position);
+ void hide();
protected:
void enterEvent(QEvent *e);
@@ -55,20 +58,18 @@ protected:
private Q_SLOTS:
void showMessage(QString title, QString msg, bool useDialog = false);
- void hide();
void connected(QString host);
void disconnected();
void addHost(QString host);
void delHost(QString host);
void pvsConnect(QAction *action);
void pvsDisconnect();
- void setVncAllow(int i);
void sendFile();
void receiveFile();
+ void incomingMulticastFile(qulonglong, QString sender, QString basename, qulonglong size);
private:
void setupMenu();
- void setLocation(int location);
void hide(bool b);
QMenu *_menu;
@@ -82,6 +83,7 @@ private:
ClientVNCViewer *_vncViewer;
AboutDialog *_aboutDialog;
+ QAction *_showAction;
QAction *_disconnectAction;
QAction *_startChatAction;
QAction *_sendFileAction;
@@ -90,7 +92,7 @@ private:
QAction *_aboutAction;
QAction *_quitAction;
- int _location;
+ int _position;
QPoint _clickPoint;
QString _passwd;
diff --git a/src/pvsmgr.cpp b/src/pvsmgr.cpp
index 83f5fe0..dd00c0e 100644
--- a/src/pvsmgr.cpp
+++ b/src/pvsmgr.cpp
@@ -18,7 +18,6 @@
#include <QtGui/QDesktopServices>
#include "gui/mainWindow.h"
#include "util/consoleLogger.h"
-#include "util/pvsSettingsManager.h"
#include "util/CertManager.h"
QApplication *qtApp;
@@ -47,7 +46,6 @@ int main(int argc, char** argv)
exit(123);
}
*/
- PVSSettingsManager::getManager()->setConfigFile(getPolicyFilePath("serverconf"));
MainWindow w;
w.show();
return qtApp->exec();
diff --git a/src/pvsmgrtouch.cpp b/src/pvsmgrtouch.cpp
index fa34294..d14ea56 100644
--- a/src/pvsmgrtouch.cpp
+++ b/src/pvsmgrtouch.cpp
@@ -16,9 +16,7 @@
#include <QtGui>
#include <QtGui/QDesktopServices>
-#include "gui/touchgui.h"
#include "util/consoleLogger.h"
-#include "util/pvsSettingsManager.h"
#include "util/CertManager.h"
QApplication *qtApp;
@@ -47,7 +45,6 @@ int main(int argc, char** argv)
exit(123);
}
*/
- PVSSettingsManager::getManager()->setConfigFile(getPolicyFilePath("serverconf"));
pvsMainWindow w;
w.show();
return qtApp->exec();
diff --git a/src/util/clientGUIUtils.cpp b/src/util/clientGUIUtils.cpp
index a8a9487..ff002d3 100644
--- a/src/util/clientGUIUtils.cpp
+++ b/src/util/clientGUIUtils.cpp
@@ -143,13 +143,3 @@ bool BlankScreen::unlock()
return !(locked = false);
}
-static Display* _dpy = 0;
-
-Display* X11Info::display()
-{
- if(!_dpy)
- {
- _dpy = XOpenDisplay(0);
- }
- return _dpy;
-}
diff --git a/src/util/clientGUIUtils.h b/src/util/clientGUIUtils.h
index 4da0a99..7f7ea47 100644..100755
--- a/src/util/clientGUIUtils.h
+++ b/src/util/clientGUIUtils.h
@@ -1,21 +1,20 @@
+#ifndef _BLANKSCREEN_H_
+#define _BLANKSCREEN_H_
+
#include "src/util/consoleLogger.h"
-#include <X11/Xlib.h> // Every Xlib program must include this
-#include <X11/cursorfont.h>
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
-
#define REFRESH_RATE 0.15
-
-#ifndef _BLANKSCREEN_H_
-#define _BLANKSCREEN_H_
+class BlankScreen_Sysdep;
class BlankScreen
{
public:
BlankScreen();
+ virtual ~BlankScreen();
void draw(bool force = false);
bool lock();
bool unlock();
@@ -23,23 +22,17 @@ public:
bool lock_inputs();
private:
- Display *dpy;
- Window win;
- XEvent ev;
- int scr;
-
- bool locked;
-
-
- QString lockMsg;
- int blackColor, whiteColor;
- int offX, offY;
+ BlankScreen_Sysdep* _sysdep;
};
+#ifndef __WIN32__
+# include <X11/Xlib.h>
+
class X11Info
{
public:
static Display* display();
};
+#endif /* !__WIN32__ */
#endif
diff --git a/src/util/clientGUIUtils_Win32.cpp b/src/util/clientGUIUtils_Win32.cpp
new file mode 100755
index 0000000..1b4d2ae
--- /dev/null
+++ b/src/util/clientGUIUtils_Win32.cpp
@@ -0,0 +1,46 @@
+
+#include "clientGUIUtils.h"
+#include <qwidget.h>
+
+struct BlankScreen_Sysdep {
+
+ bool locked;
+ QWidget* blankwin;
+
+ QString lockMsg;
+ int blackColor, whiteColor;
+ int offX, offY;
+};
+
+BlankScreen::BlankScreen()
+{
+ _sysdep = new BlankScreen_Sysdep;
+ _sysdep->blankwin = new QWidget(0, Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
+ _sysdep->blankwin->setWindowState(Qt::WindowFullScreen);
+ _sysdep->blankwin->show();
+}
+
+BlankScreen::~BlankScreen()
+{
+ delete _sysdep;
+}
+
+void BlankScreen::draw(bool force)
+{
+
+}
+
+bool BlankScreen::lock()
+{
+ return true;
+}
+
+bool BlankScreen::lock_inputs()
+{
+ return true;
+}
+
+bool BlankScreen::unlock()
+{
+ return true;
+}
diff --git a/src/util/clientGUIUtils_X11.cpp b/src/util/clientGUIUtils_X11.cpp
new file mode 100755
index 0000000..4b5afe0
--- /dev/null
+++ b/src/util/clientGUIUtils_X11.cpp
@@ -0,0 +1,179 @@
+#include "clientGUIUtils.h"
+#include <X11/Xlib.h>
+#include <X11/cursorfont.h>
+
+
+struct BlankScreen_Sysdep {
+
+ Display *dpy;
+ Window win;
+ XEvent ev;
+ int scr;
+
+ bool locked;
+
+
+ QString lockMsg;
+ int blackColor, whiteColor;
+ int offX, offY;
+};
+
+BlankScreen::BlankScreen()
+{
+ _sysdep = new BlankScreen_Sysdep;
+ _sysdep->dpy = XOpenDisplay(NULL);
+ _sysdep->scr = DefaultScreen(_sysdep->dpy);
+ assert(_sysdep->dpy);
+ _sysdep->blackColor = BlackPixel(_sysdep->dpy, DefaultScreen(_sysdep->dpy));
+ _sysdep->whiteColor = WhitePixel(_sysdep->dpy, DefaultScreen(_sysdep->dpy));
+// win = XCreateSimpleWindow(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), 0, 0, 200, 100, 0, blackColor, whiteColor);
+ _sysdep->win = XCreateSimpleWindow(_sysdep->dpy, RootWindow(_sysdep->dpy, _sysdep->scr), 10, 10, 200, 200, 1, WhitePixel(_sysdep->dpy, _sysdep->scr), BlackPixel(_sysdep->dpy, _sysdep->scr));
+
+ XSelectInput(_sysdep->dpy, _sysdep->win, ExposureMask | KeyPressMask);
+ _sysdep->locked = false;
+ _sysdep->offX = _sysdep->offY = 0;
+}
+
+BlankScreen::~BlankScreen()
+{
+ delete _sysdep;
+}
+
+void BlankScreen::draw(bool force)
+{
+ if (_sysdep->locked)// no need to draw if we're not showing the window
+ {
+ XWindowAttributes xwa;
+ XGetWindowAttributes(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), &xwa);
+ int hx = (xwa.width)>>2, hy = (xwa.height)>>2;
+
+ if (XCheckTypedEvent(_sysdep->dpy, Expose, &_sysdep->ev) || force )
+ {
+ hx += _sysdep->offX;
+ hy += _sysdep->offY;
+
+ GC gcc = XCreateGC(_sysdep->dpy, _sysdep->win, 0, NULL);
+ XSetForeground(_sysdep->dpy, gcc, _sysdep->whiteColor);
+// XClearArea(_sysdep->dpy, _sysdep->win, 0, 0, xwa.width, xwa.height, false);
+ if (_sysdep->lockMsg.size() > 0)
+ {
+ char *msg = const_cast<char*>(_sysdep->lockMsg.toUtf8().data());
+ XDrawString(_sysdep->dpy, _sysdep->win, gcc/*DefaultGC(dpy, scr)*/, hx, hy, msg, strlen(msg));
+ }
+ else
+ {
+ }
+ }
+ }
+}
+
+bool BlankScreen::lock()
+{
+#define lock_test
+
+ if (_sysdep->locked)
+ return _sysdep->locked;
+
+ // We want to get MapNotify events
+ XSelectInput(_sysdep->dpy, _sysdep->win, StructureNotifyMask);
+
+ // "Map" the window (that is, make it appear on the screen)
+ XMapWindow(_sysdep->dpy, _sysdep->win);
+
+ // Create a "Graphics Context"
+ //GC gc = XCreateGC(dpy, win, 0, NULL);
+
+ XEvent xev;
+ Atom wm_state = XInternAtom(_sysdep->dpy, "_NET_WM_STATE", False);
+ Atom fullscreen = XInternAtom(_sysdep->dpy, "_NET_WM_STATE_FULLSCREEN", False);
+ memset(&xev, 0, sizeof(xev));
+ xev.type = ClientMessage;
+ xev.xclient.window = _sysdep->win;
+ xev.xclient.message_type = wm_state;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1;
+ xev.xclient.data.l[1] = fullscreen;
+ xev.xclient.data.l[2] = 0;
+
+ XSendEvent(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), False,
+ SubstructureNotifyMask, &xev);
+
+
+
+
+ // Wait for the MapNotify event
+ for (;;)
+ {
+ XEvent e;
+ XNextEvent(_sysdep->dpy, &e);
+ if (e.type == MapNotify)
+ break;
+ }
+ //Flush it!
+ //XFlush(_sysdep->dpy);
+
+#ifndef lock_test
+ // load the locked cursor, so people dont think they can click anything
+ // TODO: Use some kind of invisible cursor instead of the wait-cursor
+ Cursor _sysdep->locked_cur = XCreateFontCursor(_sysdep->dpy, XC_watch);
+ XDefineCursor(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy),_sysdep->locked_cur);
+#endif
+
+ // grabbing of keyboard and mouse and hide the cursor
+ XGrabKeyboard(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), false, GrabModeAsync, GrabModeAsync, CurrentTime);
+ XGrabPointer(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), false, 0, GrabModeAsync, GrabModeAsync, None, NULL, CurrentTime);
+
+ if (!_sysdep->locked)
+ ConsoleLog writeLine(QString("Locked"));
+
+ // see header for more information on this switch
+ return _sysdep->locked = true;
+}
+
+bool BlankScreen::lock_inputs()
+{
+ // grabbing of keyboard and mouse and hide the cursor
+ XGrabKeyboard(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), false, GrabModeAsync, GrabModeAsync, CurrentTime);
+ XGrabPointer(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), false, 0, GrabModeAsync, GrabModeAsync, None, NULL, CurrentTime);
+ return true;
+}
+
+bool BlankScreen::unlock()
+{
+
+ if (_sysdep->dpy)
+ {
+
+ int retval = -1;
+
+ //reset cursor to arrow (no *real* default here...)
+ Cursor normal_cur = XCreateFontCursor(_sysdep->dpy, XC_arrow);
+ XDefineCursor(_sysdep->dpy, DefaultRootWindow(_sysdep->dpy), normal_cur);
+
+ // ungrabbing of keyboard and mouse
+ XUngrabPointer(_sysdep->dpy, CurrentTime);
+ XUngrabKeyboard(_sysdep->dpy, CurrentTime);
+
+
+ retval = XUnmapWindow(_sysdep->dpy,_sysdep->win);
+ if (retval == BadWindow)
+ ConsoleLog writeError(QString("Bad window while unmapping. Badwindow: ").append(int2String(retval)));
+ XFlush(_sysdep->dpy);
+ }
+ if (_sysdep->locked)
+ ConsoleLog writeLine(QString("Unlocked"));
+
+ _sysdep->lockMsg.clear();
+ return !(_sysdep->locked = false);
+}
+
+static Display* _dpy = 0;
+
+Display* X11Info::display()
+{
+ if(!_dpy)
+ {
+ _dpy = XOpenDisplay(0);
+ }
+ return _dpy;
+}
diff --git a/src/util/consoleLogger.cpp b/src/util/consoleLogger.cpp
index b523b40..9189543 100644..100755
--- a/src/util/consoleLogger.cpp
+++ b/src/util/consoleLogger.cpp
@@ -226,21 +226,17 @@ void ConsoleLogger::_prepareLog()
_logFileGood = false;
_readLog();
- mkdir(getPolicyFilePath(QString()).toUtf8().data(), 0777);
+ createPolicyDir();
QString fullpath;
fullpath.append(_logPath);
//TODO: handle wether path/ or path were entered?
fullpath.append(_logName);
_logFile.open(fullpath.toUtf8().data(), std::ofstream::out | std::ofstream::app);
if (_logFile.good())
- {
_logFileGood = true;
- writeTerminal(QString("LogPath/Name changed to: ").append(fullpath));
- }
else
- {
- printf("ERROR: Logfile ( %s ) not accessible/found. Logs will not be available.\n", _logPath.toUtf8().data());
- }
+ qDebug("ERROR: Logfile ( %s ) not accessible/found. Logs will not be available.", qPrintable(_logPath));
+
_logFile.close();
}
diff --git a/src/util/consoleLogger.h b/src/util/consoleLogger.h
index 3a0950d..e4cb291 100644
--- a/src/util/consoleLogger.h
+++ b/src/util/consoleLogger.h
@@ -116,7 +116,7 @@ public:
_line.push_back('\n'); // add an explicit newline char, so it looks better in the logfile
//#ifndef as_daemon
if (_level == LOG_TERMINAL) // may look strange here, but its quite central :-)
- printf("%s\n", _line.toUtf8().data());
+ qDebug("%s", qPrintable(_line));
//#endif
};
LOG_LEVEL getLevel()
diff --git a/src/util/pvsSettingsManager.cpp b/src/util/pvsSettingsManager.cpp
deleted file mode 100644
index a6a742b..0000000
--- a/src/util/pvsSettingsManager.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-#include "pvsSettingsManager.h"
-#include "TextFile.h"
-
-PVSSettingsManager* PVSSettingsManager::getManager()
-{
- if (myself)
- return myself;
- else
- return myself = new PVSSettingsManager;
-}
-
-void PVSSettingsManager::setConfigFile(QString path)
-{
- if (path.size() && fileExists(path))
- {
- _path = path;
- _parseFile(_path);
-
- }
- else
- ConsoleLog writeError(QString("Can't open config file \"").append(QString(path).append("\"")));
-}
-
-bool PVSSettingsManager::hasEntry(QString name)
-{
- for (SettingsIter it = settingsList.begin(); it != settingsList.end(); it++)
- {
- if ((*it).first.compare(name) == 0)
- {
- return true;
- }
- }
- return false;
-}
-
-QString PVSSettingsManager::getEntryString(QString name)
-{
- for (SettingsIter it = settingsList.begin(); it != settingsList.end(); it++)
- {
- if ((*it).first.compare(name) == 0)
- {
- return (*it).second;
- }
- }
- return QString();
-}
-
-void PVSSettingsManager::writeEntry(QString name, QString value)
-{
- if (name.size() && value.size())
- return;
- bool unique = true;
- for (SettingsIter it = settingsList.begin(); it != settingsList.end(); it++)
- {
- if ((*it).first.compare(name) == 0)
- {
- unique = false;
- (*it).second = value;
- break;
- }
- }
- if (unique)
- {
- SettingsEntry tmp(name, value);
- settingsList.push_back(tmp);
- }
-}
-
-
-PVSSettingsManager* PVSSettingsManager::myself = NULL;
-
-PVSSettingsManager::PVSSettingsManager()
-{
-
-}
-
-void PVSSettingsManager::setConfigs()
-{
- //default settings
- _configs.setValue("Chat/chatstate", "on");
- _configs.setValue("Chat/chatmode", "bossmode");
- _configs.setValue("Room/roomId", "0");
- _configs.setValue("VNC/permit", "off");
- _configs.setValue("VNC/quality", "high");
- _configs.sync();
-}
-void PVSSettingsManager::reWriteConfigs(QString set, QString val)
-{
- _configs.setValue(set, val);
- _configs.sync();
-}
-
-void PVSSettingsManager::readConfigs(QString sett, QString vall)
-{
- //TODO: read the config file..
- _configs.value("Chat/chatstate").toBool();
- _configs.value("Chat/chatmode").toString();
- _configs.value("Room/room").toInt();
- _configs.value("VNC/permit").toBool();
- _configs.value("VNC/quality").toString();
-}
-
-void PVSSettingsManager::_parseFile(QString path)
-{
- QString line;
- TextFile file(path);
-
- SettingsList tmpList;
-
- if (file.good())
- {
- while (!file.eof())
- {
- line = file.readLine();
- if (!(line.length() <=1)) // ignore blank
- {
- if (!(line[0] == '#' || line[0] == '/' || line[0] == '[')) // ignore comments and section headers
- {
- SettingsEntry tmp = _parseLine(line);
- if (tmp.first.size() && tmp.second.size())
- {
- bool unique = true;
- for (SettingsIter it = tmpList.begin(); it != tmpList.end(); it++)
- {
- if ((*it).first.compare(tmp.first) == 0)
- {
- unique = false;
- break;
- }
- }
- if (unique)
- tmpList.push_back(tmp);
- }
- }
- }
- }
- }
- else
- {
- ConsoleLog writeError(QString("No configfile \"").append(QString(path).append("\" found or file corrupt.")));
- }
-
- if (tmpList.size())
- settingsList = tmpList;
-}
-#ifdef verbose
-ConsoleLog writeLine(QString("Dumping Config Content of ").append(QString(path).append(" : ")));
-for (SettingsIter it = settingsList.begin(); it != settingsList.end(); it++)
-{
- ConsoleLog writeLine(QString("Option: ").append(QString((*it).first).append(QString(" | Value: ").append((*it).second))));
-}
-ConsoleLog writeLine(QString("End of ").append(QString(path).append(".")));
-#endif
-
-SettingsEntry PVSSettingsManager::_parseLine(QString line)
-{
- QString name;
- QString value;
-
- name = lineSplitter(line, "=\n\t", true);
- value = lineSplitter(line, "=\n\t", false);
-
- if (!(name.size() && value.size()))
- return SettingsEntry("","");
-
-
- // remove whitespaces in front of option name
- for (int i = 0; i < name.size(); i++)
- {
- if (name[i] == '\t' || name[i] == ' ')
- {
- name.remove(i, 1);
- i--;
- }
- else
- break;
- }
- // whitespaces after the value are trimmed by the lineSplitter
-
- SettingsEntry tmp(name, value);
- return tmp;
-}
-
-
-
diff --git a/src/util/pvsSettingsManager.h b/src/util/pvsSettingsManager.h
deleted file mode 100644
index 78607eb..0000000
--- a/src/util/pvsSettingsManager.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/// documentation test 1
-/// line 2
-/// line 3
-#ifndef _PVSSETTINGSMANGER_H_
-#define _PVSSETTINGSMANGER_H_
-
-#include <list>
-#include <map>
-#include <src/util/util.h>
-#include <src/util/consoleLogger.h>
-#include <QSettings>
-
-
-/// documentation test 1.1
-/// line 2.1
-/// line 3.1
-
-typedef std::pair<QString, QString> SettingsEntry; ///< first = option name, second = option value
-typedef std::list<SettingsEntry> SettingsList; ///< obvious
-typedef std::list<SettingsEntry>::iterator SettingsIter;
-
-
-class PVSSettingsManager;
-/// documentation test 1.2
-/// line 2.2
-/// line 3.2
-class PVSSettingsManager
-{
-public:
- static PVSSettingsManager* getManager();
- void setConfigFile(QString path);
- bool hasEntry(QString name);
- QString getEntryString(QString name);
- void writeEntry(QString name, QString value);
- void setConfigs();
- void reWriteConfigs(QString set, QString val);
- void readConfigs(QString sett, QString vall);
-private:
- static PVSSettingsManager* myself;
- PVSSettingsManager();
- void _parseFile(QString path);
- SettingsEntry _parseLine(QString line);
- QString _path;
- SettingsList settingsList;
- QSettings _configs;
-
-};
-
-
-#endif
diff --git a/src/util/util.cpp b/src/util/util.cpp
index 946168e..05a209f 100644..100755
--- a/src/util/util.cpp
+++ b/src/util/util.cpp
@@ -6,7 +6,11 @@
#include <cstdlib>
#include <QStringList>
#include <iostream>
-
+#include <QDir>
+#ifdef __WIN32__
+ #include <windows.h>
+ #include <Lmcons.h>
+#endif //__WIN32__
PVSServerEntry::PVSServerEntry(QString name)
{
@@ -45,7 +49,11 @@ int getRandom(int min, int max)
if (init)
{
init = false;
+ #ifndef __WIN32__
srand ( time(NULL) + getpid() );
+ #else
+ srand ( time(NULL) ); /*might be solved by another random factor*/
+ #endif
}
if (min >= max) return rand();
return rand() % (max-min+1) + min;
@@ -184,15 +192,28 @@ QString colonSplitter(QString line, bool first)
QString getUserName()
{
- struct passwd* passUser = getpwuid(getuid());
QString username;
- if (passUser)
- {
- username = QString(passUser->pw_name);
- }
+ #ifdef __WIN32__
+ WCHAR* lpszSystemInfo; // pointer to system information
+ DWORD cchBuff = 256; // size of user name
+ WCHAR tchBuffer[UNLEN + 1]; // buffer for expanded string
+
+ lpszSystemInfo = tchBuffer;
+
+ // Get and display the user name.
+ GetUserNameW(lpszSystemInfo, &cchBuff);
+
+ //Unicode string needs to be converted
+ username = QString::fromWCharArray(lpszSystemInfo);
+ #else
+ struct passwd* passUser = getpwuid(getuid());
+ if (passUser)
+ username = QString(passUser->pw_name);
+
+ #endif //#ifdef __WIN32__
if (username.isEmpty())
{
- printf("USERNAME COULDNT BE RETRIEVED!\n");
+ qDebug("USERNAME COULDNT BE RETRIEVED!");
username = QString("USERNAMEERROR");
}
return username;
@@ -202,19 +223,21 @@ QString getUserName()
QString getFullUsername()
{
QString fullname = getUserName();
- struct passwd *pd;
+ #ifndef __WIN32__
+ struct passwd *pd;
- if (NULL == (pd = getpwuid(getuid())))
- {ConsoleLog writeError("getpwuid() error.");}
- else
- {
- QString tmp = pd->pw_gecos;
- QStringList userData = tmp.split(",");
- if(userData[0].length() > 0 )
+ if (NULL == (pd = getpwuid(getuid())))
+ {ConsoleLog writeError("getpwuid() error.");}
+ else
{
- fullname = userData[0];
+ QString tmp = pd->pw_gecos;
+ QStringList userData = tmp.split(",");
+ if(userData[0].length() > 0 )
+ {
+ fullname = userData[0];
+ }
}
- }
+ #endif //__WIN32__ //might be completed some time to a full solution for WIN32
return fullname;
}
@@ -266,7 +289,8 @@ bool policyFileExists(QString fileName)
void createPolicyDir()
{
- mkdir(getPolicyDir().toUtf8().data(), 0777);
+ QDir(QDesktopServices::storageLocation(QDesktopServices::HomeLocation)).mkdir(".pvs");
+ //assuming PolicyDir is defined like in getPolicyDir()
}
void createPolicyFiles()
@@ -299,7 +323,7 @@ QString readPassFromPassFile()
}
bool getAllowed()
{
- printf("Checking %s\n", getPolicyFilePath(QString(".allow")).toUtf8().data());
+ qDebug("Checking %s", qPrintable(getPolicyFilePath(QString(".allow"))));
TextFile file(getPolicyFilePath(".allow"));
if (file.good()) // should have been checked via exists before, but better be safe
{
@@ -314,7 +338,7 @@ bool getAllowed()
(allowed.compare(QString("TRUE")) == 0) )
return true;
}
- printf("...negative\n");
+ qDebug("...negative");
return false;
}
diff --git a/src/util/util.h b/src/util/util.h
index 6ddefc6..4f2d0ee 100644..100755
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -4,7 +4,11 @@
#include <list>
#include <fstream>
#include <iostream>
-#include <pwd.h>
+#ifndef __WIN32__
+ #include <pwd.h>
+#else
+ /*#include "pwd_win32.h"*/
+#endif /*__WIN32*/
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/src/version.h b/src/version.h
index ac24ac2..de5c6aa 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1,2 +1,2 @@
-#define VERSION_STRING "2.0.1.0"
-#define VERSION_NUMBER 2010
+#define VERSION_STRING "2.0.5"
+#define VERSION_NUMBER 205