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/
36 #include "modbus-private.h"
39 #define MSG_LENGTH_UNDEFINED -1
41 /* Exported version */
42 const unsigned int libmodbus_version_major
= LIBMODBUS_VERSION_MAJOR
;
43 const unsigned int libmodbus_version_minor
= LIBMODBUS_VERSION_MINOR
;
44 const unsigned int libmodbus_version_micro
= LIBMODBUS_VERSION_MICRO
;
46 /* Max between RTU and TCP max adu length (so TCP) */
47 #define MAX_MESSAGE_LENGTH 260
49 /* 3 steps are used to parse the query */
56 const char *modbus_strerror(int errnum
) {
59 return "Illegal function";
61 return "Illegal data address";
63 return "Illegal data value";
65 return "Slave device or server failure";
69 return "Slave device or server is busy";
71 return "Negative acknowledge";
73 return "Memory parity error";
75 return "Gateway path unavailable";
77 return "Target device failed to respond";
81 return "Invalid data";
83 return "Invalid exception code";
85 return "Too many data";
87 return "Response not from requested slave";
89 return strerror(errnum
);
93 void _error_print(modbus_t
*ctx
, const char *context
)
96 fprintf(stderr
, "ERROR %s", modbus_strerror(errno
));
97 if (context
!= NULL
) {
98 fprintf(stderr
, ": %s\n", context
);
100 fprintf(stderr
, "\n");
105 int _sleep_and_flush(modbus_t
*ctx
)
108 /* usleep doesn't exist on Windows */
109 Sleep((ctx
->response_timeout
.tv_sec
* 1000) +
110 (ctx
->response_timeout
.tv_usec
/ 1000));
112 /* usleep source code */
113 struct timespec request
, remaining
;
114 request
.tv_sec
= ctx
->response_timeout
.tv_sec
;
115 request
.tv_nsec
= ((long int)ctx
->response_timeout
.tv_usec
% 1000000)
117 while (nanosleep(&request
, &remaining
) == -1 && errno
== EINTR
)
120 return modbus_flush(ctx
);
123 int modbus_flush(modbus_t
*ctx
)
125 int rc
= ctx
->backend
->flush(ctx
);
126 if (rc
!= -1 && ctx
->debug
) {
127 /* Not all backends are able to return the number of bytes flushed */
128 printf("Bytes flushed (%d)\n", rc
);
133 /* Computes the length of the expected response */
134 static unsigned int compute_response_length_from_request(modbus_t
*ctx
, uint8_t *req
)
137 const int offset
= ctx
->backend
->header_length
;
139 switch (req
[offset
]) {
141 case _FC_READ_DISCRETE_INPUTS
: {
142 /* Header + nb values (code from write_bits) */
143 int nb
= (req
[offset
+ 3] << 8) | req
[offset
+ 4];
144 length
= 2 + (nb
/ 8) + ((nb
% 8) ? 1 : 0);
147 case _FC_WRITE_AND_READ_REGISTERS
:
148 case _FC_READ_HOLDING_REGISTERS
:
149 case _FC_READ_INPUT_REGISTERS
:
150 /* Header + 2 * nb values */
151 length
= 2 + 2 * (req
[offset
+ 3] << 8 | req
[offset
+ 4]);
153 case _FC_READ_EXCEPTION_STATUS
:
156 case _FC_REPORT_SLAVE_ID
:
157 /* The response is device specific (the header provides the
159 return MSG_LENGTH_UNDEFINED
;
164 return offset
+ length
+ ctx
->backend
->checksum_length
;
167 /* Sends a request/response */
168 static int send_msg(modbus_t
*ctx
, uint8_t *msg
, int msg_length
)
173 msg_length
= ctx
->backend
->send_msg_pre(msg
, msg_length
);
176 for (i
= 0; i
< msg_length
; i
++)
177 printf("[%.2X]", msg
[i
]);
181 /* In recovery mode, the write command will be issued until to be
182 successful! Disabled by default. */
184 rc
= ctx
->backend
->send(ctx
, msg
, msg_length
);
186 _error_print(ctx
, NULL
);
187 if (ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_LINK
) {
188 int saved_errno
= errno
;
190 if ((errno
== EBADF
|| errno
== ECONNRESET
|| errno
== EPIPE
)) {
194 _sleep_and_flush(ctx
);
199 } while ((ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_LINK
) &&
202 if (rc
> 0 && rc
!= msg_length
) {
210 int modbus_send_raw_request(modbus_t
*ctx
, uint8_t *raw_req
, int raw_req_length
)
213 uint8_t req
[MAX_MESSAGE_LENGTH
];
216 if (raw_req_length
< 2) {
217 /* The raw request must contain function and slave at least */
222 sft
.slave
= raw_req
[0];
223 sft
.function
= raw_req
[1];
224 /* The t_id is left to zero */
226 /* This response function only set the header so it's convenient here */
227 req_length
= ctx
->backend
->build_response_basis(&sft
, req
);
229 if (raw_req_length
> 2) {
230 /* Copy data after function code */
231 memcpy(req
+ req_length
, raw_req
+ 2, raw_req_length
- 2);
232 req_length
+= raw_req_length
- 2;
235 return send_msg(ctx
, req
, req_length
);
239 * ---------- Request Indication ----------
240 * | Client | ---------------------->| Server |
241 * ---------- Confirmation Response ----------
244 /* Computes the length to read after the function received */
245 static uint8_t compute_meta_length_after_function(int function
,
250 if (msg_type
== MSG_INDICATION
) {
251 if (function
<= _FC_WRITE_SINGLE_REGISTER
) {
253 } else if (function
== _FC_WRITE_MULTIPLE_COILS
||
254 function
== _FC_WRITE_MULTIPLE_REGISTERS
) {
256 } else if (function
== _FC_WRITE_AND_READ_REGISTERS
) {
259 /* _FC_READ_EXCEPTION_STATUS, _FC_REPORT_SLAVE_ID */
263 /* MSG_CONFIRMATION */
265 case _FC_WRITE_SINGLE_COIL
:
266 case _FC_WRITE_SINGLE_REGISTER
:
267 case _FC_WRITE_MULTIPLE_COILS
:
268 case _FC_WRITE_MULTIPLE_REGISTERS
:
279 /* Computes the length to read after the meta information (address, count, etc) */
280 static int compute_data_length_after_meta(modbus_t
*ctx
, uint8_t *msg
,
283 int function
= msg
[ctx
->backend
->header_length
];
286 if (msg_type
== MSG_INDICATION
) {
288 case _FC_WRITE_MULTIPLE_COILS
:
289 case _FC_WRITE_MULTIPLE_REGISTERS
:
290 length
= msg
[ctx
->backend
->header_length
+ 5];
292 case _FC_WRITE_AND_READ_REGISTERS
:
293 length
= msg
[ctx
->backend
->header_length
+ 9];
299 /* MSG_CONFIRMATION */
300 if (function
<= _FC_READ_INPUT_REGISTERS
||
301 function
== _FC_REPORT_SLAVE_ID
||
302 function
== _FC_WRITE_AND_READ_REGISTERS
) {
303 length
= msg
[ctx
->backend
->header_length
+ 1];
309 length
+= ctx
->backend
->checksum_length
;
315 /* Waits a response from a modbus server or a request from a modbus client.
316 This function blocks if there is no replies (3 timeouts).
318 The function shall return the number of received characters and the received
319 message in an array of uint8_t if successful. Otherwise it shall return -1
320 and errno is set to one of the values defined below:
325 - read() or recv() error codes
328 int _modbus_receive_msg(modbus_t
*ctx
, uint8_t *msg
, msg_type_t msg_type
)
333 struct timeval
*p_tv
;
339 if (msg_type
== MSG_INDICATION
) {
340 printf("Waiting for a indication...\n");
342 printf("Waiting for a confirmation...\n");
346 /* Add a file descriptor to the set */
348 FD_SET(ctx
->s
, &rset
);
350 /* We need to analyse the message step by step. At the first step, we want
351 * to reach the function code because all packets contain this
353 step
= _STEP_FUNCTION
;
354 length_to_read
= ctx
->backend
->header_length
+ 1;
356 if (msg_type
== MSG_INDICATION
) {
357 /* Wait for a message, we don't know when the message will be
361 tv
.tv_sec
= ctx
->response_timeout
.tv_sec
;
362 tv
.tv_usec
= ctx
->response_timeout
.tv_usec
;
366 while (length_to_read
!= 0) {
367 rc
= ctx
->backend
->select(ctx
, &rset
, p_tv
, length_to_read
);
369 _error_print(ctx
, "select");
370 if (ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_LINK
) {
371 int saved_errno
= errno
;
373 if (errno
== ETIMEDOUT
) {
374 _sleep_and_flush(ctx
);
375 } else if (errno
== EBADF
) {
384 rc
= ctx
->backend
->recv(ctx
, msg
+ msg_length
, length_to_read
);
391 _error_print(ctx
, "read");
392 if ((ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_LINK
) &&
393 (errno
== ECONNRESET
|| errno
== ECONNREFUSED
||
395 int saved_errno
= errno
;
398 /* Could be removed by previous calls */
404 /* Display the hex code of each character received */
407 for (i
=0; i
< rc
; i
++)
408 printf("<%.2X>", msg
[msg_length
+ i
]);
411 /* Sums bytes received */
413 /* Computes remaining bytes */
414 length_to_read
-= rc
;
416 if (length_to_read
== 0) {
419 /* Function code position */
420 length_to_read
= compute_meta_length_after_function(
421 msg
[ctx
->backend
->header_length
],
423 if (length_to_read
!= 0) {
426 } /* else switches straight to the next step */
428 length_to_read
= compute_data_length_after_meta(
430 if ((msg_length
+ length_to_read
) > (int)ctx
->backend
->max_adu_length
) {
432 _error_print(ctx
, "too many data");
442 if (length_to_read
> 0 && ctx
->byte_timeout
.tv_sec
!= -1) {
443 /* If there is no character in the buffer, the allowed timeout
444 interval between two consecutive bytes is defined by
446 tv
.tv_sec
= ctx
->byte_timeout
.tv_sec
;
447 tv
.tv_usec
= ctx
->byte_timeout
.tv_usec
;
455 return ctx
->backend
->check_integrity(ctx
, msg
, msg_length
);
458 /* Receive the request from a modbus master */
459 int modbus_receive(modbus_t
*ctx
, uint8_t *req
)
461 return ctx
->backend
->receive(ctx
, req
);
464 /* Receives the confirmation.
466 The function shall store the read response in rsp and return the number of
467 values (bits or words). Otherwise, its shall return -1 and errno is set.
469 The function doesn't check the confirmation is the expected response to the
472 int modbus_receive_confirmation(modbus_t
*ctx
, uint8_t *rsp
)
474 return _modbus_receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
477 static int check_confirmation(modbus_t
*ctx
, uint8_t *req
,
478 uint8_t *rsp
, int rsp_length
)
481 int rsp_length_computed
;
482 const int offset
= ctx
->backend
->header_length
;
483 const int function
= rsp
[offset
];
485 if (ctx
->backend
->pre_check_confirmation
) {
486 rc
= ctx
->backend
->pre_check_confirmation(ctx
, req
, rsp
, rsp_length
);
488 if (ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_PROTOCOL
) {
489 _sleep_and_flush(ctx
);
495 rsp_length_computed
= compute_response_length_from_request(ctx
, req
);
498 if (function
>= 0x80) {
499 if (rsp_length
== (offset
+ 2 + ctx
->backend
->checksum_length
) &&
500 req
[offset
] == (rsp
[offset
] - 0x80)) {
501 /* Valid exception code received */
503 int exception_code
= rsp
[offset
+ 1];
504 if (exception_code
< MODBUS_EXCEPTION_MAX
) {
505 errno
= MODBUS_ENOBASE
+ exception_code
;
509 _error_print(ctx
, NULL
);
513 _error_print(ctx
, NULL
);
519 if ((rsp_length
== rsp_length_computed
||
520 rsp_length_computed
== MSG_LENGTH_UNDEFINED
) &&
525 /* Check function code */
526 if (function
!= req
[offset
]) {
529 "Received function not corresponding to the requestd (0x%X != 0x%X)\n",
530 function
, req
[offset
]);
532 if (ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_PROTOCOL
) {
533 _sleep_and_flush(ctx
);
539 /* Check the number of values is corresponding to the request */
542 case _FC_READ_DISCRETE_INPUTS
:
543 /* Read functions, 8 values in a byte (nb
544 * of values in the request and byte count in
546 req_nb_value
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
547 req_nb_value
= (req_nb_value
/ 8) + ((req_nb_value
% 8) ? 1 : 0);
548 rsp_nb_value
= rsp
[offset
+ 1];
550 case _FC_WRITE_AND_READ_REGISTERS
:
551 case _FC_READ_HOLDING_REGISTERS
:
552 case _FC_READ_INPUT_REGISTERS
:
553 /* Read functions 1 value = 2 bytes */
554 req_nb_value
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
555 rsp_nb_value
= (rsp
[offset
+ 1] / 2);
557 case _FC_WRITE_MULTIPLE_COILS
:
558 case _FC_WRITE_MULTIPLE_REGISTERS
:
559 /* N Write functions */
560 req_nb_value
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
561 rsp_nb_value
= (rsp
[offset
+ 3] << 8) | rsp
[offset
+ 4];
563 case _FC_REPORT_SLAVE_ID
:
564 /* Report slave ID (bytes received) */
565 req_nb_value
= rsp_nb_value
= rsp
[offset
+ 1];
568 /* 1 Write functions & others */
569 req_nb_value
= rsp_nb_value
= 1;
572 if (req_nb_value
== rsp_nb_value
) {
577 "Quantity not corresponding to the request (%d != %d)\n",
578 rsp_nb_value
, req_nb_value
);
581 if (ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_PROTOCOL
) {
582 _sleep_and_flush(ctx
);
591 "Message length not corresponding to the computed length (%d != %d)\n",
592 rsp_length
, rsp_length_computed
);
594 if (ctx
->error_recovery
& MODBUS_ERROR_RECOVERY_PROTOCOL
) {
595 _sleep_and_flush(ctx
);
604 static int response_io_status(int address
, int nb
,
605 uint8_t *tab_io_status
,
606 uint8_t *rsp
, int offset
)
612 for (i
= address
; i
< address
+nb
; i
++) {
613 byte
|= tab_io_status
[i
] << shift
;
616 rsp
[offset
++] = byte
;
624 rsp
[offset
++] = byte
;
629 /* Build the exception response */
630 static int response_exception(modbus_t
*ctx
, sft_t
*sft
,
631 int exception_code
, uint8_t *rsp
)
635 sft
->function
= sft
->function
+ 0x80;
636 rsp_length
= ctx
->backend
->build_response_basis(sft
, rsp
);
638 /* Positive exception code */
639 rsp
[rsp_length
++] = exception_code
;
644 /* Send a response to the received request.
645 Analyses the request and constructs a response.
647 If an error occurs, this function construct the response
650 int modbus_reply(modbus_t
*ctx
, const uint8_t *req
,
651 int req_length
, modbus_mapping_t
*mb_mapping
)
653 int offset
= ctx
->backend
->header_length
;
654 int slave
= req
[offset
- 1];
655 int function
= req
[offset
];
656 uint16_t address
= (req
[offset
+ 1] << 8) + req
[offset
+ 2];
657 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
662 sft
.function
= function
;
663 sft
.t_id
= ctx
->backend
->prepare_response_tid(req
, &req_length
);
666 case _FC_READ_COILS
: {
667 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
669 if ((address
+ nb
) > mb_mapping
->nb_bits
) {
671 fprintf(stderr
, "Illegal data address %0X in read_bits\n",
674 rsp_length
= response_exception(
676 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
678 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
679 rsp
[rsp_length
++] = (nb
/ 8) + ((nb
% 8) ? 1 : 0);
680 rsp_length
= response_io_status(address
, nb
,
681 mb_mapping
->tab_bits
,
686 case _FC_READ_DISCRETE_INPUTS
: {
687 /* Similar to coil status (but too many arguments to use a
689 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
691 if ((address
+ nb
) > mb_mapping
->nb_input_bits
) {
693 fprintf(stderr
, "Illegal data address %0X in read_input_bits\n",
696 rsp_length
= response_exception(
698 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
700 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
701 rsp
[rsp_length
++] = (nb
/ 8) + ((nb
% 8) ? 1 : 0);
702 rsp_length
= response_io_status(address
, nb
,
703 mb_mapping
->tab_input_bits
,
708 case _FC_READ_HOLDING_REGISTERS
: {
709 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
711 if ((address
+ nb
) > mb_mapping
->nb_registers
) {
713 fprintf(stderr
, "Illegal data address %0X in read_registers\n",
716 rsp_length
= response_exception(
718 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
722 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
723 rsp
[rsp_length
++] = nb
<< 1;
724 for (i
= address
; i
< address
+ nb
; i
++) {
725 rsp
[rsp_length
++] = mb_mapping
->tab_registers
[i
] >> 8;
726 rsp
[rsp_length
++] = mb_mapping
->tab_registers
[i
] & 0xFF;
731 case _FC_READ_INPUT_REGISTERS
: {
732 /* Similar to holding registers (but too many arguments to use a
734 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
736 if ((address
+ nb
) > mb_mapping
->nb_input_registers
) {
738 fprintf(stderr
, "Illegal data address %0X in read_input_registers\n",
741 rsp_length
= response_exception(
743 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
747 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
748 rsp
[rsp_length
++] = nb
<< 1;
749 for (i
= address
; i
< address
+ nb
; i
++) {
750 rsp
[rsp_length
++] = mb_mapping
->tab_input_registers
[i
] >> 8;
751 rsp
[rsp_length
++] = mb_mapping
->tab_input_registers
[i
] & 0xFF;
756 case _FC_WRITE_SINGLE_COIL
:
757 if (address
>= mb_mapping
->nb_bits
) {
759 fprintf(stderr
, "Illegal data address %0X in write_bit\n",
762 rsp_length
= response_exception(
764 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
766 int data
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
768 if (data
== 0xFF00 || data
== 0x0) {
769 mb_mapping
->tab_bits
[address
] = (data
) ? ON
: OFF
;
770 memcpy(rsp
, req
, req_length
);
771 rsp_length
= req_length
;
775 "Illegal data value %0X in write_bit request at address %0X\n",
778 rsp_length
= response_exception(
780 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE
, rsp
);
784 case _FC_WRITE_SINGLE_REGISTER
:
785 if (address
>= mb_mapping
->nb_registers
) {
787 fprintf(stderr
, "Illegal data address %0X in write_register\n",
790 rsp_length
= response_exception(
792 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
794 int data
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
796 mb_mapping
->tab_registers
[address
] = data
;
797 memcpy(rsp
, req
, req_length
);
798 rsp_length
= req_length
;
801 case _FC_WRITE_MULTIPLE_COILS
: {
802 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
804 if ((address
+ nb
) > mb_mapping
->nb_bits
) {
806 fprintf(stderr
, "Illegal data address %0X in write_bits\n",
809 rsp_length
= response_exception(
811 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
814 modbus_set_bits_from_bytes(mb_mapping
->tab_bits
, address
, nb
, &req
[offset
+ 6]);
816 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
817 /* 4 to copy the bit address (2) and the quantity of bits */
818 memcpy(rsp
+ rsp_length
, req
+ rsp_length
, 4);
823 case _FC_WRITE_MULTIPLE_REGISTERS
: {
824 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
826 if ((address
+ nb
) > mb_mapping
->nb_registers
) {
828 fprintf(stderr
, "Illegal data address %0X in write_registers\n",
831 rsp_length
= response_exception(
833 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
836 for (i
= address
, j
= 6; i
< address
+ nb
; i
++, j
+= 2) {
837 /* 6 and 7 = first value */
838 mb_mapping
->tab_registers
[i
] =
839 (req
[offset
+ j
] << 8) + req
[offset
+ j
+ 1];
842 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
843 /* 4 to copy the address (2) and the no. of registers */
844 memcpy(rsp
+ rsp_length
, req
+ rsp_length
, 4);
849 case _FC_REPORT_SLAVE_ID
: {
853 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
854 /* Skip byte count for now */
855 byte_count_pos
= rsp_length
++;
856 rsp
[rsp_length
++] = _REPORT_SLAVE_ID
;
857 /* Run indicator status to ON */
858 rsp
[rsp_length
++] = 0xFF;
859 /* LMB + length of LIBMODBUS_VERSION_STRING */
860 str_len
= 3 + strlen(LIBMODBUS_VERSION_STRING
);
861 memcpy(rsp
+ rsp_length
, "LMB" LIBMODBUS_VERSION_STRING
, str_len
);
862 rsp_length
+= str_len
;
863 rsp
[byte_count_pos
] = rsp_length
- byte_count_pos
- 1;
866 case _FC_READ_EXCEPTION_STATUS
:
868 fprintf(stderr
, "FIXME Not implemented\n");
874 case _FC_WRITE_AND_READ_REGISTERS
: {
875 int nb
= (req
[offset
+ 3] << 8) + req
[offset
+ 4];
876 uint16_t address_write
= (req
[offset
+ 5] << 8) + req
[offset
+ 6];
877 int nb_write
= (req
[offset
+ 7] << 8) + req
[offset
+ 8];
879 if ((address
+ nb
) > mb_mapping
->nb_registers
||
880 (address_write
+ nb_write
) > mb_mapping
->nb_registers
) {
883 "Illegal data read address %0X or write address %0X write_and_read_registers\n",
884 address
+ nb
, address_write
+ nb_write
);
886 rsp_length
= response_exception(ctx
, &sft
,
887 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS
, rsp
);
890 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
891 rsp
[rsp_length
++] = nb
<< 1;
894 10 and 11 are the offset of the first values to write */
895 for (i
= address_write
, j
= 10; i
< address_write
+ nb_write
; i
++, j
+= 2) {
896 mb_mapping
->tab_registers
[i
] =
897 (req
[offset
+ j
] << 8) + req
[offset
+ j
+ 1];
900 /* and read the data for the response */
901 for (i
= address
; i
< address
+ nb
; i
++) {
902 rsp
[rsp_length
++] = mb_mapping
->tab_registers
[i
] >> 8;
903 rsp
[rsp_length
++] = mb_mapping
->tab_registers
[i
] & 0xFF;
910 rsp_length
= response_exception(ctx
, &sft
,
911 MODBUS_EXCEPTION_ILLEGAL_FUNCTION
,
916 return send_msg(ctx
, rsp
, rsp_length
);
919 int modbus_reply_exception(modbus_t
*ctx
, const uint8_t *req
,
920 unsigned int exception_code
)
922 int offset
= ctx
->backend
->header_length
;
923 int slave
= req
[offset
- 1];
924 int function
= req
[offset
];
925 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
927 int dummy_length
= 99;
931 sft
.function
= function
+ 0x80;;
932 sft
.t_id
= ctx
->backend
->prepare_response_tid(req
, &dummy_length
);
933 rsp_length
= ctx
->backend
->build_response_basis(&sft
, rsp
);
935 /* Positive exception code */
936 if (exception_code
< MODBUS_EXCEPTION_MAX
) {
937 rsp
[rsp_length
++] = exception_code
;
938 return send_msg(ctx
, rsp
, rsp_length
);
945 /* Reads IO status */
946 static int read_io_status(modbus_t
*ctx
, int function
,
947 int addr
, int nb
, uint8_t *dest
)
952 uint8_t req
[_MIN_REQ_LENGTH
];
953 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
955 req_length
= ctx
->backend
->build_request_basis(ctx
, function
, addr
, nb
, req
);
957 rc
= send_msg(ctx
, req
, req_length
);
964 rc
= _modbus_receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
968 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
972 offset
= ctx
->backend
->header_length
+ 2;
973 offset_end
= offset
+ rc
;
974 for (i
= offset
; i
< offset_end
; i
++) {
975 /* Shift reg hi_byte to temp */
978 for (bit
= 0x01; (bit
& 0xff) && (pos
< nb
);) {
979 dest
[pos
++] = (temp
& bit
) ? TRUE
: FALSE
;
989 /* Reads the boolean status of bits and sets the array elements
990 in the destination to TRUE or FALSE (single bits). */
991 int modbus_read_bits(modbus_t
*ctx
, int addr
, int nb
, uint8_t *dest
)
995 if (nb
> MODBUS_MAX_READ_BITS
) {
998 "ERROR Too many bits requested (%d > %d)\n",
999 nb
, MODBUS_MAX_READ_BITS
);
1005 rc
= read_io_status(ctx
, _FC_READ_COILS
, addr
, nb
, dest
);
1014 /* Same as modbus_read_bits but reads the remote device input table */
1015 int modbus_read_input_bits(modbus_t
*ctx
, int addr
, int nb
, uint8_t *dest
)
1019 if (nb
> MODBUS_MAX_READ_BITS
) {
1022 "ERROR Too many discrete inputs requested (%d > %d)\n",
1023 nb
, MODBUS_MAX_READ_BITS
);
1029 rc
= read_io_status(ctx
, _FC_READ_DISCRETE_INPUTS
, addr
, nb
, dest
);
1037 /* Reads the data from a remove device and put that data into an array */
1038 static int read_registers(modbus_t
*ctx
, int function
, int addr
, int nb
,
1043 uint8_t req
[_MIN_REQ_LENGTH
];
1044 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
1046 if (nb
> MODBUS_MAX_READ_REGISTERS
) {
1049 "ERROR Too many registers requested (%d > %d)\n",
1050 nb
, MODBUS_MAX_READ_REGISTERS
);
1056 req_length
= ctx
->backend
->build_request_basis(ctx
, function
, addr
, nb
, req
);
1058 rc
= send_msg(ctx
, req
, req_length
);
1063 rc
= _modbus_receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
1067 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
1071 offset
= ctx
->backend
->header_length
;
1073 for (i
= 0; i
< rc
; i
++) {
1074 /* shift reg hi_byte to temp OR with lo_byte */
1075 dest
[i
] = (rsp
[offset
+ 2 + (i
<< 1)] << 8) |
1076 rsp
[offset
+ 3 + (i
<< 1)];
1083 /* Reads the holding registers of remote device and put the data into an
1085 int modbus_read_registers(modbus_t
*ctx
, int addr
, int nb
, uint16_t *dest
)
1089 if (nb
> MODBUS_MAX_READ_REGISTERS
) {
1092 "ERROR Too many registers requested (%d > %d)\n",
1093 nb
, MODBUS_MAX_READ_REGISTERS
);
1099 status
= read_registers(ctx
, _FC_READ_HOLDING_REGISTERS
,
1104 /* Reads the input registers of remote device and put the data into an array */
1105 int modbus_read_input_registers(modbus_t
*ctx
, int addr
, int nb
,
1110 if (nb
> MODBUS_MAX_READ_REGISTERS
) {
1112 "ERROR Too many input registers requested (%d > %d)\n",
1113 nb
, MODBUS_MAX_READ_REGISTERS
);
1118 status
= read_registers(ctx
, _FC_READ_INPUT_REGISTERS
,
1124 /* Write a value to the specified register of the remote device.
1125 Used by write_bit and write_register */
1126 static int write_single(modbus_t
*ctx
, int function
, int addr
, int value
)
1130 uint8_t req
[_MIN_REQ_LENGTH
];
1132 req_length
= ctx
->backend
->build_request_basis(ctx
, function
, addr
, value
, req
);
1134 rc
= send_msg(ctx
, req
, req_length
);
1136 /* Used by write_bit and write_register */
1137 uint8_t rsp
[_MIN_REQ_LENGTH
];
1139 rc
= _modbus_receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
1143 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
1149 /* Turns ON or OFF a single bit of the remote device */
1150 int modbus_write_bit(modbus_t
*ctx
, int addr
, int status
)
1152 return write_single(ctx
, _FC_WRITE_SINGLE_COIL
, addr
,
1153 status
? 0xFF00 : 0);
1156 /* Writes a value in one register of the remote device */
1157 int modbus_write_register(modbus_t
*ctx
, int addr
, int value
)
1159 return write_single(ctx
, _FC_WRITE_SINGLE_REGISTER
, addr
, value
);
1162 /* Write the bits of the array in the remote device */
1163 int modbus_write_bits(modbus_t
*ctx
, int addr
, int nb
, const uint8_t *src
)
1172 uint8_t req
[MAX_MESSAGE_LENGTH
];
1174 if (nb
> MODBUS_MAX_WRITE_BITS
) {
1176 fprintf(stderr
, "ERROR Writing too many bits (%d > %d)\n",
1177 nb
, MODBUS_MAX_WRITE_BITS
);
1183 req_length
= ctx
->backend
->build_request_basis(ctx
,
1184 _FC_WRITE_MULTIPLE_COILS
,
1186 byte_count
= (nb
/ 8) + ((nb
% 8) ? 1 : 0);
1187 req
[req_length
++] = byte_count
;
1189 for (i
= 0; i
< byte_count
; i
++) {
1193 req
[req_length
] = 0;
1195 while ((bit
& 0xFF) && (bit_check
++ < nb
)) {
1197 req
[req_length
] |= bit
;
1199 req
[req_length
] &=~ bit
;
1206 rc
= send_msg(ctx
, req
, req_length
);
1208 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
1210 rc
= _modbus_receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
1214 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
1221 /* Write the values from the array to the registers of the remote device */
1222 int modbus_write_registers(modbus_t
*ctx
, int addr
, int nb
, const uint16_t *src
)
1229 uint8_t req
[MAX_MESSAGE_LENGTH
];
1231 if (nb
> MODBUS_MAX_WRITE_REGISTERS
) {
1234 "ERROR Trying to write to too many registers (%d > %d)\n",
1235 nb
, MODBUS_MAX_WRITE_REGISTERS
);
1241 req_length
= ctx
->backend
->build_request_basis(ctx
,
1242 _FC_WRITE_MULTIPLE_REGISTERS
,
1244 byte_count
= nb
* 2;
1245 req
[req_length
++] = byte_count
;
1247 for (i
= 0; i
< nb
; i
++) {
1248 req
[req_length
++] = src
[i
] >> 8;
1249 req
[req_length
++] = src
[i
] & 0x00FF;
1252 rc
= send_msg(ctx
, req
, req_length
);
1254 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
1256 rc
= _modbus_receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
1260 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
1266 /* Write multiple registers from src array to remote device and read multiple
1267 registers from remote device to dest array. */
1268 int modbus_write_and_read_registers(modbus_t
*ctx
,
1269 int write_addr
, int write_nb
, const uint16_t *src
,
1270 int read_addr
, int read_nb
, uint16_t *dest
)
1277 uint8_t req
[MAX_MESSAGE_LENGTH
];
1278 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
1280 if (write_nb
> MODBUS_MAX_RW_WRITE_REGISTERS
) {
1283 "ERROR Too many registers to write (%d > %d)\n",
1284 write_nb
, MODBUS_MAX_RW_WRITE_REGISTERS
);
1290 if (read_nb
> MODBUS_MAX_READ_REGISTERS
) {
1293 "ERROR Too many registers requested (%d > %d)\n",
1294 read_nb
, MODBUS_MAX_READ_REGISTERS
);
1299 req_length
= ctx
->backend
->build_request_basis(ctx
,
1300 _FC_WRITE_AND_READ_REGISTERS
,
1301 read_addr
, read_nb
, req
);
1303 req
[req_length
++] = write_addr
>> 8;
1304 req
[req_length
++] = write_addr
& 0x00ff;
1305 req
[req_length
++] = write_nb
>> 8;
1306 req
[req_length
++] = write_nb
& 0x00ff;
1307 byte_count
= write_nb
* 2;
1308 req
[req_length
++] = byte_count
;
1310 for (i
= 0; i
< write_nb
; i
++) {
1311 req
[req_length
++] = src
[i
] >> 8;
1312 req
[req_length
++] = src
[i
] & 0x00FF;
1315 rc
= send_msg(ctx
, req
, req_length
);
1319 rc
= _modbus_receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
1323 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
1327 offset
= ctx
->backend
->header_length
;
1329 /* If rc is negative, the loop is jumped ! */
1330 for (i
= 0; i
< rc
; i
++) {
1331 /* shift reg hi_byte to temp OR with lo_byte */
1332 dest
[i
] = (rsp
[offset
+ 2 + (i
<< 1)] << 8) |
1333 rsp
[offset
+ 3 + (i
<< 1)];
1340 /* Send a request to get the slave ID of the device (only available in serial
1342 int modbus_report_slave_id(modbus_t
*ctx
, uint8_t *dest
)
1346 uint8_t req
[_MIN_REQ_LENGTH
];
1348 req_length
= ctx
->backend
->build_request_basis(ctx
, _FC_REPORT_SLAVE_ID
,
1351 /* HACKISH, addr and count are not used */
1354 rc
= send_msg(ctx
, req
, req_length
);
1358 uint8_t rsp
[MAX_MESSAGE_LENGTH
];
1360 rc
= _modbus_receive_msg(ctx
, rsp
, MSG_CONFIRMATION
);
1364 rc
= check_confirmation(ctx
, req
, rsp
, rc
);
1368 offset
= ctx
->backend
->header_length
+ 2;
1370 /* Byte count, slave id, run indicator status,
1372 for (i
=0; i
< rc
; i
++) {
1373 dest
[i
] = rsp
[offset
+ i
];
1380 void _modbus_init_common(modbus_t
*ctx
)
1382 /* Slave and socket are initialized to -1 */
1387 ctx
->error_recovery
= MODBUS_ERROR_RECOVERY_NONE
;
1389 ctx
->response_timeout
.tv_sec
= 0;
1390 ctx
->response_timeout
.tv_usec
= _RESPONSE_TIMEOUT
;
1392 ctx
->byte_timeout
.tv_sec
= 0;
1393 ctx
->byte_timeout
.tv_usec
= _BYTE_TIMEOUT
;
1396 /* Define the slave number */
1397 int modbus_set_slave(modbus_t
*ctx
, int slave
)
1399 return ctx
->backend
->set_slave(ctx
, slave
);
1402 int modbus_set_error_recovery(modbus_t
*ctx
,
1403 modbus_error_recovery_mode error_recovery
)
1405 /* The type of modbus_error_recovery_mode is unsigned enum */
1406 ctx
->error_recovery
= (uint8_t) error_recovery
;
1410 void modbus_set_socket(modbus_t
*ctx
, int socket
)
1415 int modbus_get_socket(modbus_t
*ctx
)
1420 /* Get the timeout interval used to wait for a response */
1421 void modbus_get_response_timeout(modbus_t
*ctx
, struct timeval
*timeout
)
1423 *timeout
= ctx
->response_timeout
;
1426 void modbus_set_response_timeout(modbus_t
*ctx
, const struct timeval
*timeout
)
1428 ctx
->response_timeout
= *timeout
;
1431 /* Get the timeout interval between two consecutive bytes of a message */
1432 void modbus_get_byte_timeout(modbus_t
*ctx
, struct timeval
*timeout
)
1434 *timeout
= ctx
->byte_timeout
;
1437 void modbus_set_byte_timeout(modbus_t
*ctx
, const struct timeval
*timeout
)
1439 ctx
->byte_timeout
= *timeout
;
1442 int modbus_get_header_length(modbus_t
*ctx
)
1444 return ctx
->backend
->header_length
;
1447 int modbus_connect(modbus_t
*ctx
)
1449 return ctx
->backend
->connect(ctx
);
1452 void modbus_close(modbus_t
*ctx
)
1457 ctx
->backend
->close(ctx
);
1460 void modbus_free(modbus_t
*ctx
)
1465 free(ctx
->backend_data
);
1469 void modbus_set_debug(modbus_t
*ctx
, int boolean
)
1471 ctx
->debug
= boolean
;
1474 /* Allocates 4 arrays to store bits, input bits, registers and inputs
1475 registers. The pointers are stored in modbus_mapping structure.
1477 The modbus_mapping_new() function shall return the new allocated structure if
1478 successful. Otherwise it shall return NULL and set errno to ENOMEM. */
1479 modbus_mapping_t
* modbus_mapping_new(int nb_bits
, int nb_input_bits
,
1480 int nb_registers
, int nb_input_registers
)
1482 modbus_mapping_t
*mb_mapping
;
1484 mb_mapping
= (modbus_mapping_t
*)malloc(sizeof(modbus_mapping_t
));
1485 if (mb_mapping
== NULL
) {
1490 mb_mapping
->nb_bits
= nb_bits
;
1492 mb_mapping
->tab_bits
= NULL
;
1494 /* Negative number raises a POSIX error */
1495 mb_mapping
->tab_bits
=
1496 (uint8_t *) malloc(nb_bits
* sizeof(uint8_t));
1497 if (mb_mapping
->tab_bits
== NULL
) {
1501 memset(mb_mapping
->tab_bits
, 0, nb_bits
* sizeof(uint8_t));
1505 mb_mapping
->nb_input_bits
= nb_input_bits
;
1506 if (nb_input_bits
== 0) {
1507 mb_mapping
->tab_input_bits
= NULL
;
1509 mb_mapping
->tab_input_bits
=
1510 (uint8_t *) malloc(nb_input_bits
* sizeof(uint8_t));
1511 if (mb_mapping
->tab_input_bits
== NULL
) {
1512 free(mb_mapping
->tab_bits
);
1516 memset(mb_mapping
->tab_input_bits
, 0, nb_input_bits
* sizeof(uint8_t));
1520 mb_mapping
->nb_registers
= nb_registers
;
1521 if (nb_registers
== 0) {
1522 mb_mapping
->tab_registers
= NULL
;
1524 mb_mapping
->tab_registers
=
1525 (uint16_t *) malloc(nb_registers
* sizeof(uint16_t));
1526 if (mb_mapping
->tab_registers
== NULL
) {
1527 free(mb_mapping
->tab_input_bits
);
1528 free(mb_mapping
->tab_bits
);
1532 memset(mb_mapping
->tab_registers
, 0, nb_registers
* sizeof(uint16_t));
1536 mb_mapping
->nb_input_registers
= nb_input_registers
;
1537 if (nb_input_registers
== 0) {
1538 mb_mapping
->tab_input_registers
= NULL
;
1540 mb_mapping
->tab_input_registers
=
1541 (uint16_t *) malloc(nb_input_registers
* sizeof(uint16_t));
1542 if (mb_mapping
->tab_input_registers
== NULL
) {
1543 free(mb_mapping
->tab_registers
);
1544 free(mb_mapping
->tab_input_bits
);
1545 free(mb_mapping
->tab_bits
);
1549 memset(mb_mapping
->tab_input_registers
, 0,
1550 nb_input_registers
* sizeof(uint16_t));
1556 /* Frees the 4 arrays */
1557 void modbus_mapping_free(modbus_mapping_t
*mb_mapping
)
1559 if (mb_mapping
== NULL
) {
1563 free(mb_mapping
->tab_input_registers
);
1564 free(mb_mapping
->tab_registers
);
1565 free(mb_mapping
->tab_input_bits
);
1566 free(mb_mapping
->tab_bits
);
1570 #ifndef HAVE_STRLCPY
1572 * Function strlcpy was originally developed by
1573 * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code.
1574 * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
1575 * for more information.
1577 * Thank you Ulrich Drepper... not!
1579 * Copy src to string dest of size dest_size. At most dest_size-1 characters
1580 * will be copied. Always NUL terminates (unless dest_size == 0). Returns
1581 * strlen(src); if retval >= dest_size, truncation occurred.
1583 size_t strlcpy(char *dest
, const char *src
, size_t dest_size
)
1585 register char *d
= dest
;
1586 register const char *s
= src
;
1587 register size_t n
= dest_size
;
1589 /* Copy as many bytes as will fit */
1590 if (n
!= 0 && --n
!= 0) {
1592 if ((*d
++ = *s
++) == 0)
1597 /* Not enough room in dest, add NUL and traverse rest of src */
1600 *d
= '\0'; /* NUL-terminate dest */
1605 return (s
- src
- 1); /* count does not include NUL */