Commit e10ee2d58551c6fab08e91cced6368d8d7910bbb
Committed by
Stéphane Raimbault
1 parent
e2e22503
Do not reply on broadcast requests (fixes #153)
According to the Modbus specification (http://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf, section 2.1) a Modbus RTU master can send a broadcast to all of it's slaves. This broadcasts can only be write requests as otherwise collisions could occur, eg. on a RS-485 bus. When receiving such a broadcast, the slave should process the request as usual, but must not reply anything, neither a normal response nor an exception reply in case of an error. Adjust the unit test for this case, too. Signed-off-by: Michael Heimpold <mhei@heimpold.de>
Showing
2 changed files
with
4 additions
and
3 deletions
src/modbus.c
| @@ -1055,7 +1055,8 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -1055,7 +1055,8 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 1055 | break; | 1055 | break; |
| 1056 | } | 1056 | } |
| 1057 | 1057 | ||
| 1058 | - return send_msg(ctx, rsp, rsp_length); | 1058 | + /* Suppress any response when the request was a broadcast */ |
| 1059 | + return slave ? send_msg(ctx, rsp, rsp_length) : 0; | ||
| 1059 | } | 1060 | } |
| 1060 | 1061 | ||
| 1061 | int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, | 1062 | int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, |
tests/unit-test-client.c
| @@ -429,8 +429,8 @@ int main(int argc, char *argv[]) | @@ -429,8 +429,8 @@ int main(int argc, char *argv[]) | ||
| 429 | 429 | ||
| 430 | rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, | 430 | rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, |
| 431 | UT_REGISTERS_NB, tab_rp_registers); | 431 | UT_REGISTERS_NB, tab_rp_registers); |
| 432 | - printf("2/3 Reply after a broadcast query: "); | ||
| 433 | - ASSERT_TRUE(rc == UT_REGISTERS_NB, ""); | 432 | + printf("2/3 No reply after a broadcast query: "); |
| 433 | + ASSERT_TRUE(rc == -1 && errno == ETIMEDOUT, ""); | ||
| 434 | 434 | ||
| 435 | /* Restore slave */ | 435 | /* Restore slave */ |
| 436 | if (use_backend == RTU) { | 436 | if (use_backend == RTU) { |