Commit 2b985f816374e79c9afb739944315cbb611fa762
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.
Showing
10 changed files
with
62 additions
and
33 deletions
NEWS
| @@ -10,6 +10,8 @@ libmodbus 2.1.1 (2010-XX-XX) | @@ -10,6 +10,8 @@ libmodbus 2.1.1 (2010-XX-XX) | ||
| 10 | Reported by David Olivari. | 10 | Reported by David Olivari. |
| 11 | - Fix #463299 - New functions to define the timeouts of begin and end of trame | 11 | - Fix #463299 - New functions to define the timeouts of begin and end of trame |
| 12 | Original patch by Sisyph (eric-paul). | 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 | libmodbus 2.1.0 (2010-03-24) | 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,7 +363,7 @@ static int build_response_basis_tcp(sft_t *sft, uint8_t *response) | ||
| 363 | 363 | ||
| 364 | /* Length will be set later by modbus_send (4 and 5) */ | 364 | /* Length will be set later by modbus_send (4 and 5) */ |
| 365 | 365 | ||
| 366 | - response[6] = sft->slave; | 366 | + response[6] = 0xFF; |
| 367 | response[7] = sft->function; | 367 | response[7] = sft->function; |
| 368 | 368 | ||
| 369 | return PRESET_RESPONSE_LENGTH_TCP; | 369 | return PRESET_RESPONSE_LENGTH_TCP; |
| @@ -887,8 +887,10 @@ int modbus_slave_manage(modbus_param_t *mb_param, const uint8_t *query, | @@ -887,8 +887,10 @@ int modbus_slave_manage(modbus_param_t *mb_param, const uint8_t *query, | ||
| 887 | int resp_length = 0; | 887 | int resp_length = 0; |
| 888 | sft_t sft; | 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 | if (mb_param->debug) { | 894 | if (mb_param->debug) { |
| 893 | printf("Request for slave %d ignored (not %d)\n", | 895 | printf("Request for slave %d ignored (not %d)\n", |
| 894 | slave, mb_param->slave); | 896 | slave, mb_param->slave); |
| @@ -1483,7 +1485,7 @@ void init_common(modbus_param_t *mb_param) | @@ -1483,7 +1485,7 @@ void init_common(modbus_param_t *mb_param) | ||
| 1483 | - stop_bits: 1, 2 | 1485 | - stop_bits: 1, 2 |
| 1484 | - slave: slave number | 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 | int baud, const char *parity, int data_bit, | 1489 | int baud, const char *parity, int data_bit, |
| 1488 | int stop_bit, int slave) | 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,9 +1498,10 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device, | ||
| 1496 | mb_param->stop_bit = stop_bit; | 1498 | mb_param->stop_bit = stop_bit; |
| 1497 | mb_param->type_com = RTU; | 1499 | mb_param->type_com = RTU; |
| 1498 | mb_param->error_recovery = FALSE; | 1500 | mb_param->error_recovery = FALSE; |
| 1499 | - mb_param->slave = slave; | ||
| 1500 | 1501 | ||
| 1501 | init_common(mb_param); | 1502 | init_common(mb_param); |
| 1503 | + | ||
| 1504 | + return modbus_set_slave(mb_param, slave); | ||
| 1502 | } | 1505 | } |
| 1503 | 1506 | ||
| 1504 | /* Initializes the modbus_param_t structure for TCP. | 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,35 +1513,48 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device, | ||
| 1510 | to 1024 because it's not necessary to be root to use this port | 1513 | to 1024 because it's not necessary to be root to use this port |
| 1511 | number. | 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 | memset(mb_param, 0, sizeof(modbus_param_t)); | 1518 | memset(mb_param, 0, sizeof(modbus_param_t)); |
| 1516 | strncpy(mb_param->ip, ip, sizeof(char)*16); | 1519 | strncpy(mb_param->ip, ip, sizeof(char)*16); |
| 1517 | mb_param->port = port; | 1520 | mb_param->port = port; |
| 1518 | mb_param->type_com = TCP; | 1521 | mb_param->type_com = TCP; |
| 1519 | mb_param->error_recovery = FALSE; | 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 | init_common(mb_param); | 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 | It's not recommanded to enable error recovery for slave/server. | 1551 | It's not recommanded to enable error recovery for slave/server. |
| 1536 | 1552 | ||
| 1537 | When enabled, the library will attempt an immediate reconnection which may | 1553 | When enabled, the library will attempt an immediate reconnection which may |
| 1538 | hang for several seconds if the network to the remote target unit is down. | 1554 | hang for several seconds if the network to the remote target unit is down. |
| 1539 | The write will try a infinite close/connect loop until to be successful and | 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 | certainly not available anymore after reconnection, except for slave/server). | 1558 | certainly not available anymore after reconnection, except for slave/server). |
| 1543 | */ | 1559 | */ |
| 1544 | int modbus_set_error_recovery(modbus_param_t *mb_param, int enabled) | 1560 | int modbus_set_error_recovery(modbus_param_t *mb_param, int enabled) |
src/modbus.h.in
| @@ -39,6 +39,7 @@ extern "C" { | @@ -39,6 +39,7 @@ extern "C" { | ||
| 39 | 39 | ||
| 40 | #define MODBUS_TCP_DEFAULT_PORT 502 | 40 | #define MODBUS_TCP_DEFAULT_PORT 502 |
| 41 | #define MODBUS_BROADCAST_ADDRESS 0 | 41 | #define MODBUS_BROADCAST_ADDRESS 0 |
| 42 | +#define MODBUS_TCP_SLAVE 0xFF | ||
| 42 | 43 | ||
| 43 | /* Slave index */ | 44 | /* Slave index */ |
| 44 | #define HEADER_LENGTH_RTU 1 | 45 | #define HEADER_LENGTH_RTU 1 |
| @@ -249,12 +250,11 @@ typedef struct { | @@ -249,12 +250,11 @@ typedef struct { | ||
| 249 | uint16_t *tab_holding_registers; | 250 | uint16_t *tab_holding_registers; |
| 250 | } modbus_mapping_t; | 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 | int modbus_set_error_recovery(modbus_param_t *mb_param, int enabled); | 258 | int modbus_set_error_recovery(modbus_param_t *mb_param, int enabled); |
| 259 | 259 | ||
| 260 | void modbus_get_timeout_begin(modbus_param_t *mb_param, struct timeval *timeout); | 260 | void modbus_get_timeout_begin(modbus_param_t *mb_param, struct timeval *timeout); |
tests/bandwidth-master.c
| @@ -26,7 +26,6 @@ | @@ -26,7 +26,6 @@ | ||
| 26 | #include <modbus.h> | 26 | #include <modbus.h> |
| 27 | 27 | ||
| 28 | /* Tests based on PI-MBUS-300 documentation */ | 28 | /* Tests based on PI-MBUS-300 documentation */ |
| 29 | -#define MY_ID 1 | ||
| 30 | #define SERVER_ID 17 | 29 | #define SERVER_ID 17 |
| 31 | #define NB_LOOPS 100000 | 30 | #define NB_LOOPS 100000 |
| 32 | 31 | ||
| @@ -55,7 +54,7 @@ int main(void) | @@ -55,7 +54,7 @@ int main(void) | ||
| 55 | int rc; | 54 | int rc; |
| 56 | 55 | ||
| 57 | /* TCP */ | 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 | rc = modbus_connect(&mb_param); | 58 | rc = modbus_connect(&mb_param); |
| 60 | if (rc == -1) { | 59 | if (rc == -1) { |
| 61 | fprintf(stderr, "Connexion failed: %s\n", | 60 | fprintf(stderr, "Connexion failed: %s\n", |
tests/bandwidth-slave-many-up.c
| @@ -48,7 +48,7 @@ int main(void) | @@ -48,7 +48,7 @@ int main(void) | ||
| 48 | /* Maximum file descriptor number */ | 48 | /* Maximum file descriptor number */ |
| 49 | int fdmax; | 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 | rc = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0); | 53 | rc = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0); |
| 54 | if (rc == -1) { | 54 | if (rc == -1) { |
tests/bandwidth-slave-one.c
| @@ -30,7 +30,7 @@ int main(void) | @@ -30,7 +30,7 @@ int main(void) | ||
| 30 | modbus_mapping_t mb_mapping; | 30 | modbus_mapping_t mb_mapping; |
| 31 | int rc; | 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 | rc = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0); | 35 | rc = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0); |
| 36 | if (rc == -1) { | 36 | if (rc == -1) { |
tests/random-test-master.c
| @@ -64,7 +64,7 @@ int main(void) | @@ -64,7 +64,7 @@ int main(void) | ||
| 64 | */ | 64 | */ |
| 65 | 65 | ||
| 66 | /* TCP */ | 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 | modbus_set_debug(&mb_param, TRUE); | 68 | modbus_set_debug(&mb_param, TRUE); |
| 69 | if (modbus_connect(&mb_param) == -1) { | 69 | if (modbus_connect(&mb_param) == -1) { |
| 70 | fprintf(stderr, "Connection failed: %s\n", | 70 | fprintf(stderr, "Connection failed: %s\n", |
tests/random-test-slave.c
| @@ -29,7 +29,7 @@ int main(void) | @@ -29,7 +29,7 @@ int main(void) | ||
| 29 | modbus_mapping_t mb_mapping; | 29 | modbus_mapping_t mb_mapping; |
| 30 | int rc; | 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 | /* modbus_set_debug(&mb_param, TRUE); */ | 33 | /* modbus_set_debug(&mb_param, TRUE); */ |
| 34 | 34 | ||
| 35 | rc = modbus_mapping_new(&mb_mapping, 500, 500, 500, 500); | 35 | rc = modbus_mapping_new(&mb_mapping, 500, 500, 500, 500); |
tests/unit-test-master.c
| @@ -46,7 +46,7 @@ int main(void) | @@ -46,7 +46,7 @@ int main(void) | ||
| 46 | */ | 46 | */ |
| 47 | 47 | ||
| 48 | /* TCP */ | 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 | modbus_set_debug(&mb_param, TRUE); | 50 | modbus_set_debug(&mb_param, TRUE); |
| 51 | 51 | ||
| 52 | if (modbus_connect(&mb_param) == -1) { | 52 | if (modbus_connect(&mb_param) == -1) { |
| @@ -450,16 +450,28 @@ int main(void) | @@ -450,16 +450,28 @@ int main(void) | ||
| 450 | 450 | ||
| 451 | /** SLAVE REPLY **/ | 451 | /** SLAVE REPLY **/ |
| 452 | printf("\nTEST SLAVE REPLY:\n"); | 452 | printf("\nTEST SLAVE REPLY:\n"); |
| 453 | + | ||
| 453 | rc = read_holding_registers(&mb_param, 18, | 454 | rc = read_holding_registers(&mb_param, 18, |
| 454 | UT_HOLDING_REGISTERS_ADDRESS, | 455 | UT_HOLDING_REGISTERS_ADDRESS, |
| 455 | UT_HOLDING_REGISTERS_NB_POINTS, | 456 | UT_HOLDING_REGISTERS_NB_POINTS, |
| 456 | tab_rp_registers); | 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 | } else { | 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 | rc = read_holding_registers(&mb_param, MODBUS_BROADCAST_ADDRESS, | 477 | rc = read_holding_registers(&mb_param, MODBUS_BROADCAST_ADDRESS, |
tests/unit-test-slave.c
| @@ -32,7 +32,7 @@ int main(void) | @@ -32,7 +32,7 @@ int main(void) | ||
| 32 | int rc; | 32 | int rc; |
| 33 | int i; | 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 | modbus_set_debug(&mb_param, TRUE); | 36 | modbus_set_debug(&mb_param, TRUE); |
| 37 | modbus_set_error_recovery(&mb_param, TRUE); | 37 | modbus_set_error_recovery(&mb_param, TRUE); |
| 38 | 38 |