add support user-defined modbus functions (#3461)

This commit is contained in:
gazoodle 2022-05-19 01:49:12 +01:00 committed by GitHub
parent 0ed7db979b
commit 4f52d43347
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -68,6 +68,26 @@ bool Modbus::parse_modbus_byte_(uint8_t byte) {
uint8_t data_len = raw[2]; uint8_t data_len = raw[2];
uint8_t data_offset = 3; uint8_t data_offset = 3;
// Per https://modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf Ch 5 User-Defined function codes
if (((function_code >= 65) && (function_code <= 72)) || ((function_code >= 100) && (function_code <= 110))) {
// Handle user-defined function, since we don't know how big this ought to be,
// ideally we should delegate the entire length detection to whatever handler is
// installed, but wait, there is the CRC, and if we get a hit there is a good
// chance that this is a complete message ... admittedly there is a small chance is
// isn't but that is quite small given the purpose of the CRC in the first place
data_len = at;
data_offset = 1;
uint16_t computed_crc = crc16(raw, data_offset + data_len);
uint16_t remote_crc = uint16_t(raw[data_offset + data_len]) | (uint16_t(raw[data_offset + data_len + 1]) << 8);
if (computed_crc != remote_crc)
return true;
ESP_LOGD(TAG, "Modbus user-defined function %02X found", function_code);
} else {
// the response for write command mirrors the requests and data startes at offset 2 instead of 3 for read commands // the response for write command mirrors the requests and data startes at offset 2 instead of 3 for read commands
if (function_code == 0x5 || function_code == 0x06 || function_code == 0xF || function_code == 0x10) { if (function_code == 0x5 || function_code == 0x06 || function_code == 0xF || function_code == 0x10) {
data_offset = 2; data_offset = 2;
@ -96,6 +116,7 @@ bool Modbus::parse_modbus_byte_(uint8_t byte) {
ESP_LOGW(TAG, "Modbus CRC Check failed! %02X!=%02X", computed_crc, remote_crc); ESP_LOGW(TAG, "Modbus CRC Check failed! %02X!=%02X", computed_crc, remote_crc);
return false; return false;
} }
}
std::vector<uint8_t> data(this->rx_buffer_.begin() + data_offset, this->rx_buffer_.begin() + data_offset + data_len); std::vector<uint8_t> data(this->rx_buffer_.begin() + data_offset, this->rx_buffer_.begin() + data_offset + data_len);
bool found = false; bool found = false;
for (auto *device : this->devices_) { for (auto *device : this->devices_) {