diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c8e3e7..fad427c 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 -O2") +add_definitions(" -std=c++11 -Wall -O2 -g") install(TARGETS serialmultiplexer RUNTIME DESTINATION bin) diff --git a/main.cpp b/main.cpp index bb63c82..d72bc84 100644 --- a/main.cpp +++ b/main.cpp @@ -18,8 +18,7 @@ #define VERSION "v0.7" -volatile bool stop = false; -volatile bool resettSerialPort = false; +sig_atomic_t stop = false; void intHandler(int sig) { @@ -136,21 +135,32 @@ int openSerialPort(const Config& config) return serial; } +void serialConnect(const Config& config, int* serial) +{ + if(*serial != -1) + close(*serial); + std::cout<<"Using serial port: "< clients; + int serial = openSerialPort(config); if(!config.noSerial) { - std::cout<<"Using serial port: "< clients; + else + { + std::cout<<"Sinkless mode\n"; + } std::thread* acceptThread; TCPServerSocket* servSock; @@ -172,7 +182,7 @@ int main(int argc, char* argv[]) std::cout<<"opening TCP socket on port "<setBlocking(false); acceptThread = new std::thread(acceptThreadFunction, servSock, &clients, &clientsMutex, pollQue); } @@ -184,21 +194,27 @@ int main(int argc, char* argv[]) signal(SIGINT, intHandler); signal(SIGTERM, intHandler); - signal(SIGPIPE, SIG_IGN); //ignore SIGPIPE + signal(SIGPIPE, SIG_IGN); std::cout<<"starting loop\n"; while(!stop) { struct epoll_event ev; - if( epoll_wait(pollQue, &ev, 1, 2000) == 1) + if(epoll_wait(pollQue, &ev, 1, 2000) == 1) { if(ev.data.fd != -1) { - int i = ev.data.fd; - std::cout<<"client poll\n"; clientsMutex.lock(); - if(ev.events & EPOLLIN) clients[i].run(&clients, serial, config.verbose); + int i = ev.data.fd; + if(abs(i) >= 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(); @@ -210,24 +226,38 @@ int main(int argc, char* argv[]) else { char buffer[4096]; - int readlen = sRead(serial, buffer, 4096); + ssize_t readlen = sRead(serial, buffer, 4096); + if(readlen < 0 && (errno != EAGAIN || errno != EWOULDBLOCK)) + { + std::cout<<"Serial port error reconnecting\n"; + serialConnect(config, &serial); + } if(config.verbose) { std::cout<<"Sending \""; - for(size_t i = 0; i < readlen; ++i) std::cout<join(); delete acceptThread; - for(ClientHandler& client : clients) client.cleanUp(); + for(ClientHandler& client : clients) + client.cleanUp(); servSock->cleanUp(); delete servSock; return 0; diff --git a/serial_io.cpp b/serial_io.cpp index 34e57a6..317fb3c 100644 --- a/serial_io.cpp +++ b/serial_io.cpp @@ -1,13 +1,15 @@ #include "serial_io.h" -void sWrite(int port, char string[], size_t length) +ssize_t sWrite(int port, char string[], size_t length) { - if(port != -1) write(port, string, length); + if(port != -1) return write(port, string, length); + else return 0; } -void sWrite(int port, const char string[], size_t length) +ssize_t sWrite(int port, const char string[], size_t length) { - if(port != -1) write(port, string, length); + if(port != -1) return write(port, string, length); + else return 0; } ssize_t sRead(int port, void *buf, size_t count) diff --git a/serial_io.h b/serial_io.h index 844e74e..f0c99b3 100644 --- a/serial_io.h +++ b/serial_io.h @@ -6,13 +6,14 @@ #ifdef __cplusplus #include +#include #endif #define BAUDRATE B38400 -void sWrite(int port, char string[], size_t length); +ssize_t sWrite(int port, char string[], size_t length); -void sWrite(int port, const char string[], size_t length); +ssize_t sWrite(int port, const char string[], size_t length); ssize_t sRead(int port, void *buf, size_t count); @@ -24,5 +25,17 @@ int serialport_set_config(int fd, int baud); int serialport_init(const char* device, int baud = BAUDRATE, bool block = false); +#ifdef __cplusplus +class serialIoException: public std::runtime_error +{ + public: + int fd; + int errorNumber; + serialIoException(int fd_, int errorNumber_): + std::runtime_error("file descriptor error, fd: " + std::to_string(fd_) + " errno: " + std::to_string(errorNumber_) + "\n"), fd(fd_), errorNumber(errorNumber_) + {} +}; +#endif + #endif // SERIAL_H