Commit b1adc3717fbf1cf4e3a9117ad57fcfb035809159

Authored by Michael Heimpold
Committed by Stéphane Raimbault
1 parent 0f06a0cd

Fix modbus_reply for TCP when unit id == 0 (fixes #376)

According to the Modbus standard, the unit identifier is choosen by the
TCP client and can be any value:

"This field is used for intra-system routing purpose.  It is typically
used to communicate to a MODBUS+ or a MODBUS serial line slave through a
gateway between an Ethernet TCP-IP network and a MODBUS serial line.
This field is set by the MODBUS Client in the request and must be returned
with the same value in the response by the server."

So the current check in modbus_reply must be extended to check whether
we are in a RTU or TCP context.

Also the unit-test has to be adjusted.

Signed-off-by: Michael Heimpold <mhei@heimpold.de>
src/modbus.c
@@ -996,7 +996,8 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, @@ -996,7 +996,8 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
996 } 996 }
997 997
998 /* Suppress any responses when the request was a broadcast */ 998 /* Suppress any responses when the request was a broadcast */
999 - return (slave == MODBUS_BROADCAST_ADDRESS) ? 0 : send_msg(ctx, rsp, rsp_length); 999 + return (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU &&
  1000 + slave == MODBUS_BROADCAST_ADDRESS) ? 0 : send_msg(ctx, rsp, rsp_length);
1000 } 1001 }
1001 1002
1002 int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, 1003 int modbus_reply_exception(modbus_t *ctx, const uint8_t *req,
tests/unit-test-client.c
@@ -488,19 +488,28 @@ int main(int argc, char *argv[]) @@ -488,19 +488,28 @@ int main(int argc, char *argv[])
488 printf("1-C/3 No response from slave %d with invalid request: ", 488 printf("1-C/3 No response from slave %d with invalid request: ",
489 INVALID_SERVER_ID); 489 INVALID_SERVER_ID);
490 ASSERT_TRUE(rc == -1 && errno == ETIMEDOUT, ""); 490 ASSERT_TRUE(rc == -1 && errno == ETIMEDOUT, "");
  491 +
  492 +
  493 + rc = modbus_set_slave(ctx, MODBUS_BROADCAST_ADDRESS);
  494 + ASSERT_TRUE(rc != -1, "Invalid broacast address");
  495 +
  496 + rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS,
  497 + UT_REGISTERS_NB, tab_rp_registers);
  498 + printf("2/3 No reply after a broadcast query: ");
  499 + ASSERT_TRUE(rc == -1 && errno == ETIMEDOUT, "");
491 } else { 500 } else {
492 /* Response in TCP mode */ 501 /* Response in TCP mode */
493 printf("1/3 Response from slave %d: ", INVALID_SERVER_ID); 502 printf("1/3 Response from slave %d: ", INVALID_SERVER_ID);
494 ASSERT_TRUE(rc == UT_REGISTERS_NB, ""); 503 ASSERT_TRUE(rc == UT_REGISTERS_NB, "");
495 - }  
496 504
497 - rc = modbus_set_slave(ctx, MODBUS_BROADCAST_ADDRESS);  
498 - ASSERT_TRUE(rc != -1, "Invalid broacast address"); 505 + rc = modbus_set_slave(ctx, MODBUS_BROADCAST_ADDRESS);
  506 + ASSERT_TRUE(rc != -1, "Invalid broacast address");
499 507
500 - rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS,  
501 - UT_REGISTERS_NB, tab_rp_registers);  
502 - printf("2/3 No reply after a broadcast query: ");  
503 - ASSERT_TRUE(rc == -1 && errno == ETIMEDOUT, ""); 508 + rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS,
  509 + UT_REGISTERS_NB, tab_rp_registers);
  510 + printf("2/3 Reply after a query with unit id == 0: ");
  511 + ASSERT_TRUE(rc == UT_REGISTERS_NB, "");
  512 + }
504 513
505 /* Restore slave */ 514 /* Restore slave */
506 modbus_set_slave(ctx, old_slave); 515 modbus_set_slave(ctx, old_slave);