summaryrefslogtreecommitdiffstats
path: root/src/net/pvsLocalhostCommunicator.cpp
diff options
context:
space:
mode:
authorSebastian2010-05-12 19:42:27 +0200
committerSebastian2010-05-12 19:42:27 +0200
commitce3329047d378a14006ce74ec273ac59e3375303 (patch)
tree782430f270b4c7aca1b35d5b7813518e3797c555 /src/net/pvsLocalhostCommunicator.cpp
downloadpvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.gz
pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.xz
pvs-ce3329047d378a14006ce74ec273ac59e3375303.zip
initial import of latest svn version
Diffstat (limited to 'src/net/pvsLocalhostCommunicator.cpp')
-rw-r--r--src/net/pvsLocalhostCommunicator.cpp104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/net/pvsLocalhostCommunicator.cpp b/src/net/pvsLocalhostCommunicator.cpp
new file mode 100644
index 0000000..199b39c
--- /dev/null
+++ b/src/net/pvsLocalhostCommunicator.cpp
@@ -0,0 +1,104 @@
+#include "pvsLocalhostCommunicator.h"
+#include "src/util/consoleLogger.h"
+#include "src/net/pvsMsg.h"
+
+static QHostAddress localhost(QHostAddress::LocalHost);
+#define localport 14913
+
+PVSLocalhostCommunicator::PVSLocalhostCommunicator(QString path)
+{
+ _isServer = _isRunning = false;
+ _sock = NULL;
+}
+
+void PVSLocalhostCommunicator::run()
+{
+ if (_isRunning)
+ return;
+
+ // First try to run as server
+ _sock = new QUdpSocket();
+ // We'll bind only to localhost, so nobody else can send commands (from remote hosts)
+ // Otherwise we had to check the remote addr when receiving a datagram, but this
+ // wouldn't be as secure since you can easily fake it
+ _sock->bind(localhost, localport); // QUdpSocket::DontShareAddress? would need root
+ connect(_sock, SIGNAL(readyRead()), this, SLOT(sock_dataArrival()));
+
+ if (_sock->state() == QAbstractSocket::BoundState)
+ {
+ // OK, we are the first daemon to run
+ _isServer = true;
+ _isRunning = true;
+ return;
+ }
+ if (_sock->bind())
+ {
+ _isRunning = true;
+ }
+}
+
+void PVSLocalhostCommunicator::stop()
+{
+ _isRunning = false;
+ _sock->deleteLater();
+ _sock = NULL;
+}
+
+void PVSLocalhostCommunicator::sock_dataArrival()
+{
+ if (_sock == NULL) return;
+
+ qint64 dsize;
+ while ((dsize = _sock->pendingDatagramSize()) > -1) // returns -1 if no more datagrams are pending
+ {
+ if (dsize < 4) // anything shorter than 4 bytes is not a valid PVSMsg anyways, so take a shortcut
+ {
+ char x;
+ _sock->readDatagram(&x, 1, NULL, NULL);
+ continue; // discard the packet and see if there is more
+ }
+
+ PVSMsg receiver;
+ receiver.readMessage(_sock, true);
+
+ if (receiver.isMsgComplete())
+ {
+ // we received a message, so fire away
+ ConsoleLog writeNetwork(QString("Received UDS command: ").append(receiver.getIdent()));
+ _daemonDispatcher.fire(receiver.getIdent(), receiver);
+ } // If the msg is not complete we have to discard it, since UDP
+ // is packet oriented and we could not say for sure if the next one
+ // would be the continuation of this msg.
+ // Usually on the loopback interface it is safe to send datagrams
+ // up to 8kb, so this is not be an issue anyway.
+ }
+}
+
+void PVSLocalhostCommunicator::sendCommand(QString ident, QString cmd)
+{
+ if (_isRunning && !_isServer && _sock != NULL)
+ {
+ PVSMsg sender(PVSDAEMON, ident, cmd);
+ char *data;
+ int len;
+ sender.getBinaryData(data, len);
+ QByteArray qba(data, len);
+ printf("Sending %d bytes to daemon...\n", qba.length());
+ qint64 result = _sock->writeDatagram(qba, localhost, localport);
+ _sock->waitForBytesWritten(100);
+
+ // simply bail out on an error or disconnect or whatever
+ if (result != len)
+ {
+ if (result == -1)
+ {
+ printf("Error sending PVSMsg to daemon: %s\n", _sock->errorString().toUtf8().data());
+ }
+ else
+ {
+ printf("Sent PVSMsg was incomplete.\n");
+ }
+ stop();
+ }
+ }
+}