diff options
| author | Sebastian | 2010-05-12 19:42:27 +0200 |
|---|---|---|
| committer | Sebastian | 2010-05-12 19:42:27 +0200 |
| commit | ce3329047d378a14006ce74ec273ac59e3375303 (patch) | |
| tree | 782430f270b4c7aca1b35d5b7813518e3797c555 /src/core/pvsConnectionManager.cpp | |
| download | pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.gz pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.xz pvs-ce3329047d378a14006ce74ec273ac59e3375303.zip | |
initial import of latest svn version
Diffstat (limited to 'src/core/pvsConnectionManager.cpp')
| -rw-r--r-- | src/core/pvsConnectionManager.cpp | 483 |
1 files changed, 483 insertions, 0 deletions
diff --git a/src/core/pvsConnectionManager.cpp b/src/core/pvsConnectionManager.cpp new file mode 100644 index 0000000..8a35ca9 --- /dev/null +++ b/src/core/pvsConnectionManager.cpp @@ -0,0 +1,483 @@ +/* +# 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/core/pvsConnectionManager.cpp +# ----------------------------------------------------------------------------- +*/ + +#include "pvsConnectionManager.h" +#include "src/gui/mainWindow.h" +#include <QApplication> +#include "src/setup.h" +#include "src/util/CertManager.h" +#include "src/util/serviceDiscoveryUtil.h" + +PVSConnectionManager* PVSConnectionManager::singleCM; + + +PVSConnectionManager* PVSConnectionManager::getManager() +{ + if (!singleCM) + singleCM = new PVSConnectionManager(); + return singleCM; +} + +PVSConnectionManager::PVSConnectionManager() +{ + _busy = false; + _needPassword = false; + loadCommands(); + ConsoleLog writeLine(QString("Connection Manager created.")); + ConsoleLog writeChat("Log for chat is now running"); + + if (!(_pvsServer.startListen(SERVER_PORT_INT))) + ConsoleLog writeError(QString("Server listening failed!")); + setUpdateRate(500); + _sdBroadcaster.setFingerprint( + CertManager::getCertificate("manager").digest(QCryptographicHash::Sha1) + ); + _timerId = startTimer(1000); +} + +PVSConnectionManager::~PVSConnectionManager() +{ + killTimer(_timerId); +} + +void PVSConnectionManager::setUpdateRate(int newRate) +{ + // TODO: Iterate over list of clients and set the updateRate on each vncConnection + // Object. The timer does not influence the update rate of the thumbs, thus the code + // here was removed. +} + +void PVSConnectionManager::timerEvent(QTimerEvent *event) +{ + update(); +} + +void PVSConnectionManager::onClientNew(PVSClientConnection* newConnection) +{ + PVSClient* tmp = getClientFromConnection(newConnection); + if (tmp == NULL) + { + PVSClient* newCon = new PVSClient(newConnection); + _listClients.push_back(newCon); + sendEventToClients(QString("addedConnection"), newConnection, ""); + } + else + { + // already got that one... strange, eh? + } +} + +void PVSConnectionManager::onClientRemove(PVSClientConnection* removedConnection) +{ + PVSClient* tmp = getClientFromConnection(removedConnection); + if (tmp == NULL) return; + MainWindow::getWindow()->removeConnection(tmp); + removeConnection(tmp); + if(tmp->getUserName().length() > 0) + { + ConsoleLog writeChat(tmp->getUserName()+" has left the chat."); + sendEventToClients("removedClient", removedConnection , tmp->getUserName()+":"+tmp->getIp()); + } +} + +// Inform all chat clients about a new event. +void PVSConnectionManager::sendEventToClients(QString event, PVSClientConnection* connection, QString clientName) +{ + if(event.compare("addedConnection") == 0) + { + // send the client list to new Connection. + for (std::list<PVSClient*>::iterator it = _listClients.begin(); it != _listClients.end(); it++) + { + QString name = (**it).getUserName(); + QString ip = (**it).getIp(); + if (name.length() == 0) continue; + connection->push_back_send(PVSMsg(PVSMESSAGE, "clientToAdd", ":" + name + ":" + ip, 0)); + } + } + if(event.compare("addedClient") == 0) + { + // send name to everybody to all connected clients. + _pvsServer.sendToAll(PVSMsg(PVSMESSAGE, "clientToAdd", ":" + clientName, 0)); + connection->push_back_send(PVSMsg(PVSMESSAGE, "assignedName", ":" + clientName, 0)); + connection->push_back_send(PVSMsg(PVSMESSAGE, "clientToAdd", ":PVSMGR:local", 0)); + } + if(event.compare("removedClient") == 0) + { + // send name of removed client to connected clients. + _pvsServer.sendToAll(PVSMsg(PVSMESSAGE, "clientToRemove", ":"+ clientName, 0)); + } +} + +PVSClient* PVSConnectionManager::getClientFromConnection(PVSClientConnection* client) +{ + if (!_listClients.empty()) + { + + for (std::list<PVSClient*>::iterator it = _listClients.begin(); it != _listClients.end(); it++) + { + if ((*it)->getPVSClientConnection()) + { + if ((*it)->getPVSClientConnection() == client) + { + return (*it); + } + } + } + } + return NULL; +} + +PVSClient* PVSConnectionManager::getClientFromConnectionId(int id) +{ + if (_listClients.empty()) return NULL; + for (std::list<PVSClient*>::iterator it = _listClients.begin(); it != _listClients.end(); it++) + { + if ((*it)->getConnectionId() == id) return (*it); + } + return NULL; +} + +PVSClient* PVSConnectionManager::getClientFromVNCConnection(VNCConnection* client) +{ + if (!_listClients.empty()) + { + + for (std::list<PVSClient*>::iterator it = _listClients.begin(); it != _listClients.end(); it++) + { + if ((*it)->getVNCConnection()) + { + if ((*it)->getVNCConnection() == client) + { + return (*it); + } + } + } + } + return NULL; +} + +PVSClient* PVSConnectionManager::getClientFromIp(QString ip) +{ + if (!_listClients.empty()) + { + for (std::list<PVSClient*>::iterator it = _listClients.begin(); it != _listClients.end(); it++) + { + // ok, probably this could be handled better inside the PVSConnection itself + // but makeshift for now + if ((*it)->getPVSClientConnection()) + { + if ((*it)->getIp() == ip) + { + return (*it); + } + } + } + } + return NULL; +} + +void PVSConnectionManager::onCommand(PVSMsg command) +{ + QString message = command.getMessage(); + QString ident = command.getIdent(); + if (ident.compare("VNCSRVRESULT") == 0) + { + int e = string2Int(message); + QString id = int2String(command.getSndID()); + switch (e) + { + case 0: + ConsoleLog writeLine("[Client: " + id + ", VNCSRV] Server should be running"); + break; + case 1: + ConsoleLog writeError("[Client: " + id + ", VNCSRV] Server returned general error"); + break; + case 2: + ConsoleLog writeError("[Client: " + id + ", VNCSRV] ~/.pvs/vncpasswd not found"); + break; + case 3: + ConsoleLog writeError("[Client: " + id + ", VNCSRV] VNC-Script not found"); + break; + case 127: + ConsoleLog writeError("[Client: " + id + ", VNCSRV] command not found (vnc-server installed?)"); + break; + default: + ConsoleLog writeError("[Client: " + id + ", VNCSRV] unknown error"); + break; + } + } +} +void PVSConnectionManager::onChat(PVSMsg chatMsg) +{ + + QString nick_to = chatMsg.getIdent(); + int sndID = chatMsg.getSndID(); + PVSClientConnection* clientConnection = NULL; + PVSClient* client; + QStringList l = chatMsg.getMessage().split(":"); + QString nick_from = l[0]; + QString msg = chatMsg.getMessage().remove(0, l[0].size()+1); + + if (nick_to == "@all") // public message. + { + _pvsServer.sendToAll(chatMsg); + MainWindow::getWindow()->receiveChatMsg(nick_from, nick_to, msg);// get Msg on PVSMgr's Chat-GUI. + ConsoleLog writeChat(nick_from +" wrote '"+msg+"' in @all-Channel."); + } + else // private message. + { + if(nick_from == "PVSMGR") //Msg from Server + { + MainWindow::getWindow()->receiveChatMsg(nick_from, nick_to, msg); // get Msg on PVSMgr's Chat-GUI. + ConsoleLog writeChat(nick_from+" wrote '" + msg + "' to " + nick_to); // write the event to the chat log. + } + else + { + clientConnection = _pvsServer.getConnectionFromId(sndID); // become your own message. + if (clientConnection) + { + clientConnection->push_back_send(chatMsg); + } + else + { + ConsoleLog writeError("Got Chat Message from unknown ID"); + } + } + if(nick_to == "PVSMGR") //Msg to Server + { + MainWindow::getWindow()->receiveChatMsg(nick_from, nick_to, msg); // get Msg on PVSMgr's Chat-GUI. + ConsoleLog writeChat(nick_from+" wrote '" + msg + "' to " + nick_to);// write the event to the chat log. + } + else + { + client = getClientFromUsername(nick_to); // private receiver become the message. + if (client) + { + client->sendMessage(chatMsg); + ConsoleLog writeChat(nick_from+" wrote '" + msg + "' to " + nick_to);// write the event to the chat log. + } + else + { + ConsoleLog writeError("[CHAT] There is no client with username: " + nick_to); + } + } + + } +} + +PVSClient* PVSConnectionManager::getClientFromUsername(QString name) +{ + if (!(_listClients.empty())) + { + // Check for ping timeout + for (std::list<PVSClient*>::iterator it = _listClients.begin(); it!= _listClients.end(); it++) + { + PVSClient *client = *it; + if (client) + if (client->getUserName() == name) + return client; + } + } + return NULL; +} + +void PVSConnectionManager::onLoginPassword(PVSMsg command) +{ + if (!_needPassword) return; // No password required + if (_password == command.getMessage()) return; // No password set + PVSClient* tmp = getClientFromConnectionId(command.getSndID()); + tmp->sendMessage( + PVSMsg(PVSLOGIN, "FAILED", "Wrong password.") + ); + tmp->shutDownClient(); +} + +// Set usernamen and loginname a client. +void PVSConnectionManager::onLoginUsername(PVSMsg command) +{ + QStringList l = command.getMessage().split(","); + PVSClient* tmp = getClientFromConnectionId(command.getSndID()); + if (tmp->getUserName().length() > 0) return; + ConsoleLog writeError("(PVSConnectionManager::onUsername) was fired."); + if(l[0] == "PVSMGR") + { + l[0] = "fake_PVSMGR"; + } + int counter = 0; + QString uname = l[0]; + while (getClientFromUsername(uname) != NULL) + { + uname = l[0].append(QString::number(counter++, 16)); + } + if (tmp) + { + tmp->setUsername(uname); + tmp->setLoginName(l[1]); + MainWindow::getWindow()->addConnection(tmp); + ConsoleLog writeChat(tmp->getUserName()+" has joined the chat."); + sendEventToClients(QString("addedClient"), tmp->getPVSClientConnection(), tmp->getUserName() +":"+ tmp->getIp()); + } + else + ConsoleLog writeError("(PVSConnectionManager::onUsername) Couldnt find connection to user-id"); +} + +void PVSConnectionManager::onVncPassword(PVSMsg command) +{ + PVSClient* tmp = getClientFromConnectionId(command.getSndID()); + + if (tmp) + { + tmp->setVncPassword(command.getMessage()); + return; + } + else + ConsoleLog writeError("couldnt find matching connection to id!"); +} + +void PVSConnectionManager::onVncRwPassword(PVSMsg command) +{ + PVSClient* tmp = getClientFromConnectionId(command.getSndID()); + + if (tmp) + { + tmp->setVncRwPassword(command.getMessage()); + return; + } + else + ConsoleLog writeError("couldnt find matching connection to id!"); +} + +void PVSConnectionManager::onVncAllow(PVSMsg command) +{ + PVSClient* tmp = getClientFromConnectionId(command.getSndID()); + + if (tmp) + { + if (command.getMessage().compare("YES") == 0) + { + tmp->setAllowed(true); + return; + } + tmp->setAllowed(false); + } +} + +void PVSConnectionManager::onVncPort(PVSMsg command) +{ + PVSClient* tmp = getClientFromConnectionId(command.getSndID()); + if (tmp) + { + int port = string2Int(command.getMessage()); + if (port > 0) + tmp->setVncPort(port); + } + +} + +void PVSConnectionManager::onVncProjection(PVSMsg command) +{ + if (command.getMessage().compare(QString("YES")) == 0) + ConsoleLog writeLine("Client is watching.(connected via vnc)"); + if (command.getMessage().compare(QString("NO")) == 0) + ConsoleLog writeLine("Client failed to connect via vnc."); +} + +void PVSConnectionManager::removeConnection(PVSClient* newConnection) +{ + if (newConnection != NULL) + { + for (std::list<PVSClient*>::iterator it = _listClients.begin(); it != _listClients.end(); it++) + { + if (newConnection == (*it)) + { + // remove it from the list to keep this method from causing trouble when being called more than + // once in the process + _listClients.remove(newConnection); + + // it is important to tell the GUI that the vnc is gone (or ... will be) + // before we really shut it down, since the removal procedure of the + // frames shouldnt be messed with from here. + MainWindow::getWindow()->onConnectionRemoved(newConnection); // to kill vncConnection + + // now that the gui nows about it and does no longer call the vnc-stuff + newConnection->shutDownVNC(); + // and its gone... + + // clean up on the connection + newConnection->shutDownClient(); // just to be sure + newConnection->onClientDisconnected(); + + + newConnection->deleteLater(); + return; + } + } + } + else + { + // well, not our problem obviously + } +} + +bool PVSConnectionManager::update() +{ + if (_busy) return true; // already ongoing, so scrap that. + + _busy = true; // lock method + + if (!_listClients.empty()) + { + // now update the rest and check if they are alive + // otherwise mark dead connections + for (std::list<PVSClient*>::iterator it = _listClients.begin(); it != _listClients.end(); it++) + { + PVSClient* current = (*it); + current->tick(); + } + } + + //QApplication::processEvents(QEventLoop::AllEvents, 5); + + _busy = false; // we're done, so unlock + return true; +} + +void PVSConnectionManager::loadCommands() +{ + _pvsServer.addLoginHandler("USERNAME", this, &PVSConnectionManager::onLoginUsername); + _pvsServer.addLoginHandler("PASSWORD", this, &PVSConnectionManager::onLoginPassword); + _pvsServer.addCommandHandler("*", this, &PVSConnectionManager::onCommand); + _pvsServer.addCommandHandler("VNC", this, &PVSConnectionManager::onVncAllow); + _pvsServer.addCommandHandler("PORT", this, &PVSConnectionManager::onVncPort); + _pvsServer.addCommandHandler("PASSWORD", this, &PVSConnectionManager::onVncPassword); + _pvsServer.addCommandHandler("RWPASSWORD", this, &PVSConnectionManager::onVncRwPassword); + _pvsServer.addCommandHandler("PROJECTING", this, &PVSConnectionManager::onVncProjection); + _pvsServer.addChatHandler("*", this, &PVSConnectionManager::onChat); +} + +QString PVSConnectionManager::setNeedPassword(bool enabled) +{ + _needPassword = enabled; + if (enabled && _password.isEmpty()) + { + _password = QString::number(getRandom(1000, 9999), 10); + } + return _password; +} + +QString PVSConnectionManager::getSessionName() +{ + return sha1ToReadable(CertManager::getCertificate("manager").digest(QCryptographicHash::Sha1)); +} |
