1 /* 2 * Copyright © 2010-2012 Stéphane Raimbault <stephane.raimbault@gmail.com> 3 * 4 * SPDX-License-Identifier: LGPL-2.1+ 5 */ 6 7 #ifndef MODBUS_PRIVATE_H 8 #define MODBUS_PRIVATE_H 9 10 #ifndef _MSC_VER 11 # include <stdint.h> 12 # include <sys/time.h> 13 #else 14 # include "stdint.h" 15 # include <time.h> 16 typedef int ssize_t; 17 #endif 18 #include <sys/types.h> 19 #include <config.h> 20 21 #include "modbus.h" 22 23 MODBUS_BEGIN_DECLS 24 25 /* It's not really the minimal length (the real one is report slave ID 26 * in RTU (4 bytes)) but it's a convenient size to use in RTU or TCP 27 * communications to read many values or write a single one. 28 * Maximum between : 29 * - HEADER_LENGTH_TCP (7) + function (1) + address (2) + number (2) 30 * - HEADER_LENGTH_RTU (1) + function (1) + address (2) + number (2) + CRC (2) 31 */ 32 #define _MIN_REQ_LENGTH 12 33 34 #define _REPORT_SLAVE_ID 180 35 36 #define _MODBUS_EXCEPTION_RSP_LENGTH 5 37 38 /* Timeouts in microsecond (0.5 s) */ 39 #define _RESPONSE_TIMEOUT 500000 40 #define _BYTE_TIMEOUT 500000 41 42 typedef enum { 43 _MODBUS_BACKEND_TYPE_RTU=0, 44 _MODBUS_BACKEND_TYPE_TCP 45 } modbus_backend_type_t; 46 47 /* 48 * ---------- Request Indication ---------- 49 * | Client | ---------------------->| Server | 50 * ---------- Confirmation Response ---------- 51 */ 52 typedef enum { 53 /* Request message on the server side */ 54 MSG_INDICATION, 55 /* Request message on the client side */ 56 MSG_CONFIRMATION 57 } msg_type_t; 58 59 /* This structure reduces the number of params in functions and so 60 * optimizes the speed of execution (~ 37%). */ 61 typedef struct _sft { 62 int slave; 63 int function; 64 int t_id; 65 } sft_t; 66 67 typedef struct _modbus_backend { 68 unsigned int backend_type; 69 unsigned int header_length; 70 unsigned int checksum_length; 71 unsigned int max_adu_length; 72 int (*set_slave) (modbus_t *ctx, int slave); 73 int (*build_request_basis) (modbus_t *ctx, int function, int addr, 74 int nb, uint8_t *req); 75 int (*build_response_basis) (sft_t *sft, uint8_t *rsp); 76 int (*prepare_response_tid) (const uint8_t *req, int *req_length); 77 int (*send_msg_pre) (uint8_t *req, int req_length); 78 ssize_t (*send) (modbus_t *ctx, const uint8_t *req, int req_length); 79 int (*receive) (modbus_t *ctx, uint8_t *req); 80 ssize_t (*recv) (modbus_t *ctx, uint8_t *rsp, int rsp_length); 81 int (*check_integrity) (modbus_t *ctx, uint8_t *msg, 82 const int msg_length); 83 int (*pre_check_confirmation) (modbus_t *ctx, const uint8_t *req, 84 const uint8_t *rsp, int rsp_length); 85 int (*connect) (modbus_t *ctx); 86 void (*close) (modbus_t *ctx); 87 int (*flush) (modbus_t *ctx); 88 int (*select) (modbus_t *ctx, fd_set *rset, struct timeval *tv, int msg_length); 89 void (*free) (modbus_t *ctx); 90 } modbus_backend_t; 91 92 struct _modbus { 93 /* Slave address */ 94 int slave; 95 /* Socket or file descriptor */ 96 int s; 97 int debug; 98 int error_recovery; 99 struct timeval response_timeout; 100 struct timeval byte_timeout; 101 struct timeval indication_timeout; 102 const modbus_backend_t *backend; 103 void *backend_data; 104 }; 105 106 void _modbus_init_common(modbus_t *ctx); 107 void _error_print(modbus_t *ctx, const char *context); 108 int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type); 109 110 #ifndef HAVE_STRLCPY 111 size_t strlcpy(char *dest, const char *src, size_t dest_size); 112 #endif 113 114 MODBUS_END_DECLS 115 116 #endif /* MODBUS_PRIVATE_H */ 117