I use boost asio async_read_some, the data I want to read STXdataETXlrc, if it were not for lrc I would use async_read_until, how can I continue reading until I get ETXlrc? appreciate all the help.
/huvcbo
I use boost asio async_read_some, the data I want to read STXdataETXlrc, if it were not for lrc I would use async_read_until, how can I continue reading until I get ETXlrc? appreciate all the help.
/huvcbo
From the very sparse information, I'm assuming you are talking in the context of serial comms.
In that case, the simplest way to get started might be to use Asio's composed read operations (like read
, read_until
etc).
comm::read_until(sp, buf, '\x03');
With a bit of syntactic sugar you can write more expressively:
enum ControlCodes : uint8_t {
STX = 2,
ETX = 3,
};
E.g.:
#include <boost/asio.hpp>
#include <boost/asio/serial_port.hpp>
#include <iostream>
namespace comm = boost::asio;
enum ControlCodes : uint8_t {
STX = 2,
ETX = 3,
};
int main(int argc, char** argv) {
comm::io_context ioc;
comm::serial_port sp(ioc, argc > 1 ? argv[1] : "/dev/ttyS6");
sp.set_option(comm::serial_port::baud_rate(115'200));
std::vector<uint8_t> data;
comm::read_until(sp, comm::dynamic_buffer(data), ETX);
}
You could then proceed to to a fixed-length read to get the checksum. More involved overloads of read_until
allow you to write MatchCondition
instead so you can combine it all in a single call: https://www.boost.org/doc/libs/1_78_0/doc/html/boost_asio/reference/read_until.html.
Here's an example that uses the boost::regex
overload, that shows the message and whether the checksum verifies:
#include <boost/asio.hpp>
#include <boost/asio/serial_port.hpp>
#include <boost/regex.hpp>
#include <fmt/ranges.h>
#include <numeric>
namespace comm = boost::asio;
enum ControlCodes : uint8_t {
STX = 2,
ETX = 3,
};
int main(int argc, char** argv) {
comm::io_context ioc;
comm::serial_port sp(ioc, argc > 1 ? argv[1] : "/dev/ttyS6");
sp.set_option(comm::serial_port::baud_rate(115'200));
std::vector<uint8_t> buffer;
auto n = comm::read_until(sp, comm::dynamic_buffer(buffer), boost::regex("\x03."));
auto raw = buffer.data();
bool ok = n >= 3 && *raw == STX;
if (ok) {
auto b = raw + 1;
auto e = b + n - 3; // payload excludes STX, ETX, LRC
auto lrc = accumulate(b, e, uint8_t(0), std::bit_xor<>{});
bool verified = raw[n - 1] == lrc;
fmt::print("Checksum {} bytes verified {}, buffer {::#02x} (expected {:#02x})\n",
n, verified, buffer, lrc);
} else {
fmt::print("Message not wellformed {} bytes buffer {::#02x}\n", n, buffer);
}
}
Tested locally using socat
: