36 #define MSG_LENGTH_UNDEFINED -1 44 #define MAX_MESSAGE_LENGTH 260 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 strerror(errnum);
92 if (context != NULL) {
93 fprintf(stderr,
": %s\n", context);
95 fprintf(stderr,
"\n");
108 struct timespec request, remaining;
112 while (nanosleep(&request, &remaining) == -1 && errno == EINTR)
121 if (rc != -1 && ctx->
debug) {
122 printf(
"%d bytes flushed\n", rc);
133 switch (req[offset]) {
137 int nb = (req[offset + 3] << 8) | req[offset + 4];
138 length = 2 + (nb / 8) + ((nb % 8) ? 1 : 0);
145 length = 2 + 2 * (req[offset + 3] << 8 | req[offset + 4]);
170 for (i = 0; i < msg_length; i++)
171 printf(
"[%.2X]", msg[i]);
182 int saved_errno = errno;
184 if ((errno == EBADF || errno == ECONNRESET || errno == EPIPE)) {
196 if (rc > 0 && rc != msg_length) {
210 if (raw_req_length < 2) {
216 sft.
slave = raw_req[0];
223 if (raw_req_length > 2) {
225 memcpy(req + req_length, raw_req + 2, raw_req_length - 2);
226 req_length += raw_req_length - 2;
229 return send_msg(ctx, req, req_length);
334 struct timeval *p_tv;
341 printf(
"Waiting for a indication...\n");
343 printf(
"Waiting for a confirmation...\n");
349 FD_SET(ctx->
s, &rfds);
367 while (length_to_read != 0) {
372 int saved_errno = errno;
374 if (errno == ETIMEDOUT) {
376 }
else if (errno == EBADF) {
385 rc = ctx->
backend->
recv(ctx, msg + msg_length, length_to_read);
394 (errno == ECONNRESET || errno == ECONNREFUSED ||
396 int saved_errno = errno;
408 for (i=0; i < rc; i++)
409 printf(
"<%.2X>", msg[msg_length + i]);
415 length_to_read -= rc;
417 if (length_to_read == 0) {
424 if (length_to_read != 0) {
443 if (length_to_read > 0 && ctx->
byte_timeout.tv_sec != -1) {
479 uint8_t *rsp,
int rsp_length)
482 int rsp_length_computed;
498 if (rsp_length == rsp_length_computed ||
502 const int function = rsp[offset];
505 if (
function != req[offset]) {
508 "Received function not corresponding to the request (%d != %d)\n",
509 function, req[offset]);
525 req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
526 req_nb_value = (req_nb_value / 8) + ((req_nb_value % 8) ? 1 : 0);
527 rsp_nb_value = rsp[offset + 1];
533 req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
534 rsp_nb_value = (rsp[offset + 1] / 2);
539 req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
540 rsp_nb_value = (rsp[offset + 3] << 8) | rsp[offset + 4];
544 req_nb_value = rsp_nb_value = rsp[offset + 1];
548 req_nb_value = rsp_nb_value = 1;
551 if (req_nb_value == rsp_nb_value) {
556 "Quantity not corresponding to the request (%d != %d)\n",
557 rsp_nb_value, req_nb_value);
568 req[offset] == (rsp[offset] - 0x80)) {
571 int exception_code = rsp[offset + 1];
582 "Message length not corresponding to the computed length (%d != %d)\n",
583 rsp_length, rsp_length_computed);
596 uint8_t *tab_io_status,
597 uint8_t *rsp,
int offset)
603 for (i = address; i < address+nb; i++) {
604 byte |= tab_io_status[i] << shift;
607 rsp[offset++] = byte;
615 rsp[offset++] = byte;
622 int exception_code, uint8_t *rsp)
630 rsp[rsp_length++] = exception_code;
645 int slave = req[offset - 1];
646 int function = req[offset];
647 uint16_t address = (req[offset + 1] << 8) + req[offset + 2];
663 int nb = (req[offset + 3] << 8) + req[offset + 4];
668 "Illegal nb of values %d in read_bits (max %d)\n",
674 }
else if ((address + nb) > mb_mapping->
nb_bits) {
676 fprintf(stderr,
"Illegal data address %0X in read_bits\n",
684 rsp[rsp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
694 int nb = (req[offset + 3] << 8) + req[offset + 4];
699 "Illegal nb of values %d in read_input_bits (max %d)\n",
707 fprintf(stderr,
"Illegal data address %0X in read_input_bits\n",
715 rsp[rsp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
723 int nb = (req[offset + 3] << 8) + req[offset + 4];
728 "Illegal nb of values %d in read_holding_registers (max %d)\n",
736 fprintf(stderr,
"Illegal data address %0X in read_registers\n",
746 rsp[rsp_length++] = nb << 1;
747 for (i = address; i < address + nb; i++) {
757 int nb = (req[offset + 3] << 8) + req[offset + 4];
762 "Illegal number of values %d in read_input_registers (max %d)\n",
770 fprintf(stderr,
"Illegal data address %0X in read_input_registers\n",
780 rsp[rsp_length++] = nb << 1;
781 for (i = address; i < address + nb; i++) {
789 if (address >= mb_mapping->
nb_bits) {
791 fprintf(stderr,
"Illegal data address %0X in write_bit\n",
798 int data = (req[offset + 3] << 8) + req[offset + 4];
800 if (data == 0xFF00 || data == 0x0) {
802 memcpy(rsp, req, req_length);
803 rsp_length = req_length;
807 "Illegal data value %0X in write_bit request at address %0X\n",
819 fprintf(stderr,
"Illegal data address %0X in write_register\n",
826 int data = (req[offset + 3] << 8) + req[offset + 4];
829 memcpy(rsp, req, req_length);
830 rsp_length = req_length;
834 int nb = (req[offset + 3] << 8) + req[offset + 4];
839 "Illegal number of values %d in write_bits (max %d)\n",
845 }
else if ((address + nb) > mb_mapping->
nb_bits) {
847 fprintf(stderr,
"Illegal data address %0X in write_bits\n",
859 memcpy(rsp + rsp_length, req + rsp_length, 4);
865 int nb = (req[offset + 3] << 8) + req[offset + 4];
870 "Illegal number of values %d in write_registers (max %d)\n",
878 fprintf(stderr,
"Illegal data address %0X in write_registers\n",
886 for (i = address, j = 6; i < address + nb; i++, j += 2) {
889 (req[offset + j] << 8) + req[offset + j + 1];
894 memcpy(rsp + rsp_length, req + rsp_length, 4);
905 byte_count_pos = rsp_length++;
908 rsp[rsp_length++] = 0xFF;
912 rsp_length += str_len;
913 rsp[byte_count_pos] = rsp_length - byte_count_pos - 1;
918 fprintf(stderr,
"FIXME Not implemented\n");
925 int nb = (req[offset + 3] << 8) + req[offset + 4];
926 uint16_t address_write = (req[offset + 5] << 8) + req[offset + 6];
927 int nb_write = (req[offset + 7] << 8) + req[offset + 8];
928 int nb_write_bytes = req[offset + 9];
932 nb_write_bytes != nb_write * 2) {
935 "Illegal nb of values (W%d, R%d) in write_and_read_registers (max W%d, R%d)\n",
943 (address_write + nb_write) > mb_mapping->
nb_registers) {
946 "Illegal data read address %0X or write address %0X write_and_read_registers\n",
947 address + nb, address_write + nb_write);
954 rsp[rsp_length++] = nb << 1;
958 for (i = address_write, j = 10; i < address_write + nb_write; i++, j += 2) {
960 (req[offset + j] << 8) + req[offset + j + 1];
964 for (i = address; i < address + nb; i++) {
979 return send_msg(ctx, rsp, rsp_length);
983 unsigned int exception_code)
986 int slave = req[offset - 1];
987 int function = req[offset];
990 int dummy_length = 99;
1005 rsp[rsp_length++] = exception_code;
1006 return send_msg(ctx, rsp, rsp_length);
1015 int addr,
int nb, uint8_t *dest)
1025 rc =
send_msg(ctx, req, req_length);
1041 offset_end = offset + rc;
1042 for (i = offset; i < offset_end; i++) {
1046 for (bit = 0x01; (bit & 0xff) && (pos < nb);) {
1047 dest[pos++] = (temp & bit) ?
TRUE :
FALSE;
1066 "ERROR Too many bits requested (%d > %d)\n",
1090 "ERROR Too many discrete inputs requested (%d > %d)\n",
1117 "ERROR Too many registers requested (%d > %d)\n",
1126 rc =
send_msg(ctx, req, req_length);
1141 for (i = 0; i < rc; i++) {
1143 dest[i] = (rsp[offset + 2 + (i << 1)] << 8) |
1144 rsp[offset + 3 + (i << 1)];
1160 "ERROR Too many registers requested (%d > %d)\n",
1180 "ERROR Too many input registers requested (%d > %d)\n",
1202 rc =
send_msg(ctx, req, req_length);
1221 status ? 0xFF00 : 0);
1244 fprintf(stderr,
"ERROR Writing too many bits (%d > %d)\n",
1254 byte_count = (nb / 8) + ((nb % 8) ? 1 : 0);
1255 req[req_length++] = byte_count;
1257 for (i = 0; i < byte_count; i++) {
1261 req[req_length] = 0;
1263 while ((bit & 0xFF) && (bit_check++ < nb)) {
1265 req[req_length] |= bit;
1267 req[req_length] &=~ bit;
1274 rc =
send_msg(ctx, req, req_length);
1302 "ERROR Trying to write to too many registers (%d > %d)\n",
1312 byte_count = nb * 2;
1313 req[req_length++] = byte_count;
1315 for (i = 0; i < nb; i++) {
1316 req[req_length++] = src[i] >> 8;
1317 req[req_length++] = src[i] & 0x00FF;
1320 rc =
send_msg(ctx, req, req_length);
1337 int write_addr,
int write_nb,
const uint16_t *src,
1338 int read_addr,
int read_nb, uint16_t *dest)
1351 "ERROR Too many registers to write (%d > %d)\n",
1361 "ERROR Too many registers requested (%d > %d)\n",
1369 read_addr, read_nb, req);
1371 req[req_length++] = write_addr >> 8;
1372 req[req_length++] = write_addr & 0x00ff;
1373 req[req_length++] = write_nb >> 8;
1374 req[req_length++] = write_nb & 0x00ff;
1375 byte_count = write_nb * 2;
1376 req[req_length++] = byte_count;
1378 for (i = 0; i < write_nb; i++) {
1379 req[req_length++] = src[i] >> 8;
1380 req[req_length++] = src[i] & 0x00FF;
1383 rc =
send_msg(ctx, req, req_length);
1398 for (i = 0; i < rc; i++) {
1400 dest[i] = (rsp[offset + 2 + (i << 1)] << 8) |
1401 rsp[offset + 3 + (i << 1)];
1422 rc =
send_msg(ctx, req, req_length);
1440 for (i=0; i < rc; i++) {
1441 dest[i] = rsp[offset + i];
1539 ctx->
debug = boolean;
1548 int nb_registers,
int nb_input_registers)
1553 if (mb_mapping == NULL) {
1558 mb_mapping->
nb_bits = nb_bits;
1564 (uint8_t *) malloc(nb_bits *
sizeof(uint8_t));
1565 if (mb_mapping->
tab_bits == NULL) {
1569 memset(mb_mapping->
tab_bits, 0, nb_bits *
sizeof(uint8_t));
1574 if (nb_input_bits == 0) {
1578 (uint8_t *) malloc(nb_input_bits *
sizeof(uint8_t));
1584 memset(mb_mapping->
tab_input_bits, 0, nb_input_bits *
sizeof(uint8_t));
1589 if (nb_registers == 0) {
1593 (uint16_t *) malloc(nb_registers *
sizeof(uint16_t));
1600 memset(mb_mapping->
tab_registers, 0, nb_registers *
sizeof(uint16_t));
1605 if (nb_input_registers == 0) {
1609 (uint16_t *) malloc(nb_input_registers *
sizeof(uint16_t));
1618 nb_input_registers *
sizeof(uint16_t));
1627 if (mb_mapping == NULL) {
1638 #ifndef HAVE_STRLCPY 1651 size_t strlcpy(
char *dest,
const char *src,
size_t dest_size)
1653 register char *d = dest;
1654 register const char *s = src;
1655 register size_t n = dest_size;
1658 if (n != 0 && --n != 0) {
1660 if ((*d++ = *s++) == 0)
1673 return (s - src - 1);
#define MODBUS_MAX_WRITE_REGISTERS
int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int exception_code)
unsigned int header_length
#define LIBMODBUS_VERSION_MICRO
void _modbus_init_common(modbus_t *ctx)
#define _RESPONSE_TIMEOUT
int modbus_send_raw_request(modbus_t *ctx, uint8_t *raw_req, int raw_req_length)
void modbus_set_debug(modbus_t *ctx, int boolean)
int(* filter_request)(modbus_t *ctx, int slave)
size_t strlcpy(char *dest, const char *src, size_t dest_size)
int modbus_set_slave(modbus_t *ctx, int slave)
static int write_single(modbus_t *ctx, int function, int addr, int value)
int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
#define MAX_MESSAGE_LENGTH
#define _FC_WRITE_AND_READ_REGISTERS
int(* send_msg_pre)(uint8_t *req, int req_length)
int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src)
static unsigned int compute_response_length_from_request(modbus_t *ctx, uint8_t *req)
void modbus_mapping_free(modbus_mapping_t *mb_mapping)
static int compute_data_length_after_meta(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
unsigned int max_adu_length
const modbus_backend_t * backend
int(* check_integrity)(modbus_t *ctx, uint8_t *msg, const int msg_length)
void modbus_set_byte_timeout(modbus_t *ctx, const struct timeval *timeout)
int(* select)(modbus_t *ctx, fd_set *rfds, struct timeval *tv, int msg_length)
int modbus_get_socket(modbus_t *ctx)
ssize_t(* send)(modbus_t *ctx, const uint8_t *req, int req_length)
#define MODBUS_MAX_READ_REGISTERS
int modbus_flush(modbus_t *ctx)
const char * modbus_strerror(int errnum)
modbus_mapping_t * modbus_mapping_new(int nb_bits, int nb_input_bits, int nb_registers, int nb_input_registers)
#define _FC_READ_EXCEPTION_STATUS
static uint8_t compute_meta_length_after_function(int function, msg_type_t msg_type)
void modbus_get_byte_timeout(modbus_t *ctx, struct timeval *timeout)
void(* close)(modbus_t *ctx)
static int check_confirmation(modbus_t *ctx, uint8_t *req, uint8_t *rsp, int rsp_length)
#define _FC_WRITE_MULTIPLE_REGISTERS
#define _FC_WRITE_SINGLE_REGISTER
int _sleep_and_flush(modbus_t *ctx)
int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
#define _FC_REPORT_SLAVE_ID
void modbus_set_response_timeout(modbus_t *ctx, const struct timeval *timeout)
int modbus_write_bit(modbus_t *ctx, int addr, int status)
int modbus_write_and_read_registers(modbus_t *ctx, int write_addr, int write_nb, const uint16_t *src, int read_addr, int read_nb, uint16_t *dest)
#define _FC_READ_HOLDING_REGISTERS
int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery)
int(* build_request_basis)(modbus_t *ctx, int function, int addr, int nb, uint8_t *req)
int(* pre_check_confirmation)(modbus_t *ctx, const uint8_t *req, const uint8_t *rsp, int rsp_length)
unsigned int checksum_length
int(* connect)(modbus_t *ctx)
int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src)
int(* flush)(modbus_t *ctx)
int modbus_get_header_length(modbus_t *ctx)
void modbus_set_socket(modbus_t *ctx, int socket)
const unsigned int libmodbus_version_major
#define _FC_READ_INPUT_REGISTERS
#define LIBMODBUS_VERSION_MAJOR
ssize_t(* recv)(modbus_t *ctx, uint8_t *rsp, int rsp_length)
#define MODBUS_MAX_WRITE_BITS
#define LIBMODBUS_VERSION_MINOR
static int response_io_status(int address, int nb, uint8_t *tab_io_status, uint8_t *rsp, int offset)
const unsigned int libmodbus_version_minor
void modbus_set_bits_from_bytes(uint8_t *dest, int index, unsigned int nb_bits, const uint8_t *tab_byte)
#define MODBUS_MAX_RW_WRITE_REGISTERS
#define LIBMODBUS_VERSION_STRING
uint16_t * tab_input_registers
modbus_error_recovery_mode
void modbus_get_response_timeout(modbus_t *ctx, struct timeval *timeout)
static int read_io_status(modbus_t *ctx, int function, int addr, int nb, uint8_t *dest)
#define MSG_LENGTH_UNDEFINED
int modbus_receive(modbus_t *ctx, uint8_t *req)
#define _FC_READ_DISCRETE_INPUTS
static int read_registers(modbus_t *ctx, int function, int addr, int nb, uint16_t *dest)
void _error_print(modbus_t *ctx, const char *context)
int(* build_response_basis)(sft_t *sft, uint8_t *rsp)
int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
static int send_msg(modbus_t *ctx, uint8_t *msg, int msg_length)
int(* prepare_response_tid)(const uint8_t *req, int *req_length)
#define _FC_WRITE_MULTIPLE_COILS
#define _FC_WRITE_SINGLE_COIL
struct timeval byte_timeout
modbus_mapping_t * mb_mapping
const unsigned int libmodbus_version_micro
static int receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp)
#define MODBUS_MAX_READ_BITS
void modbus_close(modbus_t *ctx)
static int response_exception(modbus_t *ctx, sft_t *sft, int exception_code, uint8_t *rsp)
int modbus_reply(modbus_t *ctx, const uint8_t *req, int req_length, modbus_mapping_t *mb_mapping)
void modbus_free(modbus_t *ctx)
int(* set_slave)(modbus_t *ctx, int slave)
int modbus_report_slave_id(modbus_t *ctx, uint8_t *dest)
int modbus_connect(modbus_t *ctx)
int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
struct timeval response_timeout
int modbus_write_register(modbus_t *ctx, int addr, int value)