diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 02917e2..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -cmake_minimum_required(VERSION 3.0) -project(serialmultiplexer) - -set(SRC_FILES main.cpp serial_io.cpp Socket.cpp ) -set(LIBS -pthread ) - -add_executable(${PROJECT_NAME} ${SRC_FILES}) - -target_link_libraries( ${PROJECT_NAME} ${LIBS}) -add_definitions(" -std=c++11 -Wall -O2 -g") - -install(TARGETS serialmultiplexer RUNTIME DESTINATION bin) diff --git a/clienthandler.cpp b/clienthandler.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/clienthandler.h b/clienthandler.h deleted file mode 100644 index e8eedbb..0000000 --- a/clienthandler.h +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "Socket.h" -#include "serial_io.h" - -class ClientHandler -{ -private: - bool _isBroadcasting = false; - CommunicatingSocket *_socket; - bool _disconnected = false; - - -public: - - void cleanUp(); - ClientHandler(CommunicatingSocket * const socket); - ~ClientHandler(); - bool operator==(int fd); - bool operator!=(int fd); - bool operator==(ClientHandler& other); - bool operator!=(ClientHandler& other); - bool isDisconnected(); - bool run(std::vector* clients, int serial, bool verbose = false); - void write(const char* buffer, const size_t len); - void dropData(); -}; - -ClientHandler::ClientHandler(CommunicatingSocket * const socket): _socket(socket) -{} - -ClientHandler::~ClientHandler() -{ -} - -void ClientHandler::cleanUp() -{ - _socket->cleanUp(); - delete _socket; -} - -void ClientHandler::dropData() -{ - std::array buffer; - while(_socket->recv(buffer.data(), 4096) > 0); -} - -bool ClientHandler::run(std::vector* clients, int serial, bool verbose) -{ - std::array buffer; - int reclen = 0; - try - { - reclen = _socket->recv(buffer.data(), 4096); - if(verbose) std::cout<<"Recived "< 0) - { - if(!_isBroadcasting && reclen >= 5 && strncmp( buffer.data(), "bcst:", 5) == 0) _isBroadcasting = true; - - if(_isBroadcasting) - { - if(verbose) std::cout<<"Boradcasting "<send(buffer, len); - } - catch (SocketException &e) - { - std::cout<getFD(); -} - - -bool ClientHandler::operator!=(int fd) -{ - return fd != _socket->getFD(); -} - -bool ClientHandler::operator==(ClientHandler& other) -{ - return _socket->getFD() == other._socket->getFD(); -} - - -bool ClientHandler::operator!=(ClientHandler& other) -{ - return !(operator==(other)); -} diff --git a/main.cpp b/main.cpp index 6a5fe2f..de71444 100644 --- a/main.cpp +++ b/main.cpp @@ -14,17 +14,25 @@ #include "serial_io.h" #include "Socket.h" -#include "clienthandler.h" -#define VERSION "v0.7" +#define VERSION "v0.5" -sig_atomic_t stop = false; +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\ @@ -77,6 +85,7 @@ static int parseCmdArgs(int argc, char** argv, Config *config) { config->noSerial=true; } + else if (std::string(argv[i]) == "-r" || std::string(argv[i]) == "--rates") { printRates(); @@ -94,22 +103,18 @@ static int parseCmdArgs(int argc, char** argv, Config *config) return 0; } -void acceptThreadFunction( TCPServerSocket* servSock, std::vector* clients, std::mutex* clientsMutex, int pollQue ) +void acceptThreadFunction( TCPServerSocket* servSock, std::vector* clientSockets, std::mutex* clientSocketsMutex, 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 = newSock->getFD(); - clientsMutex->unlock(); + clientSocketsMutex->lock(); + clientSockets->push_back(newSock); // Wait for a client to connect + clientSocketsMutex->unlock(); epoll_ctl(pollQue, EPOLL_CTL_ADD, newSock->getFD(), &ev); - char welcomeMesg[] = "UVOS serial multiplexer " VERSION "\n"; - clients->back().write(welcomeMesg, sizeof(welcomeMesg)-1); + 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::seconds(1)); @@ -124,73 +129,44 @@ int openSerialPort(const Config& config) std::cout<<"Opeing serial port: "< clients; - + ev.events = EPOLLIN; + int serial = openSerialPort(config); if(!config.noSerial) { - if(serial == -1) - return 1; + std::cout<<"Using serial port: "< clientSockets; std::thread* acceptThread; TCPServerSocket* servSock; @@ -198,9 +174,9 @@ int main(int argc, char* argv[]) std::cout<<"opening TCP socket on port "<setBlocking(false); - acceptThread = new std::thread(acceptThreadFunction, servSock, &clients, &clientsMutex, pollQue); + acceptThread = new std::thread(acceptThreadFunction, servSock, &clientSockets, &clientSocketsMutex, pollQue); } catch(SocketException &e) { @@ -208,80 +184,114 @@ int main(int argc, char* argv[]) return 1; } + char buffer[4096]; + signal(SIGINT, intHandler); signal(SIGTERM, intHandler); - signal(SIGPIPE, SIG_IGN); + signal(SIGALRM, alarmHandler); + + if(config.reinit) alarm(600); + std::cout<<"starting loop\n"; while(!stop) { - struct epoll_event ev; - if(epoll_wait(pollQue, &ev, 1, 2000) == 1) + epoll_wait(pollQue, &ev, 1, 2000); + int readlen = sRead(serial, buffer, 4096); + for(unsigned int i = 0; i < clientSockets.size(); i++) { - if(ev.data.fd != -1) + clientSocketsMutex.lock(); + try { - std::vector::iterator client = - std::find(clients.begin(), clients.end(), ev.data.fd); - if(client == clients.end()) - continue; - clientsMutex.lock(); - std::cout<<"client poll\n"; - if(ev.events & EPOLLIN) + if(readlen > 0) { - try + if(config.verbose) { - client->run(&clients, serial, 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) { - close(serial); - serialPortReconnect(config, ex.what()); + std::cout<<"rec: "; + for( int j = 0; j < reclen; j++ )std::cout<isDisconnected()) - { - client->cleanUp(); - clients.erase(client); - std::cout<<"client disconnected\n"; - } - clientsMutex.unlock(); - } - else - { - char buffer[4096]; - ssize_t readlen = sRead(serial, buffer, 4096); - if(readlen < 0 && (errno != EAGAIN || errno != EWOULDBLOCK)) - { - close(serial); - serialPortReconnect(config, strerror(errno)); - } - if(config.verbose) - { - std::cout<<"Sending \""; - for(ssize_t i = 0; i < readlen; ++i) + if(strncmp( inBuffer, "bcst:", 5) == 0) { - if(buffer[i] == '\n') - std::cout<<"\\n"; + if(config.verbose) + { + std::cout<<"bcst: "; + for( int j = 6; j < reclen; j++ )std::cout<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 - std::cout<send(response, sizeof(response)); + } } - std::cout<<"\" to clients from serial\n"; + 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; } - clientsMutex.unlock(); } + 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(ClientHandler& client : clients) - client.cleanUp(); + 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 317fb3c..34e57a6 100644 --- a/serial_io.cpp +++ b/serial_io.cpp @@ -1,15 +1,13 @@ #include "serial_io.h" -ssize_t sWrite(int port, char string[], size_t length) +void sWrite(int port, char string[], size_t length) { - if(port != -1) return write(port, string, length); - else return 0; + if(port != -1) write(port, string, length); } -ssize_t sWrite(int port, const char string[], size_t length) +void sWrite(int port, const char string[], size_t length) { - if(port != -1) return write(port, string, length); - else return 0; + if(port != -1) write(port, string, length); } ssize_t sRead(int port, void *buf, size_t count) diff --git a/serial_io.h b/serial_io.h index 0e78d0f..844e74e 100644 --- a/serial_io.h +++ b/serial_io.h @@ -6,15 +6,13 @@ #ifdef __cplusplus #include -#include -#include #endif #define BAUDRATE B38400 -ssize_t sWrite(int port, char string[], size_t length); +void sWrite(int port, char string[], size_t length); -ssize_t sWrite(int port, const char string[], size_t length); +void sWrite(int port, const char string[], size_t length); ssize_t sRead(int port, void *buf, size_t count); @@ -26,17 +24,5 @@ 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_) + " error: " + strerror(errorNumber_) + "\n"), fd(fd_), errorNumber(errorNumber_) - {} -}; -#endif - #endif // SERIAL_H