SerialPortMultiplexer/clienthandler.h
2024-08-08 21:10:29 +02:00

136 lines
2.6 KiB
C++

#pragma once
#include <vector>
#include <array>
#include <algorithm>
#include <iostream>
#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<ClientHandler>* 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<char, 4096> buffer;
while(_socket->recv(buffer.data(), 4096) > 0);
}
bool ClientHandler::run(std::vector<ClientHandler>* clients, int serial, bool verbose)
{
std::array<char, 4096> buffer;
int reclen = 0;
try
{
reclen = _socket->recv(buffer.data(), 4096);
if(verbose)
std::cout<<"Recived "<<reclen<<" bytes\n";
}
catch (SocketException &e)
{
std::cout<<e.what()<<std::endl;
_disconnected = true;
}
if(reclen > 0)
{
if(!_isBroadcasting && reclen >= 5 && strncmp( buffer.data(), "bcst:", 5) == 0)
_isBroadcasting = true;
if(_isBroadcasting)
{
if(verbose)
std::cout<<"Boradcasting "<<reclen<<" bytes\n";
for(ClientHandler& item : *clients)
if(operator!=(item))
item.write(buffer.data(), reclen);
char* newline = std::find(buffer.begin(), buffer.end(), '\n');
if(newline != std::end(buffer))
_isBroadcasting = false;
}
else
{
if(verbose)
std::cout<<"wrote "<<reclen<<" bytes to serial\n";
if(sWrite(serial, buffer.data(), reclen) < 0 && (errno != EAGAIN || errno != EWOULDBLOCK))
{
throw serialIoException(serial, errno);
}
}
}
else if(reclen == 0)
_disconnected = true;
return !_disconnected;
}
bool ClientHandler::isDisconnected()
{
return _disconnected;
}
void ClientHandler::write(const char* buffer, const size_t len)
{
try
{
_socket->send(buffer, len);
}
catch (SocketException &e)
{
std::cout<<e.what()<<std::endl;
_disconnected = true;
}
}
bool ClientHandler::operator==(int fd)
{
return fd == _socket->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));
}