Skip to content

Commit

Permalink
Update server implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
janekbaraniewski committed Apr 29, 2024
1 parent 47f1565 commit 244da03
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 53 deletions.
19 changes: 18 additions & 1 deletion include/RealSerialPort.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "ISerialPort.h"
#include <boost/asio.hpp>
#include <boost/log/trivial.hpp>

using boost::asio::serial_port_base;

Expand All @@ -11,7 +12,15 @@ class RealSerialPort : public ISerialPort {
explicit RealSerialPort(boost::asio::io_service& io) : port(io) {}

void open(const std::string& device, serial_port_base::baud_rate baudRate) override {
port.open(device);
try {
port.open(device);
setSerialOptions(baudRate);
} catch (const boost::system::system_error& e) {
BOOST_LOG_TRIVIAL(error) << "Failed to open serial port: " << e.what();
}
}

void setSerialOptions(serial_port_base::baud_rate baudRate) {
port.set_option(baudRate);
port.set_option(serial_port_base::character_size(8));
port.set_option(serial_port_base::parity(serial_port_base::parity::none));
Expand All @@ -20,10 +29,18 @@ class RealSerialPort : public ISerialPort {
}

void async_read_some(const boost::asio::mutable_buffer& buffer, std::function<void(const boost::system::error_code&, std::size_t)> handler) override {
if (!port.is_open()) {
BOOST_LOG_TRIVIAL(error) << "Attempt to read from a closed serial port.";
return;
}
port.async_read_some(buffer, handler);
}

void async_write(const boost::asio::const_buffer& buffer, std::function<void(const boost::system::error_code&, std::size_t)> handler) override {
if (!port.is_open()) {
BOOST_LOG_TRIVIAL(error) << "Attempt to write to a closed serial port.";
return;
}
boost::asio::async_write(port, buffer, handler);
}

Expand Down
36 changes: 18 additions & 18 deletions include/SerialServer.h
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
#ifndef SERVER_H
#define SERVER_H
#ifndef SERIALSERVER_H
#define SERIALSERVER_H

#include "common.hpp"
#include "ISerialPort.h"
#include "RealSerialPort.h"

using namespace boost::asio;
using ip::tcp;
using std::string;
#include <boost/asio.hpp>
#include <array>

class SerialServer {
public:
SerialServer(boost::asio::io_service& io_service, const std::string& device, unsigned int baud_rate);

void run();

private:
void start_accept();
void handle_session();
void async_read_socket();
void async_read_serial();

boost::asio::io_service& io_service_;
ISerialPort& serial_;
boost::asio::ip::tcp::acceptor& acceptor_;
boost::asio::ip::tcp::acceptor acceptor_;
boost::asio::ip::tcp::socket socket_;
std::array<char, 1024> buf; // Buffer for data

void start_accept();
void do_read_write();
public:
SerialServer(boost::asio::io_service& io, ISerialPort& serial, boost::asio::ip::tcp::acceptor& acceptor);
void run();
RealSerialPort serial_port_;
std::array<char, 1024> buffer_;
};

#endif // SERVER_H
#endif // SERIALSERVER_H
69 changes: 40 additions & 29 deletions src/SerialServer.cpp
Original file line number Diff line number Diff line change
@@ -1,52 +1,63 @@
#include "SerialServer.h"
#include <boost/log/trivial.hpp>

using namespace boost::asio;
using namespace boost::program_options;
using ip::tcp;
using std::string;
using std::endl;

SerialServer::SerialServer(io_service& io, ISerialPort& serial, tcp::acceptor& acceptor)
: io_service_(io), serial_(serial), acceptor_(acceptor), socket_(io) {
BOOST_LOG_TRIVIAL(info) << "Starting server and waiting for connection...";
start_accept();
}
SerialServer::SerialServer(boost::asio::io_service& io_service, const std::string& device, unsigned int baud_rate)
: io_service_(io_service),
acceptor_(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 3333)),
socket_(io_service),
serial_port_(io_service) {
serial_port_.open(device, boost::asio::serial_port_base::baud_rate(baud_rate));
}

void SerialServer::run() {
BOOST_LOG_TRIVIAL(info) << "Server is running.";
start_accept();
io_service_.run();
BOOST_LOG_TRIVIAL(info) << "Server stopped.";
}

void SerialServer::start_accept() {
acceptor_.async_accept(socket_, [this](boost::system::error_code ec) {
if (!ec) {
BOOST_LOG_TRIVIAL(info) << "Client connected. Starting to handle read/write operations.";
do_read_write();
} else {
BOOST_LOG_TRIVIAL(error) << "Error accepting connection: " << ec.message();
start_accept();
handle_session();
}
start_accept();
});
}

void SerialServer::do_read_write() {
// Asynchronous read from serial port
serial_.async_read_some(boost::asio::buffer(buf), [this](boost::system::error_code ec, std::size_t length) {
if (!ec && length > 0) {
// Data is available
async_write(socket_, boost::asio::buffer(buf, length), [this](boost::system::error_code ec, std::size_t) {
void SerialServer::handle_session() {
async_read_socket();
async_read_serial();
}

void SerialServer::async_read_socket() {
socket_.async_read_some(boost::asio::buffer(buffer_), [this](boost::system::error_code ec, std::size_t length) {
if (!ec) {
serial_port_.async_write(boost::asio::buffer(buffer_, length), [this](boost::system::error_code ec, std::size_t) {
if (!ec) {
BOOST_LOG_TRIVIAL(info) << "Data successfully written to client.";
async_read_socket();
} else {
BOOST_LOG_TRIVIAL(error) << "Error writing to client: " << ec.message();
}
});
} else if (!ec) {
BOOST_LOG_TRIVIAL(info) << "No data received from serial. Waiting...";
} else {
BOOST_LOG_TRIVIAL(error) << "Error reading from serial port: " << ec.message();
BOOST_LOG_TRIVIAL(error) << "Read error on socket: " << ec.message();
socket_.close();
}
});
}

void SerialServer::async_read_serial() {
serial_port_.async_read_some(boost::asio::buffer(buffer_), [this](boost::system::error_code ec, std::size_t length) {
if (!ec) {
boost::asio::async_write(socket_, boost::asio::buffer(buffer_, length), [this](boost::system::error_code ec, std::size_t) {
if (!ec) {
async_read_serial();
} else {
BOOST_LOG_TRIVIAL(error) << "Error sending to socket: " << ec.message();
}
});
} else {
BOOST_LOG_TRIVIAL(error) << "Read error on serial port: " << ec.message();
socket_.close();
}
do_read_write(); // Continue the loop
});
}
7 changes: 2 additions & 5 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@ using std::cerr;
using std::endl;

void setup_and_run_server(io_service& io, const variables_map& vm) {
tcp::acceptor acceptor(io, tcp::endpoint(tcp::v4(), vm["port"].as<unsigned short>()));
RealSerialPort realSerial(io);
realSerial.open(vm["device"].as<string>(), boost::asio::serial_port_base::baud_rate(vm["baud"].as<unsigned int>()));

SerialServer server(io, realSerial, acceptor);
unsigned int baud_rate = vm["baud"].as<unsigned int>(); // Get baud rate as unsigned int
SerialServer server(io, vm["device"].as<string>(), baud_rate);
server.run();
}

Expand Down

0 comments on commit 244da03

Please sign in to comment.