/* * ConnectionManager.cpp * * Copyright (C) 2008 Matthias Schiffer * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "ConnectionManager.h" #include #include #include #include #include namespace Mad { namespace Core { void ConnectionManager::refreshPollfds() { // TODO: refreshPollfds() pollfds.clear(); pollfdMap.clear(); for(std::list::iterator listener = listeners.begin(); listener != listeners.end(); ++listener) { std::vector fds = (*listener)->getPollfds(); for(std::vector::iterator fd = fds.begin(); fd != fds.end(); ++fd) { pollfds.push_back(*fd); pollfdMap.insert(std::make_pair(fd->fd, &pollfds.back().revents)); } } for(std::list::iterator con = daemonConnections.begin(); con != daemonConnections.end(); ++con) { pollfds.push_back((*con)->getPollfd()); pollfdMap.insert(std::make_pair(pollfds.back().fd, &pollfds.back().revents)); } for(std::list::iterator con = clientConnections.begin(); con != clientConnections.end(); ++con) { pollfds.push_back((*con)->getPollfd()); pollfdMap.insert(std::make_pair(pollfds.back().fd, &pollfds.back().revents)); } } void ConnectionManager::daemonReceiveHandler(const Net::Connection *connection, const Net::Packet &packet) { std::cout << "Received daemon packet:" << std::endl; std::cout << " Type: " << packet.getType() << std::endl; std::cout << " Request ID: 0x" << std::hex << std::uppercase << packet.getRequestId() << std::dec << std::endl; std::cout << " Length: " << packet.getLength() << std::endl; for(std::list::iterator con = daemonConnections.begin(); con != daemonConnections.end(); ++con) { if(*con == connection) { (*con)->disconnect(); break; } } } void ConnectionManager::clientReceiveHandler(const Net::Connection *connection, const Net::Packet &packet) { std::cout << "Received client packet:" << std::endl; std::cout << " Type: " << packet.getType() << std::endl; std::cout << " Request ID: 0x" << std::hex << std::uppercase << packet.getRequestId() << std::dec << std::endl; std::cout << " Length: " << packet.getLength() << std::endl; for(std::list::iterator con = clientConnections.begin(); con != clientConnections.end(); ++con) { if(*con == connection) { (*con)->disconnect(); break; } } } ConnectionManager::ConnectionManager() { try { // TODO: Get listener addresses from config listeners.push_back(new Net::Listener(Net::IPAddress("0.0.0.0", 6666))); } catch(Net::Exception &e) { // TODO: Log error } refreshPollfds(); } ConnectionManager::~ConnectionManager() { for(std::list::iterator con = daemonConnections.begin(); con != daemonConnections.end(); ++con) delete *con; for(std::list::iterator con = clientConnections.begin(); con != clientConnections.end(); ++con) delete *con; } void ConnectionManager::run() { // TODO: Logging for(std::list::iterator con = daemonConnections.begin(); con != daemonConnections.end();) { if((*con)->isConnected()) { std::map::iterator events = pollfdMap.find((*con)->getSocket()); if(events != pollfdMap.end()) (*con)->sendReceive(*events->second); else (*con)->sendReceive(); ++con; } else { delete *con; daemonConnections.erase(con++); } } for(std::list::iterator con = clientConnections.begin(); con != clientConnections.end();) { if((*con)->isConnected()) { std::map::iterator events = pollfdMap.find((*con)->getSocket()); if(events != pollfdMap.end()) (*con)->sendReceive(*events->second); else (*con)->sendReceive(); ++con; } else { delete *con; clientConnections.erase(con++); } } for(std::list::iterator listener = listeners.begin(); listener != listeners.end(); ++listener) { Net::ServerConnection *con; while((con = (*listener)->getConnection(pollfdMap)) != 0) { if(con->isDaemonConnection()) { daemonConnections.push_back(con); con->signalReceive().connect(sigc::mem_fun(this, &ConnectionManager::daemonReceiveHandler)); } else { clientConnections.push_back(con); con->signalReceive().connect(sigc::mem_fun(this, &ConnectionManager::clientReceiveHandler)); } } } refreshPollfds(); } } }