Skip to content

Commit a128551

Browse files
Merge pull request #6 from janekbaraniewski/basic-functionality-testing
Basic functionality testing
2 parents 92b71ea + e39ff94 commit a128551

File tree

9 files changed

+192
-104
lines changed

9 files changed

+192
-104
lines changed

include/ISerialPort.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ using std::string;
99

1010
class ISerialPort {
1111
public:
12-
virtual void open(const string& device) = 0;
13-
virtual void set_option(const serial_port_base::baud_rate& option) = 0;
12+
virtual void open(const string& device, boost::asio::serial_port_base::baud_rate baudRate) = 0;
13+
// virtual void set_option(const serial_port_base::baud_rate& option) = 0;
1414
virtual void async_read_some(const boost::asio::mutable_buffer& buffer, std::function<void(const boost::system::error_code&, std::size_t)> handler) = 0;
1515
virtual void async_write(const boost::asio::const_buffer& buffer, std::function<void(const boost::system::error_code&, std::size_t)> handler) = 0;
1616
virtual ~ISerialPort() = default;

include/RealSerialPort.h

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,48 @@
33

44
#include "ISerialPort.h"
55
#include <boost/asio.hpp>
6+
#include <boost/log/trivial.hpp>
7+
8+
using boost::asio::serial_port_base;
69

710
class RealSerialPort : public ISerialPort {
811
public:
9-
explicit RealSerialPort(io_service& io) : port(io) {}
10-
11-
void open(const string& device) override {
12-
port.open(device);
12+
explicit RealSerialPort(boost::asio::io_service& io) : port(io) {}
13+
14+
void open(const std::string& device, serial_port_base::baud_rate baudRate) override {
15+
BOOST_LOG_TRIVIAL(info) << "Setting up connection to serial port " << device;
16+
try {
17+
port.open(device);
18+
setSerialOptions(baudRate);
19+
} catch (const boost::system::system_error& e) {
20+
BOOST_LOG_TRIVIAL(error) << "Failed to open serial port: " << e.what();
21+
}
1322
}
1423

15-
void set_option(const serial_port_base::baud_rate& option) override {
16-
port.set_option(option);
24+
void setSerialOptions(serial_port_base::baud_rate baudRate) {
25+
BOOST_LOG_TRIVIAL(info) << "Setting connection options.";
26+
port.set_option(baudRate);
27+
port.set_option(serial_port_base::character_size(8));
28+
port.set_option(serial_port_base::parity(serial_port_base::parity::none));
29+
port.set_option(serial_port_base::stop_bits(serial_port_base::stop_bits::one));
30+
port.set_option(serial_port_base::flow_control(serial_port_base::flow_control::none));
1731
}
1832

1933
void async_read_some(const boost::asio::mutable_buffer& buffer, std::function<void(const boost::system::error_code&, std::size_t)> handler) override {
34+
BOOST_LOG_TRIVIAL(info) << "Read some.";
35+
if (!port.is_open()) {
36+
BOOST_LOG_TRIVIAL(error) << "Attempt to read from a closed serial port.";
37+
return;
38+
}
2039
port.async_read_some(buffer, handler);
2140
}
2241

2342
void async_write(const boost::asio::const_buffer& buffer, std::function<void(const boost::system::error_code&, std::size_t)> handler) override {
43+
BOOST_LOG_TRIVIAL(info) << "write some some.";
44+
if (!port.is_open()) {
45+
BOOST_LOG_TRIVIAL(error) << "Attempt to write to a closed serial port.";
46+
return;
47+
}
2448
boost::asio::async_write(port, buffer, handler);
2549
}
2650

include/SerialClient.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ class SerialClient {
1818
public:
1919
SerialClient(boost::asio::io_service& io_service, const std::string& server_ip, unsigned short server_port, const std::string& vsp_name);
2020
void run();
21-
void do_read_write();
21+
void do_read_vsp();
22+
void do_read_socket();
2223
};
2324

2425
#endif // CLIENT_H

include/SerialServer.h

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
#ifndef SERVER_H
2-
#define SERVER_H
1+
#ifndef SERIALSERVER_H
2+
#define SERIALSERVER_H
33

4-
#include "common.hpp"
5-
#include "ISerialPort.h"
64
#include "RealSerialPort.h"
7-
8-
using namespace boost::asio;
9-
using ip::tcp;
10-
using std::string;
5+
#include <boost/asio.hpp>
6+
#include <array>
117

128
class SerialServer {
139
public:
14-
SerialServer(io_service& io, ISerialPort& serial, tcp::acceptor& acceptor);
10+
SerialServer(boost::asio::io_service& io_service, const std::string& device, unsigned int baud_rate);
11+
1512
void run();
1613

1714
private:
18-
io_service& io_service_;
19-
ISerialPort& serial_;
20-
tcp::acceptor& acceptor_;
21-
tcp::socket socket_;
22-
2315
void start_accept();
24-
void do_read_write();
16+
void handle_session();
17+
void async_read_socket();
18+
void async_read_serial();
19+
20+
boost::asio::io_service& io_service_;
21+
boost::asio::ip::tcp::acceptor acceptor_;
22+
boost::asio::ip::tcp::socket socket_;
23+
RealSerialPort serial_port_;
24+
std::array<char, 1024> buffer_;
2525
};
2626

27-
#endif // SERVER_H
27+
#endif // SERIALSERVER_H

include/VirtualSerialPort.h

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,22 @@
11
#ifndef VIRTUALSERIALPORT_H
22
#define VIRTUALSERIALPORT_H
33

4-
#include <string>
5-
#include <functional>
6-
#include <fcntl.h>
7-
#include <unistd.h>
8-
#include <termios.h>
9-
#include <stdexcept>
10-
#include <iostream>
11-
#include <sys/stat.h>
4+
#include "common.hpp"
5+
#include <grp.h>
126

137
class VirtualSerialPort {
148
public:
15-
VirtualSerialPort(const std::string& device);
9+
VirtualSerialPort(boost::asio::io_context& io_context, const std::string& device);
1610
~VirtualSerialPort();
1711

12+
void async_read(boost::asio::mutable_buffer buffer, std::function<void(const boost::system::error_code&, std::size_t)> handler);
13+
void async_write(boost::asio::const_buffer buffer, std::function<void(const boost::system::error_code&, std::size_t)> handler);
1814
void close();
19-
bool write(const std::string& data);
20-
std::string read();
2115

2216
private:
23-
int master_fd_;
24-
int slave_fd_;
17+
boost::asio::posix::stream_descriptor master_fd_;
2518
std::string device_name_;
19+
void setup_pty(int fd);
2620
};
2721

2822
#endif // VIRTUALSERIALPORT_H

src/SerialClient.cpp

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ using std::cerr;
99
using std::endl;
1010

1111
SerialClient::SerialClient(boost::asio::io_service& io_service, const std::string& server_ip, unsigned short server_port, const std::string& vsp_name)
12-
: io_service_(io_service), socket_(io_service), vsp_(vsp_name) {
12+
: io_service_(io_service), socket_(io_service), vsp_(io_service, vsp_name) {
1313
BOOST_LOG_TRIVIAL(info) << "Initializing client...";
1414
boost::asio::ip::tcp::resolver resolver(io_service);
1515
auto endpoint_iterator = resolver.resolve({server_ip, std::to_string(server_port)});
@@ -21,23 +21,49 @@ SerialClient::SerialClient(boost::asio::io_service& io_service, const std::strin
2121

2222
void SerialClient::run() {
2323
BOOST_LOG_TRIVIAL(info) << "Starting client I/O operations.";
24-
do_read_write();
24+
do_read_socket();
25+
do_read_vsp();
2526
io_service_.run();
2627
}
2728

28-
void SerialClient::do_read_write() {
29+
void SerialClient::do_read_socket() {
2930
socket_.async_read_some(boost::asio::buffer(buffer_), [this](boost::system::error_code ec, std::size_t length) {
30-
if (!ec) {
31-
std::string data(buffer_.begin(), buffer_.begin() + length);
32-
BOOST_LOG_TRIVIAL(info) << "Received data: " << data;
33-
if (vsp_.write(data)) {
34-
BOOST_LOG_TRIVIAL(info) << "Data written to virtual serial port.";
35-
} else {
36-
BOOST_LOG_TRIVIAL(error) << "Failed to write to virtual serial port.";
37-
}
38-
do_read_write();
39-
} else {
40-
BOOST_LOG_TRIVIAL(error) << "Read error: " << ec.message();
31+
if (!ec && length > 0) {
32+
std::string data(buffer_.data(), length);
33+
std::fill(std::begin(buffer_), std::end(buffer_), 0);
34+
35+
BOOST_LOG_TRIVIAL(debug) << "Received from server: " << data;
36+
37+
vsp_.async_write(boost::asio::buffer(data), [this](boost::system::error_code ec, std::size_t) {
38+
if (!ec) {
39+
do_read_socket();
40+
} else {
41+
BOOST_LOG_TRIVIAL(error) << "Write to VSP failed: " << ec.message();
42+
}
43+
});
44+
} else if (ec) {
45+
BOOST_LOG_TRIVIAL(error) << "Read error on socket: " << ec.message();
46+
}
47+
});
48+
}
49+
50+
void SerialClient::do_read_vsp() {
51+
vsp_.async_read(boost::asio::buffer(buffer_), [this](boost::system::error_code ec, std::size_t length) {
52+
if (!ec && length > 0) {
53+
std::string data(buffer_.data(), length);
54+
std::fill(std::begin(buffer_), std::end(buffer_), 0);
55+
56+
BOOST_LOG_TRIVIAL(debug) << "Received from VSP: " << data;
57+
58+
async_write(socket_, boost::asio::buffer(data), [this](boost::system::error_code ec, std::size_t) {
59+
if (!ec) {
60+
do_read_vsp();
61+
} else {
62+
BOOST_LOG_TRIVIAL(error) << "Write to socket failed: " << ec.message();
63+
}
64+
});
65+
} else if (ec) {
66+
BOOST_LOG_TRIVIAL(error) << "Read error on VSP: " << ec.message();
4167
}
4268
});
4369
}

src/SerialServer.cpp

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,74 @@
11
#include "SerialServer.h"
2+
#include <boost/log/trivial.hpp>
23

3-
using namespace boost::asio;
4-
using namespace boost::program_options;
5-
using ip::tcp;
6-
using std::string;
7-
using std::endl;
8-
9-
SerialServer::SerialServer(io_service& io, ISerialPort& serial, tcp::acceptor& acceptor)
10-
: io_service_(io), serial_(serial), acceptor_(acceptor), socket_(io) {
11-
BOOST_LOG_TRIVIAL(info) << "Starting server and waiting for connection...";
12-
start_accept();
13-
}
4+
SerialServer::SerialServer(boost::asio::io_service& io_service, const std::string& device, unsigned int baud_rate)
5+
: io_service_(io_service),
6+
acceptor_(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 3333)),
7+
socket_(io_service),
8+
serial_port_(io_service) {
9+
serial_port_.open(device, boost::asio::serial_port_base::baud_rate(baud_rate));
10+
}
1411

1512
void SerialServer::run() {
16-
BOOST_LOG_TRIVIAL(info) << "Server is running.";
13+
BOOST_LOG_TRIVIAL(info) << "SerialServer::run";
14+
start_accept();
15+
BOOST_LOG_TRIVIAL(info) << "ioservice::run";
1716
io_service_.run();
18-
BOOST_LOG_TRIVIAL(info) << "Server stopped.";
1917
}
2018

2119
void SerialServer::start_accept() {
20+
BOOST_LOG_TRIVIAL(info) << "SerialServer::start_accept";
21+
2222
acceptor_.async_accept(socket_, [this](boost::system::error_code ec) {
23+
BOOST_LOG_TRIVIAL(info) << "SerialServer::acceptor::async_accept";
2324
if (!ec) {
24-
BOOST_LOG_TRIVIAL(info) << "Client connected. Starting to handle read/write operations.";
25-
do_read_write();
26-
} else {
27-
BOOST_LOG_TRIVIAL(error) << "Error accepting connection: " << ec.message();
25+
handle_session();
2826
}
27+
start_accept();
2928
});
3029
}
3130

32-
void SerialServer::do_read_write() {
33-
static boost::array<char, 128> buf;
34-
serial_.async_read_some(boost::asio::buffer(buf), [this](boost::system::error_code ec, std::size_t length) {
31+
void SerialServer::handle_session() {
32+
BOOST_LOG_TRIVIAL(info) << "SerialServer::handle_session";
33+
34+
async_read_socket();
35+
async_read_serial();
36+
}
37+
38+
void SerialServer::async_read_socket() {
39+
BOOST_LOG_TRIVIAL(info) << "SerialServer::async_read_socket";
40+
41+
socket_.async_read_some(boost::asio::buffer(buffer_), [this](boost::system::error_code ec, std::size_t length) {
3542
if (!ec) {
36-
async_write(socket_, boost::asio::buffer(buf, length), [this](boost::system::error_code ec, std::size_t) {
43+
serial_port_.async_write(boost::asio::buffer(buffer_, length), [this](boost::system::error_code ec, std::size_t) {
3744
if (!ec) {
38-
BOOST_LOG_TRIVIAL(info) << "Data successfully written to client. Continuing read/write loop.";
39-
do_read_write();
45+
async_read_socket();
4046
} else {
4147
BOOST_LOG_TRIVIAL(error) << "Error writing to client: " << ec.message();
4248
}
4349
});
4450
} else {
45-
BOOST_LOG_TRIVIAL(error) << "Error reading from serial port: " << ec.message();
51+
BOOST_LOG_TRIVIAL(error) << "Read error on socket: " << ec.message();
52+
socket_.close();
53+
}
54+
});
55+
}
56+
57+
void SerialServer::async_read_serial() {
58+
BOOST_LOG_TRIVIAL(info) << "SerialServer::async_read_serial";
59+
60+
serial_port_.async_read_some(boost::asio::buffer(buffer_), [this](boost::system::error_code ec, std::size_t length) {
61+
if (!ec) {
62+
boost::asio::async_write(socket_, boost::asio::buffer(buffer_, length), [this](boost::system::error_code ec, std::size_t) {
63+
if (!ec) {
64+
async_read_serial();
65+
} else {
66+
BOOST_LOG_TRIVIAL(error) << "Error sending to socket: " << ec.message();
67+
}
68+
});
69+
} else {
70+
BOOST_LOG_TRIVIAL(error) << "Read error on serial port: " << ec.message();
71+
socket_.close();
4672
}
4773
});
4874
}

0 commit comments

Comments
 (0)