2 * Copyright © 2001-2011 Stéphane Raimbault <stephane.raimbault@gmail.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 * This library implements the Modbus protocol.
20 * http://libmodbus.org/
33 #include "modbus-private.h"
36 #define MSG_LENGTH_UNDEFINED -1
38 /* Exported version */
39 const unsigned int libmodbus_version_major
= LIBMODBUS_VERSION_MAJOR
;
40 const unsigned int libmodbus_version_minor
= LIBMODBUS_VERSION_MINOR
;
41 const unsigned int libmodbus_version_micro
= LIBMODBUS_VERSION_MICRO
;
43 /* Max between RTU and TCP max adu length (so TCP) */
44 #define MAX_MESSAGE_LENGTH 260
46 /* 3 steps are used to parse the query */
53 const char *modbus_strerror(int errnum
) {
56 return "Illegal function";
58 return "Illegal data address";
60 return "Illegal data value";
62 return "Slave device or server failure";
66 return "Slave device or server is busy";
68 return "Negative acknowledge";
70 return "Memory parity error";
72 return "Gateway path unavailable";
74 return "Target device failed to respond";
78 return "Invalid data";
80 return "Invalid exception code";
82 return "Too many data";
84 return "Response not from requested slave";
86 return strerror(errnum
);
90 void _error_print(modbus_t
*ctx
, const char *context
)
93 fprintf(stderr
, "ERROR %s", modbus_strerror(errno
));
94 if (context
!= NULL
) {
95 fprintf(stderr
, ": %s\n", context
);
97 fprintf(stderr
, "\n");
102 int _sleep_and_flush(modbus_t
*ctx
)
105 /* usleep doesn't exist on Windows */
106 Sleep((ctx
->response_timeout
.tv_sec
* 1000) +
107 (ctx
->response_timeout
.tv_usec
/ 1000));
109 /* usleep source code */
110 struct timespec request
, remaining
;
111 request
.tv_sec
= ctx
->response_timeout
.tv_sec
;
112 request
.tv_nsec
= ((long int)ctx
->response_timeout
.tv_usec
% 1000000)
114 while (nanosleep(&request
, &remaining
) == -1 && errno
== EINTR
)
117 return modbus_flush(ctx
);
120 int modbus_flush(modbus_t
*ctx
)
122 int rc
= ctx
->backend
->flush(ctx
);
123 if (rc
!= -1 && ctx
->debug
) {
124 printf("%d bytes flushed\n", rc
);
129 /* Computes the length of the expected response */
130 static unsigned int compute_response_length_from_request(modbus_t
*ctx
, uint8_t *req
)
133 const int offset
= ctx
->backend
->header_length
;
135 switch (req
[offset
]) {
137 case _FC_READ_DISCRETE_INPUTS
: {
138 /* Header + nb values (code from write_bits) */
139 int nb
= (req
[offset
+ 3] << 8) | req
[offset
+ 4];
140 length
= 2 + (nb
/ 8) + ((nb
% 8) ? 1 : 0);
143 case _FC_WRITE_AND_READ_REGISTERS
:
144 case _FC_READ_HOLDING_REGISTERS
:
145 case _FC_READ_INPUT_REGISTERS
:
146 /* Header + 2 * nb values */
147 length
= 2 + 2 * (req
[offset
+ 3] << 8 | req
[offset
+ 4]);
149 case _FC_READ_EXCEPTION_STATUS
:
152 case _FC_REPORT_SLAVE_ID
:
153 /* The response is device specific (the header provides the
155 return MSG_LENGTH_UNDEFINED
;
160 return offset
+ length
+ ctx
->backend
->checksum_length
;
163 /* Sends a request/response */
164 static int send_msg(modbus_t
*ctx
, uint8_t *msg
, int msg_length
)
169 msg_length
= ctx
->backend
->send_msg_pre(msg
, msg_length
);
172 for (i
= 0; i
< msg_length
; i
++)
173 printf("[%.2X]", msg
[i
]);
177 /* In recovery mode, the write command will be issued until to be
178 successful! Disabled by default. */
180 rc
= ctx
->backend
->send(ctx
, msg
, msg_length
);
182 _error_print(ctx
, NULL
);
183 if (ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_LINK
) {
184 int saved_errno
= errno
;
186 if ((errno
== EBADF
|| errno
== ECONNRESET
|| errno
== EPIPE
)) {
190 _sleep_and_flush(ctx
);
195 } while ((ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_LINK
) &&
198 if (rc
> 0 && rc
!= msg_length
) {
206 int modbus_send_raw_request(modbus_t
*ctx
, uint8_t *raw_req
, int raw_req_length
)
209 uint8_t req
[MAX_MESSAGE_LENGTH
];
212 if (raw_req_length
< 2) {
213 /* The raw request must contain function and slave at least */
218 sft
.slave
= raw_req
[0];
219 sft
.function
= raw_req
[1];
220 /* The t_id is left to zero */
222 /* This response function only set the header so it's convenient here */
223 req_length
= ctx
->backend
->build_response_basis(&sft
, req
);
225 if (raw_req_length
> 2) {
226 /* Copy data after function code */
227 memcpy(req
+ req_length
, raw_req
+ 2, raw_req_length
- 2);
228 req_length
+= raw_req_length
- 2;
231 return send_msg(ctx
, req
, req_length
);
235 ---------- Request Indication ----------
236 | Client | ---------------------->| Server |
237 ---------- Confirmation Response ----------
241 /* Request message on the server side */
243 /* Request message on the client side */
247 /* Computes the length to read after the function received */
248 static uint8_t compute_meta_length_after_function(int function
,
253 if (msg_type
== MSG_INDICATION
) {
254 if (function
<= _FC_WRITE_SINGLE_REGISTER
) {
256 } else if (function
== _FC_WRITE_MULTIPLE_COILS
||
257 function
== _FC_WRITE_MULTIPLE_REGISTERS
) {
259 } else if (function
== _FC_WRITE_AND_READ_REGISTERS
) {
262 /* _FC_READ_EXCEPTION_STATUS, _FC_REPORT_SLAVE_ID */
266 /* MSG_CONFIRMATION */
268 case _FC_WRITE_SINGLE_COIL
:
269 case _FC_WRITE_SINGLE_REGISTER
:
270 case _FC_WRITE_MULTIPLE_COILS
:
271 case _FC_WRITE_MULTIPLE_REGISTERS
:
282 /* Computes the length to read after the meta information (address, count, etc) */
283 static int compute_data_length_after_meta(modbus_t
*ctx
, uint8_t *msg
,
286 int function
= msg
[ctx
->backend
->header_length
];
289 if (msg_type
== MSG_INDICATION
) {
291 case _FC_WRITE_MULTIPLE_COILS
:
292 case _FC_WRITE_MULTIPLE_REGISTERS
:
293 length
= msg
[ctx
->backend
->header_length
+ 5];
295 case _FC_WRITE_AND_READ_REGISTERS
:
296 length
= msg
[ctx
->backend
->header_length
+ 9];
302 /* MSG_CONFIRMATION */
303 if (function
<= _FC_READ_INPUT_REGISTERS
||
304 function
== _FC_REPORT_SLAVE_ID
||
305 function
== _FC_WRITE_AND_READ_REGISTERS
) {
306 length
= msg
[ctx
->backend
->header_length
+ 1];
312 length
+= ctx
->backend
->checksum_length
;
318 /* Waits a response from a modbus server or a request from a modbus client.
319 This function blocks if there is no replies (3 timeouts).
321 The function shall return the number of received characters and the received
322 message in an array of uint8_t if successful. Otherwise it shall return -1
323 and errno is set to one of the values defined below:
328 - read() or recv() error codes
331 static int receive_msg(modbus_t
*ctx
, uint8_t *msg
, msg_type_t msg_type
)
336 struct timeval
*p_tv
;
342 if (msg_type
== MSG_INDICATION
) {
343 printf("Waiting for a indication...\n");
345 printf("Waiting for a confirmation...\n");
349 /* Add a file descriptor to the set */
351 FD_SET(ctx
->s
, &rfds
);
353 /* We need to analyse the message step by step. At the first step, we want
354 * to reach the function code because all packets contain this
356 step
= _STEP_FUNCTION
;
357 length_to_read
= ctx
->backend
->header_length
+ 1;
359 if (msg_type
== MSG_INDICATION
) {
360 /* Wait for a message, we don't know when the message will be
364 tv
.tv_sec
= ctx
->response_timeout
.tv_sec
;
365 tv
.tv_usec
= ctx
->response_timeout
.tv_usec
;
369 while (length_to_read
!= 0) {
370 rc
= ctx
->backend
->select(ctx
, &rfds
, p_tv
, length_to_read
);
372 _error_print(ctx
, "select");
373 if (ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_LINK
) {
374 int saved_errno
= errno
;
376 if (errno
== ETIMEDOUT
) {
377 _sleep_and_flush(ctx
);
378 } else if (errno
== EBADF
) {
387 rc
= ctx
->backend
->recv(ctx
, msg
+ msg_length
, length_to_read
);
394 _error_print(ctx
, "read");
395 if ((ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_LINK
) &&
396 (errno
== ECONNRESET
|| errno
== ECONNREFUSED
||
398 int saved_errno
= errno
;
401 /* Could be removed by previous calls */
407 /* Display the hex code of each character received */
410 for (i
=0; i
< rc
; i
++)
411 printf("<%.2X>", msg
[msg_length
+ i
]);
414 /* Sums bytes received */
416 /* Computes remaining bytes */
417 length_to_read
-= rc
;
419 if (length_to_read
== 0) {
422 /* Function code position */
423 length_to_read
= compute_meta_length_after_function(
424 msg
[ctx
->backend
->header_length
],
426 if (length_to_read
!= 0) {
429 } /* else switches straight to the next step */
431 length_to_read
= compute_data_length_after_meta(
433 if ((msg_length
+ length_to_read
) > ctx
->backend
->max_adu_length
) {
435 _error_print(ctx
, "too many data");
445 if (length_to_read
> 0 && ctx
->byte_timeout
.tv_sec
!= -1) {
446 /* If there is no character in the buffer, the allowed timeout
447 interval between two consecutive bytes is defined by
449 tv
.tv_sec
= ctx
->byte_timeout
.tv_sec
;
450 tv
.tv_usec
= ctx
->byte_timeout
.tv_usec
;
458 return ctx
->backend
->check_integrity(ctx
, msg
, msg_length
);
461 /* Receive the request from a modbus master */
462 int modbus_receive(modbus_t
*ctx
, uint8_t *req
)
464 return receive_msg(ctx
, req
, MSG_INDICATION
);
467 /* Receives the confirmation.
469 The function shall store the read response in rsp and return the number of
470 values (bits or words). Otherwise, its shall return -1 and errno is set.
472 The function doesn't check the confirmation is the expected response to the
475 int modbus_receive_confirmation(modbus_t
*ctx
, uint8_t *rsp
)
477 return receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
480 static int check_confirmation(modbus_t
*ctx
, uint8_t *req
,
481 uint8_t *rsp
, int rsp_length
)
484 int rsp_length_computed
;
485 const int offset
= ctx
->backend
->header_length
;
487 if (ctx
->backend
->pre_check_confirmation
) {
488 rc
= ctx
->backend
->pre_check_confirmation(ctx
, req
, rsp
, rsp_length
);
490 if (ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_PROTOCOL
) {
491 _sleep_and_flush(ctx
);
497 rsp_length_computed
= compute_response_length_from_request(ctx
, req
);
500 if (rsp_length
== rsp_length_computed
||
501 rsp_length_computed
== MSG_LENGTH_UNDEFINED
) {
504 const int function
= rsp
[offset
];
506 /* Check function code */
507 if (function
!= req
[offset
]) {
510 "Received function not corresponding to the request (%d != %d)\n",
511 function
, req
[offset
]);
513 if (ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_PROTOCOL
) {
514 _sleep_and_flush(ctx
);
520 /* Check the number of values is corresponding to the request */
523 case _FC_READ_DISCRETE_INPUTS
:
524 /* Read functions, 8 values in a byte (nb
525 * of values in the request and byte count in
527 req_nb_value
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
528 req_nb_value
= (req_nb_value
/ 8) + ((req_nb_value
% 8) ? 1 : 0);
529 rsp_nb_value
= rsp
[offset
+ 1];
531 case _FC_WRITE_AND_READ_REGISTERS
:
532 case _FC_READ_HOLDING_REGISTERS
:
533 case _FC_READ_INPUT_REGISTERS
:
534 /* Read functions 1 value = 2 bytes */
535 req_nb_value
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
536 rsp_nb_value
= (rsp
[offset
+ 1] / 2);
538 case _FC_WRITE_MULTIPLE_COILS
:
539 case _FC_WRITE_MULTIPLE_REGISTERS
:
540 /* N Write functions */
541 req_nb_value
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
542 rsp_nb_value
= (rsp
[offset
+ 3] << 8) | rsp
[offset
+ 4];
544 case _FC_REPORT_SLAVE_ID
:
545 /* Report slave ID (bytes received) */
546 req_nb_value
= rsp_nb_value
= rsp
[offset
+ 1];
549 /* 1 Write functions & others */
550 req_nb_value
= rsp_nb_value
= 1;
553 if (req_nb_value
== rsp_nb_value
) {
558 "Quantity not corresponding to the request (%d != %d)\n",
559 rsp_nb_value
, req_nb_value
);
562 if (ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_PROTOCOL
) {
563 _sleep_and_flush(ctx
);
569 } else if (rsp_length
== (offset
+ 2 + ctx
->backend
->checksum_length
) &&
570 req
[offset
] == (rsp
[offset
] - 0x80)) {
571 /* EXCEPTION CODE RECEIVED */
573 int exception_code
= rsp
[offset
+ 1];
574 if (exception_code
< MODBUS_EXCEPTION_MAX
) {
575 errno
= MODBUS_ENOBASE
+ exception_code
;
579 _error_print(ctx
, NULL
);
584 "Message length not corresponding to the computed length (%d != %d)\n",
585 rsp_length
, rsp_length_computed
);
587 if (ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_PROTOCOL
) {
588 _sleep_and_flush(ctx
);
597 static int response_io_status(int address
, int nb
,
598 uint8_t *tab_io_status
,
599 uint8_t *rsp
, int offset
)
605 for (i
= address
; i
< address
+nb
; i
++) {
606 byte
|= tab_io_status
[i
] << shift
;
609 rsp
[offset
++] = byte
;
617 rsp
[offset
++] = byte
;
622 /* Build the exception response */
623 static int response_exception(modbus_t
*ctx
, sft_t
*sft
,
624 int exception_code
, uint8_t *rsp
)
628 sft
->function
= sft
->function
+ 0x80;
629 rsp_length
= ctx
->backend
->build_response_basis(sft
, rsp
);
631 /* Positive exception code */
632 rsp
[rsp_length
++] = exception_code
;
637 /* Send a response to the received request.
638 Analyses the request and constructs a response.
640 If an error occurs, this function construct the response
643 int modbus_reply(modbus_t
*ctx
, const uint8_t *req
,
644 int req_length
, modbus_mapping_t
*mb_mapping
)
646 int offset
= ctx
->backend
->header_length
;
647 int slave
= req
[offset
- 1];
648 int function
= req
[offset
];
649 uint16_t address
= (req
[offset
+ 1] << 8) + req
[offset
+ 2];
650 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
654 if (ctx
->backend
->filter_request(ctx
, slave
) == 1) {
660 sft
.function
= function
;
661 sft
.t_id
= ctx
->backend
->prepare_response_tid(req
, &req_length
);
664 case _FC_READ_COILS
: {
665 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
667 if ((address
+ nb
) > mb_mapping
->nb_bits
) {
669 fprintf(stderr
, "Illegal data address %0X in read_bits\n",
672 rsp_length
= response_exception(
674 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
676 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
677 rsp
[rsp_length
++] = (nb
/ 8) + ((nb
% 8) ? 1 : 0);
678 rsp_length
= response_io_status(address
, nb
,
679 mb_mapping
->tab_bits
,
684 case _FC_READ_DISCRETE_INPUTS
: {
685 /* Similar to coil status (but too many arguments to use a
687 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
689 if ((address
+ nb
) > mb_mapping
->nb_input_bits
) {
691 fprintf(stderr
, "Illegal data address %0X in read_input_bits\n",
694 rsp_length
= response_exception(
696 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
698 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
699 rsp
[rsp_length
++] = (nb
/ 8) + ((nb
% 8) ? 1 : 0);
700 rsp_length
= response_io_status(address
, nb
,
701 mb_mapping
->tab_input_bits
,
706 case _FC_READ_HOLDING_REGISTERS
: {
707 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
709 if ((address
+ nb
) > mb_mapping
->nb_registers
) {
711 fprintf(stderr
, "Illegal data address %0X in read_registers\n",
714 rsp_length
= response_exception(
716 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
720 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
721 rsp
[rsp_length
++] = nb
<< 1;
722 for (i
= address
; i
< address
+ nb
; i
++) {
723 rsp
[rsp_length
++] = mb_mapping
->tab_registers
[i
] >> 8;
724 rsp
[rsp_length
++] = mb_mapping
->tab_registers
[i
] & 0xFF;
729 case _FC_READ_INPUT_REGISTERS
: {
730 /* Similar to holding registers (but too many arguments to use a
732 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
734 if ((address
+ nb
) > mb_mapping
->nb_input_registers
) {
736 fprintf(stderr
, "Illegal data address %0X in read_input_registers\n",
739 rsp_length
= response_exception(
741 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
745 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
746 rsp
[rsp_length
++] = nb
<< 1;
747 for (i
= address
; i
< address
+ nb
; i
++) {
748 rsp
[rsp_length
++] = mb_mapping
->tab_input_registers
[i
] >> 8;
749 rsp
[rsp_length
++] = mb_mapping
->tab_input_registers
[i
] & 0xFF;
754 case _FC_WRITE_SINGLE_COIL
:
755 if (address
>= mb_mapping
->nb_bits
) {
757 fprintf(stderr
, "Illegal data address %0X in write_bit\n",
760 rsp_length
= response_exception(
762 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
764 int data
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
766 if (data
== 0xFF00 || data
== 0x0) {
767 mb_mapping
->tab_bits
[address
] = (data
) ? ON
: OFF
;
768 memcpy(rsp
, req
, req_length
);
769 rsp_length
= req_length
;
773 "Illegal data value %0X in write_bit request at address %0X\n",
776 rsp_length
= response_exception(
778 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE
, rsp
);
782 case _FC_WRITE_SINGLE_REGISTER
:
783 if (address
>= mb_mapping
->nb_registers
) {
785 fprintf(stderr
, "Illegal data address %0X in write_register\n",
788 rsp_length
= response_exception(
790 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
792 int data
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
794 mb_mapping
->tab_registers
[address
] = data
;
795 memcpy(rsp
, req
, req_length
);
796 rsp_length
= req_length
;
799 case _FC_WRITE_MULTIPLE_COILS
: {
800 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
802 if ((address
+ nb
) > mb_mapping
->nb_bits
) {
804 fprintf(stderr
, "Illegal data address %0X in write_bits\n",
807 rsp_length
= response_exception(
809 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
812 modbus_set_bits_from_bytes(mb_mapping
->tab_bits
, address
, nb
, &req
[offset
+ 6]);
814 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
815 /* 4 to copy the bit address (2) and the quantity of bits */
816 memcpy(rsp
+ rsp_length
, req
+ rsp_length
, 4);
821 case _FC_WRITE_MULTIPLE_REGISTERS
: {
822 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
824 if ((address
+ nb
) > mb_mapping
->nb_registers
) {
826 fprintf(stderr
, "Illegal data address %0X in write_registers\n",
829 rsp_length
= response_exception(
831 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
834 for (i
= address
, j
= 6; i
< address
+ nb
; i
++, j
+= 2) {
835 /* 6 and 7 = first value */
836 mb_mapping
->tab_registers
[i
] =
837 (req
[offset
+ j
] << 8) + req
[offset
+ j
+ 1];
840 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
841 /* 4 to copy the address (2) and the no. of registers */
842 memcpy(rsp
+ rsp_length
, req
+ rsp_length
, 4);
847 case _FC_REPORT_SLAVE_ID
: {
851 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
852 /* Skip byte count for now */
853 byte_count_pos
= rsp_length
++;
854 rsp
[rsp_length
++] = _REPORT_SLAVE_ID
;
855 /* Run indicator status to ON */
856 rsp
[rsp_length
++] = 0xFF;
857 /* LMB + length of LIBMODBUS_VERSION_STRING */
858 str_len
= 3 + strlen(LIBMODBUS_VERSION_STRING
);
859 memcpy(rsp
+ rsp_length
, "LMB" LIBMODBUS_VERSION_STRING
, str_len
);
860 rsp_length
+= str_len
;
861 rsp
[byte_count_pos
] = rsp_length
- byte_count_pos
- 1;
864 case _FC_READ_EXCEPTION_STATUS
:
866 fprintf(stderr
, "FIXME Not implemented\n");
872 case _FC_WRITE_AND_READ_REGISTERS
: {
873 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
874 uint16_t address_write
= (req
[offset
+ 5] << 8) + req
[offset
+ 6];
875 int nb_write
= (req
[offset
+ 7] << 8) + req
[offset
+ 8];
877 if ((address
+ nb
) > mb_mapping
->nb_registers
||
878 (address_write
+ nb_write
) > mb_mapping
->nb_registers
) {
881 "Illegal data read address %0X or write address %0X write_and_read_registers\n",
882 address
+ nb
, address_write
+ nb_write
);
884 rsp_length
= response_exception(ctx
, &sft
,
885 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
888 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
889 rsp
[rsp_length
++] = nb
<< 1;
892 10 and 11 are the offset of the first values to write */
893 for (i
= address_write
, j
= 10; i
< address_write
+ nb_write
; i
++, j
+= 2) {
894 mb_mapping
->tab_registers
[i
] =
895 (req
[offset
+ j
] << 8) + req
[offset
+ j
+ 1];
898 /* and read the data for the response */
899 for (i
= address
; i
< address
+ nb
; i
++) {
900 rsp
[rsp_length
++] = mb_mapping
->tab_registers
[i
] >> 8;
901 rsp
[rsp_length
++] = mb_mapping
->tab_registers
[i
] & 0xFF;
908 rsp_length
= response_exception(ctx
, &sft
,
909 MODBUS_EXCEPTION_ILLEGAL_FUNCTION
,
914 return send_msg(ctx
, rsp
, rsp_length
);
917 int modbus_reply_exception(modbus_t
*ctx
, const uint8_t *req
,
918 unsigned int exception_code
)
920 int offset
= ctx
->backend
->header_length
;
921 int slave
= req
[offset
- 1];
922 int function
= req
[offset
];
923 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
925 int dummy_length
= 99;
928 if (ctx
->backend
->filter_request(ctx
, slave
) == 1) {
934 sft
.function
= function
+ 0x80;;
935 sft
.t_id
= ctx
->backend
->prepare_response_tid(req
, &dummy_length
);
936 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
938 /* Positive exception code */
939 if (exception_code
< MODBUS_EXCEPTION_MAX
) {
940 rsp
[rsp_length
++] = exception_code
;
941 return send_msg(ctx
, rsp
, rsp_length
);
948 /* Reads IO status */
949 static int read_io_status(modbus_t
*ctx
, int function
,
950 int addr
, int nb
, uint8_t *dest
)
955 uint8_t req
[_MIN_REQ_LENGTH
];
956 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
958 req_length
= ctx
->backend
->build_request_basis(ctx
, function
, addr
, nb
, req
);
960 rc
= send_msg(ctx
, req
, req_length
);
967 rc
= receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
971 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
975 offset
= ctx
->backend
->header_length
+ 2;
976 offset_end
= offset
+ rc
;
977 for (i
= offset
; i
< offset_end
; i
++) {
978 /* Shift reg hi_byte to temp */
981 for (bit
= 0x01; (bit
& 0xff) && (pos
< nb
);) {
982 dest
[pos
++] = (temp
& bit
) ? TRUE
: FALSE
;
992 /* Reads the boolean status of bits and sets the array elements
993 in the destination to TRUE or FALSE (single bits). */
994 int modbus_read_bits(modbus_t
*ctx
, int addr
, int nb
, uint8_t *dest
)
998 if (nb
> MODBUS_MAX_READ_BITS
) {
1001 "ERROR Too many bits requested (%d > %d)\n",
1002 nb
, MODBUS_MAX_READ_BITS
);
1008 rc
= read_io_status(ctx
, _FC_READ_COILS
, addr
, nb
, dest
);
1017 /* Same as modbus_read_bits but reads the remote device input table */
1018 int modbus_read_input_bits(modbus_t
*ctx
, int addr
, int nb
, uint8_t *dest
)
1022 if (nb
> MODBUS_MAX_READ_BITS
) {
1025 "ERROR Too many discrete inputs requested (%d > %d)\n",
1026 nb
, MODBUS_MAX_READ_BITS
);
1032 rc
= read_io_status(ctx
, _FC_READ_DISCRETE_INPUTS
, addr
, nb
, dest
);
1040 /* Reads the data from a remove device and put that data into an array */
1041 static int read_registers(modbus_t
*ctx
, int function
, int addr
, int nb
,
1046 uint8_t req
[_MIN_REQ_LENGTH
];
1047 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
1049 if (nb
> MODBUS_MAX_READ_REGISTERS
) {
1052 "ERROR Too many registers requested (%d > %d)\n",
1053 nb
, MODBUS_MAX_READ_REGISTERS
);
1059 req_length
= ctx
->backend
->build_request_basis(ctx
, function
, addr
, nb
, req
);
1061 rc
= send_msg(ctx
, req
, req_length
);
1066 rc
= receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
1070 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
1074 offset
= ctx
->backend
->header_length
;
1076 for (i
= 0; i
< rc
; i
++) {
1077 /* shift reg hi_byte to temp OR with lo_byte */
1078 dest
[i
] = (rsp
[offset
+ 2 + (i
<< 1)] << 8) |
1079 rsp
[offset
+ 3 + (i
<< 1)];
1086 /* Reads the holding registers of remote device and put the data into an
1088 int modbus_read_registers(modbus_t
*ctx
, int addr
, int nb
, uint16_t *dest
)
1092 if (nb
> MODBUS_MAX_READ_REGISTERS
) {
1095 "ERROR Too many registers requested (%d > %d)\n",
1096 nb
, MODBUS_MAX_READ_REGISTERS
);
1102 status
= read_registers(ctx
, _FC_READ_HOLDING_REGISTERS
,
1107 /* Reads the input registers of remote device and put the data into an array */
1108 int modbus_read_input_registers(modbus_t
*ctx
, int addr
, int nb
,
1113 if (nb
> MODBUS_MAX_READ_REGISTERS
) {
1115 "ERROR Too many input registers requested (%d > %d)\n",
1116 nb
, MODBUS_MAX_READ_REGISTERS
);
1121 status
= read_registers(ctx
, _FC_READ_INPUT_REGISTERS
,
1127 /* Write a value to the specified register of the remote device.
1128 Used by write_bit and write_register */
1129 static int write_single(modbus_t
*ctx
, int function
, int addr
, int value
)
1133 uint8_t req
[_MIN_REQ_LENGTH
];
1135 req_length
= ctx
->backend
->build_request_basis(ctx
, function
, addr
, value
, req
);
1137 rc
= send_msg(ctx
, req
, req_length
);
1139 /* Used by write_bit and write_register */
1140 uint8_t rsp
[_MIN_REQ_LENGTH
];
1142 rc
= receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
1146 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
1152 /* Turns ON or OFF a single bit of the remote device */
1153 int modbus_write_bit(modbus_t
*ctx
, int addr
, int status
)
1155 return write_single(ctx
, _FC_WRITE_SINGLE_COIL
, addr
,
1156 status
? 0xFF00 : 0);
1159 /* Writes a value in one register of the remote device */
1160 int modbus_write_register(modbus_t
*ctx
, int addr
, int value
)
1162 return write_single(ctx
, _FC_WRITE_SINGLE_REGISTER
, addr
, value
);
1165 /* Write the bits of the array in the remote device */
1166 int modbus_write_bits(modbus_t
*ctx
, int addr
, int nb
, const uint8_t *src
)
1175 uint8_t req
[MAX_MESSAGE_LENGTH
];
1177 if (nb
> MODBUS_MAX_WRITE_BITS
) {
1179 fprintf(stderr
, "ERROR Writing too many bits (%d > %d)\n",
1180 nb
, MODBUS_MAX_WRITE_BITS
);
1186 req_length
= ctx
->backend
->build_request_basis(ctx
,
1187 _FC_WRITE_MULTIPLE_COILS
,
1189 byte_count
= (nb
/ 8) + ((nb
% 8) ? 1 : 0);
1190 req
[req_length
++] = byte_count
;
1192 for (i
= 0; i
< byte_count
; i
++) {
1196 req
[req_length
] = 0;
1198 while ((bit
& 0xFF) && (bit_check
++ < nb
)) {
1200 req
[req_length
] |= bit
;
1202 req
[req_length
] &=~ bit
;
1209 rc
= send_msg(ctx
, req
, req_length
);
1211 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
1213 rc
= receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
1217 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
1224 /* Write the values from the array to the registers of the remote device */
1225 int modbus_write_registers(modbus_t
*ctx
, int addr
, int nb
, const uint16_t *src
)
1232 uint8_t req
[MAX_MESSAGE_LENGTH
];
1234 if (nb
> MODBUS_MAX_WRITE_REGISTERS
) {
1237 "ERROR Trying to write to too many registers (%d > %d)\n",
1238 nb
, MODBUS_MAX_WRITE_REGISTERS
);
1244 req_length
= ctx
->backend
->build_request_basis(ctx
,
1245 _FC_WRITE_MULTIPLE_REGISTERS
,
1247 byte_count
= nb
* 2;
1248 req
[req_length
++] = byte_count
;
1250 for (i
= 0; i
< nb
; i
++) {
1251 req
[req_length
++] = src
[i
] >> 8;
1252 req
[req_length
++] = src
[i
] & 0x00FF;
1255 rc
= send_msg(ctx
, req
, req_length
);
1257 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
1259 rc
= receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
1263 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
1269 /* Write multiple registers from src array to remote device and read multiple
1270 registers from remote device to dest array. */
1271 int modbus_write_and_read_registers(modbus_t
*ctx
,
1272 int write_addr
, int write_nb
, const uint16_t *src
,
1273 int read_addr
, int read_nb
, uint16_t *dest
)
1280 uint8_t req
[MAX_MESSAGE_LENGTH
];
1281 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
1283 if (write_nb
> MODBUS_MAX_RW_WRITE_REGISTERS
) {
1286 "ERROR Too many registers to write (%d > %d)\n",
1287 write_nb
, MODBUS_MAX_RW_WRITE_REGISTERS
);
1293 if (read_nb
> MODBUS_MAX_READ_REGISTERS
) {
1296 "ERROR Too many registers requested (%d > %d)\n",
1297 read_nb
, MODBUS_MAX_READ_REGISTERS
);
1302 req_length
= ctx
->backend
->build_request_basis(ctx
,
1303 _FC_WRITE_AND_READ_REGISTERS
,
1304 read_addr
, read_nb
, req
);
1306 req
[req_length
++] = write_addr
>> 8;
1307 req
[req_length
++] = write_addr
& 0x00ff;
1308 req
[req_length
++] = write_nb
>> 8;
1309 req
[req_length
++] = write_nb
& 0x00ff;
1310 byte_count
= write_nb
* 2;
1311 req
[req_length
++] = byte_count
;
1313 for (i
= 0; i
< write_nb
; i
++) {
1314 req
[req_length
++] = src
[i
] >> 8;
1315 req
[req_length
++] = src
[i
] & 0x00FF;
1318 rc
= send_msg(ctx
, req
, req_length
);
1322 rc
= receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
1326 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
1330 offset
= ctx
->backend
->header_length
;
1332 /* If rc is negative, the loop is jumped ! */
1333 for (i
= 0; i
< rc
; i
++) {
1334 /* shift reg hi_byte to temp OR with lo_byte */
1335 dest
[i
] = (rsp
[offset
+ 2 + (i
<< 1)] << 8) |
1336 rsp
[offset
+ 3 + (i
<< 1)];
1343 /* Send a request to get the slave ID of the device (only available in serial
1345 int modbus_report_slave_id(modbus_t
*ctx
, uint8_t *dest
)
1349 uint8_t req
[_MIN_REQ_LENGTH
];
1351 req_length
= ctx
->backend
->build_request_basis(ctx
, _FC_REPORT_SLAVE_ID
,
1354 /* HACKISH, addr and count are not used */
1357 rc
= send_msg(ctx
, req
, req_length
);
1361 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
1363 rc
= receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
1367 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
1371 offset
= ctx
->backend
->header_length
+ 2;
1373 /* Byte count, slave id, run indicator status,
1375 for (i
=0; i
< rc
; i
++) {
1376 dest
[i
] = rsp
[offset
+ i
];
1383 void _modbus_init_common(modbus_t
*ctx
)
1385 /* Slave and socket are initialized to -1 */
1390 ctx
->error_recovery
= MODBUS_ERROR_RECOVERY_NONE
;
1392 ctx
->response_timeout
.tv_sec
= 0;
1393 ctx
->response_timeout
.tv_usec
= _RESPONSE_TIMEOUT
;
1395 ctx
->byte_timeout
.tv_sec
= 0;
1396 ctx
->byte_timeout
.tv_usec
= _BYTE_TIMEOUT
;
1399 /* Define the slave number */
1400 int modbus_set_slave(modbus_t
*ctx
, int slave
)
1402 return ctx
->backend
->set_slave(ctx
, slave
);
1405 int modbus_set_error_recovery(modbus_t
*ctx
,
1406 modbus_error_recovery_mode error_recovery
)
1408 if (error_recovery
>= 0) {
1409 ctx
->error_recovery
= (uint8_t) error_recovery
;
1418 void modbus_set_socket(modbus_t
*ctx
, int socket
)
1423 int modbus_get_socket(modbus_t
*ctx
)
1428 /* Get the timeout interval used to wait for a response */
1429 void modbus_get_response_timeout(modbus_t
*ctx
, struct timeval
*timeout
)
1431 *timeout
= ctx
->response_timeout
;
1434 void modbus_set_response_timeout(modbus_t
*ctx
, const struct timeval
*timeout
)
1436 ctx
->response_timeout
= *timeout
;
1439 /* Get the timeout interval between two consecutive bytes of a message */
1440 void modbus_get_byte_timeout(modbus_t
*ctx
, struct timeval
*timeout
)
1442 *timeout
= ctx
->byte_timeout
;
1445 void modbus_set_byte_timeout(modbus_t
*ctx
, const struct timeval
*timeout
)
1447 ctx
->byte_timeout
= *timeout
;
1450 int modbus_get_header_length(modbus_t
*ctx
)
1452 return ctx
->backend
->header_length
;
1455 int modbus_connect(modbus_t
*ctx
)
1457 return ctx
->backend
->connect(ctx
);
1460 void modbus_close(modbus_t
*ctx
)
1465 ctx
->backend
->close(ctx
);
1468 void modbus_free(modbus_t
*ctx
)
1473 free(ctx
->backend_data
);
1477 void modbus_set_debug(modbus_t
*ctx
, int boolean
)
1479 ctx
->debug
= boolean
;
1482 /* Allocates 4 arrays to store bits, input bits, registers and inputs
1483 registers. The pointers are stored in modbus_mapping structure.
1485 The modbus_mapping_new() function shall return the new allocated structure if
1486 successful. Otherwise it shall return NULL and set errno to ENOMEM. */
1487 modbus_mapping_t
* modbus_mapping_new(int nb_bits
, int nb_input_bits
,
1488 int nb_registers
, int nb_input_registers
)
1490 modbus_mapping_t
*mb_mapping
;
1492 mb_mapping
= (modbus_mapping_t
*)malloc(sizeof(modbus_mapping_t
));
1493 if (mb_mapping
== NULL
) {
1498 mb_mapping
->nb_bits
= nb_bits
;
1500 mb_mapping
->tab_bits
= NULL
;
1502 /* Negative number raises a POSIX error */
1503 mb_mapping
->tab_bits
=
1504 (uint8_t *) malloc(nb_bits
* sizeof(uint8_t));
1505 if (mb_mapping
->tab_bits
== NULL
) {
1509 memset(mb_mapping
->tab_bits
, 0, nb_bits
* sizeof(uint8_t));
1513 mb_mapping
->nb_input_bits
= nb_input_bits
;
1514 if (nb_input_bits
== 0) {
1515 mb_mapping
->tab_input_bits
= NULL
;
1517 mb_mapping
->tab_input_bits
=
1518 (uint8_t *) malloc(nb_input_bits
* sizeof(uint8_t));
1519 if (mb_mapping
->tab_input_bits
== NULL
) {
1520 free(mb_mapping
->tab_bits
);
1524 memset(mb_mapping
->tab_input_bits
, 0, nb_input_bits
* sizeof(uint8_t));
1528 mb_mapping
->nb_registers
= nb_registers
;
1529 if (nb_registers
== 0) {
1530 mb_mapping
->tab_registers
= NULL
;
1532 mb_mapping
->tab_registers
=
1533 (uint16_t *) malloc(nb_registers
* sizeof(uint16_t));
1534 if (mb_mapping
->tab_registers
== NULL
) {
1535 free(mb_mapping
->tab_input_bits
);
1536 free(mb_mapping
->tab_bits
);
1540 memset(mb_mapping
->tab_registers
, 0, nb_registers
* sizeof(uint16_t));
1544 mb_mapping
->nb_input_registers
= nb_input_registers
;
1545 if (nb_input_registers
== 0) {
1546 mb_mapping
->tab_input_registers
= NULL
;
1548 mb_mapping
->tab_input_registers
=
1549 (uint16_t *) malloc(nb_input_registers
* sizeof(uint16_t));
1550 if (mb_mapping
->tab_input_registers
== NULL
) {
1551 free(mb_mapping
->tab_registers
);
1552 free(mb_mapping
->tab_input_bits
);
1553 free(mb_mapping
->tab_bits
);
1557 memset(mb_mapping
->tab_input_registers
, 0,
1558 nb_input_registers
* sizeof(uint16_t));
1564 /* Frees the 4 arrays */
1565 void modbus_mapping_free(modbus_mapping_t
*mb_mapping
)
1567 if (mb_mapping
!= NULL
) {
1571 free(mb_mapping
->tab_input_registers
);
1572 free(mb_mapping
->tab_registers
);
1573 free(mb_mapping
->tab_input_bits
);
1574 free(mb_mapping
->tab_bits
);
1578 #ifndef HAVE_STRLCPY
1580 * Function strlcpy was originally developed by
1581 * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code.
1582 * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
1583 * for more information.
1585 * Thank you Ulrich Drepper... not!
1587 * Copy src to string dest of size dest_size. At most dest_size-1 characters
1588 * will be copied. Always NUL terminates (unless dest_size == 0). Returns
1589 * strlen(src); if retval >= dest_size, truncation occurred.
1591 size_t strlcpy(char *dest
, const char *src
, size_t dest_size
)
1593 register char *d
= dest
;
1594 register const char *s
= src
;
1595 register size_t n
= dest_size
;
1597 /* Copy as many bytes as will fit */
1598 if (n
!= 0 && --n
!= 0) {
1600 if ((*d
++ = *s
++) == 0)
1605 /* Not enough room in dest, add NUL and traverse rest of src */
1608 *d
= '\0'; /* NUL-terminate dest */
1613 return (s
- src
- 1); /* count does not include NUL */