22
33#include < cstring>
44#include < fcntl.h>
5- #include < format>
6- #include < iostream>
75#include < mutex>
86#include < termios.h>
97#include < unistd.h>
8+ #include < print>
109
1110auto Serial::open (const std::filesystem::path &path, const int baud_rate)
12- -> std::optional<std::shared_ptr<Serial>>
11+ -> std::optional<std::shared_ptr<Serial>>
1312{
1413 // NOLINTNEXTLINE
1514 const auto fd = ::open (path.c_str (), O_RDWR | O_NOCTTY | O_SYNC);
1615 if (fd < 0 ) {
17- std::cerr << std::format (
18- " [ERROR] failed to open serial port {}: {}\n " , path.string (), strerror (errno)
16+ std::print (
17+ stderr,
18+ " [ERROR] failed to open serial port {}: {}\n " ,
19+ path.string (),
20+ strerror (errno)
1921 );
2022 return std::nullopt ;
2123 }
2224
2325 struct termios tty{};
2426 if (tcgetattr (fd, &tty) < 0 ) {
25- std::cerr << std::format (
26- " [ERROR] failed to get tty current attributes for {}: {}\n " , path.string (), strerror (errno)
27+ std::print (
28+ stderr,
29+ " [ERROR] failed to get tty current attributes for {}: {}\n " ,
30+ path.string (),
31+ strerror (errno)
2732 );
2833 ::close (fd);
2934 return std::nullopt ;
@@ -41,7 +46,7 @@ auto Serial::open(const std::filesystem::path &path, const int baud_rate)
4146
4247 /* setup for non-canonical mode */
4348 tty.c_iflag &=
44- ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
49+ ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
4550 tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
4651 tty.c_oflag &= ~OPOST;
4752
@@ -50,27 +55,32 @@ auto Serial::open(const std::filesystem::path &path, const int baud_rate)
5055 tty.c_cc [VTIME] = 10 ; // Adjust timeout as needed
5156
5257 if (tcsetattr (fd, TCSANOW, &tty) != 0 ) {
53- std::cerr << std::format (
54- " [ERROR] failed to set tty attributes for {}: {}\n " , path.string (), strerror (errno)
58+ std::print (
59+ stderr,
60+ " [ERROR] failed to set tty attributes for {}: {}\n " ,
61+ path.string (),
62+ strerror (errno)
5563 );
5664 ::close (fd);
5765 return std::nullopt ;
5866 }
5967
6068 auto serial_instance = std::shared_ptr<Serial>(new Serial (fd));
61- serial_instance->read_thread = std::thread (&Serial::read_loop, serial_instance);
69+ serial_instance->read_thread =
70+ std::thread (&Serial::read_loop, serial_instance);
6271 serial_instance->connected .store (true , std::memory_order_relaxed);
6372 serial_instance->stop_reading .store (false , std::memory_order_relaxed);
6473
6574 return serial_instance;
6675}
6776
68- Serial::Serial (int fd) : fd(fd), connected(false ), stop_reading(false ) {}
77+ Serial::Serial (int fd)
78+ : fd(fd),
79+ connected(false ),
80+ stop_reading(false )
81+ {}
6982
70- Serial::~Serial ()
71- {
72- close ();
73- }
83+ Serial::~Serial () { close (); }
7484
7585void Serial::close ()
7686{
@@ -80,25 +90,25 @@ void Serial::close()
8090 }
8191 connected.store (false , std::memory_order_relaxed);
8292 stop_reading.store (true , std::memory_order_relaxed);
83- if (read_thread.joinable ()) {
84- read_thread.join ();
85- }
93+ if (read_thread.joinable ()) { read_thread.join (); }
8694}
8795
8896void Serial::read_loop ()
8997{
9098 while (!stop_reading.load (std::memory_order_relaxed)) {
91- char msg[256 ];
92- const auto bytes = ::read (fd, static_cast <char *>(msg), sizeof (msg));
99+ char msg[256 ];
100+ const auto bytes = ::read (fd, static_cast <char *>(msg), sizeof (msg));
93101 if (bytes > 0 ) {
94- std::string received_data (static_cast <char *>(msg), bytes);
102+ std::string received_data (static_cast <char *>(msg), bytes);
95103 {
96104 std::lock_guard<std::mutex> lock (read_buffer_mutex);
97105 read_buffer.push_back (received_data);
98106 }
99107 } else if (bytes < 0 ) {
100- std::cerr << std::format (
101- " [ERROR] failed to read from serial port: {}\n " , strerror (errno)
108+ std::print (
109+ stderr,
110+ " [ERROR] failed to read from serial port: {}\n " ,
111+ strerror (errno)
102112 );
103113 // FIXME: Consider what to do on read error: try to reconnect, signal error, etc.
104114 break ;
0 commit comments