From ce3329047d378a14006ce74ec273ac59e3375303 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 12 May 2010 19:42:27 +0200 Subject: initial import of latest svn version --- src/net/pvsLocalhostCommunicator.cpp | 104 +++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/net/pvsLocalhostCommunicator.cpp (limited to 'src/net/pvsLocalhostCommunicator.cpp') 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(); + } + } +} -- cgit v1.2.3-55-g7522