15#include <netinet/in.h>
16#include <sys/socket.h>
31using Clock = std::chrono::steady_clock;
39 std::map<uint8_t, uint8_t>
state;
52 sock_ = socket(AF_INET, SOCK_DGRAM, 0);
56 setsockopt(
sock_, SOL_SOCKET, SO_REUSEADDR, &reuse,
sizeof(reuse));
57 struct sockaddr_in addr{};
58 addr.sin_family = AF_INET;
59 addr.sin_port = htons(
port_);
60 inet_pton(AF_INET,
"127.0.0.1", &addr.sin_addr);
61 if (bind(
sock_,
reinterpret_cast<struct sockaddr*
>(&addr),
sizeof(addr)) < 0) {
66 struct timeval tv{.tv_sec = 0, .tv_usec = 20000};
67 setsockopt(
sock_, SOL_SOCKET, SO_RCVTIMEO, &tv,
sizeof(tv));
70 thread_ = std::thread([
this]() {
88 std::lock_guard<std::mutex>
lk(
mutex_);
96 ssize_t
n = recv(
sock_, buf,
sizeof(buf), 0);
99 daq::PacketHeader header;
100 std::vector<daq::ActuatorCommand> cmds;
104 for (
const auto& c : cmds) {
105 b.channels.insert(c.actuator_id);
106 b.state[c.actuator_id] = c.actuator_state;
109 std::chrono::duration_cast<std::chrono::milliseconds>(Clock::now() -
t0_).count();
111 std::lock_guard<std::mutex>
lk(
mutex_);
117 b.at_ms -
bursts_.back().at_ms < 50)
133inline long long firstCommand(
const std::vector<Burst>& bursts, uint8_t
ch, uint8_t hw,
134 long long after_ms = -1) {
135 for (
const auto&
b : bursts) {
136 if (
b.at_ms < after_ms)
138 auto it =
b.state.find(
ch);
139 if (it !=
b.state.end() && it->second == hw)
BoardListener(uint16_t port)
std::vector< Burst > bursts_
std::atomic< bool > running_
BoardListener(uint16_t port)
std::vector< Burst > bursts() const
static const emmc_port_t port
*brief create JSON pointer *sa reference_tokens const string_t const string_t & b
bool parse_actuator_command_packet(const uint8_t *buffer, size_t buffer_size, PacketHeader &header_out, std::vector< ActuatorCommand > &commands_out)
Parses an Actuator Command packet from buffer.
A fake actuator board: binds the actuator command UDP port on loopback and records what was actually ...
std::chrono::steady_clock Clock
long long firstCommand(const std::vector< Burst > &bursts, uint8_t ch, uint8_t hw, long long after_ms=-1)
When ch was first commanded to hw at or after after_ms.
*brief user defined string literal for JSON values *sa std::size_t n
One received command burst: when it arrived (ms since the listener started) and what it said.
std::map< uint8_t, uint8_t > state
channel -> commanded hardware state (1 = energised; for an NC valve that is OPEN).
std::set< uint8_t > channels
Channels the batch carried.
static std::string ch(int ain, const std::string &kind, const std::string &extra="", const std::string &board="lj")