Commit 2b985f816374e79c9afb739944315cbb611fa762

Authored by Stéphane Raimbault
1 parent 9ea54e09

Fix #591142 - Slave id check should be disabled in TCP connection

A new API will be committed to remove the slave in TCP communication.
... ... @@ -10,6 +10,8 @@ libmodbus 2.1.1 (2010-XX-XX)
10 10 Reported by David Olivari.
11 11 - Fix #463299 - New functions to define the timeouts of begin and end of trame
12 12 Original patch by Sisyph (eric-paul).
  13 +- Fix #591142 - Slave id check should be disabled in TCP connection
  14 + Reported by aladdinwu.
13 15  
14 16 libmodbus 2.1.0 (2010-03-24)
15 17 ============================
... ...
src/modbus.c
... ... @@ -363,7 +363,7 @@ static int build_response_basis_tcp(sft_t *sft, uint8_t *response)
363 363  
364 364 /* Length will be set later by modbus_send (4 and 5) */
365 365  
366   - response[6] = sft->slave;
  366 + response[6] = 0xFF;
367 367 response[7] = sft->function;
368 368  
369 369 return PRESET_RESPONSE_LENGTH_TCP;
... ... @@ -887,8 +887,10 @@ int modbus_slave_manage(modbus_param_t *mb_param, const uint8_t *query,
887 887 int resp_length = 0;
888 888 sft_t sft;
889 889  
890   - if (slave != mb_param->slave && slave != MODBUS_BROADCAST_ADDRESS) {
891   - // Ignores the query (not for me)
  890 + /* Filter on the Modbus unit identifier (slave) in RTU mode */
  891 + if (mb_param->type_com == RTU &&
  892 + slave != mb_param->slave && slave != MODBUS_BROADCAST_ADDRESS) {
  893 + /* Ignores the query (not for me) */
892 894 if (mb_param->debug) {
893 895 printf("Request for slave %d ignored (not %d)\n",
894 896 slave, mb_param->slave);
... ... @@ -1483,7 +1485,7 @@ void init_common(modbus_param_t *mb_param)
1483 1485 - stop_bits: 1, 2
1484 1486 - slave: slave number
1485 1487 */
1486   -void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
  1488 +int modbus_init_rtu(modbus_param_t *mb_param, const char *device,
1487 1489 int baud, const char *parity, int data_bit,
1488 1490 int stop_bit, int slave)
1489 1491 {
... ... @@ -1496,9 +1498,10 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
1496 1498 mb_param->stop_bit = stop_bit;
1497 1499 mb_param->type_com = RTU;
1498 1500 mb_param->error_recovery = FALSE;
1499   - mb_param->slave = slave;
1500 1501  
1501 1502 init_common(mb_param);
  1503 +
  1504 + return modbus_set_slave(mb_param, slave);
1502 1505 }
1503 1506  
1504 1507 /* Initializes the modbus_param_t structure for TCP.
... ... @@ -1510,35 +1513,48 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
1510 1513 to 1024 because it's not necessary to be root to use this port
1511 1514 number.
1512 1515 */
1513   -void modbus_init_tcp(modbus_param_t *mb_param, const char *ip, int port, int slave)
  1516 +int modbus_init_tcp(modbus_param_t *mb_param, const char *ip, int port)
1514 1517 {
1515 1518 memset(mb_param, 0, sizeof(modbus_param_t));
1516 1519 strncpy(mb_param->ip, ip, sizeof(char)*16);
1517 1520 mb_param->port = port;
1518 1521 mb_param->type_com = TCP;
1519 1522 mb_param->error_recovery = FALSE;
1520   - mb_param->slave = slave;
  1523 + /* Can be changed after to reach remote serial Modbus device */
  1524 + mb_param->slave = 0xFF;
1521 1525  
1522 1526 init_common(mb_param);
  1527 +
  1528 + return 0;
1523 1529 }
1524 1530  
1525   -/* Define the slave number */
1526   -void modbus_set_slave(modbus_param_t *mb_param, int slave)
  1531 +/* Define the slave number, the special value MODBUS_TCP_SLAVE (0xFF) can be
  1532 + * used in TCP mode to restore the default value. */
  1533 +int modbus_set_slave(modbus_param_t *mb_param, int slave)
1527 1534 {
1528   - mb_param->slave = slave;
  1535 + if (slave >= 1 && slave <= 247) {
  1536 + mb_param->slave = slave;
  1537 + } else if (mb_param->type_com == TCP && slave == MODBUS_TCP_SLAVE) {
  1538 + mb_param->slave = slave;
  1539 + } else {
  1540 + errno = EINVAL;
  1541 + return -1;
  1542 + }
  1543 +
  1544 + return 0;
1529 1545 }
1530 1546  
1531 1547 /*
1532   - When disabled (default), it is expected that the application will check for error
1533   - returns and deal with them as necessary.
  1548 + When disabled (default), it is expected that the application will check for
  1549 + error returns and deal with them as necessary.
1534 1550  
1535 1551 It's not recommanded to enable error recovery for slave/server.
1536 1552  
1537 1553 When enabled, the library will attempt an immediate reconnection which may
1538 1554 hang for several seconds if the network to the remote target unit is down.
1539 1555 The write will try a infinite close/connect loop until to be successful and
1540   - the select/read calls will just try to retablish the connection one time
1541   - then will return an error (if the connecton was down, the values to read are
  1556 + the select/read calls will just try to retablish the connection one time then
  1557 + will return an error (if the connecton was down, the values to read are
1542 1558 certainly not available anymore after reconnection, except for slave/server).
1543 1559 */
1544 1560 int modbus_set_error_recovery(modbus_param_t *mb_param, int enabled)
... ...
src/modbus.h.in
... ... @@ -39,6 +39,7 @@ extern &quot;C&quot; {
39 39  
40 40 #define MODBUS_TCP_DEFAULT_PORT 502
41 41 #define MODBUS_BROADCAST_ADDRESS 0
  42 +#define MODBUS_TCP_SLAVE 0xFF
42 43  
43 44 /* Slave index */
44 45 #define HEADER_LENGTH_RTU 1
... ... @@ -249,12 +250,11 @@ typedef struct {
249 250 uint16_t *tab_holding_registers;
250 251 } modbus_mapping_t;
251 252  
252   -void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
253   - int baud, const char *parity, int data_bit,
254   - int stop_bit, int slave);
255   -void modbus_init_tcp(modbus_param_t *mb_param, const char *ip_address, int port,
256   - int slave);
257   -void modbus_set_slave(modbus_param_t *mb_param, int slave);
  253 +int modbus_init_rtu(modbus_param_t *mb_param, const char *device,
  254 + int baud, const char *parity, int data_bit,
  255 + int stop_bit, int slave);
  256 +int modbus_init_tcp(modbus_param_t *mb_param, const char *ip_address, int port);
  257 +int modbus_set_slave(modbus_param_t *mb_param, int slave);
258 258 int modbus_set_error_recovery(modbus_param_t *mb_param, int enabled);
259 259  
260 260 void modbus_get_timeout_begin(modbus_param_t *mb_param, struct timeval *timeout);
... ...
tests/bandwidth-master.c
... ... @@ -26,7 +26,6 @@
26 26 #include <modbus.h>
27 27  
28 28 /* Tests based on PI-MBUS-300 documentation */
29   -#define MY_ID 1
30 29 #define SERVER_ID 17
31 30 #define NB_LOOPS 100000
32 31  
... ... @@ -55,7 +54,7 @@ int main(void)
55 54 int rc;
56 55  
57 56 /* TCP */
58   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502, MY_ID);
  57 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
59 58 rc = modbus_connect(&mb_param);
60 59 if (rc == -1) {
61 60 fprintf(stderr, "Connexion failed: %s\n",
... ...
tests/bandwidth-slave-many-up.c
... ... @@ -48,7 +48,7 @@ int main(void)
48 48 /* Maximum file descriptor number */
49 49 int fdmax;
50 50  
51   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502, 17);
  51 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
52 52  
53 53 rc = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0);
54 54 if (rc == -1) {
... ...
tests/bandwidth-slave-one.c
... ... @@ -30,7 +30,7 @@ int main(void)
30 30 modbus_mapping_t mb_mapping;
31 31 int rc;
32 32  
33   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502, 17);
  33 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
34 34  
35 35 rc = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0);
36 36 if (rc == -1) {
... ...
tests/random-test-master.c
... ... @@ -64,7 +64,7 @@ int main(void)
64 64 */
65 65  
66 66 /* TCP */
67   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502, MY_ID);
  67 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
68 68 modbus_set_debug(&mb_param, TRUE);
69 69 if (modbus_connect(&mb_param) == -1) {
70 70 fprintf(stderr, "Connection failed: %s\n",
... ...
tests/random-test-slave.c
... ... @@ -29,7 +29,7 @@ int main(void)
29 29 modbus_mapping_t mb_mapping;
30 30 int rc;
31 31  
32   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502, 17);
  32 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
33 33 /* modbus_set_debug(&mb_param, TRUE); */
34 34  
35 35 rc = modbus_mapping_new(&mb_mapping, 500, 500, 500, 500);
... ...
tests/unit-test-master.c
... ... @@ -46,7 +46,7 @@ int main(void)
46 46 */
47 47  
48 48 /* TCP */
49   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502, CLIENT_ID);
  49 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
50 50 modbus_set_debug(&mb_param, TRUE);
51 51  
52 52 if (modbus_connect(&mb_param) == -1) {
... ... @@ -450,16 +450,28 @@ int main(void)
450 450  
451 451 /** SLAVE REPLY **/
452 452 printf("\nTEST SLAVE REPLY:\n");
  453 +
453 454 rc = read_holding_registers(&mb_param, 18,
454 455 UT_HOLDING_REGISTERS_ADDRESS,
455 456 UT_HOLDING_REGISTERS_NB_POINTS,
456 457 tab_rp_registers);
457   - printf("1/3 No reply from slave %d: ", 18);
458   - if (rc == -1 && errno == ETIMEDOUT) {
459   - printf("OK\n");
  458 + printf("1/3 No or response from slave %d: ", 18);
  459 + if (mb_param.type_com == RTU) {
  460 + /* No response in RTU mode */
  461 + if (rc == -1 && errno == ETIMEDOUT) {
  462 + printf("OK\n");
  463 + } else {
  464 + printf("FAILED\n");
  465 + goto close;
  466 + }
460 467 } else {
461   - printf("FAILED\n");
462   - goto close;
  468 + /* Response in TCP mode */
  469 + if (rc == UT_HOLDING_REGISTERS_NB_POINTS) {
  470 + printf("OK\n");
  471 + } else {
  472 + printf("FAILED\n");
  473 + goto close;
  474 + }
463 475 }
464 476  
465 477 rc = read_holding_registers(&mb_param, MODBUS_BROADCAST_ADDRESS,
... ...
tests/unit-test-slave.c
... ... @@ -32,7 +32,7 @@ int main(void)
32 32 int rc;
33 33 int i;
34 34  
35   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502, SERVER_ID);
  35 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
36 36 modbus_set_debug(&mb_param, TRUE);
37 37 modbus_set_error_recovery(&mb_param, TRUE);
38 38  
... ...