#include #include #include #include #include #include #include #include #include #include #include #include #include #include "serial_io.h" #include "Socket.h" #include "clienthandler.h" #define VERSION "v0.7" sig_atomic_t stop = false; void intHandler(int sig) { stop = true; } static void printUsage() { std::cout<<"usage mulitplexer [option]\n\ Available options:\n\ -h, --help print this help\n\ -p, --serialport serial port device to use\n\ -P, --port tcp port to use\n\ -b, --baud set baud rate with termios id\n\ -r, --rates list Available baud rates\n\ -v, --verbose Run in verbose mode\n\ -i, --spreint Peridoicly reinit serialport\n\ -s, --sinkless run without serial port\n"; } struct Config { std::string portFileName = "/dev/ttyUSB0"; unsigned short port = 6856; int baud = B9600; bool noSerial = false; bool verbose = false; bool reinit = false; }; static int parseCmdArgs(int argc, char** argv, Config *config) { for (int i = 1; i < argc; i++) { if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") { printUsage(); return -1; } else if (std::string(argv[i]) == "--serialport" || std::string(argv[i]) == "-p") { if(argc > i) config->portFileName = argv[i+1]; else return -1; } else if (std::string(argv[i]) == "--port" || std::string(argv[i]) == "-P") { if(argc > i) config->port = atoi(argv[i+1]); else return -1; } else if (std::string(argv[i]) == "--baud" || std::string(argv[i]) == "-b") { if(argc > i) config->baud = atoi(argv[i+1]); else return -1; } else if (std::string(argv[i]) == "--sinkless" || std::string(argv[i]) == "-s" ) { config->noSerial=true; } else if (std::string(argv[i]) == "-r" || std::string(argv[i]) == "--rates") { printRates(); return -1; } else if (std::string(argv[i]) == "-v" || std::string(argv[i]) == "--verbose") { config->verbose=true; } else if (std::string(argv[i]) == "-i" || std::string(argv[i]) == "--spreint") { config->reinit=true; } } return 0; } void acceptThreadFunction( TCPServerSocket* servSock, std::vector* clients, std::mutex* clientsMutex, int pollQue ) { while(!stop) { TCPSocket* newSock = servSock->accept(); if(newSock != nullptr) { 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); 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)); } } int openSerialPort(const Config& config) { int serial = -1; if(!config.noSerial) { std::cout<<"Opeing serial port: "< clients; int serial = openSerialPort(config); if(!config.noSerial) { serialConnect(config, &serial); if(serial == -1) return 1; else { struct epoll_event ev = {}; ev.events = EPOLLIN; ev.data.fd = -1; epoll_ctl(pollQue, EPOLL_CTL_ADD, serial, &ev); } tcflush(serial, TCIOFLUSH); } else { std::cout<<"Sinkless mode\n"; } std::thread* acceptThread; TCPServerSocket* servSock; std::cout<<"opening TCP socket on port "<setBlocking(false); acceptThread = new std::thread(acceptThreadFunction, servSock, &clients, &clientsMutex, pollQue); } catch(SocketException &e) { std::cerr<<"Could not open port"<= clients.size()) { clientsMutex.unlock(); continue; } std::cout<<"client poll\n"; if(ev.events & EPOLLIN) clients[i].run(&clients, serial, config.verbose); if((ev.events & (EPOLLHUP | EPOLLERR)) || clients[i].isDisconnected()) { clients[i].cleanUp(); clients.erase(clients.begin()+i); std::cout<<"client "<join(); delete acceptThread; for(ClientHandler& client : clients) client.cleanUp(); servSock->cleanUp(); delete servSock; return 0; }