19 #include <uuid/modbus.h>
43 auto &response =
requests_.front()->response();
45 if (response.status() == ResponseStatus::QUEUED) {
55 if (response.status() == ResponseStatus::TRANSMIT) {
59 if (response.status() == ResponseStatus::WAITING) {
63 if (response.done()) {
69 uint32_t now_ms =
input();
79 logger.
err(F(
"Received unexpected frame while idle from device %u"),
frame_[0]);
87 auto &response = request.response();
92 response.status(ResponseStatus::FAILURE_INVALID);
101 response.status(ResponseStatus::TRANSMIT);
109 int available =
serial_.availableForWrite();
111 if (available <= 0) {
124 requests_.front()->response().status(ResponseStatus::WAITING);
128 uint32_t now_ms = ::millis();
132 int available =
serial_.available();
134 if (available <= 0) {
138 while (available-- > 0) {
152 }
while (data != -1);
158 uint32_t now_ms =
input();
161 auto &request = *
requests_.front().get();
163 if ((now_ms -
last_tx_ms_) >= request.timeout_ms()) {
164 if (request.device() == DeviceAddressType::BROADCAST) {
165 request.response().status(ResponseStatus::SUCCESS);
167 request.response().status(ResponseStatus::FAILURE_TIMEOUT);
168 logger.
notice(F(
"Timeout waiting for response to function %02X from device %u"),
179 auto &request = *
requests_.front().get();
180 auto &response = request.response();
185 response.status(ResponseStatus::FAILURE_TOO_SHORT);
191 response.status(ResponseStatus::FAILURE_TOO_LONG);
200 if (exp_crc != act_crc) {
201 response.status(ResponseStatus::FAILURE_CRC);
202 logger.
err(F(
"Received frame with invalid CRC %04X from device %u with function %02X, expected %04X"),
207 if (request.device() == DeviceAddressType::BROADCAST) {
208 response.status(ResponseStatus::FAILURE_UNEXPECTED);
209 logger.
err(F(
"Received unexpected broadcast response with function code %02X from device %u"),
214 if (
frame_[0] != request.device()) {
215 response.status(ResponseStatus::FAILURE_ADDRESS);
216 logger.
err(F(
"Received function %02X from device %u, expected device %u"),
221 if ((
frame_[1] & ~0x80) != request.function_code()) {
222 response.status(ResponseStatus::FAILURE_FUNCTION);
223 logger.
err(F(
"Received function %02X from device %u, expected function %02X"),
230 response.status(ResponseStatus::FAILURE_LENGTH);
231 logger.
err(F(
"Exception with no code for function %02X from device %u"),
234 response.status(ResponseStatus::EXCEPTION);
235 response.exception_code(
frame_[2]);
236 logger.
notice(F(
"Exception code %02X for function %02X from device %u"),
237 response.exception_code(),
frame_[1] & ~0x80,
frame_[0]);
247 static constexpr uint8_t BYTES_PER_LINE = 16;
248 static constexpr uint8_t CHARS_PER_BYTE = 3;
249 std::vector<char> message(CHARS_PER_BYTE * BYTES_PER_LINE + 1);
253 snprintf_P(&message[CHARS_PER_BYTE * pos++], CHARS_PER_BYTE + 1,
259 if (pos == BYTES_PER_LINE || i ==
frame_pos_ - 1) {
269 uint16_t crc = 0xFFFF;
274 for (uint8_t b = 0; b < 8; b++) {