Skip to content

Commit 158699c

Browse files
Update logging around serial port operations, add locking on i/o
1 parent 98bdcac commit 158699c

File tree

3 files changed

+44
-31
lines changed

3 files changed

+44
-31
lines changed

include/RealSerialPort.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class RealSerialPort : public ISerialPort {
3131
}
3232

3333
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.";
34+
// BOOST_LOG_TRIVIAL(info) << "Read some.";
3535
if (!port.is_open()) {
3636
BOOST_LOG_TRIVIAL(error) << "Attempt to read from a closed serial port.";
3737
return;

include/VirtualSerialPort.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class VirtualSerialPort {
1717
boost::asio::posix::stream_descriptor master_fd_;
1818
std::array<char, 1024> read_buffer_;
1919
std::string device_name_;
20+
std::mutex mutex_;
2021

2122
void setup_pty(int fd);
2223
};

src/VirtualSerialPort.cpp

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,52 @@
22

33
VirtualSerialPort::VirtualSerialPort(boost::asio::io_context& io_context, const std::string& device)
44
: master_fd_(io_context), device_name_("/dev/" + device) {
5+
std::lock_guard<std::mutex> lock(mutex_);
56
int master_fd = posix_openpt(O_RDWR | O_NOCTTY);
67
if (master_fd == -1) {
78
BOOST_LOG_TRIVIAL(error) << "Failed to open PTY master: " << strerror(errno);
89
throw std::runtime_error("Failed to open PTY master");
910
}
10-
if (grantpt(master_fd) != 0 || unlockpt(master_fd) != 0) {
11-
BOOST_LOG_TRIVIAL(error) << "Failed to grant or unlock PTY: " << strerror(errno);
12-
throw std::runtime_error("Failed to grant or unlock PTY");
13-
}
14-
15-
char* slave_name = ptsname(master_fd);
16-
if (!slave_name) {
17-
BOOST_LOG_TRIVIAL(error) << "Failed to get PTY slave name";
18-
throw std::runtime_error("Failed to get PTY slave name");
19-
}
20-
21-
if (unlink(device_name_.c_str()) == -1 && errno != ENOENT) {
22-
BOOST_LOG_TRIVIAL(error) << "Failed to remove existing symlink: " << strerror(errno);
23-
throw std::runtime_error("Failed to remove existing symlink");
24-
}
25-
26-
if (symlink(slave_name, device_name_.c_str()) != 0) {
27-
BOOST_LOG_TRIVIAL(error) << "Failed to create symlink for PTY slave: " << strerror(errno);
28-
throw std::runtime_error("Failed to create symlink for PTY slave");
29-
}
30-
31-
chmod(device_name_.c_str(), 0660);
32-
struct group* tty_grp = getgrnam("tty");
33-
if (tty_grp && chown(device_name_.c_str(), -1, tty_grp->gr_gid) == -1) {
34-
BOOST_LOG_TRIVIAL(error) << "Failed to change group of device: " << strerror(errno);
35-
throw std::runtime_error("Failed to change group of device");
36-
}
37-
38-
master_fd_.assign(master_fd);
39-
setup_pty(master_fd);
11+
BOOST_LOG_TRIVIAL(info) << "PTY master opened successfully";
12+
13+
if (grantpt(master_fd) != 0 || unlockpt(master_fd) != 0) {
14+
BOOST_LOG_TRIVIAL(error) << "Failed to grant or unlock PTY: " << strerror(errno);
15+
throw std::runtime_error("Failed to grant or unlock PTY");
16+
}
17+
BOOST_LOG_TRIVIAL(info) << "PTY grant and unlock successful";
18+
19+
char* slave_name = ptsname(master_fd);
20+
if (!slave_name) {
21+
BOOST_LOG_TRIVIAL(error) << "Failed to get PTY slave name";
22+
throw std::runtime_error("Failed to get PTY slave name");
23+
}
24+
25+
if (unlink(device_name_.c_str()) == -1 && errno != ENOENT) {
26+
BOOST_LOG_TRIVIAL(error) << "Failed to remove existing symlink: " << strerror(errno);
27+
throw std::runtime_error("Failed to remove existing symlink");
28+
}
29+
BOOST_LOG_TRIVIAL(info) << "Existing symlink removed or not present";
30+
31+
if (symlink(slave_name, device_name_.c_str()) != 0) {
32+
BOOST_LOG_TRIVIAL(error) << "Failed to create symlink for PTY slave: " << strerror(errno);
33+
throw std::runtime_error("Failed to create symlink for PTY slave");
34+
}
35+
BOOST_LOG_TRIVIAL(info) << "Symlink for PTY slave created successfully";
36+
37+
chmod(device_name_.c_str(), 0660);
38+
struct group* tty_grp = getgrnam("tty");
39+
if (tty_grp && chown(device_name_.c_str(), -1, tty_grp->gr_gid) == -1) {
40+
BOOST_LOG_TRIVIAL(error) << "Failed to change group of device: " << strerror(errno);
41+
throw std::runtime_error("Failed to change group of device");
42+
}
43+
BOOST_LOG_TRIVIAL(info) << "Group changed successfully for the device";
44+
45+
master_fd_.assign(master_fd);
46+
setup_pty(master_fd);
4047
}
4148

4249
void VirtualSerialPort::setup_pty(int fd) {
50+
std::lock_guard<std::mutex> lock(mutex_);
4351
struct termios tty;
4452
if (tcgetattr(fd, &tty) != 0) {
4553
BOOST_LOG_TRIVIAL(error) << "Error from tcgetattr: " << strerror(errno);
@@ -61,6 +69,8 @@ void VirtualSerialPort::setup_pty(int fd) {
6169

6270
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
6371
BOOST_LOG_TRIVIAL(error) << "Error from tcsetattr: " << strerror(errno);
72+
} else {
73+
BOOST_LOG_TRIVIAL(info) << "PTY attributes set successfully";
6474
}
6575
}
6676

@@ -74,6 +84,7 @@ VirtualSerialPort::~VirtualSerialPort() {
7484
}
7585

7686
void VirtualSerialPort::async_read(boost::asio::mutable_buffer buffer, std::function<void(const boost::system::error_code&, std::size_t)> handler) {
87+
std::lock_guard<std::mutex> lock(mutex_);
7788
BOOST_LOG_TRIVIAL(info) << "VSP::async_read";
7889
boost::asio::async_read(master_fd_, buffer,
7990
[this, buffer, handler](const boost::system::error_code& ec, std::size_t length) {
@@ -97,6 +108,7 @@ void VirtualSerialPort::async_read(boost::asio::mutable_buffer buffer, std::func
97108

98109

99110
void VirtualSerialPort::async_write(boost::asio::const_buffer buffer, std::function<void(const boost::system::error_code&, std::size_t)> handler) {
111+
std::lock_guard<std::mutex> lock(mutex_);
100112
std::string data(boost::asio::buffer_cast<const char*>(buffer), boost::asio::buffer_size(buffer));
101113
std::stringstream hex_stream;
102114
hex_stream << std::hex << std::setfill('0');

0 commit comments

Comments
 (0)