Commit 55d9a371f1b0b8efdc43d9935071c74720253f79
1 parent
a06255be
Protect all public functions against invalid context
- change return argument from void to int - update documentation
Showing
11 changed files
with
222 additions
and
32 deletions
doc/modbus_get_byte_timeout.txt
| @@ -9,7 +9,7 @@ modbus_get_byte_timeout - get timeout between bytes | @@ -9,7 +9,7 @@ modbus_get_byte_timeout - get timeout between bytes | ||
| 9 | 9 | ||
| 10 | SYNOPSIS | 10 | SYNOPSIS |
| 11 | -------- | 11 | -------- |
| 12 | -*void modbus_get_byte_timeout(modbus_t *'ctx', struct timeval *'timeout');* | 12 | +*int modbus_get_byte_timeout(modbus_t *'ctx', struct timeval *'timeout');* |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | DESCRIPTION | 15 | DESCRIPTION |
| @@ -20,7 +20,7 @@ between two consecutive bytes of the same message in the 'timeout' argument. | @@ -20,7 +20,7 @@ between two consecutive bytes of the same message in the 'timeout' argument. | ||
| 20 | 20 | ||
| 21 | RETURN VALUE | 21 | RETURN VALUE |
| 22 | ------------ | 22 | ------------ |
| 23 | -There is no return values. | 23 | +The function shall return 0 if successful. Otherwise it shall return -1 and set errno. |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | EXAMPLE | 26 | EXAMPLE |
doc/modbus_get_response_timeout.txt
| @@ -9,7 +9,7 @@ modbus_get_response_timeout - get timeout for response | @@ -9,7 +9,7 @@ modbus_get_response_timeout - get timeout for response | ||
| 9 | 9 | ||
| 10 | SYNOPSIS | 10 | SYNOPSIS |
| 11 | -------- | 11 | -------- |
| 12 | -*void modbus_get_response_timeout(modbus_t *'ctx', struct timeval *'timeout');* | 12 | +*int modbus_get_response_timeout(modbus_t *'ctx', struct timeval *'timeout');* |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | DESCRIPTION | 15 | DESCRIPTION |
| @@ -20,7 +20,7 @@ used to wait for a response in the 'timeout' argument. | @@ -20,7 +20,7 @@ used to wait for a response in the 'timeout' argument. | ||
| 20 | 20 | ||
| 21 | RETURN VALUE | 21 | RETURN VALUE |
| 22 | ------------ | 22 | ------------ |
| 23 | -There is no return values. | 23 | +The function shall return 0 if successful. Otherwise it shall return -1 and set errno. |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | EXAMPLE | 26 | EXAMPLE |
doc/modbus_get_socket.txt
| @@ -20,7 +20,8 @@ descriptor of the libmodbus context. | @@ -20,7 +20,8 @@ descriptor of the libmodbus context. | ||
| 20 | 20 | ||
| 21 | RETURN VALUE | 21 | RETURN VALUE |
| 22 | ------------ | 22 | ------------ |
| 23 | -The current socket or file descriptor of the context. | 23 | +The function returns the current socket or file descriptor of the context if |
| 24 | +successful. Otherwise it shall return -1 and set errno. | ||
| 24 | 25 | ||
| 25 | 26 | ||
| 26 | SEE ALSO | 27 | SEE ALSO |
doc/modbus_set_byte_timeout.txt
| @@ -22,9 +22,10 @@ If the timeout value has a tv_sec of -1 then this timeout will not be used at | @@ -22,9 +22,10 @@ If the timeout value has a tv_sec of -1 then this timeout will not be used at | ||
| 22 | all. This results in modbus_set_response_timeout governing the entire timeout | 22 | all. This results in modbus_set_response_timeout governing the entire timeout |
| 23 | duration of an operation. | 23 | duration of an operation. |
| 24 | 24 | ||
| 25 | + | ||
| 25 | RETURN VALUE | 26 | RETURN VALUE |
| 26 | ------------ | 27 | ------------ |
| 27 | -There is no return values. | 28 | +The function shall return 0 if successful. Otherwise it shall return -1 and set errno. |
| 28 | 29 | ||
| 29 | 30 | ||
| 30 | SEE ALSO | 31 | SEE ALSO |
doc/modbus_set_debug.txt
| @@ -8,7 +8,7 @@ modbus_set_debug - set debug flag of the context | @@ -8,7 +8,7 @@ modbus_set_debug - set debug flag of the context | ||
| 8 | 8 | ||
| 9 | SYNOPSIS | 9 | SYNOPSIS |
| 10 | -------- | 10 | -------- |
| 11 | -*void modbus_set_debug(modbus_t *'ctx', int 'boolean');* | 11 | +*int modbus_set_debug(modbus_t *'ctx', int 'boolean');* |
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | DESCRIPTION | 14 | DESCRIPTION |
| @@ -28,7 +28,7 @@ ___________________ | @@ -28,7 +28,7 @@ ___________________ | ||
| 28 | 28 | ||
| 29 | RETURN VALUE | 29 | RETURN VALUE |
| 30 | ------------ | 30 | ------------ |
| 31 | -There is no return values. | 31 | +The function shall return 0 if successful. Otherwise it shall return -1 and set errno. |
| 32 | 32 | ||
| 33 | 33 | ||
| 34 | AUTHORS | 34 | AUTHORS |
doc/modbus_set_response_timeout.txt
| @@ -9,7 +9,7 @@ modbus_set_response_timeout - set timeout for response | @@ -9,7 +9,7 @@ modbus_set_response_timeout - set timeout for response | ||
| 9 | 9 | ||
| 10 | SYNOPSIS | 10 | SYNOPSIS |
| 11 | -------- | 11 | -------- |
| 12 | -*void modbus_set_response_timeout(modbus_t *'ctx', struct timeval *'timeout');* | 12 | +*int modbus_set_response_timeout(modbus_t *'ctx', struct timeval *'timeout');* |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | DESCRIPTION | 15 | DESCRIPTION |
| @@ -21,7 +21,7 @@ the given timeout, an error will be raised. | @@ -21,7 +21,7 @@ the given timeout, an error will be raised. | ||
| 21 | 21 | ||
| 22 | RETURN VALUE | 22 | RETURN VALUE |
| 23 | ------------ | 23 | ------------ |
| 24 | -There is no return values. | 24 | +The function shall return 0 if successful. Otherwise it shall return -1 and set errno. |
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | EXAMPLE | 27 | EXAMPLE |
doc/modbus_set_socket.txt
| @@ -9,7 +9,7 @@ modbus_set_socket - set socket of the context | @@ -9,7 +9,7 @@ modbus_set_socket - set socket of the context | ||
| 9 | 9 | ||
| 10 | SYNOPSIS | 10 | SYNOPSIS |
| 11 | -------- | 11 | -------- |
| 12 | -*void modbus_set_socket(modbus_t *'ctx', int 'socket');* | 12 | +*int modbus_set_socket(modbus_t *'ctx', int 'socket');* |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | DESCRIPTION | 15 | DESCRIPTION |
| @@ -21,7 +21,7 @@ connections to the same server. | @@ -21,7 +21,7 @@ connections to the same server. | ||
| 21 | 21 | ||
| 22 | RETURN VALUE | 22 | RETURN VALUE |
| 23 | ------------ | 23 | ------------ |
| 24 | -There is no return values. | 24 | +The function shall return 0 if successful. Otherwise it shall return -1 and set errno. |
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | EXAMPLE | 27 | EXAMPLE |
src/modbus-rtu.c
| @@ -567,8 +567,6 @@ static int _modbus_rtu_connect(modbus_t *ctx) | @@ -567,8 +567,6 @@ static int _modbus_rtu_connect(modbus_t *ctx) | ||
| 567 | /* Don't want errors to be blocking */ | 567 | /* Don't want errors to be blocking */ |
| 568 | dcb.fAbortOnError = FALSE; | 568 | dcb.fAbortOnError = FALSE; |
| 569 | 569 | ||
| 570 | - /* TODO: any other flags!? */ | ||
| 571 | - | ||
| 572 | /* Setup port */ | 570 | /* Setup port */ |
| 573 | if (!SetCommState(ctx_rtu->w_ser.fd, &dcb)) { | 571 | if (!SetCommState(ctx_rtu->w_ser.fd, &dcb)) { |
| 574 | fprintf(stderr, "ERROR Error setting new configuration (LastError %d)\n", | 572 | fprintf(stderr, "ERROR Error setting new configuration (LastError %d)\n", |
| @@ -900,6 +898,11 @@ static int _modbus_rtu_connect(modbus_t *ctx) | @@ -900,6 +898,11 @@ static int _modbus_rtu_connect(modbus_t *ctx) | ||
| 900 | 898 | ||
| 901 | int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode) | 899 | int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode) |
| 902 | { | 900 | { |
| 901 | + if (ctx == NULL) { | ||
| 902 | + errno = EINVAL; | ||
| 903 | + return -1; | ||
| 904 | + } | ||
| 905 | + | ||
| 903 | if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { | 906 | if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { |
| 904 | #if HAVE_DECL_TIOCSRS485 | 907 | #if HAVE_DECL_TIOCSRS485 |
| 905 | modbus_rtu_t *ctx_rtu = ctx->backend_data; | 908 | modbus_rtu_t *ctx_rtu = ctx->backend_data; |
| @@ -939,7 +942,13 @@ int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode) | @@ -939,7 +942,13 @@ int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode) | ||
| 939 | return -1; | 942 | return -1; |
| 940 | } | 943 | } |
| 941 | 944 | ||
| 942 | -int modbus_rtu_get_serial_mode(modbus_t *ctx) { | 945 | +int modbus_rtu_get_serial_mode(modbus_t *ctx) |
| 946 | +{ | ||
| 947 | + if (ctx == NULL) { | ||
| 948 | + errno = EINVAL; | ||
| 949 | + return -1; | ||
| 950 | + } | ||
| 951 | + | ||
| 943 | if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { | 952 | if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { |
| 944 | #if HAVE_DECL_TIOCSRS485 | 953 | #if HAVE_DECL_TIOCSRS485 |
| 945 | modbus_rtu_t *ctx_rtu = ctx->backend_data; | 954 | modbus_rtu_t *ctx_rtu = ctx->backend_data; |
| @@ -959,6 +968,11 @@ int modbus_rtu_get_serial_mode(modbus_t *ctx) { | @@ -959,6 +968,11 @@ int modbus_rtu_get_serial_mode(modbus_t *ctx) { | ||
| 959 | 968 | ||
| 960 | int modbus_rtu_set_rts(modbus_t *ctx, int mode) | 969 | int modbus_rtu_set_rts(modbus_t *ctx, int mode) |
| 961 | { | 970 | { |
| 971 | + if (ctx == NULL) { | ||
| 972 | + errno = EINVAL; | ||
| 973 | + return -1; | ||
| 974 | + } | ||
| 975 | + | ||
| 962 | if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { | 976 | if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { |
| 963 | #if HAVE_DECL_TIOCM_RTS | 977 | #if HAVE_DECL_TIOCM_RTS |
| 964 | modbus_rtu_t *ctx_rtu = ctx->backend_data; | 978 | modbus_rtu_t *ctx_rtu = ctx->backend_data; |
| @@ -985,7 +999,13 @@ int modbus_rtu_set_rts(modbus_t *ctx, int mode) | @@ -985,7 +999,13 @@ int modbus_rtu_set_rts(modbus_t *ctx, int mode) | ||
| 985 | return -1; | 999 | return -1; |
| 986 | } | 1000 | } |
| 987 | 1001 | ||
| 988 | -int modbus_rtu_get_rts(modbus_t *ctx) { | 1002 | +int modbus_rtu_get_rts(modbus_t *ctx) |
| 1003 | +{ | ||
| 1004 | + if (ctx == NULL) { | ||
| 1005 | + errno = EINVAL; | ||
| 1006 | + return -1; | ||
| 1007 | + } | ||
| 1008 | + | ||
| 989 | if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { | 1009 | if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { |
| 990 | #if HAVE_DECL_TIOCM_RTS | 1010 | #if HAVE_DECL_TIOCM_RTS |
| 991 | modbus_rtu_t *ctx_rtu = ctx->backend_data; | 1011 | modbus_rtu_t *ctx_rtu = ctx->backend_data; |
src/modbus-tcp.c
| @@ -467,7 +467,14 @@ int modbus_tcp_listen(modbus_t *ctx, int nb_connection) | @@ -467,7 +467,14 @@ int modbus_tcp_listen(modbus_t *ctx, int nb_connection) | ||
| 467 | int new_socket; | 467 | int new_socket; |
| 468 | int yes; | 468 | int yes; |
| 469 | struct sockaddr_in addr; | 469 | struct sockaddr_in addr; |
| 470 | - modbus_tcp_t *ctx_tcp = ctx->backend_data; | 470 | + modbus_tcp_t *ctx_tcp; |
| 471 | + | ||
| 472 | + if (ctx == NULL) { | ||
| 473 | + errno = EINVAL; | ||
| 474 | + return -1; | ||
| 475 | + } | ||
| 476 | + | ||
| 477 | + ctx_tcp = ctx->backend_data; | ||
| 471 | 478 | ||
| 472 | #ifdef OS_WIN32 | 479 | #ifdef OS_WIN32 |
| 473 | if (_modbus_tcp_init_win32() == -1) { | 480 | if (_modbus_tcp_init_win32() == -1) { |
| @@ -514,7 +521,14 @@ int modbus_tcp_pi_listen(modbus_t *ctx, int nb_connection) | @@ -514,7 +521,14 @@ int modbus_tcp_pi_listen(modbus_t *ctx, int nb_connection) | ||
| 514 | const char *node; | 521 | const char *node; |
| 515 | const char *service; | 522 | const char *service; |
| 516 | int new_socket; | 523 | int new_socket; |
| 517 | - modbus_tcp_pi_t *ctx_tcp_pi = ctx->backend_data; | 524 | + modbus_tcp_pi_t *ctx_tcp_pi; |
| 525 | + | ||
| 526 | + if (ctx == NULL) { | ||
| 527 | + errno = EINVAL; | ||
| 528 | + return -1; | ||
| 529 | + } | ||
| 530 | + | ||
| 531 | + ctx_tcp_pi = ctx->backend_data; | ||
| 518 | 532 | ||
| 519 | if (ctx_tcp_pi->node[0] == 0) | 533 | if (ctx_tcp_pi->node[0] == 0) |
| 520 | node = NULL; /* == any */ | 534 | node = NULL; /* == any */ |
| @@ -609,6 +623,11 @@ int modbus_tcp_accept(modbus_t *ctx, int *socket) | @@ -609,6 +623,11 @@ int modbus_tcp_accept(modbus_t *ctx, int *socket) | ||
| 609 | struct sockaddr_in addr; | 623 | struct sockaddr_in addr; |
| 610 | socklen_t addrlen; | 624 | socklen_t addrlen; |
| 611 | 625 | ||
| 626 | + if (ctx == NULL) { | ||
| 627 | + errno = EINVAL; | ||
| 628 | + return -1; | ||
| 629 | + } | ||
| 630 | + | ||
| 612 | addrlen = sizeof(addr); | 631 | addrlen = sizeof(addr); |
| 613 | #ifdef HAVE_ACCEPT4 | 632 | #ifdef HAVE_ACCEPT4 |
| 614 | /* Inherit socket flags and use accept4 call */ | 633 | /* Inherit socket flags and use accept4 call */ |
| @@ -636,6 +655,11 @@ int modbus_tcp_pi_accept(modbus_t *ctx, int *socket) | @@ -636,6 +655,11 @@ int modbus_tcp_pi_accept(modbus_t *ctx, int *socket) | ||
| 636 | struct sockaddr_storage addr; | 655 | struct sockaddr_storage addr; |
| 637 | socklen_t addrlen; | 656 | socklen_t addrlen; |
| 638 | 657 | ||
| 658 | + if (ctx == NULL) { | ||
| 659 | + errno = EINVAL; | ||
| 660 | + return -1; | ||
| 661 | + } | ||
| 662 | + | ||
| 639 | addrlen = sizeof(addr); | 663 | addrlen = sizeof(addr); |
| 640 | ctx->s = accept(*socket, (void *)&addr, &addrlen); | 664 | ctx->s = accept(*socket, (void *)&addr, &addrlen); |
| 641 | if (ctx->s == -1) { | 665 | if (ctx->s == -1) { |
src/modbus.c
| @@ -121,6 +121,11 @@ static void _sleep_response_timeout(modbus_t *ctx) | @@ -121,6 +121,11 @@ static void _sleep_response_timeout(modbus_t *ctx) | ||
| 121 | 121 | ||
| 122 | int modbus_flush(modbus_t *ctx) | 122 | int modbus_flush(modbus_t *ctx) |
| 123 | { | 123 | { |
| 124 | + if (ctx == NULL) { | ||
| 125 | + errno = EINVAL; | ||
| 126 | + return -1; | ||
| 127 | + } | ||
| 128 | + | ||
| 124 | int rc = ctx->backend->flush(ctx); | 129 | int rc = ctx->backend->flush(ctx); |
| 125 | if (rc != -1 && ctx->debug) { | 130 | if (rc != -1 && ctx->debug) { |
| 126 | /* Not all backends are able to return the number of bytes flushed */ | 131 | /* Not all backends are able to return the number of bytes flushed */ |
| @@ -217,6 +222,11 @@ int modbus_send_raw_request(modbus_t *ctx, uint8_t *raw_req, int raw_req_length) | @@ -217,6 +222,11 @@ int modbus_send_raw_request(modbus_t *ctx, uint8_t *raw_req, int raw_req_length) | ||
| 217 | uint8_t req[MAX_MESSAGE_LENGTH]; | 222 | uint8_t req[MAX_MESSAGE_LENGTH]; |
| 218 | int req_length; | 223 | int req_length; |
| 219 | 224 | ||
| 225 | + if (ctx == NULL) { | ||
| 226 | + errno = EINVAL; | ||
| 227 | + return -1; | ||
| 228 | + } | ||
| 229 | + | ||
| 220 | if (raw_req_length < 2) { | 230 | if (raw_req_length < 2) { |
| 221 | /* The raw request must contain function and slave at least */ | 231 | /* The raw request must contain function and slave at least */ |
| 222 | errno = EINVAL; | 232 | errno = EINVAL; |
| @@ -468,6 +478,11 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) | @@ -468,6 +478,11 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) | ||
| 468 | /* Receive the request from a modbus master */ | 478 | /* Receive the request from a modbus master */ |
| 469 | int modbus_receive(modbus_t *ctx, uint8_t *req) | 479 | int modbus_receive(modbus_t *ctx, uint8_t *req) |
| 470 | { | 480 | { |
| 481 | + if (ctx == NULL) { | ||
| 482 | + errno = EINVAL; | ||
| 483 | + return -1; | ||
| 484 | + } | ||
| 485 | + | ||
| 471 | return ctx->backend->receive(ctx, req); | 486 | return ctx->backend->receive(ctx, req); |
| 472 | } | 487 | } |
| 473 | 488 | ||
| @@ -481,6 +496,11 @@ int modbus_receive(modbus_t *ctx, uint8_t *req) | @@ -481,6 +496,11 @@ int modbus_receive(modbus_t *ctx, uint8_t *req) | ||
| 481 | */ | 496 | */ |
| 482 | int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp) | 497 | int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp) |
| 483 | { | 498 | { |
| 499 | + if (ctx == NULL) { | ||
| 500 | + errno = EINVAL; | ||
| 501 | + return -1; | ||
| 502 | + } | ||
| 503 | + | ||
| 484 | return _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION); | 504 | return _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION); |
| 485 | } | 505 | } |
| 486 | 506 | ||
| @@ -672,6 +692,11 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | @@ -672,6 +692,11 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, | ||
| 672 | int rsp_length = 0; | 692 | int rsp_length = 0; |
| 673 | sft_t sft; | 693 | sft_t sft; |
| 674 | 694 | ||
| 695 | + if (ctx == NULL) { | ||
| 696 | + errno = EINVAL; | ||
| 697 | + return -1; | ||
| 698 | + } | ||
| 699 | + | ||
| 675 | sft.slave = slave; | 700 | sft.slave = slave; |
| 676 | sft.function = function; | 701 | sft.function = function; |
| 677 | sft.t_id = ctx->backend->prepare_response_tid(req, &req_length); | 702 | sft.t_id = ctx->backend->prepare_response_tid(req, &req_length); |
| @@ -960,6 +985,11 @@ int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, | @@ -960,6 +985,11 @@ int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, | ||
| 960 | int dummy_length = 99; | 985 | int dummy_length = 99; |
| 961 | sft_t sft; | 986 | sft_t sft; |
| 962 | 987 | ||
| 988 | + if (ctx == NULL) { | ||
| 989 | + errno = EINVAL; | ||
| 990 | + return -1; | ||
| 991 | + } | ||
| 992 | + | ||
| 963 | sft.slave = slave; | 993 | sft.slave = slave; |
| 964 | sft.function = function + 0x80;; | 994 | sft.function = function + 0x80;; |
| 965 | sft.t_id = ctx->backend->prepare_response_tid(req, &dummy_length); | 995 | sft.t_id = ctx->backend->prepare_response_tid(req, &dummy_length); |
| @@ -1025,6 +1055,11 @@ int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest) | @@ -1025,6 +1055,11 @@ int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest) | ||
| 1025 | { | 1055 | { |
| 1026 | int rc; | 1056 | int rc; |
| 1027 | 1057 | ||
| 1058 | + if (ctx == NULL) { | ||
| 1059 | + errno = EINVAL; | ||
| 1060 | + return -1; | ||
| 1061 | + } | ||
| 1062 | + | ||
| 1028 | if (nb > MODBUS_MAX_READ_BITS) { | 1063 | if (nb > MODBUS_MAX_READ_BITS) { |
| 1029 | if (ctx->debug) { | 1064 | if (ctx->debug) { |
| 1030 | fprintf(stderr, | 1065 | fprintf(stderr, |
| @@ -1049,6 +1084,11 @@ int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest) | @@ -1049,6 +1084,11 @@ int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest) | ||
| 1049 | { | 1084 | { |
| 1050 | int rc; | 1085 | int rc; |
| 1051 | 1086 | ||
| 1087 | + if (ctx == NULL) { | ||
| 1088 | + errno = EINVAL; | ||
| 1089 | + return -1; | ||
| 1090 | + } | ||
| 1091 | + | ||
| 1052 | if (nb > MODBUS_MAX_READ_BITS) { | 1092 | if (nb > MODBUS_MAX_READ_BITS) { |
| 1053 | if (ctx->debug) { | 1093 | if (ctx->debug) { |
| 1054 | fprintf(stderr, | 1094 | fprintf(stderr, |
| @@ -1119,6 +1159,11 @@ int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest) | @@ -1119,6 +1159,11 @@ int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest) | ||
| 1119 | { | 1159 | { |
| 1120 | int status; | 1160 | int status; |
| 1121 | 1161 | ||
| 1162 | + if (ctx == NULL) { | ||
| 1163 | + errno = EINVAL; | ||
| 1164 | + return -1; | ||
| 1165 | + } | ||
| 1166 | + | ||
| 1122 | if (nb > MODBUS_MAX_READ_REGISTERS) { | 1167 | if (nb > MODBUS_MAX_READ_REGISTERS) { |
| 1123 | if (ctx->debug) { | 1168 | if (ctx->debug) { |
| 1124 | fprintf(stderr, | 1169 | fprintf(stderr, |
| @@ -1140,6 +1185,11 @@ int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, | @@ -1140,6 +1185,11 @@ int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, | ||
| 1140 | { | 1185 | { |
| 1141 | int status; | 1186 | int status; |
| 1142 | 1187 | ||
| 1188 | + if (ctx == NULL) { | ||
| 1189 | + errno = EINVAL; | ||
| 1190 | + return -1; | ||
| 1191 | + } | ||
| 1192 | + | ||
| 1143 | if (nb > MODBUS_MAX_READ_REGISTERS) { | 1193 | if (nb > MODBUS_MAX_READ_REGISTERS) { |
| 1144 | fprintf(stderr, | 1194 | fprintf(stderr, |
| 1145 | "ERROR Too many input registers requested (%d > %d)\n", | 1195 | "ERROR Too many input registers requested (%d > %d)\n", |
| @@ -1162,6 +1212,11 @@ static int write_single(modbus_t *ctx, int function, int addr, int value) | @@ -1162,6 +1212,11 @@ static int write_single(modbus_t *ctx, int function, int addr, int value) | ||
| 1162 | int req_length; | 1212 | int req_length; |
| 1163 | uint8_t req[_MIN_REQ_LENGTH]; | 1213 | uint8_t req[_MIN_REQ_LENGTH]; |
| 1164 | 1214 | ||
| 1215 | + if (ctx == NULL) { | ||
| 1216 | + errno = EINVAL; | ||
| 1217 | + return -1; | ||
| 1218 | + } | ||
| 1219 | + | ||
| 1165 | req_length = ctx->backend->build_request_basis(ctx, function, addr, value, req); | 1220 | req_length = ctx->backend->build_request_basis(ctx, function, addr, value, req); |
| 1166 | 1221 | ||
| 1167 | rc = send_msg(ctx, req, req_length); | 1222 | rc = send_msg(ctx, req, req_length); |
| @@ -1182,6 +1237,11 @@ static int write_single(modbus_t *ctx, int function, int addr, int value) | @@ -1182,6 +1237,11 @@ static int write_single(modbus_t *ctx, int function, int addr, int value) | ||
| 1182 | /* Turns ON or OFF a single bit of the remote device */ | 1237 | /* Turns ON or OFF a single bit of the remote device */ |
| 1183 | int modbus_write_bit(modbus_t *ctx, int addr, int status) | 1238 | int modbus_write_bit(modbus_t *ctx, int addr, int status) |
| 1184 | { | 1239 | { |
| 1240 | + if (ctx == NULL) { | ||
| 1241 | + errno = EINVAL; | ||
| 1242 | + return -1; | ||
| 1243 | + } | ||
| 1244 | + | ||
| 1185 | return write_single(ctx, _FC_WRITE_SINGLE_COIL, addr, | 1245 | return write_single(ctx, _FC_WRITE_SINGLE_COIL, addr, |
| 1186 | status ? 0xFF00 : 0); | 1246 | status ? 0xFF00 : 0); |
| 1187 | } | 1247 | } |
| @@ -1189,6 +1249,11 @@ int modbus_write_bit(modbus_t *ctx, int addr, int status) | @@ -1189,6 +1249,11 @@ int modbus_write_bit(modbus_t *ctx, int addr, int status) | ||
| 1189 | /* Writes a value in one register of the remote device */ | 1249 | /* Writes a value in one register of the remote device */ |
| 1190 | int modbus_write_register(modbus_t *ctx, int addr, int value) | 1250 | int modbus_write_register(modbus_t *ctx, int addr, int value) |
| 1191 | { | 1251 | { |
| 1252 | + if (ctx == NULL) { | ||
| 1253 | + errno = EINVAL; | ||
| 1254 | + return -1; | ||
| 1255 | + } | ||
| 1256 | + | ||
| 1192 | return write_single(ctx, _FC_WRITE_SINGLE_REGISTER, addr, value); | 1257 | return write_single(ctx, _FC_WRITE_SINGLE_REGISTER, addr, value); |
| 1193 | } | 1258 | } |
| 1194 | 1259 | ||
| @@ -1201,9 +1266,13 @@ int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src) | @@ -1201,9 +1266,13 @@ int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src) | ||
| 1201 | int req_length; | 1266 | int req_length; |
| 1202 | int bit_check = 0; | 1267 | int bit_check = 0; |
| 1203 | int pos = 0; | 1268 | int pos = 0; |
| 1204 | - | ||
| 1205 | uint8_t req[MAX_MESSAGE_LENGTH]; | 1269 | uint8_t req[MAX_MESSAGE_LENGTH]; |
| 1206 | 1270 | ||
| 1271 | + if (ctx == NULL) { | ||
| 1272 | + errno = EINVAL; | ||
| 1273 | + return -1; | ||
| 1274 | + } | ||
| 1275 | + | ||
| 1207 | if (nb > MODBUS_MAX_WRITE_BITS) { | 1276 | if (nb > MODBUS_MAX_WRITE_BITS) { |
| 1208 | if (ctx->debug) { | 1277 | if (ctx->debug) { |
| 1209 | fprintf(stderr, "ERROR Writing too many bits (%d > %d)\n", | 1278 | fprintf(stderr, "ERROR Writing too many bits (%d > %d)\n", |
| @@ -1258,9 +1327,13 @@ int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src) | @@ -1258,9 +1327,13 @@ int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src) | ||
| 1258 | int i; | 1327 | int i; |
| 1259 | int req_length; | 1328 | int req_length; |
| 1260 | int byte_count; | 1329 | int byte_count; |
| 1261 | - | ||
| 1262 | uint8_t req[MAX_MESSAGE_LENGTH]; | 1330 | uint8_t req[MAX_MESSAGE_LENGTH]; |
| 1263 | 1331 | ||
| 1332 | + if (ctx == NULL) { | ||
| 1333 | + errno = EINVAL; | ||
| 1334 | + return -1; | ||
| 1335 | + } | ||
| 1336 | + | ||
| 1264 | if (nb > MODBUS_MAX_WRITE_REGISTERS) { | 1337 | if (nb > MODBUS_MAX_WRITE_REGISTERS) { |
| 1265 | if (ctx->debug) { | 1338 | if (ctx->debug) { |
| 1266 | fprintf(stderr, | 1339 | fprintf(stderr, |
| @@ -1341,6 +1414,11 @@ int modbus_write_and_read_registers(modbus_t *ctx, | @@ -1341,6 +1414,11 @@ int modbus_write_and_read_registers(modbus_t *ctx, | ||
| 1341 | uint8_t req[MAX_MESSAGE_LENGTH]; | 1414 | uint8_t req[MAX_MESSAGE_LENGTH]; |
| 1342 | uint8_t rsp[MAX_MESSAGE_LENGTH]; | 1415 | uint8_t rsp[MAX_MESSAGE_LENGTH]; |
| 1343 | 1416 | ||
| 1417 | + if (ctx == NULL) { | ||
| 1418 | + errno = EINVAL; | ||
| 1419 | + return -1; | ||
| 1420 | + } | ||
| 1421 | + | ||
| 1344 | if (write_nb > MODBUS_MAX_RW_WRITE_REGISTERS) { | 1422 | if (write_nb > MODBUS_MAX_RW_WRITE_REGISTERS) { |
| 1345 | if (ctx->debug) { | 1423 | if (ctx->debug) { |
| 1346 | fprintf(stderr, | 1424 | fprintf(stderr, |
| @@ -1409,6 +1487,11 @@ int modbus_report_slave_id(modbus_t *ctx, uint8_t *dest) | @@ -1409,6 +1487,11 @@ int modbus_report_slave_id(modbus_t *ctx, uint8_t *dest) | ||
| 1409 | int req_length; | 1487 | int req_length; |
| 1410 | uint8_t req[_MIN_REQ_LENGTH]; | 1488 | uint8_t req[_MIN_REQ_LENGTH]; |
| 1411 | 1489 | ||
| 1490 | + if (ctx == NULL) { | ||
| 1491 | + errno = EINVAL; | ||
| 1492 | + return -1; | ||
| 1493 | + } | ||
| 1494 | + | ||
| 1412 | req_length = ctx->backend->build_request_basis(ctx, _FC_REPORT_SLAVE_ID, | 1495 | req_length = ctx->backend->build_request_basis(ctx, _FC_REPORT_SLAVE_ID, |
| 1413 | 0, 0, req); | 1496 | 0, 0, req); |
| 1414 | 1497 | ||
| @@ -1460,56 +1543,111 @@ void _modbus_init_common(modbus_t *ctx) | @@ -1460,56 +1543,111 @@ void _modbus_init_common(modbus_t *ctx) | ||
| 1460 | /* Define the slave number */ | 1543 | /* Define the slave number */ |
| 1461 | int modbus_set_slave(modbus_t *ctx, int slave) | 1544 | int modbus_set_slave(modbus_t *ctx, int slave) |
| 1462 | { | 1545 | { |
| 1546 | + if (ctx == NULL) { | ||
| 1547 | + errno = EINVAL; | ||
| 1548 | + return -1; | ||
| 1549 | + } | ||
| 1550 | + | ||
| 1463 | return ctx->backend->set_slave(ctx, slave); | 1551 | return ctx->backend->set_slave(ctx, slave); |
| 1464 | } | 1552 | } |
| 1465 | 1553 | ||
| 1466 | int modbus_set_error_recovery(modbus_t *ctx, | 1554 | int modbus_set_error_recovery(modbus_t *ctx, |
| 1467 | modbus_error_recovery_mode error_recovery) | 1555 | modbus_error_recovery_mode error_recovery) |
| 1468 | { | 1556 | { |
| 1557 | + if (ctx == NULL) { | ||
| 1558 | + errno = EINVAL; | ||
| 1559 | + return -1; | ||
| 1560 | + } | ||
| 1561 | + | ||
| 1469 | /* The type of modbus_error_recovery_mode is unsigned enum */ | 1562 | /* The type of modbus_error_recovery_mode is unsigned enum */ |
| 1470 | ctx->error_recovery = (uint8_t) error_recovery; | 1563 | ctx->error_recovery = (uint8_t) error_recovery; |
| 1471 | return 0; | 1564 | return 0; |
| 1472 | } | 1565 | } |
| 1473 | 1566 | ||
| 1474 | -void modbus_set_socket(modbus_t *ctx, int socket) | 1567 | +int modbus_set_socket(modbus_t *ctx, int socket) |
| 1475 | { | 1568 | { |
| 1569 | + if (ctx == NULL) { | ||
| 1570 | + errno = EINVAL; | ||
| 1571 | + return -1; | ||
| 1572 | + } | ||
| 1573 | + | ||
| 1476 | ctx->s = socket; | 1574 | ctx->s = socket; |
| 1575 | + return 0; | ||
| 1477 | } | 1576 | } |
| 1478 | 1577 | ||
| 1479 | int modbus_get_socket(modbus_t *ctx) | 1578 | int modbus_get_socket(modbus_t *ctx) |
| 1480 | { | 1579 | { |
| 1580 | + if (ctx == NULL) { | ||
| 1581 | + errno = EINVAL; | ||
| 1582 | + return -1; | ||
| 1583 | + } | ||
| 1584 | + | ||
| 1481 | return ctx->s; | 1585 | return ctx->s; |
| 1482 | } | 1586 | } |
| 1483 | 1587 | ||
| 1484 | /* Get the timeout interval used to wait for a response */ | 1588 | /* Get the timeout interval used to wait for a response */ |
| 1485 | -void modbus_get_response_timeout(modbus_t *ctx, struct timeval *timeout) | 1589 | +int modbus_get_response_timeout(modbus_t *ctx, struct timeval *timeout) |
| 1486 | { | 1590 | { |
| 1591 | + if (ctx == NULL) { | ||
| 1592 | + errno = EINVAL; | ||
| 1593 | + return -1; | ||
| 1594 | + } | ||
| 1595 | + | ||
| 1487 | *timeout = ctx->response_timeout; | 1596 | *timeout = ctx->response_timeout; |
| 1597 | + return 0; | ||
| 1488 | } | 1598 | } |
| 1489 | 1599 | ||
| 1490 | -void modbus_set_response_timeout(modbus_t *ctx, const struct timeval *timeout) | 1600 | +int modbus_set_response_timeout(modbus_t *ctx, const struct timeval *timeout) |
| 1491 | { | 1601 | { |
| 1602 | + if (ctx == NULL) { | ||
| 1603 | + errno = EINVAL; | ||
| 1604 | + return -1; | ||
| 1605 | + } | ||
| 1606 | + | ||
| 1492 | ctx->response_timeout = *timeout; | 1607 | ctx->response_timeout = *timeout; |
| 1608 | + return 0; | ||
| 1493 | } | 1609 | } |
| 1494 | 1610 | ||
| 1495 | /* Get the timeout interval between two consecutive bytes of a message */ | 1611 | /* Get the timeout interval between two consecutive bytes of a message */ |
| 1496 | -void modbus_get_byte_timeout(modbus_t *ctx, struct timeval *timeout) | 1612 | +int modbus_get_byte_timeout(modbus_t *ctx, struct timeval *timeout) |
| 1497 | { | 1613 | { |
| 1614 | + if (ctx == NULL) { | ||
| 1615 | + errno = EINVAL; | ||
| 1616 | + return -1; | ||
| 1617 | + } | ||
| 1618 | + | ||
| 1498 | *timeout = ctx->byte_timeout; | 1619 | *timeout = ctx->byte_timeout; |
| 1620 | + return 0; | ||
| 1499 | } | 1621 | } |
| 1500 | 1622 | ||
| 1501 | -void modbus_set_byte_timeout(modbus_t *ctx, const struct timeval *timeout) | 1623 | +int modbus_set_byte_timeout(modbus_t *ctx, const struct timeval *timeout) |
| 1502 | { | 1624 | { |
| 1625 | + if (ctx == NULL) { | ||
| 1626 | + errno = EINVAL; | ||
| 1627 | + return -1; | ||
| 1628 | + } | ||
| 1629 | + | ||
| 1503 | ctx->byte_timeout = *timeout; | 1630 | ctx->byte_timeout = *timeout; |
| 1631 | + return 0; | ||
| 1504 | } | 1632 | } |
| 1505 | 1633 | ||
| 1506 | int modbus_get_header_length(modbus_t *ctx) | 1634 | int modbus_get_header_length(modbus_t *ctx) |
| 1507 | { | 1635 | { |
| 1636 | + if (ctx == NULL) { | ||
| 1637 | + errno = EINVAL; | ||
| 1638 | + return -1; | ||
| 1639 | + } | ||
| 1640 | + | ||
| 1508 | return ctx->backend->header_length; | 1641 | return ctx->backend->header_length; |
| 1509 | } | 1642 | } |
| 1510 | 1643 | ||
| 1511 | int modbus_connect(modbus_t *ctx) | 1644 | int modbus_connect(modbus_t *ctx) |
| 1512 | { | 1645 | { |
| 1646 | + if (ctx == NULL) { | ||
| 1647 | + errno = EINVAL; | ||
| 1648 | + return -1; | ||
| 1649 | + } | ||
| 1650 | + | ||
| 1513 | return ctx->backend->connect(ctx); | 1651 | return ctx->backend->connect(ctx); |
| 1514 | } | 1652 | } |
| 1515 | 1653 | ||
| @@ -1529,9 +1667,15 @@ void modbus_free(modbus_t *ctx) | @@ -1529,9 +1667,15 @@ void modbus_free(modbus_t *ctx) | ||
| 1529 | ctx->backend->free(ctx); | 1667 | ctx->backend->free(ctx); |
| 1530 | } | 1668 | } |
| 1531 | 1669 | ||
| 1532 | -void modbus_set_debug(modbus_t *ctx, int boolean) | 1670 | +int modbus_set_debug(modbus_t *ctx, int boolean) |
| 1533 | { | 1671 | { |
| 1672 | + if (ctx == NULL) { | ||
| 1673 | + errno = EINVAL; | ||
| 1674 | + return -1; | ||
| 1675 | + } | ||
| 1676 | + | ||
| 1534 | ctx->debug = boolean; | 1677 | ctx->debug = boolean; |
| 1678 | + return 0; | ||
| 1535 | } | 1679 | } |
| 1536 | 1680 | ||
| 1537 | /* Allocates 4 arrays to store bits, input bits, registers and inputs | 1681 | /* Allocates 4 arrays to store bits, input bits, registers and inputs |
src/modbus.h
| @@ -156,14 +156,14 @@ typedef enum | @@ -156,14 +156,14 @@ typedef enum | ||
| 156 | 156 | ||
| 157 | EXPORT int modbus_set_slave(modbus_t* ctx, int slave); | 157 | EXPORT int modbus_set_slave(modbus_t* ctx, int slave); |
| 158 | EXPORT int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery); | 158 | EXPORT int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery); |
| 159 | -EXPORT void modbus_set_socket(modbus_t *ctx, int socket); | 159 | +EXPORT int modbus_set_socket(modbus_t *ctx, int socket); |
| 160 | EXPORT int modbus_get_socket(modbus_t *ctx); | 160 | EXPORT int modbus_get_socket(modbus_t *ctx); |
| 161 | 161 | ||
| 162 | -EXPORT void modbus_get_response_timeout(modbus_t *ctx, struct timeval *timeout); | ||
| 163 | -EXPORT void modbus_set_response_timeout(modbus_t *ctx, const struct timeval *timeout); | 162 | +EXPORT int modbus_get_response_timeout(modbus_t *ctx, struct timeval *timeout); |
| 163 | +EXPORT int modbus_set_response_timeout(modbus_t *ctx, const struct timeval *timeout); | ||
| 164 | 164 | ||
| 165 | -EXPORT void modbus_get_byte_timeout(modbus_t *ctx, struct timeval *timeout); | ||
| 166 | -EXPORT void modbus_set_byte_timeout(modbus_t *ctx, const struct timeval *timeout); | 165 | +EXPORT int modbus_get_byte_timeout(modbus_t *ctx, struct timeval *timeout); |
| 166 | +EXPORT int modbus_set_byte_timeout(modbus_t *ctx, const struct timeval *timeout); | ||
| 167 | 167 | ||
| 168 | EXPORT int modbus_get_header_length(modbus_t *ctx); | 168 | EXPORT int modbus_get_header_length(modbus_t *ctx); |
| 169 | 169 | ||
| @@ -173,7 +173,7 @@ EXPORT void modbus_close(modbus_t *ctx); | @@ -173,7 +173,7 @@ EXPORT void modbus_close(modbus_t *ctx); | ||
| 173 | EXPORT void modbus_free(modbus_t *ctx); | 173 | EXPORT void modbus_free(modbus_t *ctx); |
| 174 | 174 | ||
| 175 | EXPORT int modbus_flush(modbus_t *ctx); | 175 | EXPORT int modbus_flush(modbus_t *ctx); |
| 176 | -EXPORT void modbus_set_debug(modbus_t *ctx, int boolean); | 176 | +EXPORT int modbus_set_debug(modbus_t *ctx, int boolean); |
| 177 | 177 | ||
| 178 | EXPORT const char *modbus_strerror(int errnum); | 178 | EXPORT const char *modbus_strerror(int errnum); |
| 179 | 179 |