From 018cdd6e686830c92976bfaaa89345f3c6bc9f18 Mon Sep 17 00:00:00 2001 From: Stéphane Raimbault Date: Sun, 1 May 2011 22:47:08 +0200 Subject: [PATCH] New function modbus_receive_confirmation --- doc/Makefile.am | 1 + doc/modbus_receive_confirmation.txt | 38 ++++++++++++++++++++++++++++++++++++++ doc/modbus_send_raw_request.txt | 4 ++-- src/modbus.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------- src/modbus.h | 2 ++ tests/unit-test-client.c | 4 ++-- 6 files changed, 107 insertions(+), 31 deletions(-) create mode 100644 doc/modbus_receive_confirmation.txt diff --git a/doc/Makefile.am b/doc/Makefile.am index 460eaf2..4dd6033 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -13,6 +13,7 @@ MAN3 = \ modbus_read_input_bits.3 \ modbus_read_input_registers.3 \ modbus_read_registers.3 \ + modbus_receive_confirmation.3 \ modbus_send_raw_request.3 \ modbus_set_debug.3 \ modbus_set_error_recovery.3 \ diff --git a/doc/modbus_receive_confirmation.txt b/doc/modbus_receive_confirmation.txt new file mode 100644 index 0000000..1764654 --- /dev/null +++ b/doc/modbus_receive_confirmation.txt @@ -0,0 +1,38 @@ +modbus_receive_confirmation(3) +============================== + + +NAME +---- +modbus_receive_confirmation - receive a confirmation request + + +SYNOPSIS +-------- +*int modbus_receive_confirmation(*modbus_t 'ctx', uint8_t *'rsp');* + + +DESCRIPTION +----------- +The _modbus_receive_confirmation()_ function shall receive a request via the +socket of the context 'ctx'. This function must be used for debugging purposes +because the received response isn't checked against the initial request. This +function can be used to receive request not handled by the library. + + +RETURN VALUE +------------ +The _modbus_receive_confirmation()_ function shall store the confirmation +request in 'rsp' and return the response length if sucessful. Otherwise it shall +return -1 and set errno. + + +SEE ALSO +-------- +linkmb:modbus_send_raw_request[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_send_raw_request.txt b/doc/modbus_send_raw_request.txt index 82ffe78..84b5b9a 100644 --- a/doc/modbus_send_raw_request.txt +++ b/doc/modbus_send_raw_request.txt @@ -47,7 +47,7 @@ if (modbus_connect(ctx) == -1) { } req_length = modbus_send_raw_request(ctx, raw_req, 6 * sizeof(uint8_t)); -modbus_receive(ctx, -1, rsp); +modbus_receive_confirmation(ctx, rsp); modbus_close(ctx); modbus_free(ctx); @@ -55,7 +55,7 @@ modbus_free(ctx); SEE ALSO -------- -linkmb:modbus_receive[3] +linkmb:modbus_receive_confirmation[3] AUTHORS diff --git a/src/modbus.c b/src/modbus.c index 66ada51..0fd7fd6 100644 --- a/src/modbus.c +++ b/src/modbus.c @@ -428,32 +428,34 @@ int modbus_receive(modbus_t *ctx, int sockfd, uint8_t *req) return receive_msg(ctx, req, MSG_INDICATION); } -/* Receives the response and checks values. +/* Receives the confirmation. - The function shall return the number of values (bits or words) and the - response if successful. Otherwise, its shall return -1 and errno is set. + The function shall store the read response in rsp and return the number of + values (bits or words). Otherwise, its shall return -1 and errno is set. - Note: all functions used to send or receive data with modbus return - these values. */ -static int receive_msg_req(modbus_t *ctx, uint8_t *req, uint8_t *rsp) + The function doesn't check the confirmation is the expected response to the + initial request. +*/ +int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp) +{ + return receive_msg(ctx, rsp, MSG_CONFIRMATION); +} + +static int check_confirmation(modbus_t *ctx, uint8_t *req, + uint8_t *rsp, uint8_t rsp_length) { int rc; int rsp_length_computed; - int offset = ctx->backend->header_length; - - rc = receive_msg(ctx, rsp, MSG_CONFIRMATION); - if (rc == -1) { - return -1; - } + const int offset = ctx->backend->header_length; rsp_length_computed = compute_response_length_from_request(ctx, req); /* Check length */ - if (rc == rsp_length_computed || + if (rsp_length == rsp_length_computed || rsp_length_computed == MSG_LENGTH_UNDEFINED) { int req_nb_value; int rsp_nb_value; - int function = rsp[offset]; + const int function = rsp[offset]; /* Check function code */ if (function != req[offset]) { @@ -510,7 +512,7 @@ static int receive_msg_req(modbus_t *ctx, uint8_t *req, uint8_t *rsp) errno = EMBBADDATA; rc = -1; } - } else if (rc == (offset + 2 + ctx->backend->checksum_length) && + } else if (rsp_length == (offset + 2 + ctx->backend->checksum_length) && req[offset] == (rsp[offset] - 0x80)) { /* EXCEPTION CODE RECEIVED */ @@ -526,7 +528,7 @@ static int receive_msg_req(modbus_t *ctx, uint8_t *req, uint8_t *rsp) if (ctx->debug) { fprintf(stderr, "Message length not corresponding to the computed length (%d != %d)\n", - rc, rsp_length_computed); + rsp_length, rsp_length_computed); } errno = EMBBADDATA; rc = -1; @@ -896,7 +898,11 @@ static int read_io_status(modbus_t *ctx, int function, int offset; int offset_end; - rc = receive_msg_req(ctx, req, rsp); + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION); + if (rc == -1) + return -1; + + rc = check_confirmation(ctx, req, rsp, rc); if (rc == -1) return -1; @@ -991,10 +997,13 @@ static int read_registers(modbus_t *ctx, int function, int addr, int nb, int offset; int i; - rc = receive_msg_req(ctx, req, rsp); - if (rc == -1) { + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION); + if (rc == -1) + return -1; + + rc = check_confirmation(ctx, req, rsp, rc); + if (rc == -1) return -1; - } offset = ctx->backend->header_length; @@ -1063,7 +1072,12 @@ static int write_single(modbus_t *ctx, int function, int addr, int value) if (rc > 0) { /* Used by write_bit and write_register */ uint8_t rsp[_MIN_REQ_LENGTH]; - rc = receive_msg_req(ctx, req, rsp); + + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION); + if (rc == -1) + return -1; + + rc = check_confirmation(ctx, req, rsp, rc); } return rc; @@ -1129,7 +1143,12 @@ int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src) rc = send_msg(ctx, req, req_length); if (rc > 0) { uint8_t rsp[MAX_MESSAGE_LENGTH]; - rc = receive_msg_req(ctx, req, rsp); + + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION); + if (rc == -1) + return -1; + + rc = check_confirmation(ctx, req, rsp, rc); } @@ -1170,7 +1189,12 @@ int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src) rc = send_msg(ctx, req, req_length); if (rc > 0) { uint8_t rsp[MAX_MESSAGE_LENGTH]; - rc = receive_msg_req(ctx, req, rsp); + + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION); + if (rc == -1) + return -1; + + rc = check_confirmation(ctx, req, rsp, rc); } return rc; @@ -1228,7 +1252,14 @@ int modbus_read_and_write_registers(modbus_t *ctx, if (rc > 0) { int offset; - rc = receive_msg_req(ctx, req, rsp); + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION); + if (rc == -1) + return -1; + + rc = check_confirmation(ctx, req, rsp, rc); + if (rc == -1) + return -1; + offset = ctx->backend->header_length; /* If rc is negative, the loop is jumped ! */ @@ -1262,14 +1293,18 @@ int modbus_report_slave_id(modbus_t *ctx, uint8_t *dest) int offset; uint8_t rsp[MAX_MESSAGE_LENGTH]; - /* Byte count, slave id, run indicator status, - additional data */ - rc = receive_msg_req(ctx, req, rsp); + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION); + if (rc == -1) + return -1; + + rc = check_confirmation(ctx, req, rsp, rc); if (rc == -1) return -1; offset = ctx->backend->header_length + 2; + /* Byte count, slave id, run indicator status, + additional data */ for (i=0; i < rc; i++) { dest[i] = rsp[offset + i]; } diff --git a/src/modbus.h b/src/modbus.h index 6d51762..ad9ebfa 100644 --- a/src/modbus.h +++ b/src/modbus.h @@ -176,6 +176,8 @@ void modbus_mapping_free(modbus_mapping_t *mb_mapping); int modbus_send_raw_request(modbus_t *ctx, uint8_t *raw_req, int raw_req_length); int modbus_receive(modbus_t *ctx, int sockfd, uint8_t *req); +int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp); + int modbus_reply(modbus_t *ctx, const uint8_t *req, int req_length, modbus_mapping_t *mb_mapping); int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, diff --git a/tests/unit-test-client.c b/tests/unit-test-client.c index 093aa97..4182355 100644 --- a/tests/unit-test-client.c +++ b/tests/unit-test-client.c @@ -649,8 +649,8 @@ int main(int argc, char *argv[]) goto close; } - printf("* modbus_receive: "); - rc = modbus_receive(ctx, -1, rsp); + printf("* modbus_receive_confirmation: "); + rc = modbus_receive_confirmation(ctx, rsp); if ((use_backend == RTU && rc == 15) || ((use_backend == TCP || use_backend == TCP_PI) && rc == 19)) { -- libgit2 0.21.4