diff --git a/main.cpp b/main.cpp index ac0f5f1..08c7946 100644 --- a/main.cpp +++ b/main.cpp @@ -8,218 +8,274 @@ #include #include #include +#include #include "serial_io.h" #include "Socket.h" #define VERSION "v0.4" -bool stop = false; +volatile bool stop = false; +volatile bool resettSerialPort = false; -void intHandler(int dummy) +void intHandler(int sig) { - stop = true; + stop = true; +} + +void alarmHandler(int sig) +{ + resettSerialPort = true; + signal(sig, alarmHandler); + alarm(600); } 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\ - -s, --sinkless run without serial port\n"; + 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; + 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; - } - } - return 0; + 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* clientSockets ) { - while(!stop) - { - TCPSocket* newSock = servSock->accept(); - if(newSock != nullptr) - { - clientSockets->push_back(newSock); // Wait for a client to connect - clientSockets->back()->send("UVOS serial multiplexer " VERSION "\n", sizeof("UVOS serial multiplexer " VERSION "\n")-1); - std::cout<<"got client\n"; - } - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - } + while(!stop) + { + TCPSocket* newSock = servSock->accept(); + if(newSock != nullptr) + { + clientSockets->push_back(newSock); // Wait for a client to connect + clientSockets->back()->send("UVOS serial multiplexer " VERSION "\n", sizeof("UVOS serial multiplexer " VERSION "\n")-1); + std::cout<<"got client\n"; + } + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } +} + +int openSerialPort(const Config& config) +{ + int serial = -1; + if(!config.noSerial) + { + std::cout<<"Opeing serial port: "< clientSockets; - - std::thread* acceptThread; - TCPServerSocket* servSock; - - std::cout<<"opening TCP socket on port "<setBlocking(false); - acceptThread = new std::thread(acceptThreadFunction, servSock, &clientSockets); - } - catch(SocketException &e) - { - std::cerr<<"Could not open port"< 0) - { + } + else std::cout<<"Sinkless mode\n"; + + std::vector clientSockets; + + std::thread* acceptThread; + TCPServerSocket* servSock; + + std::cout<<"opening TCP socket on port "<setBlocking(false); + acceptThread = new std::thread(acceptThreadFunction, servSock, &clientSockets); + } + catch(SocketException &e) + { + std::cerr<<"Could not open port"< 0) + { if(config.verbose) { std::cout<<"bcst: "; for( int j = 0; j < readlen; j++ )std::cout<send(buffer, readlen); - } - - char inBuffer[4096]; - int reclen = clientSockets[i]->recv(inBuffer, 4096); - if( reclen > 0 ) - { - if(config.verbose) + clientSockets[i]->send(buffer, readlen); + } + + char inBuffer[4096]; + int reclen = clientSockets[i]->recv(inBuffer, 4096); + if( reclen > 0 ) + { + if(config.verbose) { std::cout<<"rec: "; for( int j = 0; j < reclen; j++ )std::cout<send(inBuffer+6, reclen-6); - - } - else - { + for(unsigned int j = 0; j < clientSockets.size(); j++) if(i != j) clientSockets[j]->send(inBuffer+6, reclen-6); + + } + 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; - } - } - catch(SocketException &e) - { - std::cout<cleanUp(); - clientSockets.erase(clientSockets.begin()+i); - i--; - if(i < 0) i=0; - } - } - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - acceptThread->join(); - delete acceptThread; - for(unsigned int i = 0; i < clientSockets.size(); i++) clientSockets[i]->cleanUp(); - servSock->cleanUp(); - delete servSock; - return 0; + sWrite(serial, inBuffer, reclen); + } + if(config.verbose) std::cout<cleanUp(); + clientSockets.erase(clientSockets.begin()+i); + i--; + if(i < 0) i=0; + } + } + catch(SocketException &e) + { + std::cout<cleanUp(); + clientSockets.erase(clientSockets.begin()+i); + i--; + if(i < 0) i=0; + } + } + if(resettSerialPort) + { + close(serial); + serial = openSerialPort(config); + resettSerialPort = false; + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + + acceptThread->join(); + delete acceptThread; + for(unsigned int i = 0; i < clientSockets.size(); i++) clientSockets[i]->cleanUp(); + servSock->cleanUp(); + delete servSock; + return 0; } diff --git a/serial_io.cpp b/serial_io.cpp index a1e59af..89effa0 100644 --- a/serial_io.cpp +++ b/serial_io.cpp @@ -3,7 +3,6 @@ void sWrite(int port, char string[], size_t length) { if(port != -1) write(port, string, length); - } void sWrite(int port, const char string[], size_t length) @@ -42,18 +41,10 @@ std::cout<<"Rates:\n"\ } #endif -int serialport_init(const char* device, int baud) +int serialport_set_config(int fd, int baud) { - int fd; - struct termios toptions; - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); - if (fd == -1) - { - perror("init_serialport: Unable to open port "); - return -1; - } - - if (tcgetattr(fd, &toptions) < 0) + struct termios toptions; + if (tcgetattr(fd, &toptions) < 0) { perror("init_serialport: Couldn't get term attributes"); return -1; @@ -93,6 +84,24 @@ int serialport_init(const char* device, int baud) perror("init_serialport: Couldn't set term attributes"); return -1; } + return 0; +} + +int serialport_init(const char* device, int baud, bool block = false) +{ + int fd; + fd = open(device, O_RDWR | O_NOCTTY | (block ? 0 : O_NONBLOCK)); + if (fd == -1) + { + perror("init_serialport: Unable to open port "); + return -1; + } + + if(serialport_set_config(fd, baud) != 0) + { + close(fd); + fd = -1; + } return fd; } diff --git a/serial_io.h b/serial_io.h index c41ef28..1daa375 100644 --- a/serial_io.h +++ b/serial_io.h @@ -20,6 +20,8 @@ ssize_t sRead(int port, void *buf, size_t count); void printRates(); #endif +int serialport_set_config(int fd, int baud); + int serialport_init(const char* device, int baud = BAUDRATE);