Commit 4d3bf7beeaa8c196957c8daa76fa7dc51941b859
1 parent
86418cf3
Implement report slave ID on server side
- return only useful data client side - available in TCP when a gateway to RTU is used - need to add isolated handling of indication/confirmation messages
Showing
4 changed files
with
97 additions
and
38 deletions
NEWS
| 1 | libmodbus 2.1.1 (2010-XX-XX) | 1 | libmodbus 2.1.1 (2010-XX-XX) |
| 2 | ============================ | 2 | ============================ |
| 3 | 3 | ||
| 4 | +- New API | ||
| 4 | - Remove the internal function set_message_length_tcp | 5 | - Remove the internal function set_message_length_tcp |
| 5 | - Restore slave ID (server ID) argument in functions | 6 | - Restore slave ID (server ID) argument in functions |
| 6 | - Error conventions of POSIX systems and error recover | 7 | - Error conventions of POSIX systems and error recover |
| @@ -13,6 +14,7 @@ libmodbus 2.1.1 (2010-XX-XX) | @@ -13,6 +14,7 @@ libmodbus 2.1.1 (2010-XX-XX) | ||
| 13 | - Fix #591142 - Slave id check should be disabled in TCP connection | 14 | - Fix #591142 - Slave id check should be disabled in TCP connection |
| 14 | Reported by aladdinwu. | 15 | Reported by aladdinwu. |
| 15 | - Parity setting is now a single char ('N', 'E' or 'O') | 16 | - Parity setting is now a single char ('N', 'E' or 'O') |
| 17 | +- Report slave ID server side | ||
| 16 | 18 | ||
| 17 | libmodbus 2.1.0 (2010-03-24) | 19 | libmodbus 2.1.0 (2010-03-24) |
| 18 | ============================ | 20 | ============================ |
src/modbus.c
| @@ -479,7 +479,7 @@ static int send_msg(modbus_t *ctx, uint8_t *req, int req_length) | @@ -479,7 +479,7 @@ static int send_msg(modbus_t *ctx, uint8_t *req, int req_length) | ||
| 479 | } | 479 | } |
| 480 | 480 | ||
| 481 | /* Computes the length of the header following the function code */ | 481 | /* Computes the length of the header following the function code */ |
| 482 | -static uint8_t compute_request_length_header(int function) | 482 | +static uint8_t compute_indication_length_header(int function) |
| 483 | { | 483 | { |
| 484 | int length; | 484 | int length; |
| 485 | 485 | ||
| @@ -492,6 +492,28 @@ static uint8_t compute_request_length_header(int function) | @@ -492,6 +492,28 @@ static uint8_t compute_request_length_header(int function) | ||
| 492 | /* Multiple write */ | 492 | /* Multiple write */ |
| 493 | length = 5; | 493 | length = 5; |
| 494 | else if (function == FC_REPORT_SLAVE_ID) | 494 | else if (function == FC_REPORT_SLAVE_ID) |
| 495 | + length = 0; | ||
| 496 | + else | ||
| 497 | + length = 0; | ||
| 498 | + | ||
| 499 | + return length; | ||
| 500 | +} | ||
| 501 | + | ||
| 502 | +/* Computes the length of the header following the function code */ | ||
| 503 | +static uint8_t compute_confirmation_length_header(int function) | ||
| 504 | +{ | ||
| 505 | + int length; | ||
| 506 | + | ||
| 507 | + if (function <= FC_WRITE_SINGLE_COIL || | ||
| 508 | + function == FC_WRITE_SINGLE_REGISTER) | ||
| 509 | + /* Read and single write */ | ||
| 510 | + length = 4; | ||
| 511 | + else if (function == FC_WRITE_MULTIPLE_COILS || | ||
| 512 | + function == FC_WRITE_MULTIPLE_REGISTERS) | ||
| 513 | + /* Multiple write */ | ||
| 514 | + length = 5; | ||
| 515 | + else if (function == FC_REPORT_SLAVE_ID) | ||
| 516 | + /* Report slave_ID */ | ||
| 495 | length = 1; | 517 | length = 1; |
| 496 | else | 518 | else |
| 497 | length = 0; | 519 | length = 0; |
| @@ -500,17 +522,17 @@ static uint8_t compute_request_length_header(int function) | @@ -500,17 +522,17 @@ static uint8_t compute_request_length_header(int function) | ||
| 500 | } | 522 | } |
| 501 | 523 | ||
| 502 | /* Computes the length of the data to write in the request */ | 524 | /* Computes the length of the data to write in the request */ |
| 503 | -static int compute_request_length_data(modbus_t *ctx, uint8_t *msg) | 525 | +static int compute_msg_length_data(modbus_t *ctx, uint8_t *msg) |
| 504 | { | 526 | { |
| 505 | int function = msg[TAB_HEADER_LENGTH[ctx->type_com]]; | 527 | int function = msg[TAB_HEADER_LENGTH[ctx->type_com]]; |
| 506 | int length; | 528 | int length; |
| 507 | 529 | ||
| 508 | if (function == FC_WRITE_MULTIPLE_COILS || | 530 | if (function == FC_WRITE_MULTIPLE_COILS || |
| 509 | - function == FC_WRITE_MULTIPLE_REGISTERS) | 531 | + function == FC_WRITE_MULTIPLE_REGISTERS) { |
| 510 | length = msg[TAB_HEADER_LENGTH[ctx->type_com] + 5]; | 532 | length = msg[TAB_HEADER_LENGTH[ctx->type_com] + 5]; |
| 511 | - else if (function == FC_REPORT_SLAVE_ID) | 533 | + } else if (function == FC_REPORT_SLAVE_ID) { |
| 512 | length = msg[TAB_HEADER_LENGTH[ctx->type_com] + 1]; | 534 | length = msg[TAB_HEADER_LENGTH[ctx->type_com] + 1]; |
| 513 | - else | 535 | + } else |
| 514 | length = 0; | 536 | length = 0; |
| 515 | 537 | ||
| 516 | length += TAB_CHECKSUM_LENGTH[ctx->type_com]; | 538 | length += TAB_CHECKSUM_LENGTH[ctx->type_com]; |
| @@ -573,7 +595,14 @@ static int compute_request_length_data(modbus_t *ctx, uint8_t *msg) | @@ -573,7 +595,14 @@ static int compute_request_length_data(modbus_t *ctx, uint8_t *msg) | ||
| 573 | - ETIMEDOUT | 595 | - ETIMEDOUT |
| 574 | - read() or recv() error codes | 596 | - read() or recv() error codes |
| 575 | */ | 597 | */ |
| 576 | -static int receive_msg(modbus_t *ctx, int msg_length_computed, uint8_t *msg) | 598 | +enum { |
| 599 | + /* Request message on the server side */ | ||
| 600 | + MSG_INDICATION, | ||
| 601 | + /* Request message on the client side */ | ||
| 602 | + MSG_CONFIRMATION | ||
| 603 | +}; | ||
| 604 | + | ||
| 605 | +static int receive_msg(modbus_t *ctx, int msg_length_computed, uint8_t *msg, int type) | ||
| 577 | { | 606 | { |
| 578 | int s_rc; | 607 | int s_rc; |
| 579 | int read_rc; | 608 | int read_rc; |
| @@ -586,11 +615,16 @@ static int receive_msg(modbus_t *ctx, int msg_length_computed, uint8_t *msg) | @@ -586,11 +615,16 @@ static int receive_msg(modbus_t *ctx, int msg_length_computed, uint8_t *msg) | ||
| 586 | int msg_length = 0; | 615 | int msg_length = 0; |
| 587 | 616 | ||
| 588 | if (ctx->debug) { | 617 | if (ctx->debug) { |
| 618 | + if (type == MSG_INDICATION) { | ||
| 619 | + printf("Waiting for a indication"); | ||
| 620 | + } else { | ||
| 621 | + printf("Waiting for a confirmation"); | ||
| 622 | + } | ||
| 623 | + | ||
| 589 | if (msg_length_computed == MSG_LENGTH_UNDEFINED) | 624 | if (msg_length_computed == MSG_LENGTH_UNDEFINED) |
| 590 | - printf("Waiting for a message...\n"); | 625 | + printf("...\n"); |
| 591 | else | 626 | else |
| 592 | - printf("Waiting for a message (%d bytes)...\n", | ||
| 593 | - msg_length_computed); | 627 | + printf("(%d bytes)...\n", msg_length_computed); |
| 594 | } | 628 | } |
| 595 | 629 | ||
| 596 | /* Add a file descriptor to the set */ | 630 | /* Add a file descriptor to the set */ |
| @@ -661,8 +695,13 @@ static int receive_msg(modbus_t *ctx, int msg_length_computed, uint8_t *msg) | @@ -661,8 +695,13 @@ static int receive_msg(modbus_t *ctx, int msg_length_computed, uint8_t *msg) | ||
| 661 | switch (state) { | 695 | switch (state) { |
| 662 | case FUNCTION: | 696 | case FUNCTION: |
| 663 | /* Function code position */ | 697 | /* Function code position */ |
| 664 | - length_to_read = compute_request_length_header( | ||
| 665 | - msg[TAB_HEADER_LENGTH[ctx->type_com]]); | 698 | + if (type == MSG_INDICATION) { |
| 699 | + length_to_read = compute_indication_length_header( | ||
| 700 | + msg[TAB_HEADER_LENGTH[ctx->type_com]]); | ||
| 701 | + } else { | ||
| 702 | + length_to_read = compute_confirmation_length_header( | ||
| 703 | + msg[TAB_HEADER_LENGTH[ctx->type_com]]); | ||
| 704 | + } | ||
| 666 | msg_length_computed += length_to_read; | 705 | msg_length_computed += length_to_read; |
| 667 | /* It's useless to check the value of | 706 | /* It's useless to check the value of |
| 668 | msg_length_computed in this case (only | 707 | msg_length_computed in this case (only |
| @@ -670,7 +709,7 @@ static int receive_msg(modbus_t *ctx, int msg_length_computed, uint8_t *msg) | @@ -670,7 +709,7 @@ static int receive_msg(modbus_t *ctx, int msg_length_computed, uint8_t *msg) | ||
| 670 | state = DATA; | 709 | state = DATA; |
| 671 | break; | 710 | break; |
| 672 | case DATA: | 711 | case DATA: |
| 673 | - length_to_read = compute_request_length_data(ctx, msg); | 712 | + length_to_read = compute_msg_length_data(ctx, msg); |
| 674 | msg_length_computed += length_to_read; | 713 | msg_length_computed += length_to_read; |
| 675 | if (msg_length_computed > TAB_MAX_ADU_LENGTH[ctx->type_com]) { | 714 | if (msg_length_computed > TAB_MAX_ADU_LENGTH[ctx->type_com]) { |
| 676 | errno = EMBBADDATA; | 715 | errno = EMBBADDATA; |
| @@ -727,7 +766,7 @@ int modbus_receive(modbus_t *ctx, int sockfd, uint8_t *req) | @@ -727,7 +766,7 @@ int modbus_receive(modbus_t *ctx, int sockfd, uint8_t *req) | ||
| 727 | } | 766 | } |
| 728 | 767 | ||
| 729 | /* The length of the request to receive isn't known. */ | 768 | /* The length of the request to receive isn't known. */ |
| 730 | - return receive_msg(ctx, MSG_LENGTH_UNDEFINED, req); | 769 | + return receive_msg(ctx, MSG_LENGTH_UNDEFINED, req, MSG_INDICATION); |
| 731 | } | 770 | } |
| 732 | 771 | ||
| 733 | /* Receives the response and checks values (and checksum in RTU). | 772 | /* Receives the response and checks values (and checksum in RTU). |
| @@ -744,7 +783,7 @@ static int receive_msg_req(modbus_t *ctx, uint8_t *req, uint8_t *rsp) | @@ -744,7 +783,7 @@ static int receive_msg_req(modbus_t *ctx, uint8_t *req, uint8_t *rsp) | ||
| 744 | int offset = TAB_HEADER_LENGTH[ctx->type_com]; | 783 | int offset = TAB_HEADER_LENGTH[ctx->type_com]; |
| 745 | 784 | ||
| 746 | rsp_length_computed = compute_response_length(ctx, req); | 785 | rsp_length_computed = compute_response_length(ctx, req); |
| 747 | - rc = receive_msg(ctx, rsp_length_computed, rsp); | 786 | + rc = receive_msg(ctx, rsp_length_computed, rsp, MSG_CONFIRMATION); |
| 748 | if (rc != -1) { | 787 | if (rc != -1) { |
| 749 | /* GOOD RESPONSE */ | 788 | /* GOOD RESPONSE */ |
| 750 | int req_nb_value; | 789 | int req_nb_value; |
| @@ -776,7 +815,7 @@ static int receive_msg_req(modbus_t *ctx, uint8_t *req, uint8_t *rsp) | @@ -776,7 +815,7 @@ static int receive_msg_req(modbus_t *ctx, uint8_t *req, uint8_t *rsp) | ||
| 776 | break; | 815 | break; |
| 777 | case FC_REPORT_SLAVE_ID: | 816 | case FC_REPORT_SLAVE_ID: |
| 778 | /* Report slave ID (bytes received) */ | 817 | /* Report slave ID (bytes received) */ |
| 779 | - req_nb_value = rsp_nb_value = rc; | 818 | + req_nb_value = rsp_nb_value = rsp[offset + 1]; |
| 780 | break; | 819 | break; |
| 781 | default: | 820 | default: |
| 782 | /* 1 Write functions & others */ | 821 | /* 1 Write functions & others */ |
| @@ -1088,8 +1127,15 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -1088,8 +1127,15 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 1088 | } | 1127 | } |
| 1089 | } | 1128 | } |
| 1090 | break; | 1129 | break; |
| 1091 | - case FC_READ_EXCEPTION_STATUS: | ||
| 1092 | case FC_REPORT_SLAVE_ID: | 1130 | case FC_REPORT_SLAVE_ID: |
| 1131 | + resp_length = build_response_basis(ctx, &sft, rsp); | ||
| 1132 | + /* 2 bytes */ | ||
| 1133 | + rsp[resp_length++] = 2; | ||
| 1134 | + rsp[resp_length++] = ctx->slave; | ||
| 1135 | + /* Slave is ON */ | ||
| 1136 | + rsp[resp_length++] = 0xFF; | ||
| 1137 | + break; | ||
| 1138 | + case FC_READ_EXCEPTION_STATUS: | ||
| 1093 | if (ctx->debug) { | 1139 | if (ctx->debug) { |
| 1094 | fprintf(stderr, "FIXME Not implemented\n"); | 1140 | fprintf(stderr, "FIXME Not implemented\n"); |
| 1095 | } | 1141 | } |
| @@ -1127,11 +1173,11 @@ static int read_io_status(modbus_t *ctx, int function, | @@ -1127,11 +1173,11 @@ static int read_io_status(modbus_t *ctx, int function, | ||
| 1127 | if (rc == -1) | 1173 | if (rc == -1) |
| 1128 | return -1; | 1174 | return -1; |
| 1129 | 1175 | ||
| 1130 | - offset = TAB_HEADER_LENGTH[ctx->type_com]; | 1176 | + offset = TAB_HEADER_LENGTH[ctx->type_com] + 2; |
| 1131 | offset_end = offset + rc; | 1177 | offset_end = offset + rc; |
| 1132 | for (i = offset; i < offset_end; i++) { | 1178 | for (i = offset; i < offset_end; i++) { |
| 1133 | /* Shift reg hi_byte to temp */ | 1179 | /* Shift reg hi_byte to temp */ |
| 1134 | - temp = rsp[i + 2]; | 1180 | + temp = rsp[i]; |
| 1135 | 1181 | ||
| 1136 | for (bit = 0x01; (bit & 0xff) && (pos < nb);) { | 1182 | for (bit = 0x01; (bit & 0xff) && (pos < nb);) { |
| 1137 | data_dest[pos++] = (temp & bit) ? TRUE : FALSE; | 1183 | data_dest[pos++] = (temp & bit) ? TRUE : FALSE; |
| @@ -1410,19 +1456,13 @@ int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *data | @@ -1410,19 +1456,13 @@ int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *data | ||
| 1410 | } | 1456 | } |
| 1411 | 1457 | ||
| 1412 | /* Send a request to get the slave ID of the device (only available in serial | 1458 | /* Send a request to get the slave ID of the device (only available in serial |
| 1413 | - * communication) */ | 1459 | + * communication). */ |
| 1414 | int modbus_report_slave_id(modbus_t *ctx, uint8_t *data_dest) | 1460 | int modbus_report_slave_id(modbus_t *ctx, uint8_t *data_dest) |
| 1415 | { | 1461 | { |
| 1416 | int rc; | 1462 | int rc; |
| 1417 | int req_length; | 1463 | int req_length; |
| 1418 | uint8_t req[MIN_REQ_LENGTH]; | 1464 | uint8_t req[MIN_REQ_LENGTH]; |
| 1419 | 1465 | ||
| 1420 | - if (ctx->type_com != RTU) { | ||
| 1421 | - /* Only for serial communications */ | ||
| 1422 | - errno = EINVAL; | ||
| 1423 | - return -1; | ||
| 1424 | - } | ||
| 1425 | - | ||
| 1426 | req_length = build_request_basis(ctx, FC_REPORT_SLAVE_ID, 0, 0, req); | 1466 | req_length = build_request_basis(ctx, FC_REPORT_SLAVE_ID, 0, 0, req); |
| 1427 | 1467 | ||
| 1428 | /* HACKISH, addr and count are not used */ | 1468 | /* HACKISH, addr and count are not used */ |
| @@ -1432,7 +1472,6 @@ int modbus_report_slave_id(modbus_t *ctx, uint8_t *data_dest) | @@ -1432,7 +1472,6 @@ int modbus_report_slave_id(modbus_t *ctx, uint8_t *data_dest) | ||
| 1432 | if (rc > 0) { | 1472 | if (rc > 0) { |
| 1433 | int i; | 1473 | int i; |
| 1434 | int offset; | 1474 | int offset; |
| 1435 | - int offset_end; | ||
| 1436 | uint8_t rsp[MAX_MESSAGE_LENGTH]; | 1475 | uint8_t rsp[MAX_MESSAGE_LENGTH]; |
| 1437 | 1476 | ||
| 1438 | /* Byte count, slave id, run indicator status, | 1477 | /* Byte count, slave id, run indicator status, |
| @@ -1441,11 +1480,11 @@ int modbus_report_slave_id(modbus_t *ctx, uint8_t *data_dest) | @@ -1441,11 +1480,11 @@ int modbus_report_slave_id(modbus_t *ctx, uint8_t *data_dest) | ||
| 1441 | if (rc == -1) | 1480 | if (rc == -1) |
| 1442 | return -1; | 1481 | return -1; |
| 1443 | 1482 | ||
| 1444 | - offset = TAB_HEADER_LENGTH[ctx->type_com] - 1; | ||
| 1445 | - offset_end = offset + rc; | 1483 | + offset = TAB_HEADER_LENGTH[ctx->type_com] + 2; |
| 1446 | 1484 | ||
| 1447 | - for (i = offset; i < offset_end; i++) | ||
| 1448 | - data_dest[i] = rsp[i]; | 1485 | + for (i=0; i < rc; i++) { |
| 1486 | + data_dest[i] = rsp[offset + i]; | ||
| 1487 | + } | ||
| 1449 | } | 1488 | } |
| 1450 | 1489 | ||
| 1451 | return rc; | 1490 | return rc; |
tests/unit-test-client.c
| @@ -443,7 +443,7 @@ int main(void) | @@ -443,7 +443,7 @@ int main(void) | ||
| 443 | rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, | 443 | rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, |
| 444 | UT_REGISTERS_NB_POINTS, | 444 | UT_REGISTERS_NB_POINTS, |
| 445 | tab_rp_registers); | 445 | tab_rp_registers); |
| 446 | - printf("1/3 No or response from slave %d: ", 18); | 446 | + printf("1/4 No or response from slave %d: ", 18); |
| 447 | if (is_mode_rtu) { | 447 | if (is_mode_rtu) { |
| 448 | /* No response in RTU mode */ | 448 | /* No response in RTU mode */ |
| 449 | if (rc == -1 && errno == ETIMEDOUT) { | 449 | if (rc == -1 && errno == ETIMEDOUT) { |
| @@ -466,7 +466,7 @@ int main(void) | @@ -466,7 +466,7 @@ int main(void) | ||
| 466 | rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, | 466 | rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, |
| 467 | UT_REGISTERS_NB_POINTS, | 467 | UT_REGISTERS_NB_POINTS, |
| 468 | tab_rp_registers); | 468 | tab_rp_registers); |
| 469 | - printf("2/3 Reply after a broadcast query: "); | 469 | + printf("2/4 Reply after a broadcast query: "); |
| 470 | if (rc == UT_REGISTERS_NB_POINTS) { | 470 | if (rc == UT_REGISTERS_NB_POINTS) { |
| 471 | printf("OK\n"); | 471 | printf("OK\n"); |
| 472 | } else { | 472 | } else { |
| @@ -481,6 +481,22 @@ int main(void) | @@ -481,6 +481,22 @@ int main(void) | ||
| 481 | modbus_set_slave(ctx, MODBUS_TCP_SLAVE); | 481 | modbus_set_slave(ctx, MODBUS_TCP_SLAVE); |
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | + printf("3/4 Report slave ID: \n"); | ||
| 485 | + /* tab_rp_bits is used to store bytes */ | ||
| 486 | + rc = modbus_report_slave_id(ctx, tab_rp_bits); | ||
| 487 | + if (rc == -1) { | ||
| 488 | + printf("FAILED\n"); | ||
| 489 | + goto close; | ||
| 490 | + } | ||
| 491 | + | ||
| 492 | + if ((is_mode_rtu && tab_rp_bits[0] == SERVER_ID) | ||
| 493 | + || tab_rp_bits[0] == 0xFF) { | ||
| 494 | + printf("OK\n"); | ||
| 495 | + } else { | ||
| 496 | + printf("FAILED\n"); | ||
| 497 | + goto close; | ||
| 498 | + } | ||
| 499 | + | ||
| 484 | /* Save original timeout */ | 500 | /* Save original timeout */ |
| 485 | modbus_get_timeout_begin(ctx, &timeout_begin_old); | 501 | modbus_get_timeout_begin(ctx, &timeout_begin_old); |
| 486 | 502 | ||
| @@ -492,7 +508,7 @@ int main(void) | @@ -492,7 +508,7 @@ int main(void) | ||
| 492 | rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, | 508 | rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, |
| 493 | UT_REGISTERS_NB_POINTS, | 509 | UT_REGISTERS_NB_POINTS, |
| 494 | tab_rp_registers); | 510 | tab_rp_registers); |
| 495 | - printf("3/3 Too short timeout: "); | 511 | + printf("4/4 Too short timeout: "); |
| 496 | if (rc == -1 && errno == ETIMEDOUT) { | 512 | if (rc == -1 && errno == ETIMEDOUT) { |
| 497 | printf("OK\n"); | 513 | printf("OK\n"); |
| 498 | } else { | 514 | } else { |
tests/unit-test-server.c
| @@ -39,10 +39,11 @@ int main(void) | @@ -39,10 +39,11 @@ int main(void) | ||
| 39 | modbus_set_debug(ctx, TRUE); | 39 | modbus_set_debug(ctx, TRUE); |
| 40 | modbus_set_error_recovery(ctx, TRUE); | 40 | modbus_set_error_recovery(ctx, TRUE); |
| 41 | 41 | ||
| 42 | - mb_mapping = modbus_mapping_new(UT_BITS_ADDRESS + UT_BITS_NB_POINTS, | ||
| 43 | - UT_INPUT_BITS_ADDRESS + UT_INPUT_BITS_NB_POINTS, | ||
| 44 | - UT_REGISTERS_ADDRESS + UT_REGISTERS_NB_POINTS, | ||
| 45 | - UT_INPUT_REGISTERS_ADDRESS + UT_INPUT_REGISTERS_NB_POINTS); | 42 | + mb_mapping = modbus_mapping_new( |
| 43 | + UT_BITS_ADDRESS + UT_BITS_NB_POINTS, | ||
| 44 | + UT_INPUT_BITS_ADDRESS + UT_INPUT_BITS_NB_POINTS, | ||
| 45 | + UT_REGISTERS_ADDRESS + UT_REGISTERS_NB_POINTS, | ||
| 46 | + UT_INPUT_REGISTERS_ADDRESS + UT_INPUT_REGISTERS_NB_POINTS); | ||
| 46 | if (mb_mapping == NULL) { | 47 | if (mb_mapping == NULL) { |
| 47 | fprintf(stderr, "Failed to allocate the mapping: %s\n", | 48 | fprintf(stderr, "Failed to allocate the mapping: %s\n", |
| 48 | modbus_strerror(errno)); | 49 | modbus_strerror(errno)); |
| @@ -72,7 +73,8 @@ int main(void) | @@ -72,7 +73,8 @@ int main(void) | ||
| 72 | 73 | ||
| 73 | rc = modbus_receive(ctx, -1, query); | 74 | rc = modbus_receive(ctx, -1, query); |
| 74 | if (rc > 0) { | 75 | if (rc > 0) { |
| 75 | - if (((query[HEADER_LENGTH_TCP + 3] << 8) + query[HEADER_LENGTH_TCP + 4]) | 76 | + if (((query[HEADER_LENGTH_TCP + 3] << 8) + |
| 77 | + query[HEADER_LENGTH_TCP + 4]) | ||
| 76 | == UT_REGISTERS_NB_POINTS_SPECIAL) { | 78 | == UT_REGISTERS_NB_POINTS_SPECIAL) { |
| 77 | /* Change the number of values (offset | 79 | /* Change the number of values (offset |
| 78 | TCP = 6) */ | 80 | TCP = 6) */ |