diff --git a/CMakeLists.txt b/CMakeLists.txt index fddaee1..6c8e3e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,6 @@ add_executable(${PROJECT_NAME} ${SRC_FILES}) target_link_libraries( ${PROJECT_NAME} ${LIBS}) set_target_properties( ${PROJECT_NAME} PROPERTIES COMPILE_FLAGS -m64 LINK_FLAGS -m64) -add_definitions(" -std=c++11 -Wall ") +add_definitions(" -std=c++11 -Wall -O2") install(TARGETS serialmultiplexer RUNTIME DESTINATION bin) diff --git a/main.cpp b/main.cpp index 03c1972..9897fb6 100644 --- a/main.cpp +++ b/main.cpp @@ -14,25 +14,18 @@ #include "serial_io.h" #include "Socket.h" +#include "clienthandler.h" -#define VERSION "v0.5" +#define VERSION "v0.6" volatile bool stop = false; volatile bool resettSerialPort = false; -struct epoll_event ev; void intHandler(int sig) { stop = true; } -void alarmHandler(int sig) -{ - resettSerialPort = true; - signal(sig, alarmHandler); - alarm(600); -} - static void printUsage() { std::cout<<"usage mulitplexer [option]\n\ @@ -103,18 +96,22 @@ static int parseCmdArgs(int argc, char** argv, Config *config) return 0; } -void acceptThreadFunction( TCPServerSocket* servSock, std::vector* clientSockets, std::mutex* clientSocketsMutex, int pollQue ) +void acceptThreadFunction( TCPServerSocket* servSock, std::vector* clients, std::mutex* clientsMutex, int pollQue ) { while(!stop) { TCPSocket* newSock = servSock->accept(); if(newSock != nullptr) { - clientSocketsMutex->lock(); - clientSockets->push_back(newSock); // Wait for a client to connect - clientSocketsMutex->unlock(); + clientsMutex->lock(); + clients->push_back(ClientHandler(newSock)); // Wait for a client to connect + struct epoll_event ev; + ev.events = EPOLLIN; + ev.data.fd = clients->size()-1; + clientsMutex->unlock(); epoll_ctl(pollQue, EPOLL_CTL_ADD, newSock->getFD(), &ev); - clientSockets->back()->send("UVOS serial multiplexer " VERSION "\n", sizeof("UVOS serial multiplexer " VERSION "\n")-1); + char welcomeMesg[] = "UVOS serial multiplexer " VERSION "\n"; + clients->back().write(welcomeMesg, sizeof(welcomeMesg)-1); std::cout<<"got client\n"; } std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -148,7 +145,6 @@ int main(int argc, char* argv[]) std::cout<<"UVOS serial mulitplexer "< clientSockets; + std::mutex clientsMutex; + std::vector clients; std::thread* acceptThread; TCPServerSocket* servSock; @@ -176,7 +174,7 @@ int main(int argc, char* argv[]) { servSock = new TCPServerSocket(config.port, 5, true); // Server Socket object servSock->setBlocking(false); - acceptThread = new std::thread(acceptThreadFunction, servSock, &clientSockets, &clientSocketsMutex, pollQue); + acceptThread = new std::thread(acceptThreadFunction, servSock, &clients, &clientsMutex, pollQue); } catch(SocketException &e) { @@ -184,114 +182,52 @@ int main(int argc, char* argv[]) return 1; } - char buffer[4096]; - signal(SIGINT, intHandler); signal(SIGTERM, intHandler); - signal(SIGALRM, alarmHandler); - - if(config.reinit) alarm(600); - + signal(SIGPIPE, SIG_IGN); //ignore SIGPIPE std::cout<<"starting loop\n"; while(!stop) { - epoll_wait(pollQue, &ev, 1, 2000); - int readlen = sRead(serial, buffer, 4096); - for(unsigned int i = 0; i < clientSockets.size(); i++) + struct epoll_event ev; + if( epoll_wait(pollQue, &ev, 1, 2000) == 1) { - clientSocketsMutex.lock(); - try + if(ev.data.fd != -1) { - if(readlen > 0) + int i = ev.data.fd; + std::cout<<"client poll\n"; + clientsMutex.lock(); + if(ev.events & EPOLLIN) clients[i].run(&clients, serial, config.verbose); + if((ev.events & (EPOLLHUP | EPOLLERR)) || clients[i].isDisconnected()) { - if(config.verbose) - { - std::cout<<"bcst: "; - for( int j = 0; j < readlen; j++ )std::cout<send(buffer, readlen); + clients[i].cleanUp(); + clients.erase(clients.begin()+i); + std::cout<<"client "<recv(inBuffer, 4096); - if( reclen > 0 ) + clientsMutex.unlock(); + } + else + { + char buffer[4096]; + int readlen = sRead(serial, buffer, 4096); + if(config.verbose) { - if(config.verbose) - { - std::cout<<"rec: "; - for( int j = 0; j < reclen; j++ )std::cout<send(inBuffer, reclen); - - } - else if(strncmp( inBuffer, "reinitsp", 8) == 0 && serial != -1) - { - if(serialport_set_config(serial, config.baud) == 0) - { - char response[] = "reinit serial port succsesfull\n"; - std::cerr<send(response, sizeof(response)); - } - else - { - char response[] = "reinit serial port failed!\n"; - std::cerr<send(response, sizeof(response)); - } - } - else - { - if(config.verbose) - { - std::cout<<"wrote \""; - for( int j = 0; j < reclen; j++ )std::cout<cleanUp(); - clientSockets.erase(clientSockets.begin()+i); - i--; - if(i < 0) i=0; + client.write(buffer, readlen); } } - catch(SocketException &e) - { - std::cout<cleanUp(); - clientSockets.erase(clientSockets.begin()+i); - i--; - if(i < 0) i=0; - } - clientSocketsMutex.unlock(); - } - if(resettSerialPort) - { - close(serial); - serial = openSerialPort(config); - resettSerialPort = false; } } acceptThread->join(); delete acceptThread; - for(unsigned int i = 0; i < clientSockets.size(); i++) clientSockets[i]->cleanUp(); + for(ClientHandler& client : clients) client.cleanUp(); servSock->cleanUp(); delete servSock; return 0;