Commit 66c59d6f852811900f4b7730d0d5d8f321f2226f

Authored by Stéphane Raimbault
1 parent 5ab6c0e1

Change indent level from 8 to 4

.dir-locals.el
1 1 ((nil . ((indent-tabs-mode . nil)
2   - (c-basic-offset . 8)
  2 + (c-basic-offset . 4)
3 3 (fill-column . 80))))
4 4  
... ...
src/modbus.c
... ... @@ -16,16 +16,16 @@
16 16 */
17 17  
18 18 /*
19   - The library is designed to send and receive data from a device that
20   - communicate via the Modbus protocol.
  19 + The library is designed to send and receive data from a device that
  20 + communicate via the Modbus protocol.
21 21  
22   - The function names used are inspired by the Modicon Modbus Protocol
23   - Reference Guide which can be obtained from Schneider at
24   - www.schneiderautomation.com.
  22 + The function names used are inspired by the Modicon Modbus Protocol
  23 + Reference Guide which can be obtained from Schneider at
  24 + www.schneiderautomation.com.
25 25  
26   - Documentation:
27   - http://www.easysw.com/~mike/serial/serial.html
28   - http://copyleft.free.fr/wordpress/index.php/libmodbus/
  26 + Documentation:
  27 + http://www.easysw.com/~mike/serial/serial.html
  28 + http://copyleft.free.fr/wordpress/index.php/libmodbus/
29 29 */
30 30  
31 31 #include <stdio.h>
... ... @@ -72,205 +72,205 @@ const unsigned int libmodbus_version_micro = LIBMODBUS_VERSION_MICRO;
72 72 /* This structure reduces the number of params in functions and so
73 73 * optimizes the speed of execution (~ 37%). */
74 74 typedef struct {
75   - int slave;
76   - int function;
77   - int t_id;
  75 + int slave;
  76 + int function;
  77 + int t_id;
78 78 } sft_t;
79 79  
80 80 /* Table of CRC values for high-order byte */
81 81 static uint8_t table_crc_hi[] = {
82   - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
83   - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
84   - 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
85   - 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
86   - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
87   - 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
88   - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
89   - 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
90   - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
91   - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
92   - 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
93   - 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
94   - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
95   - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
96   - 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
97   - 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
98   - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
99   - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
100   - 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
101   - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
102   - 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
103   - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
104   - 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
105   - 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
106   - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
107   - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
  82 + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  83 + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  84 + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
  85 + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  86 + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
  87 + 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  88 + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
  89 + 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  90 + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  91 + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
  92 + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
  93 + 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  94 + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  95 + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
  96 + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
  97 + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  98 + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  99 + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  100 + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
  101 + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  102 + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
  103 + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
  104 + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
  105 + 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  106 + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
  107 + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
108 108 };
109 109  
110 110 /* Table of CRC values for low-order byte */
111 111 static uint8_t table_crc_lo[] = {
112   - 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
113   - 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
114   - 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
115   - 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
116   - 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
117   - 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
118   - 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
119   - 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
120   - 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
121   - 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
122   - 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
123   - 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
124   - 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
125   - 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
126   - 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
127   - 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
128   - 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
129   - 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
130   - 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
131   - 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
132   - 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
133   - 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
134   - 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
135   - 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
136   - 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
137   - 0x43, 0x83, 0x41, 0x81, 0x80, 0x40
  112 + 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
  113 + 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
  114 + 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
  115 + 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
  116 + 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
  117 + 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
  118 + 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
  119 + 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
  120 + 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
  121 + 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
  122 + 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
  123 + 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
  124 + 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
  125 + 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
  126 + 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
  127 + 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
  128 + 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
  129 + 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
  130 + 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
  131 + 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
  132 + 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
  133 + 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
  134 + 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
  135 + 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
  136 + 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
  137 + 0x43, 0x83, 0x41, 0x81, 0x80, 0x40
138 138 };
139 139  
140 140 static const int TAB_HEADER_LENGTH[2] = {
141   - HEADER_LENGTH_RTU,
142   - HEADER_LENGTH_TCP
  141 + HEADER_LENGTH_RTU,
  142 + HEADER_LENGTH_TCP
143 143 };
144 144  
145 145 static const int TAB_CHECKSUM_LENGTH[2] = {
146   - CHECKSUM_LENGTH_RTU,
147   - CHECKSUM_LENGTH_TCP
  146 + CHECKSUM_LENGTH_RTU,
  147 + CHECKSUM_LENGTH_TCP
148 148 };
149 149  
150 150 static const int TAB_MAX_ADU_LENGTH[2] = {
151   - MAX_ADU_LENGTH_RTU,
152   - MAX_ADU_LENGTH_TCP,
  151 + MAX_ADU_LENGTH_RTU,
  152 + MAX_ADU_LENGTH_TCP,
153 153 };
154 154  
155 155 const char *modbus_strerror(int errnum) {
156   - switch (errnum) {
157   - case EMBXILFUN:
158   - return "Illegal function";
159   - case EMBXILADD:
160   - return "Illegal data address";
161   - case EMBXILVAL:
162   - return "Illegal data value";
163   - case EMBXSFAIL:
164   - return "Slave device or server failure";
165   - case EMBXACK:
166   - return "Acknowledge";
167   - case EMBXSBUSY:
168   - return "Slave device or server is busy";
169   - case EMBXNACK:
170   - return "Negative acknowledge";
171   - case EMBXMEMPAR:
172   - return "Memory parity error";
173   - case EMBXGPATH:
174   - return "Gateway path unavailable";
175   - case EMBXGTAR:
176   - return "Target device failed to respond";
177   - case EMBBADCRC:
178   - return "Invalid CRC";
179   - case EMBBADDATA:
180   - return "Invalid data";
181   - case EMBBADEXC:
182   - return "Invalid exception code";
183   - case EMBMDATA:
184   - return "Too many data";
185   - default:
186   - return strerror(errnum);
187   - }
  156 + switch (errnum) {
  157 + case EMBXILFUN:
  158 + return "Illegal function";
  159 + case EMBXILADD:
  160 + return "Illegal data address";
  161 + case EMBXILVAL:
  162 + return "Illegal data value";
  163 + case EMBXSFAIL:
  164 + return "Slave device or server failure";
  165 + case EMBXACK:
  166 + return "Acknowledge";
  167 + case EMBXSBUSY:
  168 + return "Slave device or server is busy";
  169 + case EMBXNACK:
  170 + return "Negative acknowledge";
  171 + case EMBXMEMPAR:
  172 + return "Memory parity error";
  173 + case EMBXGPATH:
  174 + return "Gateway path unavailable";
  175 + case EMBXGTAR:
  176 + return "Target device failed to respond";
  177 + case EMBBADCRC:
  178 + return "Invalid CRC";
  179 + case EMBBADDATA:
  180 + return "Invalid data";
  181 + case EMBBADEXC:
  182 + return "Invalid exception code";
  183 + case EMBMDATA:
  184 + return "Too many data";
  185 + default:
  186 + return strerror(errnum);
  187 + }
188 188 }
189 189  
190 190 static void error_print(modbus_param_t *mb_param, const char *context)
191 191 {
192   - if (mb_param->debug) {
193   - fprintf(stderr, "ERROR %s", modbus_strerror(errno));
194   - if (context != NULL) {
195   - fprintf(stderr, ": %s\n", context);
196   - } else {
197   - fprintf(stderr, "\n");
198   - }
  192 + if (mb_param->debug) {
  193 + fprintf(stderr, "ERROR %s", modbus_strerror(errno));
  194 + if (context != NULL) {
  195 + fprintf(stderr, ": %s\n", context);
  196 + } else {
  197 + fprintf(stderr, "\n");
199 198 }
  199 + }
200 200 }
201 201  
202 202 int modbus_flush(modbus_param_t *mb_param)
203 203 {
204   - int rc;
  204 + int rc;
205 205  
206   - if (mb_param->type_com == RTU) {
207   - rc = tcflush(mb_param->fd, TCIOFLUSH);
208   - } else {
209   - do {
210   - /* Extract the garbage from the socket */
211   - char devnull[MAX_ADU_LENGTH_TCP];
  206 + if (mb_param->type_com == RTU) {
  207 + rc = tcflush(mb_param->fd, TCIOFLUSH);
  208 + } else {
  209 + do {
  210 + /* Extract the garbage from the socket */
  211 + char devnull[MAX_ADU_LENGTH_TCP];
212 212 #if (!HAVE_DECL___CYGWIN__)
213   - rc = recv(mb_param->fd, devnull, MAX_ADU_LENGTH_TCP, MSG_DONTWAIT);
  213 + rc = recv(mb_param->fd, devnull, MAX_ADU_LENGTH_TCP, MSG_DONTWAIT);
214 214 #else
215   - /* On Cygwin, it's a bit more complicated to not wait */
216   - fd_set rfds;
217   - struct timeval tv;
218   -
219   - tv.tv_sec = 0;
220   - tv.tv_usec = 0;
221   - FD_ZERO(&rfds);
222   - FD_SET(mb_param->fd, &rfds);
223   - rc = select(mb_param->fd+1, &rfds, NULL, NULL, &tv);
224   - if (rc == -1) {
225   - return -1;
226   - }
227   -
228   - rc = recv(mb_param->fd, devnull, MAX_ADU_LENGTH_TCP, 0);
  215 + /* On Cygwin, it's a bit more complicated to not wait */
  216 + fd_set rfds;
  217 + struct timeval tv;
  218 +
  219 + tv.tv_sec = 0;
  220 + tv.tv_usec = 0;
  221 + FD_ZERO(&rfds);
  222 + FD_SET(mb_param->fd, &rfds);
  223 + rc = select(mb_param->fd+1, &rfds, NULL, NULL, &tv);
  224 + if (rc == -1) {
  225 + return -1;
  226 + }
  227 +
  228 + rc = recv(mb_param->fd, devnull, MAX_ADU_LENGTH_TCP, 0);
229 229 #endif
230   - if (mb_param->debug && rc != -1) {
231   - printf("\n%d bytes flushed\n", rc);
232   - }
233   - } while (rc > 0);
234   - }
  230 + if (mb_param->debug && rc != -1) {
  231 + printf("\n%d bytes flushed\n", rc);
  232 + }
  233 + } while (rc > 0);
  234 + }
235 235  
236   - return rc;
  236 + return rc;
237 237 }
238 238  
239 239 /* Computes the length of the expected response */
240 240 static unsigned int compute_response_length(modbus_param_t *mb_param,
241 241 uint8_t *query)
242 242 {
243   - int length;
244   - int offset;
245   -
246   - offset = TAB_HEADER_LENGTH[mb_param->type_com];
247   -
248   - switch (query[offset]) {
249   - case FC_READ_COIL_STATUS:
250   - case FC_READ_INPUT_STATUS: {
251   - /* Header + nb values (code from force_multiple_coils) */
252   - int nb = (query[offset + 3] << 8) | query[offset + 4];
253   - length = 2 + (nb / 8) + ((nb % 8) ? 1 : 0);
254   - }
255   - break;
256   - case FC_READ_HOLDING_REGISTERS:
257   - case FC_READ_INPUT_REGISTERS:
258   - /* Header + 2 * nb values */
259   - length = 2 + 2 * (query[offset + 3] << 8 |
260   - query[offset + 4]);
261   - break;
262   - case FC_READ_EXCEPTION_STATUS:
263   - length = 3;
264   - break;
265   - case FC_REPORT_SLAVE_ID:
266   - /* The response is device specific (the header provides the
267   - length) */
268   - return MSG_LENGTH_UNDEFINED;
269   - default:
270   - length = 5;
271   - }
272   -
273   - return length + offset + TAB_CHECKSUM_LENGTH[mb_param->type_com];
  243 + int length;
  244 + int offset;
  245 +
  246 + offset = TAB_HEADER_LENGTH[mb_param->type_com];
  247 +
  248 + switch (query[offset]) {
  249 + case FC_READ_COIL_STATUS:
  250 + case FC_READ_INPUT_STATUS: {
  251 + /* Header + nb values (code from force_multiple_coils) */
  252 + int nb = (query[offset + 3] << 8) | query[offset + 4];
  253 + length = 2 + (nb / 8) + ((nb % 8) ? 1 : 0);
  254 + }
  255 + break;
  256 + case FC_READ_HOLDING_REGISTERS:
  257 + case FC_READ_INPUT_REGISTERS:
  258 + /* Header + 2 * nb values */
  259 + length = 2 + 2 * (query[offset + 3] << 8 |
  260 + query[offset + 4]);
  261 + break;
  262 + case FC_READ_EXCEPTION_STATUS:
  263 + length = 3;
  264 + break;
  265 + case FC_REPORT_SLAVE_ID:
  266 + /* The response is device specific (the header provides the
  267 + length) */
  268 + return MSG_LENGTH_UNDEFINED;
  269 + default:
  270 + length = 5;
  271 + }
  272 +
  273 + return length + offset + TAB_CHECKSUM_LENGTH[mb_param->type_com];
274 274 }
275 275  
276 276 /* Builds a RTU query header */
... ... @@ -278,14 +278,14 @@ static int build_query_basis_rtu(int slave, int function,
278 278 int start_addr, int nb,
279 279 uint8_t *query)
280 280 {
281   - query[0] = slave;
282   - query[1] = function;
283   - query[2] = start_addr >> 8;
284   - query[3] = start_addr & 0x00ff;
285   - query[4] = nb >> 8;
286   - query[5] = nb & 0x00ff;
287   -
288   - return PRESET_QUERY_LENGTH_RTU;
  281 + query[0] = slave;
  282 + query[1] = function;
  283 + query[2] = start_addr >> 8;
  284 + query[3] = start_addr & 0x00ff;
  285 + query[4] = nb >> 8;
  286 + query[5] = nb & 0x00ff;
  287 +
  288 + return PRESET_QUERY_LENGTH_RTU;
289 289 }
290 290  
291 291 /* Builds a TCP query header */
... ... @@ -294,105 +294,105 @@ static int build_query_basis_tcp(int slave, int function,
294 294 uint8_t *query)
295 295 {
296 296  
297   - /* Extract from MODBUS Messaging on TCP/IP Implementation Guide V1.0b
298   - (page 23/46):
299   - The transaction identifier is used to associate the future response
300   - with the request. So, at a time, on a TCP connection, this identifier
301   - must be unique. */
302   - static uint16_t t_id = 0;
303   -
304   - /* Transaction ID */
305   - if (t_id < UINT16_MAX)
306   - t_id++;
307   - else
308   - t_id = 0;
309   - query[0] = t_id >> 8;
310   - query[1] = t_id & 0x00ff;
311   -
312   - /* Protocol Modbus */
313   - query[2] = 0;
314   - query[3] = 0;
315   -
316   - /* Length will be defined later by set_query_length_tcp at offsets 4
317   - and 5 */
318   -
319   - query[6] = slave;
320   - query[7] = function;
321   - query[8] = start_addr >> 8;
322   - query[9] = start_addr & 0x00ff;
323   - query[10] = nb >> 8;
324   - query[11] = nb & 0x00ff;
325   -
326   - return PRESET_QUERY_LENGTH_TCP;
  297 + /* Extract from MODBUS Messaging on TCP/IP Implementation Guide V1.0b
  298 + (page 23/46):
  299 + The transaction identifier is used to associate the future response
  300 + with the request. So, at a time, on a TCP connection, this identifier
  301 + must be unique. */
  302 + static uint16_t t_id = 0;
  303 +
  304 + /* Transaction ID */
  305 + if (t_id < UINT16_MAX)
  306 + t_id++;
  307 + else
  308 + t_id = 0;
  309 + query[0] = t_id >> 8;
  310 + query[1] = t_id & 0x00ff;
  311 +
  312 + /* Protocol Modbus */
  313 + query[2] = 0;
  314 + query[3] = 0;
  315 +
  316 + /* Length will be defined later by set_query_length_tcp at offsets 4
  317 + and 5 */
  318 +
  319 + query[6] = slave;
  320 + query[7] = function;
  321 + query[8] = start_addr >> 8;
  322 + query[9] = start_addr & 0x00ff;
  323 + query[10] = nb >> 8;
  324 + query[11] = nb & 0x00ff;
  325 +
  326 + return PRESET_QUERY_LENGTH_TCP;
327 327 }
328 328  
329 329 static int build_query_basis(modbus_param_t *mb_param, int slave,
330 330 int function, int start_addr,
331 331 int nb, uint8_t *query)
332 332 {
333   - if (mb_param->type_com == RTU)
334   - return build_query_basis_rtu(slave, function,
335   - start_addr, nb, query);
336   - else
337   - return build_query_basis_tcp(slave, function,
338   - start_addr, nb, query);
  333 + if (mb_param->type_com == RTU)
  334 + return build_query_basis_rtu(slave, function,
  335 + start_addr, nb, query);
  336 + else
  337 + return build_query_basis_tcp(slave, function,
  338 + start_addr, nb, query);
339 339 }
340 340  
341 341 /* Builds a RTU response header */
342 342 static int build_response_basis_rtu(sft_t *sft, uint8_t *response)
343 343 {
344   - response[0] = sft->slave;
345   - response[1] = sft->function;
  344 + response[0] = sft->slave;
  345 + response[1] = sft->function;
346 346  
347   - return PRESET_RESPONSE_LENGTH_RTU;
  347 + return PRESET_RESPONSE_LENGTH_RTU;
348 348 }
349 349  
350 350 /* Builds a TCP response header */
351 351 static int build_response_basis_tcp(sft_t *sft, uint8_t *response)
352 352 {
353   - /* Extract from MODBUS Messaging on TCP/IP Implementation
354   - Guide V1.0b (page 23/46):
355   - The transaction identifier is used to associate the future
356   - response with the request. */
357   - response[0] = sft->t_id >> 8;
358   - response[1] = sft->t_id & 0x00ff;
  353 + /* Extract from MODBUS Messaging on TCP/IP Implementation
  354 + Guide V1.0b (page 23/46):
  355 + The transaction identifier is used to associate the future
  356 + response with the request. */
  357 + response[0] = sft->t_id >> 8;
  358 + response[1] = sft->t_id & 0x00ff;
359 359  
360   - /* Protocol Modbus */
361   - response[2] = 0;
362   - response[3] = 0;
  360 + /* Protocol Modbus */
  361 + response[2] = 0;
  362 + response[3] = 0;
363 363  
364   - /* Length will be set later by modbus_send (4 and 5) */
  364 + /* Length will be set later by modbus_send (4 and 5) */
365 365  
366   - response[6] = 0xFF;
367   - response[7] = sft->function;
  366 + response[6] = 0xFF;
  367 + response[7] = sft->function;
368 368  
369   - return PRESET_RESPONSE_LENGTH_TCP;
  369 + return PRESET_RESPONSE_LENGTH_TCP;
370 370 }
371 371  
372 372 static int build_response_basis(modbus_param_t *mb_param, sft_t *sft,
373 373 uint8_t *response)
374 374 {
375   - if (mb_param->type_com == RTU)
376   - return build_response_basis_rtu(sft, response);
377   - else
378   - return build_response_basis_tcp(sft, response);
  375 + if (mb_param->type_com == RTU)
  376 + return build_response_basis_rtu(sft, response);
  377 + else
  378 + return build_response_basis_tcp(sft, response);
379 379 }
380 380  
381 381 /* Fast CRC */
382 382 static uint16_t crc16(uint8_t *buffer, uint16_t buffer_length)
383 383 {
384   - uint8_t crc_hi = 0xFF; /* high CRC byte initialized */
385   - uint8_t crc_lo = 0xFF; /* low CRC byte initialized */
386   - unsigned int i; /* will index into CRC lookup */
387   -
388   - /* pass through message buffer */
389   - while (buffer_length--) {
390   - i = crc_hi ^ *buffer++; /* calculate the CRC */
391   - crc_hi = crc_lo ^ table_crc_hi[i];
392   - crc_lo = table_crc_lo[i];
393   - }
394   -
395   - return (crc_hi << 8 | crc_lo);
  384 + uint8_t crc_hi = 0xFF; /* high CRC byte initialized */
  385 + uint8_t crc_lo = 0xFF; /* low CRC byte initialized */
  386 + unsigned int i; /* will index into CRC lookup */
  387 +
  388 + /* pass through message buffer */
  389 + while (buffer_length--) {
  390 + i = crc_hi ^ *buffer++; /* calculate the CRC */
  391 + crc_hi = crc_lo ^ table_crc_hi[i];
  392 + crc_lo = table_crc_lo[i];
  393 + }
  394 +
  395 + return (crc_hi << 8 | crc_lo);
396 396 }
397 397  
398 398 /* The check_crc16 function shall return the message length if the CRC is
... ... @@ -401,164 +401,163 @@ static int check_crc16(modbus_param_t *mb_param,
401 401 uint8_t *msg,
402 402 const int msg_length)
403 403 {
404   - uint16_t crc_calculated;
405   - uint16_t crc_received;
  404 + uint16_t crc_calculated;
  405 + uint16_t crc_received;
406 406  
407   - crc_calculated = crc16(msg, msg_length - 2);
408   - crc_received = (msg[msg_length - 2] << 8) | msg[msg_length - 1];
  407 + crc_calculated = crc16(msg, msg_length - 2);
  408 + crc_received = (msg[msg_length - 2] << 8) | msg[msg_length - 1];
409 409  
410   - /* Check CRC of msg */
411   - if (crc_calculated == crc_received) {
412   - return msg_length;
413   - } else {
414   - if (mb_param->debug) {
415   - fprintf(stderr, "ERROR CRC received %0X != CRC calculated %0X\n",
416   - crc_received, crc_calculated);
417   - }
418   - if (mb_param->error_recovery) {
419   - modbus_flush(mb_param);
420   - }
421   - errno = EMBBADCRC;
422   - return -1;
  410 + /* Check CRC of msg */
  411 + if (crc_calculated == crc_received) {
  412 + return msg_length;
  413 + } else {
  414 + if (mb_param->debug) {
  415 + fprintf(stderr, "ERROR CRC received %0X != CRC calculated %0X\n",
  416 + crc_received, crc_calculated);
  417 + }
  418 + if (mb_param->error_recovery) {
  419 + modbus_flush(mb_param);
423 420 }
  421 + errno = EMBBADCRC;
  422 + return -1;
  423 + }
424 424 }
425 425  
426 426 /* Sends a query/response over a serial or a TCP communication */
427 427 static int modbus_send(modbus_param_t *mb_param, uint8_t *query,
428 428 int query_length)
429 429 {
430   - int rc;
431   - uint16_t s_crc;
432   - int i;
433   -
434   - if (mb_param->type_com == RTU) {
435   - s_crc = crc16(query, query_length);
436   - query[query_length++] = s_crc >> 8;
437   - query[query_length++] = s_crc & 0x00FF;
438   - } else {
439   - /* Substract the header length to the message length */
440   - int mbap_length = query_length - 6;
441   -
442   - query[4] = mbap_length >> 8;
443   - query[5] = mbap_length & 0x00FF;
444   - }
  430 + int rc;
  431 + uint16_t s_crc;
  432 + int i;
  433 +
  434 + if (mb_param->type_com == RTU) {
  435 + s_crc = crc16(query, query_length);
  436 + query[query_length++] = s_crc >> 8;
  437 + query[query_length++] = s_crc & 0x00FF;
  438 + } else {
  439 + /* Substract the header length to the message length */
  440 + int mbap_length = query_length - 6;
  441 +
  442 + query[4] = mbap_length >> 8;
  443 + query[5] = mbap_length & 0x00FF;
  444 + }
  445 +
  446 + if (mb_param->debug) {
  447 + for (i = 0; i < query_length; i++)
  448 + printf("[%.2X]", query[i]);
  449 + printf("\n");
  450 + }
  451 +
  452 + /* In recovery mode, the write command will be issued until to be
  453 + successful! Disabled by default.
  454 + */
  455 + do {
  456 + if (mb_param->type_com == RTU)
  457 + rc = write(mb_param->fd, query, query_length);
  458 + else
  459 + /* MSG_NOSIGNAL
  460 + Requests not to send SIGPIPE on errors on stream oriented
  461 + sockets when the other end breaks the connection. The EPIPE
  462 + error is still returned. */
  463 + rc = send(mb_param->fd, query, query_length, MSG_NOSIGNAL);
445 464  
446   - if (mb_param->debug) {
447   - for (i = 0; i < query_length; i++)
448   - printf("[%.2X]", query[i]);
449   - printf("\n");
  465 + if (rc == -1) {
  466 + error_print(mb_param, NULL);
  467 + if (mb_param->error_recovery &&
  468 + (errno == EBADF || errno == ECONNRESET || errno == EPIPE)) {
  469 + modbus_close(mb_param);
  470 + modbus_connect(mb_param);
  471 + }
450 472 }
  473 + } while (mb_param->error_recovery && rc == -1);
451 474  
452   - /* In recovery mode, the write command will be issued until to be
453   - successful! Disabled by default.
454   - */
455   - do {
456   - if (mb_param->type_com == RTU)
457   - rc = write(mb_param->fd, query, query_length);
458   - else
459   - /* MSG_NOSIGNAL
460   - Requests not to send SIGPIPE on errors on stream oriented
461   - sockets when the other end breaks the connection. The EPIPE
462   - error is still returned. */
463   - rc = send(mb_param->fd, query, query_length, MSG_NOSIGNAL);
464   -
465   - if (rc == -1) {
466   - error_print(mb_param, NULL);
467   - if (mb_param->error_recovery && (errno == EBADF ||
468   - errno == ECONNRESET || errno == EPIPE)) {
469   - modbus_close(mb_param);
470   - modbus_connect(mb_param);
471   - }
472   - }
473   - } while (mb_param->error_recovery && rc == -1);
  475 + if (rc > 0 && rc != query_length) {
  476 + errno = EMBBADDATA;
  477 + return -1;
  478 + }
474 479  
475   - if (rc > 0 && rc != query_length) {
476   - errno = EMBBADDATA;
477   - return -1;
478   - }
479   -
480   - return rc;
  480 + return rc;
481 481 }
482 482  
483 483 /* Computes the length of the header following the function code */
484 484 static uint8_t compute_query_length_header(int function)
485 485 {
486   - int length;
487   -
488   - if (function <= FC_FORCE_SINGLE_COIL ||
489   - function == FC_PRESET_SINGLE_REGISTER)
490   - /* Read and single write */
491   - length = 4;
492   - else if (function == FC_FORCE_MULTIPLE_COILS ||
493   - function == FC_PRESET_MULTIPLE_REGISTERS)
494   - /* Multiple write */
495   - length = 5;
496   - else if (function == FC_REPORT_SLAVE_ID)
497   - length = 1;
498   - else
499   - length = 0;
500   -
501   - return length;
  486 + int length;
  487 +
  488 + if (function <= FC_FORCE_SINGLE_COIL ||
  489 + function == FC_PRESET_SINGLE_REGISTER)
  490 + /* Read and single write */
  491 + length = 4;
  492 + else if (function == FC_FORCE_MULTIPLE_COILS ||
  493 + function == FC_PRESET_MULTIPLE_REGISTERS)
  494 + /* Multiple write */
  495 + length = 5;
  496 + else if (function == FC_REPORT_SLAVE_ID)
  497 + length = 1;
  498 + else
  499 + length = 0;
  500 +
  501 + return length;
502 502 }
503 503  
504 504 /* Computes the length of the data to write in the query */
505 505 static int compute_query_length_data(modbus_param_t *mb_param, uint8_t *msg)
506 506 {
507   - int function = msg[TAB_HEADER_LENGTH[mb_param->type_com]];
508   - int length;
509   -
510   - if (function == FC_FORCE_MULTIPLE_COILS ||
511   - function == FC_PRESET_MULTIPLE_REGISTERS)
512   - length = msg[TAB_HEADER_LENGTH[mb_param->type_com] + 5];
513   - else if (function == FC_REPORT_SLAVE_ID)
514   - length = msg[TAB_HEADER_LENGTH[mb_param->type_com] + 1];
515   - else
516   - length = 0;
  507 + int function = msg[TAB_HEADER_LENGTH[mb_param->type_com]];
  508 + int length;
517 509  
518   - length += TAB_CHECKSUM_LENGTH[mb_param->type_com];
  510 + if (function == FC_FORCE_MULTIPLE_COILS ||
  511 + function == FC_PRESET_MULTIPLE_REGISTERS)
  512 + length = msg[TAB_HEADER_LENGTH[mb_param->type_com] + 5];
  513 + else if (function == FC_REPORT_SLAVE_ID)
  514 + length = msg[TAB_HEADER_LENGTH[mb_param->type_com] + 1];
  515 + else
  516 + length = 0;
519 517  
520   - return length;
  518 + length += TAB_CHECKSUM_LENGTH[mb_param->type_com];
  519 +
  520 + return length;
521 521 }
522 522  
523   -#define WAIT_DATA() \
524   -{ \
525   - while ((s_rc = select(mb_param->fd+1, &rfds, NULL, NULL, &tv)) == -1) { \
526   - if (errno == EINTR) { \
527   - if (mb_param->debug) { \
528   - fprintf(stderr, \
529   - "A non blocked signal was caught\n"); \
530   - } \
531   - /* Necessary after an error */ \
532   - FD_ZERO(&rfds); \
533   - FD_SET(mb_param->fd, &rfds); \
534   - } else { \
535   - error_print(mb_param, "select"); \
536   - if (mb_param->error_recovery && (errno == EBADF)) { \
537   - modbus_close(mb_param); \
538   - modbus_connect(mb_param); \
539   - errno = EBADF; \
540   - return -1; \
541   - } else { \
542   - return -1; \
543   - } \
544   - } \
545   - } \
546   - \
547   - if (s_rc == 0) { \
548   - /* Timeout */ \
549   - if (msg_length == (TAB_HEADER_LENGTH[mb_param->type_com] + 2 + \
550   - TAB_CHECKSUM_LENGTH[mb_param->type_com])) { \
551   - /* Optimization allowed because exception response is \
552   - the smallest trame in modbus protocol (3) so always \
553   - raise a timeout error. \
554   - Temporary error before exception analyze. */ \
555   - errno = EMBUNKEXC; \
556   - } else { \
557   - errno = ETIMEDOUT; \
558   - error_print(mb_param, "select"); \
559   - } \
560   - return -1; \
561   - } \
  523 +#define WAIT_DATA() { \
  524 + while ((s_rc = select(mb_param->fd+1, &rfds, NULL, NULL, &tv)) == -1) { \
  525 + if (errno == EINTR) { \
  526 + if (mb_param->debug) { \
  527 + fprintf(stderr, \
  528 + "A non blocked signal was caught\n"); \
  529 + } \
  530 + /* Necessary after an error */ \
  531 + FD_ZERO(&rfds); \
  532 + FD_SET(mb_param->fd, &rfds); \
  533 + } else { \
  534 + error_print(mb_param, "select"); \
  535 + if (mb_param->error_recovery && (errno == EBADF)) { \
  536 + modbus_close(mb_param); \
  537 + modbus_connect(mb_param); \
  538 + errno = EBADF; \
  539 + return -1; \
  540 + } else { \
  541 + return -1; \
  542 + } \
  543 + } \
  544 + } \
  545 + \
  546 + if (s_rc == 0) { \
  547 + /* Timeout */ \
  548 + if (msg_length == (TAB_HEADER_LENGTH[mb_param->type_com] + 2 + \
  549 + TAB_CHECKSUM_LENGTH[mb_param->type_com])) { \
  550 + /* Optimization allowed because exception response is \
  551 + the smallest trame in modbus protocol (3) so always \
  552 + raise a timeout error. \
  553 + Temporary error before exception analyze. */ \
  554 + errno = EMBUNKEXC; \
  555 + } else { \
  556 + errno = ETIMEDOUT; \
  557 + error_print(mb_param, "select"); \
  558 + } \
  559 + return -1; \
  560 + } \
562 561 }
563 562  
564 563 /* Waits a reply from a modbus slave or a query from a modbus master.
... ... @@ -580,144 +579,144 @@ static int receive_msg(modbus_param_t *mb_param,
580 579 int msg_length_computed,
581 580 uint8_t *msg)
582 581 {
583   - int s_rc;
584   - int read_rc;
585   - fd_set rfds;
586   - struct timeval tv;
587   - int length_to_read;
588   - uint8_t *p_msg;
589   - enum { FUNCTION, BYTE, COMPLETE };
590   - int state;
591   -
592   - int msg_length = 0;
  582 + int s_rc;
  583 + int read_rc;
  584 + fd_set rfds;
  585 + struct timeval tv;
  586 + int length_to_read;
  587 + uint8_t *p_msg;
  588 + enum { FUNCTION, BYTE, COMPLETE };
  589 + int state;
  590 +
  591 + int msg_length = 0;
  592 +
  593 + if (mb_param->debug) {
  594 + if (msg_length_computed == MSG_LENGTH_UNDEFINED)
  595 + printf("Waiting for a message...\n");
  596 + else
  597 + printf("Waiting for a message (%d bytes)...\n",
  598 + msg_length_computed);
  599 + }
  600 +
  601 + /* Add a file descriptor to the set */
  602 + FD_ZERO(&rfds);
  603 + FD_SET(mb_param->fd, &rfds);
  604 +
  605 + if (msg_length_computed == MSG_LENGTH_UNDEFINED) {
  606 + /* Wait for a message */
  607 + tv.tv_sec = 60;
  608 + tv.tv_usec = 0;
  609 +
  610 + /* The message length is undefined (query receiving) so
  611 + * we need to analyse the message step by step.
  612 + * At the first step, we want to reach the function
  613 + * code because all packets have that information. */
  614 + state = FUNCTION;
  615 + msg_length_computed = TAB_HEADER_LENGTH[mb_param->type_com] + 1;
  616 + } else {
  617 + tv.tv_sec = mb_param->timeout_begin.tv_sec;
  618 + tv.tv_usec = mb_param->timeout_begin.tv_usec;
  619 + state = COMPLETE;
  620 + }
  621 +
  622 + length_to_read = msg_length_computed;
  623 +
  624 + s_rc = 0;
  625 + WAIT_DATA();
  626 +
  627 + p_msg = msg;
  628 + while (s_rc) {
  629 + if (mb_param->type_com == RTU)
  630 + read_rc = read(mb_param->fd, p_msg, length_to_read);
  631 + else
  632 + read_rc = recv(mb_param->fd, p_msg, length_to_read, 0);
593 633  
594   - if (mb_param->debug) {
595   - if (msg_length_computed == MSG_LENGTH_UNDEFINED)
596   - printf("Waiting for a message...\n");
597   - else
598   - printf("Waiting for a message (%d bytes)...\n",
599   - msg_length_computed);
  634 + if (read_rc == 0) {
  635 + errno = ECONNRESET;
  636 + read_rc = -1;
600 637 }
601 638  
602   - /* Add a file descriptor to the set */
603   - FD_ZERO(&rfds);
604   - FD_SET(mb_param->fd, &rfds);
605   -
606   - if (msg_length_computed == MSG_LENGTH_UNDEFINED) {
607   - /* Wait for a message */
608   - tv.tv_sec = 60;
609   - tv.tv_usec = 0;
610   -
611   - /* The message length is undefined (query receiving) so
612   - * we need to analyse the message step by step.
613   - * At the first step, we want to reach the function
614   - * code because all packets have that information. */
615   - state = FUNCTION;
616   - msg_length_computed = TAB_HEADER_LENGTH[mb_param->type_com] + 1;
617   - } else {
618   - tv.tv_sec = mb_param->timeout_begin.tv_sec;
619   - tv.tv_usec = mb_param->timeout_begin.tv_usec;
620   - state = COMPLETE;
  639 + if (read_rc == -1) {
  640 + error_print(mb_param, "read");
  641 + if (mb_param->error_recovery && (errno == ECONNRESET ||
  642 + errno == ECONNREFUSED)) {
  643 + modbus_close(mb_param);
  644 + modbus_connect(mb_param);
  645 + /* Could be removed by previous calls */
  646 + errno = ECONNRESET;
  647 + return -1;
  648 + }
  649 + return -1;
621 650 }
622 651  
623   - length_to_read = msg_length_computed;
624   -
625   - s_rc = 0;
626   - WAIT_DATA();
627   -
628   - p_msg = msg;
629   - while (s_rc) {
630   - if (mb_param->type_com == RTU)
631   - read_rc = read(mb_param->fd, p_msg, length_to_read);
632   - else
633   - read_rc = recv(mb_param->fd, p_msg, length_to_read, 0);
634   -
635   - if (read_rc == 0) {
636   - errno = ECONNRESET;
637   - read_rc = -1;
638   - }
639   -
640   - if (read_rc == -1) {
641   - error_print(mb_param, "read");
642   - if (mb_param->error_recovery && (errno == ECONNRESET ||
643   - errno == ECONNREFUSED)) {
644   - modbus_close(mb_param);
645   - modbus_connect(mb_param);
646   - /* Could be removed by previous calls */
647   - errno = ECONNRESET;
648   - return -1;
649   - }
650   - return -1;
651   - }
652   -
653   - /* Sums bytes received */
654   - msg_length += read_rc;
  652 + /* Sums bytes received */
  653 + msg_length += read_rc;
655 654  
656   - /* Display the hex code of each character received */
657   - if (mb_param->debug) {
658   - int i;
659   - for (i=0; i < read_rc; i++)
660   - printf("<%.2X>", p_msg[i]);
661   - }
662   -
663   - if (msg_length < msg_length_computed) {
664   - /* Message incomplete */
665   - length_to_read = msg_length_computed - msg_length;
666   - } else {
667   - switch (state) {
668   - case FUNCTION:
669   - /* Function code position */
670   - length_to_read = compute_query_length_header(
671   - msg[TAB_HEADER_LENGTH[mb_param->type_com]]);
672   - msg_length_computed += length_to_read;
673   - /* It's useless to check the value of
674   - msg_length_computed in this case (only
675   - defined values are used). */
676   - state = BYTE;
677   - break;
678   - case BYTE:
679   - length_to_read = compute_query_length_data(mb_param, msg);
680   - msg_length_computed += length_to_read;
681   - if (msg_length_computed > TAB_MAX_ADU_LENGTH[mb_param->type_com]) {
682   - errno = EMBBADDATA;
683   - error_print(mb_param, "too many data");
684   - return -1;
685   - }
686   - state = COMPLETE;
687   - break;
688   - case COMPLETE:
689   - length_to_read = 0;
690   - break;
691   - }
692   - }
693   -
694   - /* Moves the pointer to receive other data */
695   - p_msg = &(p_msg[read_rc]);
696   -
697   - if (length_to_read > 0) {
698   - /* If no character at the buffer wait
699   - TIME_OUT_END_OF_TRAME before to generate an error. */
700   - tv.tv_sec = mb_param->timeout_end.tv_sec;
701   - tv.tv_usec = mb_param->timeout_end.tv_usec;
  655 + /* Display the hex code of each character received */
  656 + if (mb_param->debug) {
  657 + int i;
  658 + for (i=0; i < read_rc; i++)
  659 + printf("<%.2X>", p_msg[i]);
  660 + }
702 661  
703   - WAIT_DATA();
704   - } else {
705   - /* All chars are received */
706   - s_rc = FALSE;
  662 + if (msg_length < msg_length_computed) {
  663 + /* Message incomplete */
  664 + length_to_read = msg_length_computed - msg_length;
  665 + } else {
  666 + switch (state) {
  667 + case FUNCTION:
  668 + /* Function code position */
  669 + length_to_read = compute_query_length_header(
  670 + msg[TAB_HEADER_LENGTH[mb_param->type_com]]);
  671 + msg_length_computed += length_to_read;
  672 + /* It's useless to check the value of
  673 + msg_length_computed in this case (only
  674 + defined values are used). */
  675 + state = BYTE;
  676 + break;
  677 + case BYTE:
  678 + length_to_read = compute_query_length_data(mb_param, msg);
  679 + msg_length_computed += length_to_read;
  680 + if (msg_length_computed > TAB_MAX_ADU_LENGTH[mb_param->type_com]) {
  681 + errno = EMBBADDATA;
  682 + error_print(mb_param, "too many data");
  683 + return -1;
707 684 }
  685 + state = COMPLETE;
  686 + break;
  687 + case COMPLETE:
  688 + length_to_read = 0;
  689 + break;
  690 + }
708 691 }
709 692  
710   - if (mb_param->debug)
711   - printf("\n");
  693 + /* Moves the pointer to receive other data */
  694 + p_msg = &(p_msg[read_rc]);
712 695  
713   - if (mb_param->type_com == RTU) {
714   - /* Returns msg_length on success and a negative value on
715   - failure */
716   - return check_crc16(mb_param, msg, msg_length);
  696 + if (length_to_read > 0) {
  697 + /* If no character at the buffer wait
  698 + TIME_OUT_END_OF_TRAME before to generate an error. */
  699 + tv.tv_sec = mb_param->timeout_end.tv_sec;
  700 + tv.tv_usec = mb_param->timeout_end.tv_usec;
  701 +
  702 + WAIT_DATA();
717 703 } else {
718   - /* OK */
719   - return msg_length;
720   - }
  704 + /* All chars are received */
  705 + s_rc = FALSE;
  706 + }
  707 + }
  708 +
  709 + if (mb_param->debug)
  710 + printf("\n");
  711 +
  712 + if (mb_param->type_com == RTU) {
  713 + /* Returns msg_length on success and a negative value on
  714 + failure */
  715 + return check_crc16(mb_param, msg, msg_length);
  716 + } else {
  717 + /* OK */
  718 + return msg_length;
  719 + }
721 720 }
722 721  
723 722 /* Listens for any query from a modbus master in TCP, requires the socket file
... ... @@ -728,12 +727,12 @@ static int receive_msg(modbus_param_t *mb_param,
728 727 byte length if successul. Otherwise, it shall return -1 and errno is set. */
729 728 int modbus_slave_receive(modbus_param_t *mb_param, int sockfd, uint8_t *query)
730 729 {
731   - if (sockfd != -1) {
732   - mb_param->fd = sockfd;
733   - }
  730 + if (sockfd != -1) {
  731 + mb_param->fd = sockfd;
  732 + }
734 733  
735   - /* The length of the query to receive isn't known. */
736   - return receive_msg(mb_param, MSG_LENGTH_UNDEFINED, query);
  734 + /* The length of the query to receive isn't known. */
  735 + return receive_msg(mb_param, MSG_LENGTH_UNDEFINED, query);
737 736 }
738 737  
739 738 /* Receives the response and checks values (and checksum in RTU).
... ... @@ -747,127 +746,127 @@ static int modbus_receive(modbus_param_t *mb_param,
747 746 uint8_t *query,
748 747 uint8_t *response)
749 748 {
750   - int rc;
751   - int response_length_computed;
752   - int offset = TAB_HEADER_LENGTH[mb_param->type_com];
753   -
754   - response_length_computed = compute_response_length(mb_param, query);
755   - rc = receive_msg(mb_param, response_length_computed, response);
756   - if (rc != -1) {
757   - /* GOOD RESPONSE */
758   - int query_nb_value;
759   - int response_nb_value;
760   -
761   - /* The number of values is returned if it's corresponding
762   - * to the query */
763   - switch (response[offset]) {
764   - case FC_READ_COIL_STATUS:
765   - case FC_READ_INPUT_STATUS:
766   - /* Read functions, 8 values in a byte (nb
767   - * of values in the query and byte count in
768   - * the response. */
769   - query_nb_value = (query[offset + 3] << 8) + query[offset + 4];
770   - query_nb_value = (query_nb_value / 8) + ((query_nb_value % 8) ? 1 : 0);
771   - response_nb_value = response[offset + 1];
772   - break;
773   - case FC_READ_HOLDING_REGISTERS:
774   - case FC_READ_INPUT_REGISTERS:
775   - /* Read functions 1 value = 2 bytes */
776   - query_nb_value = (query[offset + 3] << 8) + query[offset + 4];
777   - response_nb_value = (response[offset + 1] / 2);
778   - break;
779   - case FC_FORCE_MULTIPLE_COILS:
780   - case FC_PRESET_MULTIPLE_REGISTERS:
781   - /* N Write functions */
782   - query_nb_value = (query[offset + 3] << 8) + query[offset + 4];
783   - response_nb_value = (response[offset + 3] << 8) | response[offset + 4];
784   - break;
785   - case FC_REPORT_SLAVE_ID:
786   - /* Report slave ID (bytes received) */
787   - query_nb_value = response_nb_value = rc;
788   - break;
789   - default:
790   - /* 1 Write functions & others */
791   - query_nb_value = response_nb_value = 1;
792   - }
  749 + int rc;
  750 + int response_length_computed;
  751 + int offset = TAB_HEADER_LENGTH[mb_param->type_com];
  752 +
  753 + response_length_computed = compute_response_length(mb_param, query);
  754 + rc = receive_msg(mb_param, response_length_computed, response);
  755 + if (rc != -1) {
  756 + /* GOOD RESPONSE */
  757 + int query_nb_value;
  758 + int response_nb_value;
  759 +
  760 + /* The number of values is returned if it's corresponding
  761 + * to the query */
  762 + switch (response[offset]) {
  763 + case FC_READ_COIL_STATUS:
  764 + case FC_READ_INPUT_STATUS:
  765 + /* Read functions, 8 values in a byte (nb
  766 + * of values in the query and byte count in
  767 + * the response. */
  768 + query_nb_value = (query[offset + 3] << 8) + query[offset + 4];
  769 + query_nb_value = (query_nb_value / 8) + ((query_nb_value % 8) ? 1 : 0);
  770 + response_nb_value = response[offset + 1];
  771 + break;
  772 + case FC_READ_HOLDING_REGISTERS:
  773 + case FC_READ_INPUT_REGISTERS:
  774 + /* Read functions 1 value = 2 bytes */
  775 + query_nb_value = (query[offset + 3] << 8) + query[offset + 4];
  776 + response_nb_value = (response[offset + 1] / 2);
  777 + break;
  778 + case FC_FORCE_MULTIPLE_COILS:
  779 + case FC_PRESET_MULTIPLE_REGISTERS:
  780 + /* N Write functions */
  781 + query_nb_value = (query[offset + 3] << 8) + query[offset + 4];
  782 + response_nb_value = (response[offset + 3] << 8) | response[offset + 4];
  783 + break;
  784 + case FC_REPORT_SLAVE_ID:
  785 + /* Report slave ID (bytes received) */
  786 + query_nb_value = response_nb_value = rc;
  787 + break;
  788 + default:
  789 + /* 1 Write functions & others */
  790 + query_nb_value = response_nb_value = 1;
  791 + }
793 792  
794   - if (query_nb_value == response_nb_value) {
795   - rc = response_nb_value;
796   - } else {
797   - if (mb_param->debug) {
798   - fprintf(stderr,
799   - "Quantity not corresponding to the query (%d != %d)\n",
800   - response_nb_value, query_nb_value);
801   - }
802   - errno = EMBBADDATA;
803   - rc = -1;
804   - }
805   - } else if (errno == EMBUNKEXC) {
806   - /* EXCEPTION CODE RECEIVED */
807   -
808   - /* CRC must be checked here (not done in receive_msg) */
809   - if (mb_param->type_com == RTU) {
810   - rc = check_crc16(mb_param, response, EXCEPTION_RESPONSE_LENGTH_RTU);
811   - if (rc == -1)
812   - return -1;
813   - }
  793 + if (query_nb_value == response_nb_value) {
  794 + rc = response_nb_value;
  795 + } else {
  796 + if (mb_param->debug) {
  797 + fprintf(stderr,
  798 + "Quantity not corresponding to the query (%d != %d)\n",
  799 + response_nb_value, query_nb_value);
  800 + }
  801 + errno = EMBBADDATA;
  802 + rc = -1;
  803 + }
  804 + } else if (errno == EMBUNKEXC) {
  805 + /* EXCEPTION CODE RECEIVED */
814 806  
815   - /* Check for exception response.
816   - 0x80 + function is stored in the exception
817   - response. */
818   - if (0x80 + query[offset] == response[offset]) {
819   - int exception_code = response[offset + 1];
820   - if (exception_code < MODBUS_EXCEPTION_MAX) {
821   - errno = MODBUS_ENOBASE + exception_code;
822   - } else {
823   - errno = EMBBADEXC;
824   - }
825   - error_print(mb_param, NULL);
826   - return -1;
827   - }
  807 + /* CRC must be checked here (not done in receive_msg) */
  808 + if (mb_param->type_com == RTU) {
  809 + rc = check_crc16(mb_param, response, EXCEPTION_RESPONSE_LENGTH_RTU);
  810 + if (rc == -1)
  811 + return -1;
  812 + }
  813 +
  814 + /* Check for exception response.
  815 + 0x80 + function is stored in the exception
  816 + response. */
  817 + if (0x80 + query[offset] == response[offset]) {
  818 + int exception_code = response[offset + 1];
  819 + if (exception_code < MODBUS_EXCEPTION_MAX) {
  820 + errno = MODBUS_ENOBASE + exception_code;
  821 + } else {
  822 + errno = EMBBADEXC;
  823 + }
  824 + error_print(mb_param, NULL);
  825 + return -1;
828 826 }
  827 + }
829 828  
830   - return rc;
  829 + return rc;
831 830 }
832 831  
833 832 static int response_io_status(int address, int nb,
834 833 uint8_t *tab_io_status,
835 834 uint8_t *response, int offset)
836 835 {
837   - int shift = 0;
838   - int byte = 0;
839   - int i;
840   -
841   - for (i = address; i < address+nb; i++) {
842   - byte |= tab_io_status[i] << shift;
843   - if (shift == 7) {
844   - /* Byte is full */
845   - response[offset++] = byte;
846   - byte = shift = 0;
847   - } else {
848   - shift++;
849   - }
  836 + int shift = 0;
  837 + int byte = 0;
  838 + int i;
  839 +
  840 + for (i = address; i < address+nb; i++) {
  841 + byte |= tab_io_status[i] << shift;
  842 + if (shift == 7) {
  843 + /* Byte is full */
  844 + response[offset++] = byte;
  845 + byte = shift = 0;
  846 + } else {
  847 + shift++;
850 848 }
  849 + }
851 850  
852   - if (shift != 0)
853   - response[offset++] = byte;
  851 + if (shift != 0)
  852 + response[offset++] = byte;
854 853  
855   - return offset;
  854 + return offset;
856 855 }
857 856  
858 857 /* Build the exception response */
859 858 static int response_exception(modbus_param_t *mb_param, sft_t *sft,
860 859 int exception_code, uint8_t *response)
861 860 {
862   - int response_length;
  861 + int response_length;
863 862  
864   - sft->function = sft->function + 0x80;
865   - response_length = build_response_basis(mb_param, sft, response);
  863 + sft->function = sft->function + 0x80;
  864 + response_length = build_response_basis(mb_param, sft, response);
866 865  
867   - /* Positive exception code */
868   - response[response_length++] = exception_code;
  866 + /* Positive exception code */
  867 + response[response_length++] = exception_code;
869 868  
870   - return response_length;
  869 + return response_length;
871 870 }
872 871  
873 872 /* Manages the received query.
... ... @@ -879,277 +878,277 @@ static int response_exception(modbus_param_t *mb_param, sft_t *sft,
879 878 int modbus_slave_manage(modbus_param_t *mb_param, const uint8_t *query,
880 879 int query_length, modbus_mapping_t *mb_mapping)
881 880 {
882   - int offset = TAB_HEADER_LENGTH[mb_param->type_com];
883   - int slave = query[offset - 1];
884   - int function = query[offset];
885   - uint16_t address = (query[offset + 1] << 8) + query[offset + 2];
886   - uint8_t response[MAX_MESSAGE_LENGTH];
887   - int resp_length = 0;
888   - sft_t sft;
889   -
890   - /* Filter on the Modbus unit identifier (slave) in RTU mode */
891   - if (mb_param->type_com == RTU &&
892   - slave != mb_param->slave && slave != MODBUS_BROADCAST_ADDRESS) {
893   - /* Ignores the query (not for me) */
894   - if (mb_param->debug) {
895   - printf("Request for slave %d ignored (not %d)\n",
896   - slave, mb_param->slave);
897   - }
898   - return 0;
  881 + int offset = TAB_HEADER_LENGTH[mb_param->type_com];
  882 + int slave = query[offset - 1];
  883 + int function = query[offset];
  884 + uint16_t address = (query[offset + 1] << 8) + query[offset + 2];
  885 + uint8_t response[MAX_MESSAGE_LENGTH];
  886 + int resp_length = 0;
  887 + sft_t sft;
  888 +
  889 + /* Filter on the Modbus unit identifier (slave) in RTU mode */
  890 + if (mb_param->type_com == RTU &&
  891 + slave != mb_param->slave && slave != MODBUS_BROADCAST_ADDRESS) {
  892 + /* Ignores the query (not for me) */
  893 + if (mb_param->debug) {
  894 + printf("Request for slave %d ignored (not %d)\n",
  895 + slave, mb_param->slave);
899 896 }
900   -
901   - sft.slave = slave;
902   - sft.function = function;
903   - if (mb_param->type_com == TCP) {
904   - sft.t_id = (query[0] << 8) + query[1];
  897 + return 0;
  898 + }
  899 +
  900 + sft.slave = slave;
  901 + sft.function = function;
  902 + if (mb_param->type_com == TCP) {
  903 + sft.t_id = (query[0] << 8) + query[1];
  904 + } else {
  905 + sft.t_id = 0;
  906 + query_length -= CHECKSUM_LENGTH_RTU;
  907 + }
  908 +
  909 + switch (function) {
  910 + case FC_READ_COIL_STATUS: {
  911 + int nb = (query[offset + 3] << 8) + query[offset + 4];
  912 +
  913 + if ((address + nb) > mb_mapping->nb_coil_status) {
  914 + if (mb_param->debug) {
  915 + fprintf(stderr, "Illegal data address %0X in read_coil_status\n",
  916 + address + nb);
  917 + }
  918 + resp_length = response_exception(
  919 + mb_param, &sft,
  920 + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
905 921 } else {
906   - sft.t_id = 0;
907   - query_length -= CHECKSUM_LENGTH_RTU;
908   - }
909   -
910   - switch (function) {
911   - case FC_READ_COIL_STATUS: {
912   - int nb = (query[offset + 3] << 8) + query[offset + 4];
913   -
914   - if ((address + nb) > mb_mapping->nb_coil_status) {
915   - if (mb_param->debug) {
916   - fprintf(stderr, "Illegal data address %0X in read_coil_status\n",
917   - address + nb);
918   - }
919   - resp_length = response_exception(
920   - mb_param, &sft,
921   - MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
922   - } else {
923   - resp_length = build_response_basis(mb_param, &sft, response);
924   - response[resp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
925   - resp_length = response_io_status(address, nb,
926   - mb_mapping->tab_coil_status,
927   - response, resp_length);
928   - }
929   - }
930   - break;
931   - case FC_READ_INPUT_STATUS: {
932   - /* Similar to coil status (but too much arguments to use a
933   - * function) */
934   - int nb = (query[offset + 3] << 8) + query[offset + 4];
935   -
936   - if ((address + nb) > mb_mapping->nb_input_status) {
937   - if (mb_param->debug) {
938   - fprintf(stderr, "Illegal data address %0X in read_input_status\n",
939   - address + nb);
940   - }
941   - resp_length = response_exception(
942   - mb_param, &sft,
943   - MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
944   - } else {
945   - resp_length = build_response_basis(mb_param, &sft, response);
946   - response[resp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
947   - resp_length = response_io_status(address, nb,
948   - mb_mapping->tab_input_status,
949   - response, resp_length);
950   - }
951   - }
952   - break;
953   - case FC_READ_HOLDING_REGISTERS: {
954   - int nb = (query[offset + 3] << 8) + query[offset + 4];
955   -
956   - if ((address + nb) > mb_mapping->nb_holding_registers) {
957   - if (mb_param->debug) {
958   - fprintf(stderr, "Illegal data address %0X in read_holding_registers\n",
959   - address + nb);
960   - }
961   - resp_length = response_exception(
962   - mb_param, &sft,
963   - MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
964   - } else {
965   - int i;
966   -
967   - resp_length = build_response_basis(mb_param, &sft, response);
968   - response[resp_length++] = nb << 1;
969   - for (i = address; i < address + nb; i++) {
970   - response[resp_length++] = mb_mapping->tab_holding_registers[i] >> 8;
971   - response[resp_length++] = mb_mapping->tab_holding_registers[i] & 0xFF;
972   - }
973   - }
974   - }
975   - break;
976   - case FC_READ_INPUT_REGISTERS: {
977   - /* Similar to holding registers (but too much arguments to use a
978   - * function) */
979   - int nb = (query[offset + 3] << 8) + query[offset + 4];
980   -
981   - if ((address + nb) > mb_mapping->nb_input_registers) {
982   - if (mb_param->debug) {
983   - fprintf(stderr, "Illegal data address %0X in read_input_registers\n",
984   - address + nb);
985   - }
986   - resp_length = response_exception(
987   - mb_param, &sft,
988   - MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
989   - } else {
990   - int i;
991   -
992   - resp_length = build_response_basis(mb_param, &sft, response);
993   - response[resp_length++] = nb << 1;
994   - for (i = address; i < address + nb; i++) {
995   - response[resp_length++] = mb_mapping->tab_input_registers[i] >> 8;
996   - response[resp_length++] = mb_mapping->tab_input_registers[i] & 0xFF;
997   - }
998   - }
999   - }
1000   - break;
1001   - case FC_FORCE_SINGLE_COIL:
1002   - if (address >= mb_mapping->nb_coil_status) {
1003   - if (mb_param->debug) {
1004   - fprintf(stderr, "Illegal data address %0X in force_singe_coil\n",
1005   - address);
1006   - }
1007   - resp_length = response_exception(
1008   - mb_param, &sft,
1009   - MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
1010   - } else {
1011   - int data = (query[offset + 3] << 8) + query[offset + 4];
1012   -
1013   - if (data == 0xFF00 || data == 0x0) {
1014   - mb_mapping->tab_coil_status[address] = (data) ? ON : OFF;
1015   -
1016   - /* In RTU mode, the CRC is computed and added
1017   - to the query by modbus_send, the computed
1018   - CRC will be same and optimisation is
1019   - possible here (FIXME). */
1020   - memcpy(response, query, query_length);
1021   - resp_length = query_length;
1022   - } else {
1023   - if (mb_param->debug) {
1024   - fprintf(stderr, "Illegal data value %0X in force_single_coil request at address %0X\n",
1025   - data, address);
1026   - }
1027   - resp_length = response_exception(
1028   - mb_param, &sft,
1029   - MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, response);
1030   - }
1031   - }
1032   - break;
1033   - case FC_PRESET_SINGLE_REGISTER:
1034   - if (address >= mb_mapping->nb_holding_registers) {
1035   - if (mb_param->debug) {
1036   - fprintf(stderr, "Illegal data address %0X in preset_holding_register\n",
1037   - address);
1038   - }
1039   - resp_length = response_exception(
1040   - mb_param, &sft,
1041   - MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
1042   - } else {
1043   - int data = (query[offset + 3] << 8) + query[offset + 4];
1044   -
1045   - mb_mapping->tab_holding_registers[address] = data;
1046   - memcpy(response, query, query_length);
1047   - resp_length = query_length;
1048   - }
1049   - break;
1050   - case FC_FORCE_MULTIPLE_COILS: {
1051   - int nb = (query[offset + 3] << 8) + query[offset + 4];
1052   -
1053   - if ((address + nb) > mb_mapping->nb_coil_status) {
1054   - if (mb_param->debug) {
1055   - fprintf(stderr, "Illegal data address %0X in force_multiple_coils\n",
1056   - address + nb);
1057   - }
1058   - resp_length = response_exception(
1059   - mb_param, &sft,
1060   - MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
1061   - } else {
1062   - /* 6 = byte count */
1063   - set_bits_from_bytes(mb_mapping->tab_coil_status, address, nb, &query[offset + 6]);
1064   -
1065   - resp_length = build_response_basis(mb_param, &sft, response);
1066   - /* 4 to copy the coil address (2) and the quantity of coils */
1067   - memcpy(response + resp_length, query + resp_length, 4);
1068   - resp_length += 4;
1069   - }
1070   - }
1071   - break;
1072   - case FC_PRESET_MULTIPLE_REGISTERS: {
1073   - int nb = (query[offset + 3] << 8) + query[offset + 4];
1074   -
1075   - if ((address + nb) > mb_mapping->nb_holding_registers) {
1076   - if (mb_param->debug) {
1077   - fprintf(stderr, "Illegal data address %0X in preset_multiple_registers\n",
1078   - address + nb);
1079   - }
1080   - resp_length = response_exception(
1081   - mb_param, &sft,
1082   - MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
1083   - } else {
1084   - int i, j;
1085   - for (i = address, j = 6; i < address + nb; i++, j += 2) {
1086   - /* 6 and 7 = first value */
1087   - mb_mapping->tab_holding_registers[i] =
1088   - (query[offset + j] << 8) + query[offset + j + 1];
1089   - }
1090   -
1091   - resp_length = build_response_basis(mb_param, &sft, response);
1092   - /* 4 to copy the address (2) and the no. of registers */
1093   - memcpy(response + resp_length, query + resp_length, 4);
1094   - resp_length += 4;
1095   - }
1096   - }
1097   - break;
1098   - case FC_READ_EXCEPTION_STATUS:
1099   - case FC_REPORT_SLAVE_ID:
  922 + resp_length = build_response_basis(mb_param, &sft, response);
  923 + response[resp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
  924 + resp_length = response_io_status(address, nb,
  925 + mb_mapping->tab_coil_status,
  926 + response, resp_length);
  927 + }
  928 + }
  929 + break;
  930 + case FC_READ_INPUT_STATUS: {
  931 + /* Similar to coil status (but too much arguments to use a
  932 + * function) */
  933 + int nb = (query[offset + 3] << 8) + query[offset + 4];
  934 +
  935 + if ((address + nb) > mb_mapping->nb_input_status) {
  936 + if (mb_param->debug) {
  937 + fprintf(stderr, "Illegal data address %0X in read_input_status\n",
  938 + address + nb);
  939 + }
  940 + resp_length = response_exception(
  941 + mb_param, &sft,
  942 + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
  943 + } else {
  944 + resp_length = build_response_basis(mb_param, &sft, response);
  945 + response[resp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
  946 + resp_length = response_io_status(address, nb,
  947 + mb_mapping->tab_input_status,
  948 + response, resp_length);
  949 + }
  950 + }
  951 + break;
  952 + case FC_READ_HOLDING_REGISTERS: {
  953 + int nb = (query[offset + 3] << 8) + query[offset + 4];
  954 +
  955 + if ((address + nb) > mb_mapping->nb_holding_registers) {
  956 + if (mb_param->debug) {
  957 + fprintf(stderr, "Illegal data address %0X in read_holding_registers\n",
  958 + address + nb);
  959 + }
  960 + resp_length = response_exception(
  961 + mb_param, &sft,
  962 + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
  963 + } else {
  964 + int i;
  965 +
  966 + resp_length = build_response_basis(mb_param, &sft, response);
  967 + response[resp_length++] = nb << 1;
  968 + for (i = address; i < address + nb; i++) {
  969 + response[resp_length++] = mb_mapping->tab_holding_registers[i] >> 8;
  970 + response[resp_length++] = mb_mapping->tab_holding_registers[i] & 0xFF;
  971 + }
  972 + }
  973 + }
  974 + break;
  975 + case FC_READ_INPUT_REGISTERS: {
  976 + /* Similar to holding registers (but too much arguments to use a
  977 + * function) */
  978 + int nb = (query[offset + 3] << 8) + query[offset + 4];
  979 +
  980 + if ((address + nb) > mb_mapping->nb_input_registers) {
  981 + if (mb_param->debug) {
  982 + fprintf(stderr, "Illegal data address %0X in read_input_registers\n",
  983 + address + nb);
  984 + }
  985 + resp_length = response_exception(
  986 + mb_param, &sft,
  987 + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
  988 + } else {
  989 + int i;
  990 +
  991 + resp_length = build_response_basis(mb_param, &sft, response);
  992 + response[resp_length++] = nb << 1;
  993 + for (i = address; i < address + nb; i++) {
  994 + response[resp_length++] = mb_mapping->tab_input_registers[i] >> 8;
  995 + response[resp_length++] = mb_mapping->tab_input_registers[i] & 0xFF;
  996 + }
  997 + }
  998 + }
  999 + break;
  1000 + case FC_FORCE_SINGLE_COIL:
  1001 + if (address >= mb_mapping->nb_coil_status) {
  1002 + if (mb_param->debug) {
  1003 + fprintf(stderr, "Illegal data address %0X in force_singe_coil\n",
  1004 + address);
  1005 + }
  1006 + resp_length = response_exception(
  1007 + mb_param, &sft,
  1008 + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
  1009 + } else {
  1010 + int data = (query[offset + 3] << 8) + query[offset + 4];
  1011 +
  1012 + if (data == 0xFF00 || data == 0x0) {
  1013 + mb_mapping->tab_coil_status[address] = (data) ? ON : OFF;
  1014 +
  1015 + /* In RTU mode, the CRC is computed and added
  1016 + to the query by modbus_send, the computed
  1017 + CRC will be same and optimisation is
  1018 + possible here (FIXME). */
  1019 + memcpy(response, query, query_length);
  1020 + resp_length = query_length;
  1021 + } else {
1100 1022 if (mb_param->debug) {
1101   - fprintf(stderr, "FIXME Not implemented\n");
  1023 + fprintf(stderr, "Illegal data value %0X in force_single_coil request at address %0X\n",
  1024 + data, address);
1102 1025 }
1103   - errno = ENOPROTOOPT;
1104   - return -1;
1105   - break;
1106   - default:
1107   - /* FIXME Invalid function exception */
1108   - break;
  1026 + resp_length = response_exception(
  1027 + mb_param, &sft,
  1028 + MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, response);
  1029 + }
  1030 + }
  1031 + break;
  1032 + case FC_PRESET_SINGLE_REGISTER:
  1033 + if (address >= mb_mapping->nb_holding_registers) {
  1034 + if (mb_param->debug) {
  1035 + fprintf(stderr, "Illegal data address %0X in preset_holding_register\n",
  1036 + address);
  1037 + }
  1038 + resp_length = response_exception(
  1039 + mb_param, &sft,
  1040 + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
  1041 + } else {
  1042 + int data = (query[offset + 3] << 8) + query[offset + 4];
  1043 +
  1044 + mb_mapping->tab_holding_registers[address] = data;
  1045 + memcpy(response, query, query_length);
  1046 + resp_length = query_length;
  1047 + }
  1048 + break;
  1049 + case FC_FORCE_MULTIPLE_COILS: {
  1050 + int nb = (query[offset + 3] << 8) + query[offset + 4];
  1051 +
  1052 + if ((address + nb) > mb_mapping->nb_coil_status) {
  1053 + if (mb_param->debug) {
  1054 + fprintf(stderr, "Illegal data address %0X in force_multiple_coils\n",
  1055 + address + nb);
  1056 + }
  1057 + resp_length = response_exception(
  1058 + mb_param, &sft,
  1059 + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
  1060 + } else {
  1061 + /* 6 = byte count */
  1062 + set_bits_from_bytes(mb_mapping->tab_coil_status, address, nb, &query[offset + 6]);
  1063 +
  1064 + resp_length = build_response_basis(mb_param, &sft, response);
  1065 + /* 4 to copy the coil address (2) and the quantity of coils */
  1066 + memcpy(response + resp_length, query + resp_length, 4);
  1067 + resp_length += 4;
  1068 + }
  1069 + }
  1070 + break;
  1071 + case FC_PRESET_MULTIPLE_REGISTERS: {
  1072 + int nb = (query[offset + 3] << 8) + query[offset + 4];
  1073 +
  1074 + if ((address + nb) > mb_mapping->nb_holding_registers) {
  1075 + if (mb_param->debug) {
  1076 + fprintf(stderr, "Illegal data address %0X in preset_multiple_registers\n",
  1077 + address + nb);
  1078 + }
  1079 + resp_length = response_exception(
  1080 + mb_param, &sft,
  1081 + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, response);
  1082 + } else {
  1083 + int i, j;
  1084 + for (i = address, j = 6; i < address + nb; i++, j += 2) {
  1085 + /* 6 and 7 = first value */
  1086 + mb_mapping->tab_holding_registers[i] =
  1087 + (query[offset + j] << 8) + query[offset + j + 1];
  1088 + }
  1089 +
  1090 + resp_length = build_response_basis(mb_param, &sft, response);
  1091 + /* 4 to copy the address (2) and the no. of registers */
  1092 + memcpy(response + resp_length, query + resp_length, 4);
  1093 + resp_length += 4;
  1094 + }
  1095 + }
  1096 + break;
  1097 + case FC_READ_EXCEPTION_STATUS:
  1098 + case FC_REPORT_SLAVE_ID:
  1099 + if (mb_param->debug) {
  1100 + fprintf(stderr, "FIXME Not implemented\n");
1109 1101 }
  1102 + errno = ENOPROTOOPT;
  1103 + return -1;
  1104 + break;
  1105 + default:
  1106 + /* FIXME Invalid function exception */
  1107 + break;
  1108 + }
1110 1109  
1111   - return modbus_send(mb_param, response, resp_length);
  1110 + return modbus_send(mb_param, response, resp_length);
1112 1111 }
1113 1112  
1114 1113 /* Reads IO status */
1115 1114 static int read_io_status(modbus_param_t *mb_param, int slave, int function,
1116 1115 int start_addr, int nb, uint8_t *data_dest)
1117 1116 {
1118   - int rc;
1119   - int query_length;
  1117 + int rc;
  1118 + int query_length;
1120 1119  
1121   - uint8_t query[MIN_QUERY_LENGTH];
1122   - uint8_t response[MAX_MESSAGE_LENGTH];
  1120 + uint8_t query[MIN_QUERY_LENGTH];
  1121 + uint8_t response[MAX_MESSAGE_LENGTH];
1123 1122  
1124   - query_length = build_query_basis(mb_param, slave, function,
1125   - start_addr, nb, query);
  1123 + query_length = build_query_basis(mb_param, slave, function,
  1124 + start_addr, nb, query);
1126 1125  
1127   - rc = modbus_send(mb_param, query, query_length);
1128   - if (rc > 0) {
1129   - int i, temp, bit;
1130   - int pos = 0;
1131   - int offset;
1132   - int offset_end;
  1126 + rc = modbus_send(mb_param, query, query_length);
  1127 + if (rc > 0) {
  1128 + int i, temp, bit;
  1129 + int pos = 0;
  1130 + int offset;
  1131 + int offset_end;
1133 1132  
1134   - rc = modbus_receive(mb_param, query, response);
1135   - if (rc == -1)
1136   - return -1;
  1133 + rc = modbus_receive(mb_param, query, response);
  1134 + if (rc == -1)
  1135 + return -1;
1137 1136  
1138   - offset = TAB_HEADER_LENGTH[mb_param->type_com];
1139   - offset_end = offset + rc;
1140   - for (i = offset; i < offset_end; i++) {
1141   - /* Shift reg hi_byte to temp */
1142   - temp = response[i + 2];
  1137 + offset = TAB_HEADER_LENGTH[mb_param->type_com];
  1138 + offset_end = offset + rc;
  1139 + for (i = offset; i < offset_end; i++) {
  1140 + /* Shift reg hi_byte to temp */
  1141 + temp = response[i + 2];
1143 1142  
1144   - for (bit = 0x01; (bit & 0xff) && (pos < nb);) {
1145   - data_dest[pos++] = (temp & bit) ? TRUE : FALSE;
1146   - bit = bit << 1;
1147   - }
  1143 + for (bit = 0x01; (bit & 0xff) && (pos < nb);) {
  1144 + data_dest[pos++] = (temp & bit) ? TRUE : FALSE;
  1145 + bit = bit << 1;
  1146 + }
1148 1147  
1149   - }
1150 1148 }
  1149 + }
1151 1150  
1152   - return rc;
  1151 + return rc;
1153 1152 }
1154 1153  
1155 1154 /* Reads the boolean status of coils and sets the array elements
... ... @@ -1157,25 +1156,25 @@ static int read_io_status(modbus_param_t *mb_param, int slave, int function,
1157 1156 int read_coil_status(modbus_param_t *mb_param, int slave, int start_addr,
1158 1157 int nb, uint8_t *data_dest)
1159 1158 {
1160   - int rc;
  1159 + int rc;
1161 1160  
1162   - if (nb > MAX_STATUS) {
1163   - if (mb_param->debug) {
1164   - fprintf(stderr,
1165   - "ERROR Too many coils status requested (%d > %d)\n",
1166   - nb, MAX_STATUS);
1167   - }
1168   - errno = EMBMDATA;
1169   - return -1;
  1161 + if (nb > MAX_STATUS) {
  1162 + if (mb_param->debug) {
  1163 + fprintf(stderr,
  1164 + "ERROR Too many coils status requested (%d > %d)\n",
  1165 + nb, MAX_STATUS);
1170 1166 }
  1167 + errno = EMBMDATA;
  1168 + return -1;
  1169 + }
1171 1170  
1172   - rc = read_io_status(mb_param, slave, FC_READ_COIL_STATUS, start_addr,
1173   - nb, data_dest);
  1171 + rc = read_io_status(mb_param, slave, FC_READ_COIL_STATUS, start_addr,
  1172 + nb, data_dest);
1174 1173  
1175   - if (rc == -1)
1176   - return -1;
1177   - else
1178   - return nb;
  1174 + if (rc == -1)
  1175 + return -1;
  1176 + else
  1177 + return nb;
1179 1178 }
1180 1179  
1181 1180  
... ... @@ -1183,67 +1182,67 @@ int read_coil_status(modbus_param_t *mb_param, int slave, int start_addr,
1183 1182 int read_input_status(modbus_param_t *mb_param, int slave, int start_addr,
1184 1183 int nb, uint8_t *data_dest)
1185 1184 {
1186   - int rc;
  1185 + int rc;
1187 1186  
1188   - if (nb > MAX_STATUS) {
1189   - if (mb_param->debug) {
1190   - fprintf(stderr,
1191   - "ERROR Too many input status requested (%d > %d)\n",
1192   - nb, MAX_STATUS);
1193   - }
1194   - errno = EMBMDATA;
1195   - return -1;
  1187 + if (nb > MAX_STATUS) {
  1188 + if (mb_param->debug) {
  1189 + fprintf(stderr,
  1190 + "ERROR Too many input status requested (%d > %d)\n",
  1191 + nb, MAX_STATUS);
1196 1192 }
  1193 + errno = EMBMDATA;
  1194 + return -1;
  1195 + }
1197 1196  
1198   - rc = read_io_status(mb_param, slave, FC_READ_INPUT_STATUS, start_addr,
1199   - nb, data_dest);
  1197 + rc = read_io_status(mb_param, slave, FC_READ_INPUT_STATUS, start_addr,
  1198 + nb, data_dest);
1200 1199  
1201   - if (rc == -1)
1202   - return -1;
1203   - else
1204   - return nb;
  1200 + if (rc == -1)
  1201 + return -1;
  1202 + else
  1203 + return nb;
1205 1204 }
1206 1205  
1207 1206 /* Reads the data from a modbus slave and put that data into an array */
1208 1207 static int read_registers(modbus_param_t *mb_param, int slave, int function,
1209 1208 int start_addr, int nb, uint16_t *data_dest)
1210 1209 {
1211   - int rc;
1212   - int query_length;
1213   - uint8_t query[MIN_QUERY_LENGTH];
1214   - uint8_t response[MAX_MESSAGE_LENGTH];
  1210 + int rc;
  1211 + int query_length;
  1212 + uint8_t query[MIN_QUERY_LENGTH];
  1213 + uint8_t response[MAX_MESSAGE_LENGTH];
1215 1214  
1216   - if (nb > MAX_REGISTERS) {
1217   - if (mb_param->debug) {
1218   - fprintf(stderr,
1219   - "ERROR Too many holding registers requested (%d > %d)\n",
1220   - nb, MAX_REGISTERS);
1221   - }
1222   - errno = EMBMDATA;
1223   - return -1;
  1215 + if (nb > MAX_REGISTERS) {
  1216 + if (mb_param->debug) {
  1217 + fprintf(stderr,
  1218 + "ERROR Too many holding registers requested (%d > %d)\n",
  1219 + nb, MAX_REGISTERS);
1224 1220 }
  1221 + errno = EMBMDATA;
  1222 + return -1;
  1223 + }
1225 1224  
1226   - query_length = build_query_basis(mb_param, slave, function,
1227   - start_addr, nb, query);
  1225 + query_length = build_query_basis(mb_param, slave, function,
  1226 + start_addr, nb, query);
1228 1227  
1229   - rc = modbus_send(mb_param, query, query_length);
1230   - if (rc > 0) {
1231   - int offset;
1232   - int i;
  1228 + rc = modbus_send(mb_param, query, query_length);
  1229 + if (rc > 0) {
  1230 + int offset;
  1231 + int i;
1233 1232  
1234   - rc = modbus_receive(mb_param, query, response);
  1233 + rc = modbus_receive(mb_param, query, response);
1235 1234  
1236   - offset = TAB_HEADER_LENGTH[mb_param->type_com];
  1235 + offset = TAB_HEADER_LENGTH[mb_param->type_com];
1237 1236  
1238   - /* If rc is negative, the loop is jumped ! */
1239   - for (i = 0; i < rc; i++) {
1240   - /* shift reg hi_byte to temp OR with lo_byte */
1241   - data_dest[i] = (response[offset + 2 + (i << 1)] << 8) |
1242   - response[offset + 3 + (i << 1)];
1243   - }
  1237 + /* If rc is negative, the loop is jumped ! */
  1238 + for (i = 0; i < rc; i++) {
  1239 + /* shift reg hi_byte to temp OR with lo_byte */
  1240 + data_dest[i] = (response[offset + 2 + (i << 1)] << 8) |
  1241 + response[offset + 3 + (i << 1)];
1244 1242 }
  1243 + }
1245 1244  
1246   - return rc;
  1245 + return rc;
1247 1246 }
1248 1247  
1249 1248 /* Reads the holding registers in a slave and put the data into an
... ... @@ -1251,21 +1250,21 @@ static int read_registers(modbus_param_t *mb_param, int slave, int function,
1251 1250 int read_holding_registers(modbus_param_t *mb_param, int slave,
1252 1251 int start_addr, int nb, uint16_t *data_dest)
1253 1252 {
1254   - int status;
  1253 + int status;
1255 1254  
1256   - if (nb > MAX_REGISTERS) {
1257   - if (mb_param->debug) {
1258   - fprintf(stderr,
1259   - "ERROR Too many holding registers requested (%d > %d)\n",
1260   - nb, MAX_REGISTERS);
1261   - }
1262   - errno = EMBMDATA;
1263   - return -1;
  1255 + if (nb > MAX_REGISTERS) {
  1256 + if (mb_param->debug) {
  1257 + fprintf(stderr,
  1258 + "ERROR Too many holding registers requested (%d > %d)\n",
  1259 + nb, MAX_REGISTERS);
1264 1260 }
  1261 + errno = EMBMDATA;
  1262 + return -1;
  1263 + }
1265 1264  
1266   - status = read_registers(mb_param, slave, FC_READ_HOLDING_REGISTERS,
1267   - start_addr, nb, data_dest);
1268   - return status;
  1265 + status = read_registers(mb_param, slave, FC_READ_HOLDING_REGISTERS,
  1266 + start_addr, nb, data_dest);
  1267 + return status;
1269 1268 }
1270 1269  
1271 1270 /* Reads the input registers in a slave and put the data into
... ... @@ -1273,20 +1272,20 @@ int read_holding_registers(modbus_param_t *mb_param, int slave,
1273 1272 int read_input_registers(modbus_param_t *mb_param, int slave, int start_addr,
1274 1273 int nb, uint16_t *data_dest)
1275 1274 {
1276   - int status;
  1275 + int status;
1277 1276  
1278   - if (nb > MAX_REGISTERS) {
1279   - fprintf(stderr,
1280   - "ERROR Too many input registers requested (%d > %d)\n",
1281   - nb, MAX_REGISTERS);
1282   - errno = EMBMDATA;
1283   - return -1;
1284   - }
  1277 + if (nb > MAX_REGISTERS) {
  1278 + fprintf(stderr,
  1279 + "ERROR Too many input registers requested (%d > %d)\n",
  1280 + nb, MAX_REGISTERS);
  1281 + errno = EMBMDATA;
  1282 + return -1;
  1283 + }
1285 1284  
1286   - status = read_registers(mb_param, slave, FC_READ_INPUT_REGISTERS,
1287   - start_addr, nb, data_dest);
  1285 + status = read_registers(mb_param, slave, FC_READ_INPUT_REGISTERS,
  1286 + start_addr, nb, data_dest);
1288 1287  
1289   - return status;
  1288 + return status;
1290 1289 }
1291 1290  
1292 1291 /* Sends a value to a register in a slave.
... ... @@ -1294,187 +1293,187 @@ int read_input_registers(modbus_param_t *mb_param, int slave, int start_addr,
1294 1293 static int set_single(modbus_param_t *mb_param, int slave, int function,
1295 1294 int addr, int value)
1296 1295 {
1297   - int rc;
1298   - int query_length;
1299   - uint8_t query[MIN_QUERY_LENGTH];
1300   -
1301   - query_length = build_query_basis(mb_param, slave, function,
1302   - addr, value, query);
1303   -
1304   - rc = modbus_send(mb_param, query, query_length);
1305   - if (rc > 0) {
1306   - /* Used by force_single_coil and
1307   - * preset_single_register */
1308   - uint8_t response[MIN_QUERY_LENGTH];
1309   - rc = modbus_receive(mb_param, query, response);
1310   - }
1311   -
1312   - return rc;
  1296 + int rc;
  1297 + int query_length;
  1298 + uint8_t query[MIN_QUERY_LENGTH];
  1299 +
  1300 + query_length = build_query_basis(mb_param, slave, function,
  1301 + addr, value, query);
  1302 +
  1303 + rc = modbus_send(mb_param, query, query_length);
  1304 + if (rc > 0) {
  1305 + /* Used by force_single_coil and
  1306 + * preset_single_register */
  1307 + uint8_t response[MIN_QUERY_LENGTH];
  1308 + rc = modbus_receive(mb_param, query, response);
  1309 + }
  1310 +
  1311 + return rc;
1313 1312 }
1314 1313  
1315 1314 /* Turns ON or OFF a single coil in the slave device */
1316 1315 int force_single_coil(modbus_param_t *mb_param, int slave, int coil_addr, int state)
1317 1316 {
1318   - int status;
  1317 + int status;
1319 1318  
1320   - if (state)
1321   - state = 0xFF00;
  1319 + if (state)
  1320 + state = 0xFF00;
1322 1321  
1323   - status = set_single(mb_param, slave, FC_FORCE_SINGLE_COIL,
1324   - coil_addr, state);
  1322 + status = set_single(mb_param, slave, FC_FORCE_SINGLE_COIL,
  1323 + coil_addr, state);
1325 1324  
1326   - return status;
  1325 + return status;
1327 1326 }
1328 1327  
1329 1328 /* Sets a value in one holding register in the slave device */
1330 1329 int preset_single_register(modbus_param_t *mb_param, int slave, int reg_addr,
1331 1330 int value)
1332 1331 {
1333   - int status;
  1332 + int status;
1334 1333  
1335   - status = set_single(mb_param, slave, FC_PRESET_SINGLE_REGISTER,
1336   - reg_addr, value);
  1334 + status = set_single(mb_param, slave, FC_PRESET_SINGLE_REGISTER,
  1335 + reg_addr, value);
1337 1336  
1338   - return status;
  1337 + return status;
1339 1338 }
1340 1339  
1341 1340 /* Sets/resets the coils in the slave from an array in argument */
1342 1341 int force_multiple_coils(modbus_param_t *mb_param, int slave, int start_addr,
1343 1342 int nb, const uint8_t *data_src)
1344 1343 {
1345   - int rc;
1346   - int i;
1347   - int byte_count;
1348   - int query_length;
1349   - int coil_check = 0;
1350   - int pos = 0;
  1344 + int rc;
  1345 + int i;
  1346 + int byte_count;
  1347 + int query_length;
  1348 + int coil_check = 0;
  1349 + int pos = 0;
1351 1350  
1352   - uint8_t query[MAX_MESSAGE_LENGTH];
  1351 + uint8_t query[MAX_MESSAGE_LENGTH];
1353 1352  
1354   - if (nb > MAX_STATUS) {
1355   - if (mb_param->debug) {
1356   - fprintf(stderr, "ERROR Writing to too many coils (%d > %d)\n",
1357   - nb, MAX_STATUS);
1358   - }
1359   - errno = EMBMDATA;
1360   - return -1;
  1353 + if (nb > MAX_STATUS) {
  1354 + if (mb_param->debug) {
  1355 + fprintf(stderr, "ERROR Writing to too many coils (%d > %d)\n",
  1356 + nb, MAX_STATUS);
1361 1357 }
  1358 + errno = EMBMDATA;
  1359 + return -1;
  1360 + }
1362 1361  
1363   - query_length = build_query_basis(mb_param, slave, FC_FORCE_MULTIPLE_COILS,
1364   - start_addr, nb, query);
1365   - byte_count = (nb / 8) + ((nb % 8) ? 1 : 0);
1366   - query[query_length++] = byte_count;
  1362 + query_length = build_query_basis(mb_param, slave, FC_FORCE_MULTIPLE_COILS,
  1363 + start_addr, nb, query);
  1364 + byte_count = (nb / 8) + ((nb % 8) ? 1 : 0);
  1365 + query[query_length++] = byte_count;
1367 1366  
1368   - for (i = 0; i < byte_count; i++) {
1369   - int bit;
  1367 + for (i = 0; i < byte_count; i++) {
  1368 + int bit;
1370 1369  
1371   - bit = 0x01;
1372   - query[query_length] = 0;
  1370 + bit = 0x01;
  1371 + query[query_length] = 0;
1373 1372  
1374   - while ((bit & 0xFF) && (coil_check++ < nb)) {
1375   - if (data_src[pos++])
1376   - query[query_length] |= bit;
1377   - else
1378   - query[query_length] &=~ bit;
  1373 + while ((bit & 0xFF) && (coil_check++ < nb)) {
  1374 + if (data_src[pos++])
  1375 + query[query_length] |= bit;
  1376 + else
  1377 + query[query_length] &=~ bit;
1379 1378  
1380   - bit = bit << 1;
1381   - }
1382   - query_length++;
  1379 + bit = bit << 1;
1383 1380 }
  1381 + query_length++;
  1382 + }
1384 1383  
1385   - rc = modbus_send(mb_param, query, query_length);
1386   - if (rc > 0) {
1387   - uint8_t response[MAX_MESSAGE_LENGTH];
1388   - rc = modbus_receive(mb_param, query, response);
1389   - }
  1384 + rc = modbus_send(mb_param, query, query_length);
  1385 + if (rc > 0) {
  1386 + uint8_t response[MAX_MESSAGE_LENGTH];
  1387 + rc = modbus_receive(mb_param, query, response);
  1388 + }
1390 1389  
1391 1390  
1392   - return rc;
  1391 + return rc;
1393 1392 }
1394 1393  
1395 1394 /* Copies the values in the slave from the array given in argument */
1396 1395 int preset_multiple_registers(modbus_param_t *mb_param, int slave, int start_addr,
1397 1396 int nb, const uint16_t *data_src)
1398 1397 {
1399   - int rc;
1400   - int i;
1401   - int query_length;
1402   - int byte_count;
1403   -
1404   - uint8_t query[MAX_MESSAGE_LENGTH];
1405   -
1406   - if (nb > MAX_REGISTERS) {
1407   - if (mb_param->debug) {
1408   - fprintf(stderr,
1409   - "ERROR Trying to write to too many registers (%d > %d)\n",
1410   - nb, MAX_REGISTERS);
1411   - }
1412   - errno = EMBMDATA;
1413   - return -1;
1414   - }
1415   -
1416   - query_length = build_query_basis(mb_param, slave, FC_PRESET_MULTIPLE_REGISTERS,
1417   - start_addr, nb, query);
1418   - byte_count = nb * 2;
1419   - query[query_length++] = byte_count;
  1398 + int rc;
  1399 + int i;
  1400 + int query_length;
  1401 + int byte_count;
1420 1402  
1421   - for (i = 0; i < nb; i++) {
1422   - query[query_length++] = data_src[i] >> 8;
1423   - query[query_length++] = data_src[i] & 0x00FF;
1424   - }
  1403 + uint8_t query[MAX_MESSAGE_LENGTH];
1425 1404  
1426   - rc = modbus_send(mb_param, query, query_length);
1427   - if (rc > 0) {
1428   - uint8_t response[MAX_MESSAGE_LENGTH];
1429   - rc = modbus_receive(mb_param, query, response);
1430   - }
  1405 + if (nb > MAX_REGISTERS) {
  1406 + if (mb_param->debug) {
  1407 + fprintf(stderr,
  1408 + "ERROR Trying to write to too many registers (%d > %d)\n",
  1409 + nb, MAX_REGISTERS);
  1410 + }
  1411 + errno = EMBMDATA;
  1412 + return -1;
  1413 + }
  1414 +
  1415 + query_length = build_query_basis(mb_param, slave, FC_PRESET_MULTIPLE_REGISTERS,
  1416 + start_addr, nb, query);
  1417 + byte_count = nb * 2;
  1418 + query[query_length++] = byte_count;
  1419 +
  1420 + for (i = 0; i < nb; i++) {
  1421 + query[query_length++] = data_src[i] >> 8;
  1422 + query[query_length++] = data_src[i] & 0x00FF;
  1423 + }
  1424 +
  1425 + rc = modbus_send(mb_param, query, query_length);
  1426 + if (rc > 0) {
  1427 + uint8_t response[MAX_MESSAGE_LENGTH];
  1428 + rc = modbus_receive(mb_param, query, response);
  1429 + }
1431 1430  
1432   - return rc;
  1431 + return rc;
1433 1432 }
1434 1433  
1435 1434 /* Request the slave ID */
1436 1435 int report_slave_id(modbus_param_t *mb_param, int slave, uint8_t *data_dest)
1437 1436 {
1438   - int rc;
1439   - int query_length;
1440   - uint8_t query[MIN_QUERY_LENGTH];
1441   -
1442   - query_length = build_query_basis(mb_param, slave,
1443   - FC_REPORT_SLAVE_ID, 0, 0, query);
1444   -
1445   - /* HACKISH, start_addr and count are not used */
1446   - query_length -= 4;
1447   -
1448   - rc = modbus_send(mb_param, query, query_length);
1449   - if (rc > 0) {
1450   - int i;
1451   - int offset;
1452   - int offset_end;
1453   - uint8_t response[MAX_MESSAGE_LENGTH];
1454   -
1455   - /* Byte count, slave id, run indicator status,
1456   - additional data */
1457   - rc = modbus_receive(mb_param, query, response);
1458   - if (rc == -1)
1459   - return rc;
1460   -
1461   - offset = TAB_HEADER_LENGTH[mb_param->type_com] - 1;
1462   - offset_end = offset + rc;
1463   -
1464   - for (i = offset; i < offset_end; i++)
1465   - data_dest[i] = response[i];
1466   - }
  1437 + int rc;
  1438 + int query_length;
  1439 + uint8_t query[MIN_QUERY_LENGTH];
  1440 +
  1441 + query_length = build_query_basis(mb_param, slave,
  1442 + FC_REPORT_SLAVE_ID, 0, 0, query);
  1443 +
  1444 + /* HACKISH, start_addr and count are not used */
  1445 + query_length -= 4;
  1446 +
  1447 + rc = modbus_send(mb_param, query, query_length);
  1448 + if (rc > 0) {
  1449 + int i;
  1450 + int offset;
  1451 + int offset_end;
  1452 + uint8_t response[MAX_MESSAGE_LENGTH];
  1453 +
  1454 + /* Byte count, slave id, run indicator status,
  1455 + additional data */
  1456 + rc = modbus_receive(mb_param, query, response);
  1457 + if (rc == -1)
  1458 + return rc;
  1459 +
  1460 + offset = TAB_HEADER_LENGTH[mb_param->type_com] - 1;
  1461 + offset_end = offset + rc;
  1462 +
  1463 + for (i = offset; i < offset_end; i++)
  1464 + data_dest[i] = response[i];
  1465 + }
1467 1466  
1468   - return rc;
  1467 + return rc;
1469 1468 }
1470 1469  
1471 1470 void init_common(modbus_param_t *mb_param)
1472 1471 {
1473   - mb_param->timeout_begin.tv_sec = 0;
1474   - mb_param->timeout_begin.tv_usec = TIME_OUT_BEGIN_OF_TRAME;
  1472 + mb_param->timeout_begin.tv_sec = 0;
  1473 + mb_param->timeout_begin.tv_usec = TIME_OUT_BEGIN_OF_TRAME;
1475 1474  
1476   - mb_param->timeout_end.tv_sec = 0;
1477   - mb_param->timeout_end.tv_usec = TIME_OUT_END_OF_TRAME;
  1475 + mb_param->timeout_end.tv_sec = 0;
  1476 + mb_param->timeout_end.tv_usec = TIME_OUT_END_OF_TRAME;
1478 1477 }
1479 1478  
1480 1479 /* Initializes the modbus_param_t structure for RTU
... ... @@ -1486,26 +1485,26 @@ void init_common(modbus_param_t *mb_param)
1486 1485 - slave: slave number
1487 1486 */
1488 1487 int modbus_init_rtu(modbus_param_t *mb_param, const char *device,
1489   - int baud, char parity, int data_bit,
1490   - int stop_bit, int slave)
  1488 + int baud, char parity, int data_bit,
  1489 + int stop_bit, int slave)
1491 1490 {
1492   - memset(mb_param, 0, sizeof(modbus_param_t));
1493   - init_common(mb_param);
1494   -
1495   - strcpy(mb_param->device, device);
1496   - mb_param->baud = baud;
1497   - if (parity == 'N' || parity == 'E' || parity == 'O') {
1498   - mb_param->parity = parity;
1499   - } else {
1500   - errno = EINVAL;
1501   - return -1;
1502   - }
1503   - mb_param->debug = FALSE;
1504   - mb_param->data_bit = data_bit;
1505   - mb_param->stop_bit = stop_bit;
1506   - mb_param->type_com = RTU;
1507   - mb_param->error_recovery = FALSE;
1508   - return modbus_set_slave(mb_param, slave);
  1491 + memset(mb_param, 0, sizeof(modbus_param_t));
  1492 + init_common(mb_param);
  1493 +
  1494 + strcpy(mb_param->device, device);
  1495 + mb_param->baud = baud;
  1496 + if (parity == 'N' || parity == 'E' || parity == 'O') {
  1497 + mb_param->parity = parity;
  1498 + } else {
  1499 + errno = EINVAL;
  1500 + return -1;
  1501 + }
  1502 + mb_param->debug = FALSE;
  1503 + mb_param->data_bit = data_bit;
  1504 + mb_param->stop_bit = stop_bit;
  1505 + mb_param->type_com = RTU;
  1506 + mb_param->error_recovery = FALSE;
  1507 + return modbus_set_slave(mb_param, slave);
1509 1508 }
1510 1509  
1511 1510 /* Initializes the modbus_param_t structure for TCP.
... ... @@ -1519,437 +1518,437 @@ int modbus_init_rtu(modbus_param_t *mb_param, const char *device,
1519 1518 */
1520 1519 int modbus_init_tcp(modbus_param_t *mb_param, const char *ip, int port)
1521 1520 {
1522   - memset(mb_param, 0, sizeof(modbus_param_t));
1523   - init_common(mb_param);
  1521 + memset(mb_param, 0, sizeof(modbus_param_t));
  1522 + init_common(mb_param);
1524 1523  
1525   - strncpy(mb_param->ip, ip, sizeof(char)*16);
1526   - mb_param->port = port;
1527   - mb_param->type_com = TCP;
1528   - mb_param->error_recovery = FALSE;
1529   - /* Can be changed after to reach remote serial Modbus device */
1530   - mb_param->slave = 0xFF;
  1524 + strncpy(mb_param->ip, ip, sizeof(char)*16);
  1525 + mb_param->port = port;
  1526 + mb_param->type_com = TCP;
  1527 + mb_param->error_recovery = FALSE;
  1528 + /* Can be changed after to reach remote serial Modbus device */
  1529 + mb_param->slave = 0xFF;
1531 1530  
1532   - return 0;
  1531 + return 0;
1533 1532 }
1534 1533  
1535 1534 /* Define the slave number, the special value MODBUS_TCP_SLAVE (0xFF) can be
1536 1535 * used in TCP mode to restore the default value. */
1537 1536 int modbus_set_slave(modbus_param_t *mb_param, int slave)
1538 1537 {
1539   - if (slave >= 1 && slave <= 247) {
1540   - mb_param->slave = slave;
1541   - } else if (mb_param->type_com == TCP && slave == MODBUS_TCP_SLAVE) {
1542   - mb_param->slave = slave;
1543   - } else {
1544   - errno = EINVAL;
1545   - return -1;
1546   - }
1547   -
1548   - return 0;
  1538 + if (slave >= 1 && slave <= 247) {
  1539 + mb_param->slave = slave;
  1540 + } else if (mb_param->type_com == TCP && slave == MODBUS_TCP_SLAVE) {
  1541 + mb_param->slave = slave;
  1542 + } else {
  1543 + errno = EINVAL;
  1544 + return -1;
  1545 + }
  1546 +
  1547 + return 0;
1549 1548 }
1550 1549  
1551 1550 /*
1552   - When disabled (default), it is expected that the application will check for
1553   - error returns and deal with them as necessary.
  1551 + When disabled (default), it is expected that the application will check for
  1552 + error returns and deal with them as necessary.
1554 1553  
1555   - It's not recommanded to enable error recovery for slave/server.
  1554 + It's not recommanded to enable error recovery for slave/server.
1556 1555  
1557   - When enabled, the library will attempt an immediate reconnection which may
1558   - hang for several seconds if the network to the remote target unit is down.
1559   - The write will try a infinite close/connect loop until to be successful and
1560   - the select/read calls will just try to retablish the connection one time then
1561   - will return an error (if the connecton was down, the values to read are
1562   - certainly not available anymore after reconnection, except for slave/server).
  1556 + When enabled, the library will attempt an immediate reconnection which may
  1557 + hang for several seconds if the network to the remote target unit is down.
  1558 + The write will try a infinite close/connect loop until to be successful and
  1559 + the select/read calls will just try to retablish the connection one time then
  1560 + will return an error (if the connecton was down, the values to read are
  1561 + certainly not available anymore after reconnection, except for slave/server).
1563 1562 */
1564 1563 int modbus_set_error_recovery(modbus_param_t *mb_param, int enabled)
1565 1564 {
1566   - if (enabled == TRUE || enabled == FALSE) {
1567   - mb_param->error_recovery = (uint8_t) enabled;
1568   - } else {
1569   - errno = EINVAL;
1570   - return -1;
1571   - }
1572   -
1573   - return 0;
  1565 + if (enabled == TRUE || enabled == FALSE) {
  1566 + mb_param->error_recovery = (uint8_t) enabled;
  1567 + } else {
  1568 + errno = EINVAL;
  1569 + return -1;
  1570 + }
  1571 +
  1572 + return 0;
1574 1573 }
1575 1574  
1576 1575 /* Get the timeout of begin of trame */
1577 1576 void modbus_get_timeout_begin(modbus_param_t *mb_param, struct timeval *timeout)
1578 1577 {
1579   - *timeout = mb_param->timeout_begin;
  1578 + *timeout = mb_param->timeout_begin;
1580 1579 }
1581 1580  
1582 1581 /* Set timeout when waiting the beginning of a trame */
1583 1582 void modbus_set_timeout_begin(modbus_param_t *mb_param, const struct timeval *timeout)
1584 1583 {
1585   - mb_param->timeout_begin = *timeout;
  1584 + mb_param->timeout_begin = *timeout;
1586 1585 }
1587 1586  
1588 1587 /* Get the timeout of end of trame */
1589 1588 void modbus_get_timeout_end(modbus_param_t *mb_param, struct timeval *timeout)
1590 1589 {
1591   - *timeout = mb_param->timeout_end;
  1590 + *timeout = mb_param->timeout_end;
1592 1591 }
1593 1592  
1594 1593 /* Set timeout when waiting the end of a trame */
1595 1594 void modbus_set_timeout_end(modbus_param_t *mb_param, const struct timeval *timeout)
1596 1595 {
1597   - mb_param->timeout_end = *timeout;
  1596 + mb_param->timeout_end = *timeout;
1598 1597 }
1599 1598  
1600 1599 /* Sets up a serial port for RTU communications */
1601 1600 static int modbus_connect_rtu(modbus_param_t *mb_param)
1602 1601 {
1603   - struct termios tios;
1604   - speed_t speed;
1605   -
  1602 + struct termios tios;
  1603 + speed_t speed;
  1604 +
  1605 + if (mb_param->debug) {
  1606 + printf("Opening %s at %d bauds (%c, %d, %d)\n",
  1607 + mb_param->device, mb_param->baud, mb_param->parity,
  1608 + mb_param->data_bit, mb_param->stop_bit);
  1609 + }
  1610 +
  1611 + /* The O_NOCTTY flag tells UNIX that this program doesn't want
  1612 + to be the "controlling terminal" for that port. If you
  1613 + don't specify this then any input (such as keyboard abort
  1614 + signals and so forth) will affect your process
  1615 +
  1616 + Timeouts are ignored in canonical input mode or when the
  1617 + NDELAY option is set on the file via open or fcntl */
  1618 + mb_param->fd = open(mb_param->device, O_RDWR | O_NOCTTY | O_NDELAY | O_EXCL);
  1619 + if (mb_param->fd == -1) {
  1620 + fprintf(stderr, "ERROR Can't open the device %s (%s)\n",
  1621 + mb_param->device, strerror(errno));
  1622 + return -1;
  1623 + }
  1624 +
  1625 + /* Save */
  1626 + tcgetattr(mb_param->fd, &(mb_param->old_tios));
  1627 +
  1628 + memset(&tios, 0, sizeof(struct termios));
  1629 +
  1630 + /* C_ISPEED Input baud (new interface)
  1631 + C_OSPEED Output baud (new interface)
  1632 + */
  1633 + switch (mb_param->baud) {
  1634 + case 110:
  1635 + speed = B110;
  1636 + break;
  1637 + case 300:
  1638 + speed = B300;
  1639 + break;
  1640 + case 600:
  1641 + speed = B600;
  1642 + break;
  1643 + case 1200:
  1644 + speed = B1200;
  1645 + break;
  1646 + case 2400:
  1647 + speed = B2400;
  1648 + break;
  1649 + case 4800:
  1650 + speed = B4800;
  1651 + break;
  1652 + case 9600:
  1653 + speed = B9600;
  1654 + break;
  1655 + case 19200:
  1656 + speed = B19200;
  1657 + break;
  1658 + case 38400:
  1659 + speed = B38400;
  1660 + break;
  1661 + case 57600:
  1662 + speed = B57600;
  1663 + break;
  1664 + case 115200:
  1665 + speed = B115200;
  1666 + break;
  1667 + default:
  1668 + speed = B9600;
1606 1669 if (mb_param->debug) {
1607   - printf("Opening %s at %d bauds (%c, %d, %d)\n",
1608   - mb_param->device, mb_param->baud, mb_param->parity,
1609   - mb_param->data_bit, mb_param->stop_bit);
1610   - }
1611   -
1612   - /* The O_NOCTTY flag tells UNIX that this program doesn't want
1613   - to be the "controlling terminal" for that port. If you
1614   - don't specify this then any input (such as keyboard abort
1615   - signals and so forth) will affect your process
1616   -
1617   - Timeouts are ignored in canonical input mode or when the
1618   - NDELAY option is set on the file via open or fcntl */
1619   - mb_param->fd = open(mb_param->device, O_RDWR | O_NOCTTY | O_NDELAY | O_EXCL);
1620   - if (mb_param->fd == -1) {
1621   - fprintf(stderr, "ERROR Can't open the device %s (%s)\n",
1622   - mb_param->device, strerror(errno));
1623   - return -1;
1624   - }
1625   -
1626   - /* Save */
1627   - tcgetattr(mb_param->fd, &(mb_param->old_tios));
1628   -
1629   - memset(&tios, 0, sizeof(struct termios));
1630   -
1631   - /* C_ISPEED Input baud (new interface)
1632   - C_OSPEED Output baud (new interface)
1633   - */
1634   - switch (mb_param->baud) {
1635   - case 110:
1636   - speed = B110;
1637   - break;
1638   - case 300:
1639   - speed = B300;
1640   - break;
1641   - case 600:
1642   - speed = B600;
1643   - break;
1644   - case 1200:
1645   - speed = B1200;
1646   - break;
1647   - case 2400:
1648   - speed = B2400;
1649   - break;
1650   - case 4800:
1651   - speed = B4800;
1652   - break;
1653   - case 9600:
1654   - speed = B9600;
1655   - break;
1656   - case 19200:
1657   - speed = B19200;
1658   - break;
1659   - case 38400:
1660   - speed = B38400;
1661   - break;
1662   - case 57600:
1663   - speed = B57600;
1664   - break;
1665   - case 115200:
1666   - speed = B115200;
1667   - break;
1668   - default:
1669   - speed = B9600;
1670   - if (mb_param->debug) {
1671   - fprintf(stderr,
1672   - "WARNING Unknown baud rate %d for %s (B9600 used)\n",
1673   - mb_param->baud, mb_param->device);
1674   - }
1675   - }
1676   -
1677   - /* Set the baud rate */
1678   - if ((cfsetispeed(&tios, speed) < 0) ||
1679   - (cfsetospeed(&tios, speed) < 0)) {
1680   - return -1;
1681   - }
1682   -
1683   - /* C_CFLAG Control options
1684   - CLOCAL Local line - do not change "owner" of port
1685   - CREAD Enable receiver
1686   - */
1687   - tios.c_cflag |= (CREAD | CLOCAL);
1688   - /* CSIZE, HUPCL, CRTSCTS (hardware flow control) */
1689   -
1690   - /* Set data bits (5, 6, 7, 8 bits)
1691   - CSIZE Bit mask for data bits
1692   - */
1693   - tios.c_cflag &= ~CSIZE;
1694   - switch (mb_param->data_bit) {
1695   - case 5:
1696   - tios.c_cflag |= CS5;
1697   - break;
1698   - case 6:
1699   - tios.c_cflag |= CS6;
1700   - break;
1701   - case 7:
1702   - tios.c_cflag |= CS7;
1703   - break;
1704   - case 8:
1705   - default:
1706   - tios.c_cflag |= CS8;
1707   - break;
1708   - }
1709   -
1710   - /* Stop bit (1 or 2) */
1711   - if (mb_param->stop_bit == 1)
1712   - tios.c_cflag &=~ CSTOPB;
1713   - else /* 2 */
1714   - tios.c_cflag |= CSTOPB;
1715   -
1716   - /* PARENB Enable parity bit
1717   - PARODD Use odd parity instead of even */
1718   - if (mb_param->parity == 'N') {
1719   - /* None */
1720   - tios.c_cflag &=~ PARENB;
1721   - } else if (mb_param->parity == 'E') {
1722   - /* Even */
1723   - tios.c_cflag |= PARENB;
1724   - tios.c_cflag &=~ PARODD;
1725   - } else {
1726   - /* Odd */
1727   - tios.c_cflag |= PARENB;
1728   - tios.c_cflag |= PARODD;
1729   - }
1730   -
1731   - /* Read the man page of termios if you need more information. */
1732   -
1733   - /* This field isn't used on POSIX systems
1734   - tios.c_line = 0;
1735   - */
1736   -
1737   - /* C_LFLAG Line options
1738   -
1739   - ISIG Enable SIGINTR, SIGSUSP, SIGDSUSP, and SIGQUIT signals
1740   - ICANON Enable canonical input (else raw)
1741   - XCASE Map uppercase \lowercase (obsolete)
1742   - ECHO Enable echoing of input characters
1743   - ECHOE Echo erase character as BS-SP-BS
1744   - ECHOK Echo NL after kill character
1745   - ECHONL Echo NL
1746   - NOFLSH Disable flushing of input buffers after
1747   - interrupt or quit characters
1748   - IEXTEN Enable extended functions
1749   - ECHOCTL Echo control characters as ^char and delete as ~?
1750   - ECHOPRT Echo erased character as character erased
1751   - ECHOKE BS-SP-BS entire line on line kill
1752   - FLUSHO Output being flushed
1753   - PENDIN Retype pending input at next read or input char
1754   - TOSTOP Send SIGTTOU for background output
1755   -
1756   - Canonical input is line-oriented. Input characters are put
1757   - into a buffer which can be edited interactively by the user
1758   - until a CR (carriage return) or LF (line feed) character is
1759   - received.
1760   -
1761   - Raw input is unprocessed. Input characters are passed
1762   - through exactly as they are received, when they are
1763   - received. Generally you'll deselect the ICANON, ECHO,
1764   - ECHOE, and ISIG options when using raw input
1765   - */
1766   -
1767   - /* Raw input */
1768   - tios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
1769   -
1770   - /* C_IFLAG Input options
1771   -
1772   - Constant Description
1773   - INPCK Enable parity check
1774   - IGNPAR Ignore parity errors
1775   - PARMRK Mark parity errors
1776   - ISTRIP Strip parity bits
1777   - IXON Enable software flow control (outgoing)
1778   - IXOFF Enable software flow control (incoming)
1779   - IXANY Allow any character to start flow again
1780   - IGNBRK Ignore break condition
1781   - BRKINT Send a SIGINT when a break condition is detected
1782   - INLCR Map NL to CR
1783   - IGNCR Ignore CR
1784   - ICRNL Map CR to NL
1785   - IUCLC Map uppercase to lowercase
1786   - IMAXBEL Echo BEL on input line too long
1787   - */
1788   - if (mb_param->parity == 'N') {
1789   - /* None */
1790   - tios.c_iflag &= ~INPCK;
1791   - } else {
1792   - tios.c_iflag |= INPCK;
1793   - }
1794   -
1795   - /* Software flow control is disabled */
1796   - tios.c_iflag &= ~(IXON | IXOFF | IXANY);
1797   -
1798   - /* C_OFLAG Output options
1799   - OPOST Postprocess output (not set = raw output)
1800   - ONLCR Map NL to CR-NL
1801   -
1802   - ONCLR ant others needs OPOST to be enabled
1803   - */
1804   -
1805   - /* Raw ouput */
1806   - tios.c_oflag &=~ OPOST;
1807   -
1808   - /* C_CC Control characters
1809   - VMIN Minimum number of characters to read
1810   - VTIME Time to wait for data (tenths of seconds)
1811   -
1812   - UNIX serial interface drivers provide the ability to
1813   - specify character and packet timeouts. Two elements of the
1814   - c_cc array are used for timeouts: VMIN and VTIME. Timeouts
1815   - are ignored in canonical input mode or when the NDELAY
1816   - option is set on the file via open or fcntl.
1817   -
1818   - VMIN specifies the minimum number of characters to read. If
1819   - it is set to 0, then the VTIME value specifies the time to
1820   - wait for every character read. Note that this does not mean
1821   - that a read call for N bytes will wait for N characters to
1822   - come in. Rather, the timeout will apply to the first
1823   - character and the read call will return the number of
1824   - characters immediately available (up to the number you
1825   - request).
1826   -
1827   - If VMIN is non-zero, VTIME specifies the time to wait for
1828   - the first character read. If a character is read within the
1829   - time given, any read will block (wait) until all VMIN
1830   - characters are read. That is, once the first character is
1831   - read, the serial interface driver expects to receive an
1832   - entire packet of characters (VMIN bytes total). If no
1833   - character is read within the time allowed, then the call to
1834   - read returns 0. This method allows you to tell the serial
1835   - driver you need exactly N bytes and any read call will
1836   - return 0 or N bytes. However, the timeout only applies to
1837   - the first character read, so if for some reason the driver
1838   - misses one character inside the N byte packet then the read
1839   - call could block forever waiting for additional input
1840   - characters.
1841   -
1842   - VTIME specifies the amount of time to wait for incoming
1843   - characters in tenths of seconds. If VTIME is set to 0 (the
1844   - default), reads will block (wait) indefinitely unless the
1845   - NDELAY option is set on the port with open or fcntl.
1846   - */
1847   - /* Unused because we use open with the NDELAY option */
1848   - tios.c_cc[VMIN] = 0;
1849   - tios.c_cc[VTIME] = 0;
1850   -
1851   - if (tcsetattr(mb_param->fd, TCSANOW, &tios) < 0) {
1852   - return -1;
1853   - }
1854   -
1855   - return 0;
  1670 + fprintf(stderr,
  1671 + "WARNING Unknown baud rate %d for %s (B9600 used)\n",
  1672 + mb_param->baud, mb_param->device);
  1673 + }
  1674 + }
  1675 +
  1676 + /* Set the baud rate */
  1677 + if ((cfsetispeed(&tios, speed) < 0) ||
  1678 + (cfsetospeed(&tios, speed) < 0)) {
  1679 + return -1;
  1680 + }
  1681 +
  1682 + /* C_CFLAG Control options
  1683 + CLOCAL Local line - do not change "owner" of port
  1684 + CREAD Enable receiver
  1685 + */
  1686 + tios.c_cflag |= (CREAD | CLOCAL);
  1687 + /* CSIZE, HUPCL, CRTSCTS (hardware flow control) */
  1688 +
  1689 + /* Set data bits (5, 6, 7, 8 bits)
  1690 + CSIZE Bit mask for data bits
  1691 + */
  1692 + tios.c_cflag &= ~CSIZE;
  1693 + switch (mb_param->data_bit) {
  1694 + case 5:
  1695 + tios.c_cflag |= CS5;
  1696 + break;
  1697 + case 6:
  1698 + tios.c_cflag |= CS6;
  1699 + break;
  1700 + case 7:
  1701 + tios.c_cflag |= CS7;
  1702 + break;
  1703 + case 8:
  1704 + default:
  1705 + tios.c_cflag |= CS8;
  1706 + break;
  1707 + }
  1708 +
  1709 + /* Stop bit (1 or 2) */
  1710 + if (mb_param->stop_bit == 1)
  1711 + tios.c_cflag &=~ CSTOPB;
  1712 + else /* 2 */
  1713 + tios.c_cflag |= CSTOPB;
  1714 +
  1715 + /* PARENB Enable parity bit
  1716 + PARODD Use odd parity instead of even */
  1717 + if (mb_param->parity == 'N') {
  1718 + /* None */
  1719 + tios.c_cflag &=~ PARENB;
  1720 + } else if (mb_param->parity == 'E') {
  1721 + /* Even */
  1722 + tios.c_cflag |= PARENB;
  1723 + tios.c_cflag &=~ PARODD;
  1724 + } else {
  1725 + /* Odd */
  1726 + tios.c_cflag |= PARENB;
  1727 + tios.c_cflag |= PARODD;
  1728 + }
  1729 +
  1730 + /* Read the man page of termios if you need more information. */
  1731 +
  1732 + /* This field isn't used on POSIX systems
  1733 + tios.c_line = 0;
  1734 + */
  1735 +
  1736 + /* C_LFLAG Line options
  1737 +
  1738 + ISIG Enable SIGINTR, SIGSUSP, SIGDSUSP, and SIGQUIT signals
  1739 + ICANON Enable canonical input (else raw)
  1740 + XCASE Map uppercase \lowercase (obsolete)
  1741 + ECHO Enable echoing of input characters
  1742 + ECHOE Echo erase character as BS-SP-BS
  1743 + ECHOK Echo NL after kill character
  1744 + ECHONL Echo NL
  1745 + NOFLSH Disable flushing of input buffers after
  1746 + interrupt or quit characters
  1747 + IEXTEN Enable extended functions
  1748 + ECHOCTL Echo control characters as ^char and delete as ~?
  1749 + ECHOPRT Echo erased character as character erased
  1750 + ECHOKE BS-SP-BS entire line on line kill
  1751 + FLUSHO Output being flushed
  1752 + PENDIN Retype pending input at next read or input char
  1753 + TOSTOP Send SIGTTOU for background output
  1754 +
  1755 + Canonical input is line-oriented. Input characters are put
  1756 + into a buffer which can be edited interactively by the user
  1757 + until a CR (carriage return) or LF (line feed) character is
  1758 + received.
  1759 +
  1760 + Raw input is unprocessed. Input characters are passed
  1761 + through exactly as they are received, when they are
  1762 + received. Generally you'll deselect the ICANON, ECHO,
  1763 + ECHOE, and ISIG options when using raw input
  1764 + */
  1765 +
  1766 + /* Raw input */
  1767 + tios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
  1768 +
  1769 + /* C_IFLAG Input options
  1770 +
  1771 + Constant Description
  1772 + INPCK Enable parity check
  1773 + IGNPAR Ignore parity errors
  1774 + PARMRK Mark parity errors
  1775 + ISTRIP Strip parity bits
  1776 + IXON Enable software flow control (outgoing)
  1777 + IXOFF Enable software flow control (incoming)
  1778 + IXANY Allow any character to start flow again
  1779 + IGNBRK Ignore break condition
  1780 + BRKINT Send a SIGINT when a break condition is detected
  1781 + INLCR Map NL to CR
  1782 + IGNCR Ignore CR
  1783 + ICRNL Map CR to NL
  1784 + IUCLC Map uppercase to lowercase
  1785 + IMAXBEL Echo BEL on input line too long
  1786 + */
  1787 + if (mb_param->parity == 'N') {
  1788 + /* None */
  1789 + tios.c_iflag &= ~INPCK;
  1790 + } else {
  1791 + tios.c_iflag |= INPCK;
  1792 + }
  1793 +
  1794 + /* Software flow control is disabled */
  1795 + tios.c_iflag &= ~(IXON | IXOFF | IXANY);
  1796 +
  1797 + /* C_OFLAG Output options
  1798 + OPOST Postprocess output (not set = raw output)
  1799 + ONLCR Map NL to CR-NL
  1800 +
  1801 + ONCLR ant others needs OPOST to be enabled
  1802 + */
  1803 +
  1804 + /* Raw ouput */
  1805 + tios.c_oflag &=~ OPOST;
  1806 +
  1807 + /* C_CC Control characters
  1808 + VMIN Minimum number of characters to read
  1809 + VTIME Time to wait for data (tenths of seconds)
  1810 +
  1811 + UNIX serial interface drivers provide the ability to
  1812 + specify character and packet timeouts. Two elements of the
  1813 + c_cc array are used for timeouts: VMIN and VTIME. Timeouts
  1814 + are ignored in canonical input mode or when the NDELAY
  1815 + option is set on the file via open or fcntl.
  1816 +
  1817 + VMIN specifies the minimum number of characters to read. If
  1818 + it is set to 0, then the VTIME value specifies the time to
  1819 + wait for every character read. Note that this does not mean
  1820 + that a read call for N bytes will wait for N characters to
  1821 + come in. Rather, the timeout will apply to the first
  1822 + character and the read call will return the number of
  1823 + characters immediately available (up to the number you
  1824 + request).
  1825 +
  1826 + If VMIN is non-zero, VTIME specifies the time to wait for
  1827 + the first character read. If a character is read within the
  1828 + time given, any read will block (wait) until all VMIN
  1829 + characters are read. That is, once the first character is
  1830 + read, the serial interface driver expects to receive an
  1831 + entire packet of characters (VMIN bytes total). If no
  1832 + character is read within the time allowed, then the call to
  1833 + read returns 0. This method allows you to tell the serial
  1834 + driver you need exactly N bytes and any read call will
  1835 + return 0 or N bytes. However, the timeout only applies to
  1836 + the first character read, so if for some reason the driver
  1837 + misses one character inside the N byte packet then the read
  1838 + call could block forever waiting for additional input
  1839 + characters.
  1840 +
  1841 + VTIME specifies the amount of time to wait for incoming
  1842 + characters in tenths of seconds. If VTIME is set to 0 (the
  1843 + default), reads will block (wait) indefinitely unless the
  1844 + NDELAY option is set on the port with open or fcntl.
  1845 + */
  1846 + /* Unused because we use open with the NDELAY option */
  1847 + tios.c_cc[VMIN] = 0;
  1848 + tios.c_cc[VTIME] = 0;
  1849 +
  1850 + if (tcsetattr(mb_param->fd, TCSANOW, &tios) < 0) {
  1851 + return -1;
  1852 + }
  1853 +
  1854 + return 0;
1856 1855 }
1857 1856  
1858 1857 /* Establishes a modbus TCP connection with a modbus slave */
1859 1858 static int modbus_connect_tcp(modbus_param_t *mb_param)
1860 1859 {
1861   - int rc;
1862   - int option;
1863   - struct sockaddr_in addr;
1864   -
1865   - mb_param->fd = socket(PF_INET, SOCK_STREAM, 0);
1866   - if (mb_param->fd == -1) {
1867   - return -1;
1868   - }
1869   -
1870   - /* Set the TCP no delay flag */
1871   - /* SOL_TCP = IPPROTO_TCP */
1872   - option = 1;
1873   - rc = setsockopt(mb_param->fd, IPPROTO_TCP, TCP_NODELAY,
1874   - (const void *)&option, sizeof(int));
1875   - if (rc == -1) {
1876   - close(mb_param->fd);
1877   - return -1;
1878   - }
  1860 + int rc;
  1861 + int option;
  1862 + struct sockaddr_in addr;
  1863 +
  1864 + mb_param->fd = socket(PF_INET, SOCK_STREAM, 0);
  1865 + if (mb_param->fd == -1) {
  1866 + return -1;
  1867 + }
  1868 +
  1869 + /* Set the TCP no delay flag */
  1870 + /* SOL_TCP = IPPROTO_TCP */
  1871 + option = 1;
  1872 + rc = setsockopt(mb_param->fd, IPPROTO_TCP, TCP_NODELAY,
  1873 + (const void *)&option, sizeof(int));
  1874 + if (rc == -1) {
  1875 + close(mb_param->fd);
  1876 + return -1;
  1877 + }
1879 1878  
1880 1879 #if (!HAVE_DECL___CYGWIN__)
1881   - /**
1882   - * Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's
1883   - * necessary to workaround that problem.
1884   - **/
1885   - /* Set the IP low delay option */
1886   - option = IPTOS_LOWDELAY;
1887   - rc = setsockopt(mb_param->fd, IPPROTO_IP, IP_TOS,
1888   - (const void *)&option, sizeof(int));
1889   - if (rc == -1) {
1890   - close(mb_param->fd);
1891   - return -1;
1892   - }
  1880 + /**
  1881 + * Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's
  1882 + * necessary to workaround that problem.
  1883 + **/
  1884 + /* Set the IP low delay option */
  1885 + option = IPTOS_LOWDELAY;
  1886 + rc = setsockopt(mb_param->fd, IPPROTO_IP, IP_TOS,
  1887 + (const void *)&option, sizeof(int));
  1888 + if (rc == -1) {
  1889 + close(mb_param->fd);
  1890 + return -1;
  1891 + }
1893 1892 #endif
1894 1893  
1895   - if (mb_param->debug) {
1896   - printf("Connecting to %s\n", mb_param->ip);
1897   - }
  1894 + if (mb_param->debug) {
  1895 + printf("Connecting to %s\n", mb_param->ip);
  1896 + }
1898 1897  
1899   - addr.sin_family = AF_INET;
1900   - addr.sin_port = htons(mb_param->port);
1901   - addr.sin_addr.s_addr = inet_addr(mb_param->ip);
1902   - rc = connect(mb_param->fd, (struct sockaddr *)&addr,
1903   - sizeof(struct sockaddr_in));
1904   - if (rc == -1) {
1905   - close(mb_param->fd);
1906   - return -1;
1907   - }
  1898 + addr.sin_family = AF_INET;
  1899 + addr.sin_port = htons(mb_param->port);
  1900 + addr.sin_addr.s_addr = inet_addr(mb_param->ip);
  1901 + rc = connect(mb_param->fd, (struct sockaddr *)&addr,
  1902 + sizeof(struct sockaddr_in));
  1903 + if (rc == -1) {
  1904 + close(mb_param->fd);
  1905 + return -1;
  1906 + }
1908 1907  
1909   - return 0;
  1908 + return 0;
1910 1909 }
1911 1910  
1912 1911 /* Establishes a modbus connexion.
1913 1912 Returns 0 on success or -1 on failure. */
1914 1913 int modbus_connect(modbus_param_t *mb_param)
1915 1914 {
1916   - int rc;
  1915 + int rc;
1917 1916  
1918   - if (mb_param->type_com == RTU)
1919   - rc = modbus_connect_rtu(mb_param);
1920   - else
1921   - rc = modbus_connect_tcp(mb_param);
  1917 + if (mb_param->type_com == RTU)
  1918 + rc = modbus_connect_rtu(mb_param);
  1919 + else
  1920 + rc = modbus_connect_tcp(mb_param);
1922 1921  
1923   - return rc;
  1922 + return rc;
1924 1923 }
1925 1924  
1926 1925 /* Closes the file descriptor in RTU mode */
1927 1926 static void modbus_close_rtu(modbus_param_t *mb_param)
1928 1927 {
1929   - tcsetattr(mb_param->fd, TCSANOW, &(mb_param->old_tios));
1930   - close(mb_param->fd);
  1928 + tcsetattr(mb_param->fd, TCSANOW, &(mb_param->old_tios));
  1929 + close(mb_param->fd);
1931 1930 }
1932 1931  
1933 1932 /* Closes the network connection and socket in TCP mode */
1934 1933 static void modbus_close_tcp(modbus_param_t *mb_param)
1935 1934 {
1936   - shutdown(mb_param->fd, SHUT_RDWR);
1937   - close(mb_param->fd);
  1935 + shutdown(mb_param->fd, SHUT_RDWR);
  1936 + close(mb_param->fd);
1938 1937 }
1939 1938  
1940 1939 /* Closes a modbus connection */
1941 1940 void modbus_close(modbus_param_t *mb_param)
1942 1941 {
1943   - if (mb_param->type_com == RTU)
1944   - modbus_close_rtu(mb_param);
1945   - else
1946   - modbus_close_tcp(mb_param);
  1942 + if (mb_param->type_com == RTU)
  1943 + modbus_close_rtu(mb_param);
  1944 + else
  1945 + modbus_close_tcp(mb_param);
1947 1946 }
1948 1947  
1949 1948 /* Activates the debug messages */
1950 1949 void modbus_set_debug(modbus_param_t *mb_param, int boolean)
1951 1950 {
1952   - mb_param->debug = boolean;
  1951 + mb_param->debug = boolean;
1953 1952 }
1954 1953  
1955 1954 /* Allocates 4 arrays to store coils, input status, input registers and
... ... @@ -1962,103 +1961,103 @@ int modbus_mapping_new(modbus_mapping_t *mb_mapping,
1962 1961 int nb_coil_status, int nb_input_status,
1963 1962 int nb_holding_registers, int nb_input_registers)
1964 1963 {
1965   - /* 0X */
1966   - mb_mapping->nb_coil_status = nb_coil_status;
1967   - mb_mapping->tab_coil_status =
1968   - (uint8_t *) malloc(nb_coil_status * sizeof(uint8_t));
1969   - if (mb_mapping->tab_coil_status == NULL) {
1970   - errno = ENOMEM;
1971   - return -1;
1972   - }
1973   - memset(mb_mapping->tab_coil_status, 0,
1974   - nb_coil_status * sizeof(uint8_t));
1975   -
1976   - /* 1X */
1977   - mb_mapping->nb_input_status = nb_input_status;
1978   - mb_mapping->tab_input_status =
1979   - (uint8_t *) malloc(nb_input_status * sizeof(uint8_t));
1980   - if (mb_mapping->tab_input_status == NULL) {
1981   - free(mb_mapping->tab_coil_status);
1982   - errno = ENOMEM;
1983   - return -1;
1984   - }
1985   - memset(mb_mapping->tab_input_status, 0,
1986   - nb_input_status * sizeof(uint8_t));
1987   -
1988   - /* 4X */
1989   - mb_mapping->nb_holding_registers = nb_holding_registers;
1990   - mb_mapping->tab_holding_registers =
1991   - (uint16_t *) malloc(nb_holding_registers * sizeof(uint16_t));
1992   - if (mb_mapping->tab_holding_registers == NULL) {
1993   - free(mb_mapping->tab_coil_status);
1994   - free(mb_mapping->tab_input_status);
1995   - errno = ENOMEM;
1996   - return -1;
1997   - }
1998   - memset(mb_mapping->tab_holding_registers, 0,
1999   - nb_holding_registers * sizeof(uint16_t));
2000   -
2001   - /* 3X */
2002   - mb_mapping->nb_input_registers = nb_input_registers;
2003   - mb_mapping->tab_input_registers =
2004   - (uint16_t *) malloc(nb_input_registers * sizeof(uint16_t));
2005   - if (mb_mapping->tab_input_registers == NULL) {
2006   - free(mb_mapping->tab_coil_status);
2007   - free(mb_mapping->tab_input_status);
2008   - free(mb_mapping->tab_holding_registers);
2009   - errno = ENOMEM;
2010   - return -1;
2011   - }
2012   - memset(mb_mapping->tab_input_registers, 0,
2013   - nb_input_registers * sizeof(uint16_t));
  1964 + /* 0X */
  1965 + mb_mapping->nb_coil_status = nb_coil_status;
  1966 + mb_mapping->tab_coil_status =
  1967 + (uint8_t *) malloc(nb_coil_status * sizeof(uint8_t));
  1968 + if (mb_mapping->tab_coil_status == NULL) {
  1969 + errno = ENOMEM;
  1970 + return -1;
  1971 + }
  1972 + memset(mb_mapping->tab_coil_status, 0,
  1973 + nb_coil_status * sizeof(uint8_t));
  1974 +
  1975 + /* 1X */
  1976 + mb_mapping->nb_input_status = nb_input_status;
  1977 + mb_mapping->tab_input_status =
  1978 + (uint8_t *) malloc(nb_input_status * sizeof(uint8_t));
  1979 + if (mb_mapping->tab_input_status == NULL) {
  1980 + free(mb_mapping->tab_coil_status);
  1981 + errno = ENOMEM;
  1982 + return -1;
  1983 + }
  1984 + memset(mb_mapping->tab_input_status, 0,
  1985 + nb_input_status * sizeof(uint8_t));
  1986 +
  1987 + /* 4X */
  1988 + mb_mapping->nb_holding_registers = nb_holding_registers;
  1989 + mb_mapping->tab_holding_registers =
  1990 + (uint16_t *) malloc(nb_holding_registers * sizeof(uint16_t));
  1991 + if (mb_mapping->tab_holding_registers == NULL) {
  1992 + free(mb_mapping->tab_coil_status);
  1993 + free(mb_mapping->tab_input_status);
  1994 + errno = ENOMEM;
  1995 + return -1;
  1996 + }
  1997 + memset(mb_mapping->tab_holding_registers, 0,
  1998 + nb_holding_registers * sizeof(uint16_t));
  1999 +
  2000 + /* 3X */
  2001 + mb_mapping->nb_input_registers = nb_input_registers;
  2002 + mb_mapping->tab_input_registers =
  2003 + (uint16_t *) malloc(nb_input_registers * sizeof(uint16_t));
  2004 + if (mb_mapping->tab_input_registers == NULL) {
  2005 + free(mb_mapping->tab_coil_status);
  2006 + free(mb_mapping->tab_input_status);
  2007 + free(mb_mapping->tab_holding_registers);
  2008 + errno = ENOMEM;
  2009 + return -1;
  2010 + }
  2011 + memset(mb_mapping->tab_input_registers, 0,
  2012 + nb_input_registers * sizeof(uint16_t));
2014 2013  
2015   - return 0;
  2014 + return 0;
2016 2015 }
2017 2016  
2018 2017 /* Frees the 4 arrays */
2019 2018 void modbus_mapping_free(modbus_mapping_t *mb_mapping)
2020 2019 {
2021   - free(mb_mapping->tab_coil_status);
2022   - free(mb_mapping->tab_input_status);
2023   - free(mb_mapping->tab_holding_registers);
2024   - free(mb_mapping->tab_input_registers);
  2020 + free(mb_mapping->tab_coil_status);
  2021 + free(mb_mapping->tab_input_status);
  2022 + free(mb_mapping->tab_holding_registers);
  2023 + free(mb_mapping->tab_input_registers);
2025 2024 }
2026 2025  
2027 2026 /* Listens for any query from one or many modbus masters in TCP */
2028 2027 int modbus_slave_listen_tcp(modbus_param_t *mb_param, int nb_connection)
2029 2028 {
2030   - int new_socket;
2031   - int yes;
2032   - struct sockaddr_in addr;
2033   -
2034   - new_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
2035   - if (new_socket == -1) {
2036   - return -1;
2037   - }
2038   -
2039   - yes = 1;
2040   - if (setsockopt(new_socket, SOL_SOCKET, SO_REUSEADDR,
2041   - (char *) &yes, sizeof(yes)) == -1) {
2042   - close(new_socket);
2043   - return -1;
2044   - }
2045   -
2046   - memset(&addr, 0, sizeof(addr));
2047   - addr.sin_family = AF_INET;
2048   - /* If the modbus port is < to 1024, we need the setuid root. */
2049   - addr.sin_port = htons(mb_param->port);
2050   - addr.sin_addr.s_addr = INADDR_ANY;
2051   - if (bind(new_socket, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
2052   - close(new_socket);
2053   - return -1;
2054   - }
2055   -
2056   - if (listen(new_socket, nb_connection) == -1) {
2057   - close(new_socket);
2058   - return -1;
2059   - }
2060   -
2061   - return new_socket;
  2029 + int new_socket;
  2030 + int yes;
  2031 + struct sockaddr_in addr;
  2032 +
  2033 + new_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  2034 + if (new_socket == -1) {
  2035 + return -1;
  2036 + }
  2037 +
  2038 + yes = 1;
  2039 + if (setsockopt(new_socket, SOL_SOCKET, SO_REUSEADDR,
  2040 + (char *) &yes, sizeof(yes)) == -1) {
  2041 + close(new_socket);
  2042 + return -1;
  2043 + }
  2044 +
  2045 + memset(&addr, 0, sizeof(addr));
  2046 + addr.sin_family = AF_INET;
  2047 + /* If the modbus port is < to 1024, we need the setuid root. */
  2048 + addr.sin_port = htons(mb_param->port);
  2049 + addr.sin_addr.s_addr = INADDR_ANY;
  2050 + if (bind(new_socket, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
  2051 + close(new_socket);
  2052 + return -1;
  2053 + }
  2054 +
  2055 + if (listen(new_socket, nb_connection) == -1) {
  2056 + close(new_socket);
  2057 + return -1;
  2058 + }
  2059 +
  2060 + return new_socket;
2062 2061 }
2063 2062  
2064 2063 /* On success, the function return a non-negative integer that is a descriptor
... ... @@ -2066,30 +2065,30 @@ int modbus_slave_listen_tcp(modbus_param_t *mb_param, int nb_connection)
2066 2065 appropriately. */
2067 2066 int modbus_slave_accept_tcp(modbus_param_t *mb_param, int *socket)
2068 2067 {
2069   - struct sockaddr_in addr;
2070   - socklen_t addrlen;
2071   -
2072   - addrlen = sizeof(struct sockaddr_in);
2073   - mb_param->fd = accept(*socket, (struct sockaddr *)&addr, &addrlen);
2074   - if (mb_param->fd == -1) {
2075   - close(*socket);
2076   - *socket = 0;
2077   - return -1;
2078   - }
2079   -
2080   - if (mb_param->debug) {
2081   - printf("The client %s is connected\n",
2082   - inet_ntoa(addr.sin_addr));
2083   - }
2084   -
2085   - return mb_param->fd;
  2068 + struct sockaddr_in addr;
  2069 + socklen_t addrlen;
  2070 +
  2071 + addrlen = sizeof(struct sockaddr_in);
  2072 + mb_param->fd = accept(*socket, (struct sockaddr *)&addr, &addrlen);
  2073 + if (mb_param->fd == -1) {
  2074 + close(*socket);
  2075 + *socket = 0;
  2076 + return -1;
  2077 + }
  2078 +
  2079 + if (mb_param->debug) {
  2080 + printf("The client %s is connected\n",
  2081 + inet_ntoa(addr.sin_addr));
  2082 + }
  2083 +
  2084 + return mb_param->fd;
2086 2085 }
2087 2086  
2088 2087 /* Closes a TCP socket */
2089 2088 void modbus_slave_close_tcp(int socket)
2090 2089 {
2091   - shutdown(socket, SHUT_RDWR);
2092   - close(socket);
  2090 + shutdown(socket, SHUT_RDWR);
  2091 + close(socket);
2093 2092 }
2094 2093  
2095 2094 /** Utils **/
... ... @@ -2098,11 +2097,11 @@ void modbus_slave_close_tcp(int socket)
2098 2097 the byte value are set) */
2099 2098 void set_bits_from_byte(uint8_t *dest, int address, const uint8_t value)
2100 2099 {
2101   - int i;
  2100 + int i;
2102 2101  
2103   - for (i=0; i<8; i++) {
2104   - dest[address+i] = (value & (1 << i)) ? ON : OFF;
2105   - }
  2102 + for (i=0; i<8; i++) {
  2103 + dest[address+i] = (value & (1 << i)) ? ON : OFF;
  2104 + }
2106 2105 }
2107 2106  
2108 2107 /* Sets many input/coil status from a table of bytes (only the bits
... ... @@ -2110,53 +2109,53 @@ void set_bits_from_byte(uint8_t *dest, int address, const uint8_t value)
2110 2109 void set_bits_from_bytes(uint8_t *dest, int address, unsigned int nb_bits,
2111 2110 const uint8_t tab_byte[])
2112 2111 {
2113   - int i;
2114   - int shift = 0;
2115   -
2116   - for (i = address; i < address + nb_bits; i++) {
2117   - dest[i] = tab_byte[(i - address) / 8] & (1 << shift) ? ON : OFF;
2118   - /* gcc doesn't like: shift = (++shift) % 8; */
2119   - shift++;
2120   - shift %= 8;
2121   - }
  2112 + int i;
  2113 + int shift = 0;
  2114 +
  2115 + for (i = address; i < address + nb_bits; i++) {
  2116 + dest[i] = tab_byte[(i - address) / 8] & (1 << shift) ? ON : OFF;
  2117 + /* gcc doesn't like: shift = (++shift) % 8; */
  2118 + shift++;
  2119 + shift %= 8;
  2120 + }
2122 2121 }
2123 2122  
2124 2123 /* Gets the byte value from many input/coil status.
2125 2124 To obtain a full byte, set nb_bits to 8. */
2126 2125 uint8_t get_byte_from_bits(const uint8_t *src, int address, unsigned int nb_bits)
2127 2126 {
2128   - int i;
2129   - uint8_t value = 0;
  2127 + int i;
  2128 + uint8_t value = 0;
2130 2129  
2131   - if (nb_bits > 8) {
2132   - assert(nb_bits < 8);
2133   - nb_bits = 8;
2134   - }
  2130 + if (nb_bits > 8) {
  2131 + assert(nb_bits < 8);
  2132 + nb_bits = 8;
  2133 + }
2135 2134  
2136   - for (i=0; i < nb_bits; i++) {
2137   - value |= (src[address+i] << i);
2138   - }
  2135 + for (i=0; i < nb_bits; i++) {
  2136 + value |= (src[address+i] << i);
  2137 + }
2139 2138  
2140   - return value;
  2139 + return value;
2141 2140 }
2142 2141  
2143 2142 /* Read a float from 4 bytes in Modbus format */
2144 2143 float modbus_read_float(const uint16_t *src)
2145 2144 {
2146   - float r = 0.0f;
2147   - uint32_t i;
  2145 + float r = 0.0f;
  2146 + uint32_t i;
2148 2147  
2149   - i = (((uint32_t)src[1]) << 16) + src[0];
2150   - memcpy(&r, &i, sizeof (r));
2151   - return r;
  2148 + i = (((uint32_t)src[1]) << 16) + src[0];
  2149 + memcpy(&r, &i, sizeof (r));
  2150 + return r;
2152 2151 }
2153 2152  
2154 2153 /* Write a float to 4 bytes in Modbus format */
2155 2154 void modbus_write_float(float real, uint16_t *dest)
2156 2155 {
2157   - uint32_t i = 0;
  2156 + uint32_t i = 0;
2158 2157  
2159   - memcpy(&i, &real, sizeof (i));
2160   - dest[0] = (uint16_t)i;
2161   - dest[1] = (uint16_t)(i >> 16);
  2158 + memcpy(&i, &real, sizeof (i));
  2159 + dest[0] = (uint16_t)i;
  2160 + dest[1] = (uint16_t)(i >> 16);
2162 2161 }
... ...
src/modbus.h.in
... ... @@ -59,7 +59,7 @@ extern &quot;C&quot; {
59 59 * Maximum between :
60 60 * - HEADER_LENGTH_TCP (7) + function (1) + address (2) + number (2)
61 61 * - HEADER_LENGTH_RTU (1) + function (1) + address (2) + number (2) + CRC (2)
62   -*/
  62 + */
63 63 #define MIN_QUERY_LENGTH 12
64 64  
65 65 /* Modbus_Application_Protocol_V1_1b.pdf Chapter 4 Section 1 Page 5:
... ... @@ -123,20 +123,20 @@ extern &quot;C&quot; {
123 123 #define MODBUS_ENOBASE 112345678
124 124  
125 125 /* Protocol exceptions */
126   -enum {
127   - MODBUS_EXCEPTION_ILLEGAL_FUNCTION = 0x01,
128   - MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
129   - MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
130   - MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE,
131   - MODBUS_EXCEPTION_ACKNOWLEDGE,
132   - MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY,
133   - MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE,
134   - MODBUS_EXCEPTION_MEMORY_PARITY,
135   - MODBUS_EXCEPTION_NOT_DEFINED,
136   - MODBUS_EXCEPTION_GATEWAY_PATH,
137   - MODBUS_EXCEPTION_GATEWAY_TARGET,
138   - MODBUS_EXCEPTION_MAX
139   -};
  126 +typedef enum {
  127 + MODBUS_EXCEPTION_ILLEGAL_FUNCTION = 0x01,
  128 + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
  129 + MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
  130 + MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE,
  131 + MODBUS_EXCEPTION_ACKNOWLEDGE,
  132 + MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY,
  133 + MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE,
  134 + MODBUS_EXCEPTION_MEMORY_PARITY,
  135 + MODBUS_EXCEPTION_NOT_DEFINED,
  136 + MODBUS_EXCEPTION_GATEWAY_PATH,
  137 + MODBUS_EXCEPTION_GATEWAY_TARGET,
  138 + MODBUS_EXCEPTION_MAX
  139 +} modbus_exception_t;
140 140  
141 141 #define EMBXILFUN (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_FUNCTION)
142 142 #define EMBXILADD (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS)
... ... @@ -177,20 +177,20 @@ enum {
177 177 #define LIBMODBUS_VERSION_STRING "@LIBMODBUS_VERSION@"
178 178  
179 179 /* Numerically encoded version libmb, like 0x010203 */
180   -#define LIBMODBUS_VERSION_HEX ((LIBMODBUS_MAJOR_VERSION << 24) | \
181   - (LIBMODBUS_MINOR_VERSION << 16) | \
  180 +#define LIBMODBUS_VERSION_HEX ((LIBMODBUS_MAJOR_VERSION << 24) | \
  181 + (LIBMODBUS_MINOR_VERSION << 16) | \
182 182 (LIBMODBUS_MICRO_VERSION << 8))
183 183  
184 184 /* Evaluates to True if the version of libmb is greater than @major, @minor and
185 185 * @micro
186 186 */
187   -#define LIBMODBUS_VERSION_CHECK(major,minor,micro) \
188   - (LIBMODBUS_VERSION_MAJOR > (major) || \
189   - (LIBMODBUS_VERSION_MAJOR == (major) && \
190   - LIBMODBUS_VERSION_MINOR > (minor)) || \
191   - (LIBMODBUS_VERSION_MAJOR == (major) && \
192   - LIBMODBUS_VERSION_MINOR == (minor) && \
193   - LIBMODBUS_VERSION_MICRO >= (micro)))
  187 +#define LIBMODBUS_VERSION_CHECK(major,minor,micro) \
  188 + (LIBMODBUS_VERSION_MAJOR > (major) || \
  189 + (LIBMODBUS_VERSION_MAJOR == (major) && \
  190 + LIBMODBUS_VERSION_MINOR > (minor)) || \
  191 + (LIBMODBUS_VERSION_MAJOR == (major) && \
  192 + LIBMODBUS_VERSION_MINOR == (minor) && \
  193 + LIBMODBUS_VERSION_MICRO >= (micro)))
194 194  
195 195 extern const unsigned int libmodbus_version_major;
196 196 extern const unsigned int libmodbus_version_minor;
... ... @@ -200,54 +200,53 @@ typedef enum { RTU=0, TCP } type_com_t;
200 200  
201 201 /* This structure is byte-aligned */
202 202 typedef struct {
203   - /* Slave address */
204   - int slave;
205   - /* Descriptor (tty or socket) */
206   - int fd;
207   - /* Communication mode: RTU or TCP */
208   - type_com_t type_com;
209   - /* Flag debug */
210   - int debug;
211   - /* TCP port */
212   - int port;
213   - /* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*"
214   - on Mac OS X for KeySpan USB<->Serial adapters this string
215   - had to be made bigger on OS X as the directory+file name
216   - was bigger than 19 bytes. Making it 67 bytes for now, but
217   - OS X does support 256 byte file names. May become a problem
218   - in the future. */
  203 + /* Slave address */
  204 + int slave;
  205 + /* Descriptor (tty or socket) */
  206 + int fd;
  207 + /* Communication mode: RTU or TCP */
  208 + type_com_t type_com;
  209 + /* Flag debug */
  210 + int debug;
  211 + /* TCP port */
  212 + int port;
  213 + /* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*" on Mac OS X for
  214 + KeySpan USB<->Serial adapters this string had to be made bigger on OS X
  215 + as the directory+file name was bigger than 19 bytes. Making it 67 bytes
  216 + for now, but OS X does support 256 byte file names. May become a problem
  217 + in the future. */
219 218 #ifdef __APPLE_CC__
220   - char device[64];
  219 + char device[64];
221 220 #else
222   - char device[16];
  221 + char device[16];
223 222 #endif
224   - /* Bauds: 9600, 19200, 57600, 115200, etc */
225   - int baud;
226   - /* Data bit */
227   - uint8_t data_bit;
228   - /* Stop bit */
229   - uint8_t stop_bit;
230   - /* Parity: 'N', 'O', 'E' */
231   - char parity;
232   - /* In error_treat with TCP, do a reconnect or just dump the error */
233   - uint8_t error_recovery;
  223 + /* Bauds: 9600, 19200, 57600, 115200, etc */
  224 + int baud;
  225 + /* Data bit */
  226 + uint8_t data_bit;
  227 + /* Stop bit */
  228 + uint8_t stop_bit;
  229 + /* Parity: 'N', 'O', 'E' */
  230 + char parity;
  231 + /* In error_treat with TCP, do a reconnect or just dump the error */
  232 + uint8_t error_recovery;
234 233 /* IP address */
235   - char ip[16];
236   - /* Save old termios settings */
237   - struct termios old_tios;
238   - struct timeval timeout_begin;
239   - struct timeval timeout_end;
  234 + char ip[16];
  235 + /* Save old termios settings */
  236 + struct termios old_tios;
  237 + struct timeval timeout_begin;
  238 + struct timeval timeout_end;
240 239 } modbus_param_t;
241 240  
242 241 typedef struct {
243   - int nb_coil_status;
244   - int nb_input_status;
245   - int nb_input_registers;
246   - int nb_holding_registers;
247   - uint8_t *tab_coil_status;
248   - uint8_t *tab_input_status;
249   - uint16_t *tab_input_registers;
250   - uint16_t *tab_holding_registers;
  242 + int nb_coil_status;
  243 + int nb_input_status;
  244 + int nb_input_registers;
  245 + int nb_holding_registers;
  246 + uint8_t *tab_coil_status;
  247 + uint8_t *tab_input_status;
  248 + uint16_t *tab_input_registers;
  249 + uint16_t *tab_holding_registers;
251 250 } modbus_mapping_t;
252 251  
253 252 int modbus_init_rtu(modbus_param_t *mb_param, const char *device,
... ...
tests/bandwidth-master.c
... ... @@ -33,123 +33,123 @@
33 33  
34 34 uint32_t gettime_ms(void)
35 35 {
36   - struct timeval tv;
37   - gettimeofday (&tv, NULL);
  36 + struct timeval tv;
  37 + gettimeofday (&tv, NULL);
38 38  
39   - return (uint32_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
  39 + return (uint32_t) tv.tv_sec * 1000 + tv.tv_usec / 1000;
40 40 }
41 41  
42 42 int main(void)
43 43 {
44   - uint8_t *tab_rp_status;
45   - uint16_t *tab_rp_registers;
46   - modbus_param_t mb_param;
47   - int i;
48   - int nb_points;
49   - double elapsed;
50   - uint32_t start;
51   - uint32_t end;
52   - uint32_t bytes;
53   - uint32_t rate;
54   - int rc;
55   -
56   - /* TCP */
57   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
58   - rc = modbus_connect(&mb_param);
  44 + uint8_t *tab_rp_status;
  45 + uint16_t *tab_rp_registers;
  46 + modbus_param_t mb_param;
  47 + int i;
  48 + int nb_points;
  49 + double elapsed;
  50 + uint32_t start;
  51 + uint32_t end;
  52 + uint32_t bytes;
  53 + uint32_t rate;
  54 + int rc;
  55 +
  56 + /* TCP */
  57 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
  58 + rc = modbus_connect(&mb_param);
  59 + if (rc == -1) {
  60 + fprintf(stderr, "Connexion failed: %s\n",
  61 + modbus_strerror(errno));
  62 + return -1;
  63 + }
  64 +
  65 + /* Allocate and initialize the memory to store the status */
  66 + tab_rp_status = (uint8_t *) malloc(MAX_STATUS * sizeof(uint8_t));
  67 + memset(tab_rp_status, 0, MAX_STATUS * sizeof(uint8_t));
  68 +
  69 + /* Allocate and initialize the memory to store the registers */
  70 + tab_rp_registers = (uint16_t *) malloc(MAX_REGISTERS * sizeof(uint16_t));
  71 + memset(tab_rp_registers, 0, MAX_REGISTERS * sizeof(uint16_t));
  72 +
  73 + printf("READ COIL STATUS\n\n");
  74 +
  75 + nb_points = MAX_STATUS;
  76 + start = gettime_ms();
  77 + for (i=0; i<NB_LOOPS; i++) {
  78 + rc = read_coil_status(&mb_param, SERVER_ID, 0, nb_points, tab_rp_status);
59 79 if (rc == -1) {
60   - fprintf(stderr, "Connexion failed: %s\n",
61   - modbus_strerror(errno));
62   - return -1;
  80 + fprintf(stderr, "%s\n", modbus_strerror(errno));
  81 + return -1;
63 82 }
64   -
65   - /* Allocate and initialize the memory to store the status */
66   - tab_rp_status = (uint8_t *) malloc(MAX_STATUS * sizeof(uint8_t));
67   - memset(tab_rp_status, 0, MAX_STATUS * sizeof(uint8_t));
68   -
69   - /* Allocate and initialize the memory to store the registers */
70   - tab_rp_registers = (uint16_t *) malloc(MAX_REGISTERS * sizeof(uint16_t));
71   - memset(tab_rp_registers, 0, MAX_REGISTERS * sizeof(uint16_t));
72   -
73   - printf("READ COIL STATUS\n\n");
74   -
75   - nb_points = MAX_STATUS;
76   - start = gettime_ms();
77   - for (i=0; i<NB_LOOPS; i++) {
78   - rc = read_coil_status(&mb_param, SERVER_ID, 0, nb_points, tab_rp_status);
79   - if (rc == -1) {
80   - fprintf(stderr, "%s\n", modbus_strerror(errno));
81   - return -1;
82   - }
83   - }
84   - end = gettime_ms();
85   - elapsed = end - start;
86   -
87   - rate = (NB_LOOPS * nb_points) * G_MSEC_PER_SEC / (end - start);
88   - printf("Transfert rate in points/seconds:\n");
89   - printf("* %'d points/s\n", rate);
90   - printf("\n");
91   -
92   - bytes = NB_LOOPS * (nb_points / 8) + ((nb_points % 8) ? 1 : 0);
93   - rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
94   - printf("Values:\n");
95   - printf("* %d x %d values\n", NB_LOOPS, nb_points);
96   - printf("* %.3f ms for %d bytes\n", elapsed, bytes);
97   - printf("* %'d KiB/s\n", rate);
98   - printf("\n");
99   -
100   - /* TCP: Query and reponse header and values */
101   - bytes = 12 + 9 + (nb_points / 8) + ((nb_points % 8) ? 1 : 0);
102   - printf("Values and TCP Modbus overhead:\n");
103   - printf("* %d x %d bytes\n", NB_LOOPS, bytes);
104   - bytes = NB_LOOPS * bytes;
105   - rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
106   - printf("* %.3f ms for %d bytes\n", elapsed, bytes);
107   - printf("* %'d KiB/s\n", rate);
108   - printf("\n\n");
109   -
110   - printf("READ HOLDING REGISTERS\n\n");
111   -
112   - nb_points = MAX_REGISTERS;
113   - start = gettime_ms();
114   - for (i=0; i<NB_LOOPS; i++) {
115   - rc = read_holding_registers(&mb_param, SERVER_ID, 0, nb_points, tab_rp_registers);
116   - if (rc == -1) {
117   - fprintf(stderr, "%s\n", modbus_strerror(errno));
118   - return -1;
119   - }
  83 + }
  84 + end = gettime_ms();
  85 + elapsed = end - start;
  86 +
  87 + rate = (NB_LOOPS * nb_points) * G_MSEC_PER_SEC / (end - start);
  88 + printf("Transfert rate in points/seconds:\n");
  89 + printf("* %'d points/s\n", rate);
  90 + printf("\n");
  91 +
  92 + bytes = NB_LOOPS * (nb_points / 8) + ((nb_points % 8) ? 1 : 0);
  93 + rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
  94 + printf("Values:\n");
  95 + printf("* %d x %d values\n", NB_LOOPS, nb_points);
  96 + printf("* %.3f ms for %d bytes\n", elapsed, bytes);
  97 + printf("* %'d KiB/s\n", rate);
  98 + printf("\n");
  99 +
  100 + /* TCP: Query and reponse header and values */
  101 + bytes = 12 + 9 + (nb_points / 8) + ((nb_points % 8) ? 1 : 0);
  102 + printf("Values and TCP Modbus overhead:\n");
  103 + printf("* %d x %d bytes\n", NB_LOOPS, bytes);
  104 + bytes = NB_LOOPS * bytes;
  105 + rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
  106 + printf("* %.3f ms for %d bytes\n", elapsed, bytes);
  107 + printf("* %'d KiB/s\n", rate);
  108 + printf("\n\n");
  109 +
  110 + printf("READ HOLDING REGISTERS\n\n");
  111 +
  112 + nb_points = MAX_REGISTERS;
  113 + start = gettime_ms();
  114 + for (i=0; i<NB_LOOPS; i++) {
  115 + rc = read_holding_registers(&mb_param, SERVER_ID, 0, nb_points, tab_rp_registers);
  116 + if (rc == -1) {
  117 + fprintf(stderr, "%s\n", modbus_strerror(errno));
  118 + return -1;
120 119 }
121   - end = gettime_ms();
122   - elapsed = end - start;
123   -
124   - rate = (NB_LOOPS * nb_points) * G_MSEC_PER_SEC / (end - start);
125   - printf("Transfert rate in points/seconds:\n");
126   - printf("* %'d registers/s\n", rate);
127   - printf("\n");
128   -
129   - bytes = NB_LOOPS * nb_points * sizeof(uint16_t);
130   - rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
131   - printf("Values:\n");
132   - printf("* %d x %d values\n", NB_LOOPS, nb_points);
133   - printf("* %.3f ms for %d bytes\n", elapsed, bytes);
134   - printf("* %'d KiB/s\n", rate);
135   - printf("\n");
136   -
137   - /* TCP:Query and reponse header and values */
138   - bytes = 12 + 9 + (nb_points * sizeof(uint16_t));
139   - printf("Values and TCP Modbus overhead:\n");
140   - printf("* %d x %d bytes\n", NB_LOOPS, bytes);
141   - bytes = NB_LOOPS * bytes;
142   - rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
143   - printf("* %.3f ms for %d bytes\n", elapsed, bytes);
144   - printf("* %'d KiB/s\n", rate);
145   - printf("\n");
146   -
147   - /* Free the memory */
148   - free(tab_rp_status);
149   - free(tab_rp_registers);
150   -
151   - /* Close the connection */
152   - modbus_close(&mb_param);
153   -
154   - return 0;
  120 + }
  121 + end = gettime_ms();
  122 + elapsed = end - start;
  123 +
  124 + rate = (NB_LOOPS * nb_points) * G_MSEC_PER_SEC / (end - start);
  125 + printf("Transfert rate in points/seconds:\n");
  126 + printf("* %'d registers/s\n", rate);
  127 + printf("\n");
  128 +
  129 + bytes = NB_LOOPS * nb_points * sizeof(uint16_t);
  130 + rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
  131 + printf("Values:\n");
  132 + printf("* %d x %d values\n", NB_LOOPS, nb_points);
  133 + printf("* %.3f ms for %d bytes\n", elapsed, bytes);
  134 + printf("* %'d KiB/s\n", rate);
  135 + printf("\n");
  136 +
  137 + /* TCP:Query and reponse header and values */
  138 + bytes = 12 + 9 + (nb_points * sizeof(uint16_t));
  139 + printf("Values and TCP Modbus overhead:\n");
  140 + printf("* %d x %d bytes\n", NB_LOOPS, bytes);
  141 + bytes = NB_LOOPS * bytes;
  142 + rate = bytes / 1024 * G_MSEC_PER_SEC / (end - start);
  143 + printf("* %.3f ms for %d bytes\n", elapsed, bytes);
  144 + printf("* %'d KiB/s\n", rate);
  145 + printf("\n");
  146 +
  147 + /* Free the memory */
  148 + free(tab_rp_status);
  149 + free(tab_rp_registers);
  150 +
  151 + /* Close the connection */
  152 + modbus_close(&mb_param);
  153 +
  154 + return 0;
155 155 }
... ...
tests/bandwidth-slave-many-up.c
... ... @@ -31,101 +31,101 @@ modbus_mapping_t mb_mapping;
31 31  
32 32 static void close_sigint(int dummy)
33 33 {
34   - modbus_slave_close_tcp(slave_socket);
35   - modbus_mapping_free(&mb_mapping);
  34 + modbus_slave_close_tcp(slave_socket);
  35 + modbus_mapping_free(&mb_mapping);
36 36  
37   - exit(dummy);
  37 + exit(dummy);
38 38 }
39 39  
40 40 int main(void)
41 41 {
42   - int master_socket;
43   - modbus_param_t mb_param;
44   - int rc;
45   - fd_set refset;
46   - fd_set rdset;
47   -
48   - /* Maximum file descriptor number */
49   - int fdmax;
50   -
51   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
52   -
53   - rc = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0);
54   - if (rc == -1) {
55   - fprintf(stderr, "Failed to allocate the mapping: %s\n",
56   - modbus_strerror(errno));
57   - return -1;
58   - }
  42 + int master_socket;
  43 + modbus_param_t mb_param;
  44 + int rc;
  45 + fd_set refset;
  46 + fd_set rdset;
59 47  
60   - slave_socket = modbus_slave_listen_tcp(&mb_param, NB_CONNECTION);
  48 + /* Maximum file descriptor number */
  49 + int fdmax;
61 50  
62   - signal(SIGINT, close_sigint);
  51 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
63 52  
64   - /* Clear the reference set of socket */
65   - FD_ZERO(&refset);
66   - /* Add the slave socket */
67   - FD_SET(slave_socket, &refset);
  53 + rc = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0);
  54 + if (rc == -1) {
  55 + fprintf(stderr, "Failed to allocate the mapping: %s\n",
  56 + modbus_strerror(errno));
  57 + return -1;
  58 + }
68 59  
69   - /* Keep track of the max file descriptor */
70   - fdmax = slave_socket;
  60 + slave_socket = modbus_slave_listen_tcp(&mb_param, NB_CONNECTION);
71 61  
72   - for (;;) {
73   - rdset = refset;
74   - if (select(fdmax+1, &rdset, NULL, NULL, NULL) == -1) {
75   - perror("Slave select() failure.");
76   - close_sigint(1);
77   - }
  62 + signal(SIGINT, close_sigint);
  63 +
  64 + /* Clear the reference set of socket */
  65 + FD_ZERO(&refset);
  66 + /* Add the slave socket */
  67 + FD_SET(slave_socket, &refset);
  68 +
  69 + /* Keep track of the max file descriptor */
  70 + fdmax = slave_socket;
78 71  
79   - /* Run through the existing connections looking for data to be
80   - * read */
81   - for (master_socket = 0; master_socket <= fdmax; master_socket++) {
82   -
83   - if (FD_ISSET(master_socket, &rdset)) {
84   - if (master_socket == slave_socket) {
85   - /* A client is asking a new connection */
86   - socklen_t addrlen;
87   - struct sockaddr_in clientaddr;
88   - int newfd;
89   -
90   - /* Handle new connections */
91   - addrlen = sizeof(clientaddr);
92   - memset(&clientaddr, 0, sizeof(clientaddr));
93   - newfd = accept(slave_socket, (struct sockaddr *)&clientaddr, &addrlen);
94   - if (newfd == -1) {
95   - perror("Server accept() error");
96   - } else {
97   - FD_SET(newfd, &refset);
98   -
99   - if (newfd > fdmax) {
100   - /* Keep track of the maximum */
101   - fdmax = newfd;
102   - }
103   - printf("New connection from %s:%d on socket %d\n",
104   - inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port, newfd);
105   - }
106   - } else {
107   - /* An already connected master has sent a new query */
108   - uint8_t query[MAX_MESSAGE_LENGTH];
109   -
110   - rc = modbus_slave_receive(&mb_param, master_socket, query);
111   - if (rc != -1) {
112   - modbus_slave_manage(&mb_param, query, rc, &mb_mapping);
113   - } else {
114   - /* Connection closed by the client, end of server */
115   - printf("Connection closed on socket %d\n", master_socket);
116   - modbus_slave_close_tcp(master_socket);
117   -
118   - /* Remove from reference set */
119   - FD_CLR(master_socket, &refset);
120   -
121   - if (master_socket == fdmax) {
122   - fdmax--;
123   - }
124   - }
125   - }
  72 + for (;;) {
  73 + rdset = refset;
  74 + if (select(fdmax+1, &rdset, NULL, NULL, NULL) == -1) {
  75 + perror("Slave select() failure.");
  76 + close_sigint(1);
  77 + }
  78 +
  79 + /* Run through the existing connections looking for data to be
  80 + * read */
  81 + for (master_socket = 0; master_socket <= fdmax; master_socket++) {
  82 +
  83 + if (FD_ISSET(master_socket, &rdset)) {
  84 + if (master_socket == slave_socket) {
  85 + /* A client is asking a new connection */
  86 + socklen_t addrlen;
  87 + struct sockaddr_in clientaddr;
  88 + int newfd;
  89 +
  90 + /* Handle new connections */
  91 + addrlen = sizeof(clientaddr);
  92 + memset(&clientaddr, 0, sizeof(clientaddr));
  93 + newfd = accept(slave_socket, (struct sockaddr *)&clientaddr, &addrlen);
  94 + if (newfd == -1) {
  95 + perror("Server accept() error");
  96 + } else {
  97 + FD_SET(newfd, &refset);
  98 +
  99 + if (newfd > fdmax) {
  100 + /* Keep track of the maximum */
  101 + fdmax = newfd;
  102 + }
  103 + printf("New connection from %s:%d on socket %d\n",
  104 + inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port, newfd);
  105 + }
  106 + } else {
  107 + /* An already connected master has sent a new query */
  108 + uint8_t query[MAX_MESSAGE_LENGTH];
  109 +
  110 + rc = modbus_slave_receive(&mb_param, master_socket, query);
  111 + if (rc != -1) {
  112 + modbus_slave_manage(&mb_param, query, rc, &mb_mapping);
  113 + } else {
  114 + /* Connection closed by the client, end of server */
  115 + printf("Connection closed on socket %d\n", master_socket);
  116 + modbus_slave_close_tcp(master_socket);
  117 +
  118 + /* Remove from reference set */
  119 + FD_CLR(master_socket, &refset);
  120 +
  121 + if (master_socket == fdmax) {
  122 + fdmax--;
126 123 }
  124 + }
127 125 }
  126 + }
128 127 }
  128 + }
129 129  
130   - return 0;
  130 + return 0;
131 131 }
... ...
tests/bandwidth-slave-one.c
... ... @@ -25,40 +25,40 @@
25 25  
26 26 int main(void)
27 27 {
28   - int socket;
29   - modbus_param_t mb_param;
30   - modbus_mapping_t mb_mapping;
31   - int rc;
  28 + int socket;
  29 + modbus_param_t mb_param;
  30 + modbus_mapping_t mb_mapping;
  31 + int rc;
32 32  
33   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
  33 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
34 34  
35   - rc = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0);
36   - if (rc == -1) {
37   - fprintf(stderr, "Failed to allocate the mapping: %s\n",
38   - modbus_strerror(errno));
39   - return -1;
40   - }
  35 + rc = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0);
  36 + if (rc == -1) {
  37 + fprintf(stderr, "Failed to allocate the mapping: %s\n",
  38 + modbus_strerror(errno));
  39 + return -1;
  40 + }
41 41  
42   - socket = modbus_slave_listen_tcp(&mb_param, 1);
43   - modbus_slave_accept_tcp(&mb_param, &socket);
  42 + socket = modbus_slave_listen_tcp(&mb_param, 1);
  43 + modbus_slave_accept_tcp(&mb_param, &socket);
44 44  
45   - for(;;) {
46   - uint8_t query[MAX_MESSAGE_LENGTH];
  45 + for(;;) {
  46 + uint8_t query[MAX_MESSAGE_LENGTH];
47 47  
48   - rc = modbus_slave_receive(&mb_param, -1, query);
49   - if (rc >= 0) {
50   - modbus_slave_manage(&mb_param, query, rc, &mb_mapping);
51   - } else {
52   - /* Connection closed by the client or server */
53   - break;
54   - }
  48 + rc = modbus_slave_receive(&mb_param, -1, query);
  49 + if (rc >= 0) {
  50 + modbus_slave_manage(&mb_param, query, rc, &mb_mapping);
  51 + } else {
  52 + /* Connection closed by the client or server */
  53 + break;
55 54 }
  55 + }
56 56  
57   - printf("Quit the loop: %s\n", modbus_strerror(errno));
  57 + printf("Quit the loop: %s\n", modbus_strerror(errno));
58 58  
59   - close(socket);
60   - modbus_mapping_free(&mb_mapping);
61   - modbus_close(&mb_param);
  59 + close(socket);
  60 + modbus_mapping_free(&mb_mapping);
  61 + modbus_close(&mb_param);
62 62  
63   - return 0;
  63 + return 0;
64 64 }
... ...
tests/random-test-master.c
... ... @@ -47,175 +47,175 @@
47 47 */
48 48 int main(void)
49 49 {
50   - int rc;
51   - int nb_fail;
52   - int nb_loop;
53   - int addr;
54   - int nb;
55   - uint8_t *tab_rq_status;
56   - uint8_t *tab_rp_status;
57   - uint16_t *tab_rq_registers;
58   - uint16_t *tab_rp_registers;
59   - modbus_param_t mb_param;
60   -
61   - /*
62   - modbus_init_rtu(&mb_param, "/dev/ttyS0", 19200, 'N', 8, 1, MY_ID);
63   - */
64   -
65   - /* TCP */
66   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
67   - modbus_set_debug(&mb_param, TRUE);
68   - if (modbus_connect(&mb_param) == -1) {
69   - fprintf(stderr, "Connection failed: %s\n",
70   - modbus_strerror(errno));
71   - return -1;
72   - }
73   -
74   - /* Allocate and initialize the different memory spaces */
75   - nb = ADDRESS_END - ADDRESS_START;
76   -
77   - tab_rq_status = (uint8_t *) malloc(nb * sizeof(uint8_t));
78   - memset(tab_rq_status, 0, nb * sizeof(uint8_t));
79   -
80   - tab_rp_status = (uint8_t *) malloc(nb * sizeof(uint8_t));
81   - memset(tab_rp_status, 0, nb * sizeof(uint8_t));
82   -
83   - tab_rq_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
84   - memset(tab_rq_registers, 0, nb * sizeof(uint16_t));
85   -
86   - tab_rp_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
87   - memset(tab_rp_registers, 0, nb * sizeof(uint16_t));
88   -
89   - nb_loop = nb_fail = 0;
90   - while (nb_loop++ < LOOP) {
91   - for (addr = ADDRESS_START; addr <= ADDRESS_END; addr++) {
92   - int i;
93   -
94   - /* Random numbers (short) */
95   - for (i=0; i<nb; i++) {
96   - tab_rq_registers[i] = (uint16_t) (65535.0*rand() / (RAND_MAX + 1.0));
97   - tab_rq_status[i] = tab_rq_registers[i] % 2;
98   - }
99   - nb = ADDRESS_END - addr;
100   -
101   - /* SINGLE COIL */
102   - rc = force_single_coil(&mb_param, SERVER_ID, addr, tab_rq_status[0]);
103   - if (rc != 1) {
104   - printf("ERROR force_single_coil (%d)\n", rc);
105   - printf("Slave = %d, address = %d, value = %d\n",
106   - SERVER_ID, addr, tab_rq_status[0]);
107   - nb_fail++;
108   - } else {
109   - rc = read_coil_status(&mb_param, SERVER_ID, addr, 1, tab_rp_status);
110   - if (rc != 1 || tab_rq_status[0] != tab_rp_status[0]) {
111   - printf("ERROR read_coil_status single (%d)\n", rc);
112   - printf("Slave = %d, address = %d\n",
113   - SERVER_ID, addr);
114   - nb_fail++;
115   - }
116   - }
117   -
118   - /* MULTIPLE COILS */
119   - rc = force_multiple_coils(&mb_param, SERVER_ID, addr, nb, tab_rq_status);
120   - if (rc != nb) {
121   - printf("ERROR force_multiple_coils (%d)\n", rc);
122   - printf("Slave = %d, address = %d, nb = %d\n",
123   - SERVER_ID, addr, nb);
124   - nb_fail++;
125   - } else {
126   - rc = read_coil_status(&mb_param, SERVER_ID, addr, nb, tab_rp_status);
127   - if (rc != nb) {
128   - printf("ERROR read_coil_status\n");
129   - printf("Slave = %d, address = %d, nb = %d\n",
130   - SERVER_ID, addr, nb);
131   - nb_fail++;
132   - } else {
133   - for (i=0; i<nb; i++) {
134   - if (tab_rp_status[i] != tab_rq_status[i]) {
135   - printf("ERROR read_coil_status\n");
136   - printf("Slave = %d, address = %d, value %d (0x%X) != %d (0x%X)\n",
137   - SERVER_ID, addr,
138   - tab_rq_status[i], tab_rq_status[i],
139   - tab_rp_status[i], tab_rp_status[i]);
140   - nb_fail++;
141   - }
142   - }
143   - }
144   - }
145   -
146   - /* SINGLE REGISTER */
147   - rc = preset_single_register(&mb_param, SERVER_ID, addr, tab_rq_registers[0]);
148   - if (rc != 1) {
149   - printf("ERROR preset_single_register (%d)\n", rc);
150   - printf("Slave = %d, address = %d, value = %d (0x%X)\n",
151   - SERVER_ID, addr, tab_rq_registers[0], tab_rq_registers[0]);
152   - nb_fail++;
153   - } else {
154   - rc = read_holding_registers(&mb_param, SERVER_ID, addr, 1, tab_rp_registers);
155   - if (rc != 1) {
156   - printf("ERROR read_holding_registers single (%d)\n", rc);
157   - printf("Slave = %d, address = %d\n",
158   - SERVER_ID, addr);
159   - nb_fail++;
160   - } else {
161   - if (tab_rq_registers[0] != tab_rp_registers[0]) {
162   - printf("ERROR read_holding_registers single\n");
163   - printf("Slave = %d, address = %d, value = %d (0x%X) != %d (0x%X)\n",
164   - SERVER_ID, addr,
165   - tab_rq_registers[0], tab_rq_registers[0],
166   - tab_rp_registers[0], tab_rp_registers[0]);
167   - nb_fail++;
168   - }
169   - }
  50 + int rc;
  51 + int nb_fail;
  52 + int nb_loop;
  53 + int addr;
  54 + int nb;
  55 + uint8_t *tab_rq_status;
  56 + uint8_t *tab_rp_status;
  57 + uint16_t *tab_rq_registers;
  58 + uint16_t *tab_rp_registers;
  59 + modbus_param_t mb_param;
  60 +
  61 + /*
  62 + modbus_init_rtu(&mb_param, "/dev/ttyS0", 19200, 'N', 8, 1, MY_ID);
  63 + */
  64 +
  65 + /* TCP */
  66 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
  67 + modbus_set_debug(&mb_param, TRUE);
  68 + if (modbus_connect(&mb_param) == -1) {
  69 + fprintf(stderr, "Connection failed: %s\n",
  70 + modbus_strerror(errno));
  71 + return -1;
  72 + }
  73 +
  74 + /* Allocate and initialize the different memory spaces */
  75 + nb = ADDRESS_END - ADDRESS_START;
  76 +
  77 + tab_rq_status = (uint8_t *) malloc(nb * sizeof(uint8_t));
  78 + memset(tab_rq_status, 0, nb * sizeof(uint8_t));
  79 +
  80 + tab_rp_status = (uint8_t *) malloc(nb * sizeof(uint8_t));
  81 + memset(tab_rp_status, 0, nb * sizeof(uint8_t));
  82 +
  83 + tab_rq_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
  84 + memset(tab_rq_registers, 0, nb * sizeof(uint16_t));
  85 +
  86 + tab_rp_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
  87 + memset(tab_rp_registers, 0, nb * sizeof(uint16_t));
  88 +
  89 + nb_loop = nb_fail = 0;
  90 + while (nb_loop++ < LOOP) {
  91 + for (addr = ADDRESS_START; addr <= ADDRESS_END; addr++) {
  92 + int i;
  93 +
  94 + /* Random numbers (short) */
  95 + for (i=0; i<nb; i++) {
  96 + tab_rq_registers[i] = (uint16_t) (65535.0*rand() / (RAND_MAX + 1.0));
  97 + tab_rq_status[i] = tab_rq_registers[i] % 2;
  98 + }
  99 + nb = ADDRESS_END - addr;
  100 +
  101 + /* SINGLE COIL */
  102 + rc = force_single_coil(&mb_param, SERVER_ID, addr, tab_rq_status[0]);
  103 + if (rc != 1) {
  104 + printf("ERROR force_single_coil (%d)\n", rc);
  105 + printf("Slave = %d, address = %d, value = %d\n",
  106 + SERVER_ID, addr, tab_rq_status[0]);
  107 + nb_fail++;
  108 + } else {
  109 + rc = read_coil_status(&mb_param, SERVER_ID, addr, 1, tab_rp_status);
  110 + if (rc != 1 || tab_rq_status[0] != tab_rp_status[0]) {
  111 + printf("ERROR read_coil_status single (%d)\n", rc);
  112 + printf("Slave = %d, address = %d\n",
  113 + SERVER_ID, addr);
  114 + nb_fail++;
  115 + }
  116 + }
  117 +
  118 + /* MULTIPLE COILS */
  119 + rc = force_multiple_coils(&mb_param, SERVER_ID, addr, nb, tab_rq_status);
  120 + if (rc != nb) {
  121 + printf("ERROR force_multiple_coils (%d)\n", rc);
  122 + printf("Slave = %d, address = %d, nb = %d\n",
  123 + SERVER_ID, addr, nb);
  124 + nb_fail++;
  125 + } else {
  126 + rc = read_coil_status(&mb_param, SERVER_ID, addr, nb, tab_rp_status);
  127 + if (rc != nb) {
  128 + printf("ERROR read_coil_status\n");
  129 + printf("Slave = %d, address = %d, nb = %d\n",
  130 + SERVER_ID, addr, nb);
  131 + nb_fail++;
  132 + } else {
  133 + for (i=0; i<nb; i++) {
  134 + if (tab_rp_status[i] != tab_rq_status[i]) {
  135 + printf("ERROR read_coil_status\n");
  136 + printf("Slave = %d, address = %d, value %d (0x%X) != %d (0x%X)\n",
  137 + SERVER_ID, addr,
  138 + tab_rq_status[i], tab_rq_status[i],
  139 + tab_rp_status[i], tab_rp_status[i]);
  140 + nb_fail++;
170 141 }
171   -
172   - /* MULTIPLE REGISTERS */
173   - rc = preset_multiple_registers(&mb_param, SERVER_ID, addr, nb,
174   - tab_rq_registers);
175   - if (rc != nb) {
176   - printf("ERROR preset_multiple_registers (%d)\n", rc);
177   - printf("Slave = %d, address = %d, nb = %d\n",
178   - SERVER_ID, addr, nb);
179   - nb_fail++;
180   - } else {
181   - rc = read_holding_registers(&mb_param, SERVER_ID, addr, nb,
182   - tab_rp_registers);
183   - if (rc != nb) {
184   - printf("ERROR read_holding_registers (%d)\n", rc);
185   - printf("Slave = %d, address = %d, nb = %d\n",
186   - SERVER_ID, addr, nb);
187   - nb_fail++;
188   - } else {
189   - for (i=0; i<nb; i++) {
190   - if (tab_rq_registers[i] != tab_rp_registers[i]) {
191   - printf("ERROR read_holding_registers\n");
192   - printf("Slave = %d, address = %d, value %d (0x%X) != %d (0x%X)\n",
193   - SERVER_ID, addr,
194   - tab_rq_registers[i], tab_rq_registers[i],
195   - tab_rp_registers[i], tab_rp_registers[i]);
196   - nb_fail++;
197   - }
198   - }
199   - }
  142 + }
  143 + }
  144 + }
  145 +
  146 + /* SINGLE REGISTER */
  147 + rc = preset_single_register(&mb_param, SERVER_ID, addr, tab_rq_registers[0]);
  148 + if (rc != 1) {
  149 + printf("ERROR preset_single_register (%d)\n", rc);
  150 + printf("Slave = %d, address = %d, value = %d (0x%X)\n",
  151 + SERVER_ID, addr, tab_rq_registers[0], tab_rq_registers[0]);
  152 + nb_fail++;
  153 + } else {
  154 + rc = read_holding_registers(&mb_param, SERVER_ID, addr, 1, tab_rp_registers);
  155 + if (rc != 1) {
  156 + printf("ERROR read_holding_registers single (%d)\n", rc);
  157 + printf("Slave = %d, address = %d\n",
  158 + SERVER_ID, addr);
  159 + nb_fail++;
  160 + } else {
  161 + if (tab_rq_registers[0] != tab_rp_registers[0]) {
  162 + printf("ERROR read_holding_registers single\n");
  163 + printf("Slave = %d, address = %d, value = %d (0x%X) != %d (0x%X)\n",
  164 + SERVER_ID, addr,
  165 + tab_rq_registers[0], tab_rq_registers[0],
  166 + tab_rp_registers[0], tab_rp_registers[0]);
  167 + nb_fail++;
  168 + }
  169 + }
  170 + }
  171 +
  172 + /* MULTIPLE REGISTERS */
  173 + rc = preset_multiple_registers(&mb_param, SERVER_ID, addr, nb,
  174 + tab_rq_registers);
  175 + if (rc != nb) {
  176 + printf("ERROR preset_multiple_registers (%d)\n", rc);
  177 + printf("Slave = %d, address = %d, nb = %d\n",
  178 + SERVER_ID, addr, nb);
  179 + nb_fail++;
  180 + } else {
  181 + rc = read_holding_registers(&mb_param, SERVER_ID, addr, nb,
  182 + tab_rp_registers);
  183 + if (rc != nb) {
  184 + printf("ERROR read_holding_registers (%d)\n", rc);
  185 + printf("Slave = %d, address = %d, nb = %d\n",
  186 + SERVER_ID, addr, nb);
  187 + nb_fail++;
  188 + } else {
  189 + for (i=0; i<nb; i++) {
  190 + if (tab_rq_registers[i] != tab_rp_registers[i]) {
  191 + printf("ERROR read_holding_registers\n");
  192 + printf("Slave = %d, address = %d, value %d (0x%X) != %d (0x%X)\n",
  193 + SERVER_ID, addr,
  194 + tab_rq_registers[i], tab_rq_registers[i],
  195 + tab_rp_registers[i], tab_rp_registers[i]);
  196 + nb_fail++;
200 197 }
201   -
  198 + }
202 199 }
  200 + }
203 201  
204   - printf("Test: ");
205   - if (nb_fail)
206   - printf("%d FAILS\n", nb_fail);
207   - else
208   - printf("SUCCESS\n");
209 202 }
210 203  
211   - /* Free the memory */
212   - free(tab_rq_status);
213   - free(tab_rp_status);
214   - free(tab_rq_registers);
215   - free(tab_rp_registers);
  204 + printf("Test: ");
  205 + if (nb_fail)
  206 + printf("%d FAILS\n", nb_fail);
  207 + else
  208 + printf("SUCCESS\n");
  209 + }
  210 +
  211 + /* Free the memory */
  212 + free(tab_rq_status);
  213 + free(tab_rp_status);
  214 + free(tab_rq_registers);
  215 + free(tab_rp_registers);
216 216  
217   - /* Close the connection */
218   - modbus_close(&mb_param);
  217 + /* Close the connection */
  218 + modbus_close(&mb_param);
219 219  
220   - return 0;
  220 + return 0;
221 221 }
... ...
tests/random-test-slave.c
... ... @@ -24,43 +24,43 @@
24 24  
25 25 int main(void)
26 26 {
27   - int socket;
28   - modbus_param_t mb_param;
29   - modbus_mapping_t mb_mapping;
30   - int rc;
  27 + int socket;
  28 + modbus_param_t mb_param;
  29 + modbus_mapping_t mb_mapping;
  30 + int rc;
31 31  
32   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
33   - /* modbus_set_debug(&mb_param, TRUE); */
  32 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
  33 + /* modbus_set_debug(&mb_param, TRUE); */
34 34  
35   - rc = modbus_mapping_new(&mb_mapping, 500, 500, 500, 500);
36   - if (rc == -1) {
37   - fprintf(stderr, "Failed to allocate the mapping: %s\n",
38   - modbus_strerror(errno));
39   - return -1;
40   - }
  35 + rc = modbus_mapping_new(&mb_mapping, 500, 500, 500, 500);
  36 + if (rc == -1) {
  37 + fprintf(stderr, "Failed to allocate the mapping: %s\n",
  38 + modbus_strerror(errno));
  39 + return -1;
  40 + }
41 41  
42   - socket = modbus_slave_listen_tcp(&mb_param, 1);
43   - modbus_slave_accept_tcp(&mb_param, &socket);
  42 + socket = modbus_slave_listen_tcp(&mb_param, 1);
  43 + modbus_slave_accept_tcp(&mb_param, &socket);
44 44  
45   - for (;;) {
46   - uint8_t query[MAX_MESSAGE_LENGTH];
47   - int rc;
  45 + for (;;) {
  46 + uint8_t query[MAX_MESSAGE_LENGTH];
  47 + int rc;
48 48  
49   - rc = modbus_slave_receive(&mb_param, -1, query);
50   - if (rc != -1) {
51   - /* rc is the query size */
52   - modbus_slave_manage(&mb_param, query, rc, &mb_mapping);
53   - } else {
54   - /* Connection closed by the client or error */
55   - break;
56   - }
  49 + rc = modbus_slave_receive(&mb_param, -1, query);
  50 + if (rc != -1) {
  51 + /* rc is the query size */
  52 + modbus_slave_manage(&mb_param, query, rc, &mb_mapping);
  53 + } else {
  54 + /* Connection closed by the client or error */
  55 + break;
57 56 }
  57 + }
58 58  
59   - printf("Quit the loop: %s\n", modbus_strerror(errno));
  59 + printf("Quit the loop: %s\n", modbus_strerror(errno));
60 60  
61   - close(socket);
62   - modbus_mapping_free(&mb_mapping);
63   - modbus_close(&mb_param);
  61 + close(socket);
  62 + modbus_mapping_free(&mb_mapping);
  63 + modbus_close(&mb_param);
64 64  
65   - return 0;
  65 + return 0;
66 66 }
... ...
tests/unit-test-master.c
... ... @@ -26,516 +26,516 @@
26 26  
27 27 int main(void)
28 28 {
29   - uint8_t *tab_rp_status;
30   - uint16_t *tab_rp_registers;
31   - uint16_t *tab_rp_registers_bad;
32   - modbus_param_t mb_param;
33   - int i;
34   - uint8_t value;
35   - int address;
36   - int nb_points;
37   - int rc;
38   - float real;
39   - struct timeval timeout_begin_old;
40   - struct timeval timeout_begin_new;
41   -
42   - /*
43   - modbus_init_rtu(&mb_param, "/dev/ttyS0", 19200, 'N', 8, 1,
44   - CLIENT_ID);
45   - */
46   -
47   - /* TCP */
48   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
49   - modbus_set_debug(&mb_param, TRUE);
50   -
51   - if (modbus_connect(&mb_param) == -1) {
52   - fprintf(stderr, "Connection failed: %s\n",
53   - modbus_strerror(errno));
54   - return -1;
55   - }
56   -
57   - /* Allocate and initialize the memory to store the status */
58   - nb_points = (UT_COIL_STATUS_NB_POINTS > UT_INPUT_STATUS_NB_POINTS) ?
59   - UT_COIL_STATUS_NB_POINTS : UT_INPUT_STATUS_NB_POINTS;
60   - tab_rp_status = (uint8_t *) malloc(nb_points * sizeof(uint8_t));
61   - memset(tab_rp_status, 0, nb_points * sizeof(uint8_t));
62   -
63   - /* Allocate and initialize the memory to store the registers */
64   - nb_points = (UT_HOLDING_REGISTERS_NB_POINTS >
65   - UT_INPUT_REGISTERS_NB_POINTS) ?
66   - UT_HOLDING_REGISTERS_NB_POINTS : UT_INPUT_REGISTERS_NB_POINTS;
67   - tab_rp_registers = (uint16_t *) malloc(nb_points * sizeof(uint16_t));
68   - memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t));
69   -
70   - printf("** UNIT TESTING **\n");
71   -
72   - printf("\nTEST WRITE/READ:\n");
73   -
74   - /** COIL STATUS **/
75   -
76   - /* Single */
77   - rc = force_single_coil(&mb_param, SERVER_ID, UT_COIL_STATUS_ADDRESS, ON);
78   - printf("1/2 force_single_coil: ");
79   - if (rc == 1) {
80   - printf("OK\n");
  29 + uint8_t *tab_rp_status;
  30 + uint16_t *tab_rp_registers;
  31 + uint16_t *tab_rp_registers_bad;
  32 + modbus_param_t mb_param;
  33 + int i;
  34 + uint8_t value;
  35 + int address;
  36 + int nb_points;
  37 + int rc;
  38 + float real;
  39 + struct timeval timeout_begin_old;
  40 + struct timeval timeout_begin_new;
  41 +
  42 + /*
  43 + modbus_init_rtu(&mb_param, "/dev/ttyS0", 19200, 'N', 8, 1,
  44 + CLIENT_ID);
  45 + */
  46 +
  47 + /* TCP */
  48 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
  49 + modbus_set_debug(&mb_param, TRUE);
  50 +
  51 + if (modbus_connect(&mb_param) == -1) {
  52 + fprintf(stderr, "Connection failed: %s\n",
  53 + modbus_strerror(errno));
  54 + return -1;
  55 + }
  56 +
  57 + /* Allocate and initialize the memory to store the status */
  58 + nb_points = (UT_COIL_STATUS_NB_POINTS > UT_INPUT_STATUS_NB_POINTS) ?
  59 + UT_COIL_STATUS_NB_POINTS : UT_INPUT_STATUS_NB_POINTS;
  60 + tab_rp_status = (uint8_t *) malloc(nb_points * sizeof(uint8_t));
  61 + memset(tab_rp_status, 0, nb_points * sizeof(uint8_t));
  62 +
  63 + /* Allocate and initialize the memory to store the registers */
  64 + nb_points = (UT_HOLDING_REGISTERS_NB_POINTS >
  65 + UT_INPUT_REGISTERS_NB_POINTS) ?
  66 + UT_HOLDING_REGISTERS_NB_POINTS : UT_INPUT_REGISTERS_NB_POINTS;
  67 + tab_rp_registers = (uint16_t *) malloc(nb_points * sizeof(uint16_t));
  68 + memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t));
  69 +
  70 + printf("** UNIT TESTING **\n");
  71 +
  72 + printf("\nTEST WRITE/READ:\n");
  73 +
  74 + /** COIL STATUS **/
  75 +
  76 + /* Single */
  77 + rc = force_single_coil(&mb_param, SERVER_ID, UT_COIL_STATUS_ADDRESS, ON);
  78 + printf("1/2 force_single_coil: ");
  79 + if (rc == 1) {
  80 + printf("OK\n");
  81 + } else {
  82 + printf("FAILED\n");
  83 + goto close;
  84 + }
  85 +
  86 + rc = read_coil_status(&mb_param, SERVER_ID, UT_COIL_STATUS_ADDRESS, 1,
  87 + tab_rp_status);
  88 + printf("2/2 read_coil_status: ");
  89 + if (rc != 1) {
  90 + printf("FAILED (nb points %d)\n", rc);
  91 + goto close;
  92 + }
  93 +
  94 + if (tab_rp_status[0] != ON) {
  95 + printf("FAILED (%0X = != %0X)\n", tab_rp_status[0], ON);
  96 + goto close;
  97 + }
  98 + printf("OK\n");
  99 + /* End single */
  100 +
  101 + /* Multiple coils */
  102 + {
  103 + uint8_t tab_value[UT_COIL_STATUS_NB_POINTS];
  104 +
  105 + set_bits_from_bytes(tab_value, 0, UT_COIL_STATUS_NB_POINTS,
  106 + UT_COIL_STATUS_TAB);
  107 + rc = force_multiple_coils(&mb_param, SERVER_ID,
  108 + UT_COIL_STATUS_ADDRESS,
  109 + UT_COIL_STATUS_NB_POINTS,
  110 + tab_value);
  111 + printf("1/2 force_multiple_coils: ");
  112 + if (rc == UT_COIL_STATUS_NB_POINTS) {
  113 + printf("OK\n");
81 114 } else {
82   - printf("FAILED\n");
83   - goto close;
84   - }
85   -
86   - rc = read_coil_status(&mb_param, SERVER_ID, UT_COIL_STATUS_ADDRESS, 1,
87   - tab_rp_status);
88   - printf("2/2 read_coil_status: ");
89   - if (rc != 1) {
90   - printf("FAILED (nb points %d)\n", rc);
91   - goto close;
92   - }
93   -
94   - if (tab_rp_status[0] != ON) {
95   - printf("FAILED (%0X = != %0X)\n", tab_rp_status[0], ON);
96   - goto close;
97   - }
  115 + printf("FAILED\n");
  116 + goto close;
  117 + }
  118 + }
  119 +
  120 + rc = read_coil_status(&mb_param, SERVER_ID, UT_COIL_STATUS_ADDRESS,
  121 + UT_COIL_STATUS_NB_POINTS, tab_rp_status);
  122 + printf("2/2 read_coil_status: ");
  123 + if (rc != UT_COIL_STATUS_NB_POINTS) {
  124 + printf("FAILED (nb points %d)\n", rc);
  125 + goto close;
  126 + }
  127 +
  128 + i = 0;
  129 + address = UT_COIL_STATUS_ADDRESS;
  130 + nb_points = UT_COIL_STATUS_NB_POINTS;
  131 + while (nb_points > 0) {
  132 + int nb_bits = (nb_points > 8) ? 8 : nb_points;
  133 +
  134 + value = get_byte_from_bits(tab_rp_status, i*8, nb_bits);
  135 + if (value != UT_COIL_STATUS_TAB[i]) {
  136 + printf("FAILED (%0X != %0X)\n",
  137 + value, UT_COIL_STATUS_TAB[i]);
  138 + goto close;
  139 + }
  140 +
  141 + nb_points -= nb_bits;
  142 + i++;
  143 + }
  144 + printf("OK\n");
  145 + /* End of multiple coils */
  146 +
  147 + /** INPUT STATUS **/
  148 + rc = read_input_status(&mb_param, SERVER_ID, UT_INPUT_STATUS_ADDRESS,
  149 + UT_INPUT_STATUS_NB_POINTS, tab_rp_status);
  150 + printf("1/1 read_input_status: ");
  151 +
  152 + if (rc != UT_INPUT_STATUS_NB_POINTS) {
  153 + printf("FAILED (nb points %d)\n", rc);
  154 + goto close;
  155 + }
  156 +
  157 + i = 0;
  158 + address = UT_INPUT_STATUS_ADDRESS;
  159 + nb_points = UT_INPUT_STATUS_NB_POINTS;
  160 + while (nb_points > 0) {
  161 + int nb_bits = (nb_points > 8) ? 8 : nb_points;
  162 +
  163 + value = get_byte_from_bits(tab_rp_status, i*8, nb_bits);
  164 + if (value != UT_INPUT_STATUS_TAB[i]) {
  165 + printf("FAILED (%0X != %0X)\n",
  166 + value, UT_INPUT_STATUS_TAB[i]);
  167 + goto close;
  168 + }
  169 +
  170 + nb_points -= nb_bits;
  171 + i++;
  172 + }
  173 + printf("OK\n");
  174 +
  175 + /** HOLDING REGISTERS **/
  176 +
  177 + /* Single register */
  178 + rc = preset_single_register(&mb_param, SERVER_ID,
  179 + UT_HOLDING_REGISTERS_ADDRESS, 0x1234);
  180 + printf("1/2 preset_single_register: ");
  181 + if (rc == 1) {
98 182 printf("OK\n");
99   - /* End single */
100   -
101   - /* Multiple coils */
102   - {
103   - uint8_t tab_value[UT_COIL_STATUS_NB_POINTS];
104   -
105   - set_bits_from_bytes(tab_value, 0, UT_COIL_STATUS_NB_POINTS,
106   - UT_COIL_STATUS_TAB);
107   - rc = force_multiple_coils(&mb_param, SERVER_ID,
108   - UT_COIL_STATUS_ADDRESS,
109   - UT_COIL_STATUS_NB_POINTS,
110   - tab_value);
111   - printf("1/2 force_multiple_coils: ");
112   - if (rc == UT_COIL_STATUS_NB_POINTS) {
113   - printf("OK\n");
114   - } else {
115   - printf("FAILED\n");
116   - goto close;
117   - }
118   - }
119   -
120   - rc = read_coil_status(&mb_param, SERVER_ID, UT_COIL_STATUS_ADDRESS,
121   - UT_COIL_STATUS_NB_POINTS, tab_rp_status);
122   - printf("2/2 read_coil_status: ");
123   - if (rc != UT_COIL_STATUS_NB_POINTS) {
124   - printf("FAILED (nb points %d)\n", rc);
125   - goto close;
126   - }
127   -
128   - i = 0;
129   - address = UT_COIL_STATUS_ADDRESS;
130   - nb_points = UT_COIL_STATUS_NB_POINTS;
131   - while (nb_points > 0) {
132   - int nb_bits = (nb_points > 8) ? 8 : nb_points;
133   -
134   - value = get_byte_from_bits(tab_rp_status, i*8, nb_bits);
135   - if (value != UT_COIL_STATUS_TAB[i]) {
136   - printf("FAILED (%0X != %0X)\n",
137   - value, UT_COIL_STATUS_TAB[i]);
138   - goto close;
139   - }
140   -
141   - nb_points -= nb_bits;
142   - i++;
143   - }
  183 + } else {
  184 + printf("FAILED\n");
  185 + goto close;
  186 + }
  187 +
  188 + rc = read_holding_registers(&mb_param, SERVER_ID,
  189 + UT_HOLDING_REGISTERS_ADDRESS,
  190 + 1, tab_rp_registers);
  191 + printf("2/2 read_holding_registers: ");
  192 + if (rc != 1) {
  193 + printf("FAILED (nb points %d)\n", rc);
  194 + goto close;
  195 + }
  196 +
  197 + if (tab_rp_registers[0] != 0x1234) {
  198 + printf("FAILED (%0X != %0X)\n",
  199 + tab_rp_registers[0], 0x1234);
  200 + goto close;
  201 + }
  202 + printf("OK\n");
  203 + /* End of single register */
  204 +
  205 + /* Many registers */
  206 + rc = preset_multiple_registers(&mb_param, SERVER_ID,
  207 + UT_HOLDING_REGISTERS_ADDRESS,
  208 + UT_HOLDING_REGISTERS_NB_POINTS,
  209 + UT_HOLDING_REGISTERS_TAB);
  210 + printf("1/2 preset_multiple_registers: ");
  211 + if (rc == UT_HOLDING_REGISTERS_NB_POINTS) {
144 212 printf("OK\n");
145   - /* End of multiple coils */
146   -
147   - /** INPUT STATUS **/
148   - rc = read_input_status(&mb_param, SERVER_ID, UT_INPUT_STATUS_ADDRESS,
149   - UT_INPUT_STATUS_NB_POINTS, tab_rp_status);
150   - printf("1/1 read_input_status: ");
151   -
152   - if (rc != UT_INPUT_STATUS_NB_POINTS) {
153   - printf("FAILED (nb points %d)\n", rc);
154   - goto close;
155   - }
156   -
157   - i = 0;
158   - address = UT_INPUT_STATUS_ADDRESS;
159   - nb_points = UT_INPUT_STATUS_NB_POINTS;
160   - while (nb_points > 0) {
161   - int nb_bits = (nb_points > 8) ? 8 : nb_points;
162   -
163   - value = get_byte_from_bits(tab_rp_status, i*8, nb_bits);
164   - if (value != UT_INPUT_STATUS_TAB[i]) {
165   - printf("FAILED (%0X != %0X)\n",
166   - value, UT_INPUT_STATUS_TAB[i]);
167   - goto close;
168   - }
169   -
170   - nb_points -= nb_bits;
171   - i++;
172   - }
  213 + } else {
  214 + printf("FAILED\n");
  215 + goto close;
  216 + }
  217 +
  218 + rc = read_holding_registers(&mb_param, SERVER_ID,
  219 + UT_HOLDING_REGISTERS_ADDRESS,
  220 + UT_HOLDING_REGISTERS_NB_POINTS,
  221 + tab_rp_registers);
  222 + printf("2/2 read_holding_registers: ");
  223 + if (rc != UT_HOLDING_REGISTERS_NB_POINTS) {
  224 + printf("FAILED (nb points %d)\n", rc);
  225 + goto close;
  226 + }
  227 +
  228 + for (i=0; i < UT_HOLDING_REGISTERS_NB_POINTS; i++) {
  229 + if (tab_rp_registers[i] != UT_HOLDING_REGISTERS_TAB[i]) {
  230 + printf("FAILED (%0X != %0X)\n",
  231 + tab_rp_registers[i],
  232 + UT_HOLDING_REGISTERS_TAB[i]);
  233 + goto close;
  234 + }
  235 + }
  236 + printf("OK\n");
  237 + /* End of many registers */
  238 +
  239 +
  240 + /** INPUT REGISTERS **/
  241 + rc = read_input_registers(&mb_param, SERVER_ID,
  242 + UT_INPUT_REGISTERS_ADDRESS,
  243 + UT_INPUT_REGISTERS_NB_POINTS,
  244 + tab_rp_registers);
  245 + printf("1/1 read_input_registers: ");
  246 + if (rc != UT_INPUT_REGISTERS_NB_POINTS) {
  247 + printf("FAILED (nb points %d)\n", rc);
  248 + goto close;
  249 + }
  250 +
  251 + for (i=0; i < UT_INPUT_REGISTERS_NB_POINTS; i++) {
  252 + if (tab_rp_registers[i] != UT_INPUT_REGISTERS_TAB[i]) {
  253 + printf("FAILED (%0X != %0X)\n",
  254 + tab_rp_registers[i], UT_INPUT_REGISTERS_TAB[i]);
  255 + goto close;
  256 + }
  257 + }
  258 + printf("OK\n");
  259 +
  260 +
  261 + printf("\nTEST FLOATS\n");
  262 + /** FLOAT **/
  263 + printf("1/2 Write float: ");
  264 + modbus_write_float(UT_REAL, tab_rp_registers);
  265 + if (tab_rp_registers[1] == (UT_IREAL >> 16) &&
  266 + tab_rp_registers[0] == (UT_IREAL & 0xFFFF)) {
  267 + printf("OK\n");
  268 + } else {
  269 + printf("FAILED (%x != %x)\n",
  270 + *((uint32_t *)tab_rp_registers), UT_IREAL);
  271 + goto close;
  272 + }
  273 +
  274 + printf("2/2 Read float: ");
  275 + real = modbus_read_float(tab_rp_registers);
  276 + if (real == UT_REAL) {
173 277 printf("OK\n");
  278 + } else {
  279 + printf("FAILED (%f != %f)\n", real, UT_REAL);
  280 + goto close;
  281 + }
174 282  
175   - /** HOLDING REGISTERS **/
  283 + printf("\nAt this point, error messages doesn't mean the test has failed\n");
176 284  
177   - /* Single register */
178   - rc = preset_single_register(&mb_param, SERVER_ID,
179   - UT_HOLDING_REGISTERS_ADDRESS, 0x1234);
180   - printf("1/2 preset_single_register: ");
181   - if (rc == 1) {
182   - printf("OK\n");
183   - } else {
184   - printf("FAILED\n");
185   - goto close;
186   - }
  285 + /** ILLEGAL DATA ADDRESS **/
  286 + printf("\nTEST ILLEGAL DATA ADDRESS:\n");
187 287  
188   - rc = read_holding_registers(&mb_param, SERVER_ID,
189   - UT_HOLDING_REGISTERS_ADDRESS,
190   - 1, tab_rp_registers);
191   - printf("2/2 read_holding_registers: ");
192   - if (rc != 1) {
193   - printf("FAILED (nb points %d)\n", rc);
194   - goto close;
195   - }
  288 + /* The mapping begins at 0 and ending at address + nb_points so
  289 + * the addresses below are not valid. */
196 290  
197   - if (tab_rp_registers[0] != 0x1234) {
198   - printf("FAILED (%0X != %0X)\n",
199   - tab_rp_registers[0], 0x1234);
200   - goto close;
201   - }
  291 + rc = read_coil_status(&mb_param, SERVER_ID,
  292 + UT_COIL_STATUS_ADDRESS,
  293 + UT_COIL_STATUS_NB_POINTS + 1,
  294 + tab_rp_status);
  295 + printf("* read_coil_status: ");
  296 + if (rc == -1 && errno == EMBXILADD)
202 297 printf("OK\n");
203   - /* End of single register */
204   -
205   - /* Many registers */
206   - rc = preset_multiple_registers(&mb_param, SERVER_ID,
207   - UT_HOLDING_REGISTERS_ADDRESS,
208   - UT_HOLDING_REGISTERS_NB_POINTS,
209   - UT_HOLDING_REGISTERS_TAB);
210   - printf("1/2 preset_multiple_registers: ");
211   - if (rc == UT_HOLDING_REGISTERS_NB_POINTS) {
212   - printf("OK\n");
213   - } else {
214   - printf("FAILED\n");
215   - goto close;
216   - }
217   -
218   - rc = read_holding_registers(&mb_param, SERVER_ID,
219   - UT_HOLDING_REGISTERS_ADDRESS,
220   - UT_HOLDING_REGISTERS_NB_POINTS,
221   - tab_rp_registers);
222   - printf("2/2 read_holding_registers: ");
223   - if (rc != UT_HOLDING_REGISTERS_NB_POINTS) {
224   - printf("FAILED (nb points %d)\n", rc);
225   - goto close;
226   - }
227   -
228   - for (i=0; i < UT_HOLDING_REGISTERS_NB_POINTS; i++) {
229   - if (tab_rp_registers[i] != UT_HOLDING_REGISTERS_TAB[i]) {
230   - printf("FAILED (%0X != %0X)\n",
231   - tab_rp_registers[i],
232   - UT_HOLDING_REGISTERS_TAB[i]);
233   - goto close;
234   - }
235   - }
  298 + else {
  299 + printf("FAILED\n");
  300 + goto close;
  301 + }
  302 +
  303 + rc = read_input_status(&mb_param, SERVER_ID,
  304 + UT_INPUT_STATUS_ADDRESS,
  305 + UT_INPUT_STATUS_NB_POINTS + 1,
  306 + tab_rp_status);
  307 + printf("* read_input_status: ");
  308 + if (rc == -1 && errno == EMBXILADD)
236 309 printf("OK\n");
237   - /* End of many registers */
238   -
239   -
240   - /** INPUT REGISTERS **/
241   - rc = read_input_registers(&mb_param, SERVER_ID,
242   - UT_INPUT_REGISTERS_ADDRESS,
243   - UT_INPUT_REGISTERS_NB_POINTS,
244   - tab_rp_registers);
245   - printf("1/1 read_input_registers: ");
246   - if (rc != UT_INPUT_REGISTERS_NB_POINTS) {
247   - printf("FAILED (nb points %d)\n", rc);
248   - goto close;
249   - }
250   -
251   - for (i=0; i < UT_INPUT_REGISTERS_NB_POINTS; i++) {
252   - if (tab_rp_registers[i] != UT_INPUT_REGISTERS_TAB[i]) {
253   - printf("FAILED (%0X != %0X)\n",
254   - tab_rp_registers[i], UT_INPUT_REGISTERS_TAB[i]);
255   - goto close;
256   - }
257   - }
  310 + else {
  311 + printf("FAILED\n");
  312 + goto close;
  313 + }
  314 +
  315 + rc = read_holding_registers(&mb_param, SERVER_ID,
  316 + UT_HOLDING_REGISTERS_ADDRESS,
  317 + UT_HOLDING_REGISTERS_NB_POINTS + 1,
  318 + tab_rp_registers);
  319 + printf("* read_holding_registers: ");
  320 + if (rc == -1 && errno == EMBXILADD)
258 321 printf("OK\n");
259   -
260   -
261   - printf("\nTEST FLOATS\n");
262   - /** FLOAT **/
263   - printf("1/2 Write float: ");
264   - modbus_write_float(UT_REAL, tab_rp_registers);
265   - if (tab_rp_registers[1] == (UT_IREAL >> 16) &&
266   - tab_rp_registers[0] == (UT_IREAL & 0xFFFF)) {
267   - printf("OK\n");
268   - } else {
269   - printf("FAILED (%x != %x)\n",
270   - *((uint32_t *)tab_rp_registers), UT_IREAL);
271   - goto close;
272   - }
273   -
274   - printf("2/2 Read float: ");
275   - real = modbus_read_float(tab_rp_registers);
276   - if (real == UT_REAL) {
277   - printf("OK\n");
278   - } else {
279   - printf("FAILED (%f != %f)\n", real, UT_REAL);
280   - goto close;
281   - }
282   -
283   - printf("\nAt this point, error messages doesn't mean the test has failed\n");
284   -
285   - /** ILLEGAL DATA ADDRESS **/
286   - printf("\nTEST ILLEGAL DATA ADDRESS:\n");
287   -
288   - /* The mapping begins at 0 and ending at address + nb_points so
289   - * the addresses below are not valid. */
290   -
291   - rc = read_coil_status(&mb_param, SERVER_ID,
292   - UT_COIL_STATUS_ADDRESS,
293   - UT_COIL_STATUS_NB_POINTS + 1,
  322 + else {
  323 + printf("FAILED\n");
  324 + goto close;
  325 + }
  326 +
  327 + rc = read_input_registers(&mb_param, SERVER_ID,
  328 + UT_INPUT_REGISTERS_ADDRESS,
  329 + UT_INPUT_REGISTERS_NB_POINTS + 1,
  330 + tab_rp_registers);
  331 + printf("* read_input_registers: ");
  332 + if (rc == -1 && errno == EMBXILADD)
  333 + printf("OK\n");
  334 + else {
  335 + printf("FAILED\n");
  336 + goto close;
  337 + }
  338 +
  339 + rc = force_single_coil(&mb_param, SERVER_ID,
  340 + UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS,
  341 + ON);
  342 + printf("* force_single_coil: ");
  343 + if (rc == -1 && errno == EMBXILADD) {
  344 + printf("OK\n");
  345 + } else {
  346 + printf("FAILED\n");
  347 + goto close;
  348 + }
  349 +
  350 + rc = force_multiple_coils(&mb_param, SERVER_ID,
  351 + UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS,
  352 + UT_COIL_STATUS_NB_POINTS,
294 353 tab_rp_status);
295   - printf("* read_coil_status: ");
296   - if (rc == -1 && errno == EMBXILADD)
297   - printf("OK\n");
298   - else {
299   - printf("FAILED\n");
300   - goto close;
301   - }
302   -
303   - rc = read_input_status(&mb_param, SERVER_ID,
304   - UT_INPUT_STATUS_ADDRESS,
305   - UT_INPUT_STATUS_NB_POINTS + 1,
306   - tab_rp_status);
307   - printf("* read_input_status: ");
308   - if (rc == -1 && errno == EMBXILADD)
309   - printf("OK\n");
310   - else {
311   - printf("FAILED\n");
312   - goto close;
313   - }
314   -
315   - rc = read_holding_registers(&mb_param, SERVER_ID,
316   - UT_HOLDING_REGISTERS_ADDRESS,
317   - UT_HOLDING_REGISTERS_NB_POINTS + 1,
318   - tab_rp_registers);
319   - printf("* read_holding_registers: ");
320   - if (rc == -1 && errno == EMBXILADD)
321   - printf("OK\n");
322   - else {
323   - printf("FAILED\n");
324   - goto close;
325   - }
326   -
327   - rc = read_input_registers(&mb_param, SERVER_ID,
328   - UT_INPUT_REGISTERS_ADDRESS,
329   - UT_INPUT_REGISTERS_NB_POINTS + 1,
330   - tab_rp_registers);
331   - printf("* read_input_registers: ");
332   - if (rc == -1 && errno == EMBXILADD)
333   - printf("OK\n");
334   - else {
335   - printf("FAILED\n");
336   - goto close;
337   - }
338   -
339   - rc = force_single_coil(&mb_param, SERVER_ID,
340   - UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS,
341   - ON);
342   - printf("* force_single_coil: ");
343   - if (rc == -1 && errno == EMBXILADD) {
344   - printf("OK\n");
345   - } else {
346   - printf("FAILED\n");
347   - goto close;
348   - }
349   -
350   - rc = force_multiple_coils(&mb_param, SERVER_ID,
351   - UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS,
352   - UT_COIL_STATUS_NB_POINTS,
353   - tab_rp_status);
354   - printf("* force_multiple_coils: ");
355   - if (rc == -1 && errno == EMBXILADD) {
356   - printf("OK\n");
357   - } else {
358   - printf("FAILED\n");
359   - goto close;
360   - }
  354 + printf("* force_multiple_coils: ");
  355 + if (rc == -1 && errno == EMBXILADD) {
  356 + printf("OK\n");
  357 + } else {
  358 + printf("FAILED\n");
  359 + goto close;
  360 + }
  361 +
  362 + rc = preset_multiple_registers(&mb_param, SERVER_ID,
  363 + UT_HOLDING_REGISTERS_ADDRESS + UT_HOLDING_REGISTERS_NB_POINTS,
  364 + UT_HOLDING_REGISTERS_NB_POINTS,
  365 + tab_rp_registers);
  366 + printf("* preset_multiple_registers: ");
  367 + if (rc == -1 && errno == EMBXILADD) {
  368 + printf("OK\n");
  369 + } else {
  370 + printf("FAILED\n");
  371 + goto close;
  372 + }
361 373  
362   - rc = preset_multiple_registers(&mb_param, SERVER_ID,
363   - UT_HOLDING_REGISTERS_ADDRESS + UT_HOLDING_REGISTERS_NB_POINTS,
364   - UT_HOLDING_REGISTERS_NB_POINTS,
365   - tab_rp_registers);
366   - printf("* preset_multiple_registers: ");
367   - if (rc == -1 && errno == EMBXILADD) {
368   - printf("OK\n");
369   - } else {
370   - printf("FAILED\n");
371   - goto close;
372   - }
373 374  
  375 + /** TOO MANY DATA **/
  376 + printf("\nTEST TOO MANY DATA ERROR:\n");
374 377  
375   - /** TOO MANY DATA **/
376   - printf("\nTEST TOO MANY DATA ERROR:\n");
  378 + rc = read_coil_status(&mb_param, SERVER_ID,
  379 + UT_COIL_STATUS_ADDRESS,
  380 + MAX_STATUS + 1,
  381 + tab_rp_status);
  382 + printf("* read_coil_status: ");
  383 + if (rc == -1 && errno == EMBMDATA) {
  384 + printf("OK\n");
  385 + } else {
  386 + printf("FAILED\n");
  387 + goto close;
  388 + }
  389 +
  390 + rc = read_input_status(&mb_param, SERVER_ID,
  391 + UT_INPUT_STATUS_ADDRESS,
  392 + MAX_STATUS + 1,
  393 + tab_rp_status);
  394 + printf("* read_input_status: ");
  395 + if (rc == -1 && errno == EMBMDATA) {
  396 + printf("OK\n");
  397 + } else {
  398 + printf("FAILED\n");
  399 + goto close;
  400 + }
  401 +
  402 + rc = read_holding_registers(&mb_param, SERVER_ID,
  403 + UT_HOLDING_REGISTERS_ADDRESS,
  404 + MAX_REGISTERS + 1,
  405 + tab_rp_registers);
  406 + printf("* read_holding_registers: ");
  407 + if (rc == -1 && errno == EMBMDATA) {
  408 + printf("OK\n");
  409 + } else {
  410 + printf("FAILED\n");
  411 + goto close;
  412 + }
  413 +
  414 + rc = read_input_registers(&mb_param, SERVER_ID,
  415 + UT_INPUT_REGISTERS_ADDRESS,
  416 + MAX_REGISTERS + 1,
  417 + tab_rp_registers);
  418 + printf("* read_input_registers: ");
  419 + if (rc == -1 && errno == EMBMDATA) {
  420 + printf("OK\n");
  421 + } else {
  422 + printf("FAILED\n");
  423 + goto close;
  424 + }
377 425  
378   - rc = read_coil_status(&mb_param, SERVER_ID,
  426 + rc = force_multiple_coils(&mb_param, SERVER_ID,
379 427 UT_COIL_STATUS_ADDRESS,
380 428 MAX_STATUS + 1,
381 429 tab_rp_status);
382   - printf("* read_coil_status: ");
383   - if (rc == -1 && errno == EMBMDATA) {
384   - printf("OK\n");
385   - } else {
386   - printf("FAILED\n");
387   - goto close;
388   - }
389   -
390   - rc = read_input_status(&mb_param, SERVER_ID,
391   - UT_INPUT_STATUS_ADDRESS,
392   - MAX_STATUS + 1,
393   - tab_rp_status);
394   - printf("* read_input_status: ");
395   - if (rc == -1 && errno == EMBMDATA) {
396   - printf("OK\n");
397   - } else {
398   - printf("FAILED\n");
399   - goto close;
400   - }
401   -
402   - rc = read_holding_registers(&mb_param, SERVER_ID,
403   - UT_HOLDING_REGISTERS_ADDRESS,
404   - MAX_REGISTERS + 1,
405   - tab_rp_registers);
406   - printf("* read_holding_registers: ");
407   - if (rc == -1 && errno == EMBMDATA) {
408   - printf("OK\n");
409   - } else {
410   - printf("FAILED\n");
411   - goto close;
412   - }
413   -
414   - rc = read_input_registers(&mb_param, SERVER_ID,
415   - UT_INPUT_REGISTERS_ADDRESS,
416   - MAX_REGISTERS + 1,
417   - tab_rp_registers);
418   - printf("* read_input_registers: ");
419   - if (rc == -1 && errno == EMBMDATA) {
420   - printf("OK\n");
421   - } else {
422   - printf("FAILED\n");
423   - goto close;
424   - }
425   -
426   - rc = force_multiple_coils(&mb_param, SERVER_ID,
427   - UT_COIL_STATUS_ADDRESS,
428   - MAX_STATUS + 1,
429   - tab_rp_status);
430   - printf("* force_multiple_coils: ");
431   - if (rc == -1 && errno == EMBMDATA) {
432   - printf("OK\n");
433   - } else {
434   - goto close;
435   - printf("FAILED\n");
436   - }
437   -
438   - rc = preset_multiple_registers(&mb_param, SERVER_ID,
439   - UT_HOLDING_REGISTERS_ADDRESS,
440   - MAX_REGISTERS + 1,
441   - tab_rp_registers);
442   - printf("* preset_multiple_registers: ");
443   - if (rc == -1 && errno == EMBMDATA) {
444   - printf("OK\n");
445   - } else {
446   - printf("FAILED\n");
447   - goto close;
448   - }
449   -
450   - /** SLAVE REPLY **/
451   - printf("\nTEST SLAVE REPLY:\n");
452   -
453   - rc = read_holding_registers(&mb_param, 18,
454   - UT_HOLDING_REGISTERS_ADDRESS,
455   - UT_HOLDING_REGISTERS_NB_POINTS,
456   - tab_rp_registers);
457   - printf("1/3 No or response from slave %d: ", 18);
458   - if (mb_param.type_com == RTU) {
459   - /* No response in RTU mode */
460   - if (rc == -1 && errno == ETIMEDOUT) {
461   - printf("OK\n");
462   - } else {
463   - printf("FAILED\n");
464   - goto close;
465   - }
  430 + printf("* force_multiple_coils: ");
  431 + if (rc == -1 && errno == EMBMDATA) {
  432 + printf("OK\n");
  433 + } else {
  434 + goto close;
  435 + printf("FAILED\n");
  436 + }
  437 +
  438 + rc = preset_multiple_registers(&mb_param, SERVER_ID,
  439 + UT_HOLDING_REGISTERS_ADDRESS,
  440 + MAX_REGISTERS + 1,
  441 + tab_rp_registers);
  442 + printf("* preset_multiple_registers: ");
  443 + if (rc == -1 && errno == EMBMDATA) {
  444 + printf("OK\n");
  445 + } else {
  446 + printf("FAILED\n");
  447 + goto close;
  448 + }
  449 +
  450 + /** SLAVE REPLY **/
  451 + printf("\nTEST SLAVE REPLY:\n");
  452 +
  453 + rc = read_holding_registers(&mb_param, 18,
  454 + UT_HOLDING_REGISTERS_ADDRESS,
  455 + UT_HOLDING_REGISTERS_NB_POINTS,
  456 + tab_rp_registers);
  457 + printf("1/3 No or response from slave %d: ", 18);
  458 + if (mb_param.type_com == RTU) {
  459 + /* No response in RTU mode */
  460 + if (rc == -1 && errno == ETIMEDOUT) {
  461 + printf("OK\n");
466 462 } else {
467   - /* Response in TCP mode */
468   - if (rc == UT_HOLDING_REGISTERS_NB_POINTS) {
469   - printf("OK\n");
470   - } else {
471   - printf("FAILED\n");
472   - goto close;
473   - }
  463 + printf("FAILED\n");
  464 + goto close;
474 465 }
475   -
476   - rc = read_holding_registers(&mb_param, MODBUS_BROADCAST_ADDRESS,
477   - UT_HOLDING_REGISTERS_ADDRESS,
478   - UT_HOLDING_REGISTERS_NB_POINTS,
479   - tab_rp_registers);
480   - printf("2/3 Reply after a broadcast query: ");
  466 + } else {
  467 + /* Response in TCP mode */
481 468 if (rc == UT_HOLDING_REGISTERS_NB_POINTS) {
482   - printf("OK\n");
483   - } else {
484   - printf("FAILED\n");
485   - goto close;
486   - }
487   -
488   - /* Save original timeout */
489   - modbus_get_timeout_begin(&mb_param, &timeout_begin_old);
490   -
491   - /* Define a new and too short timeout */
492   - timeout_begin_new.tv_sec = 0;
493   - timeout_begin_new.tv_usec = 0;
494   - modbus_set_timeout_begin(&mb_param, &timeout_begin_new);
495   -
496   - rc = read_holding_registers(&mb_param, SERVER_ID,
497   - UT_HOLDING_REGISTERS_ADDRESS,
498   - UT_HOLDING_REGISTERS_NB_POINTS,
499   - tab_rp_registers);
500   - printf("3/3 Too short timeout: ");
501   - if (rc == -1 && errno == ETIMEDOUT) {
502   - printf("OK\n");
  469 + printf("OK\n");
503 470 } else {
504   - printf("FAILED\n");
505   - goto close;
  471 + printf("FAILED\n");
  472 + goto close;
506 473 }
  474 + }
507 475  
508   - /* Restore original timeout */
509   - modbus_set_timeout_begin(&mb_param, &timeout_begin_old);
510   -
511   - /** BAD RESPONSE **/
512   - printf("\nTEST BAD RESPONSE ERROR:\n");
513   -
514   - /* Allocate only the required space */
515   - tab_rp_registers_bad = (uint16_t *) malloc(
516   - UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL * sizeof(uint16_t));
517   - rc = read_holding_registers(&mb_param, SERVER_ID,
518   - UT_HOLDING_REGISTERS_ADDRESS,
519   - UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL,
520   - tab_rp_registers_bad);
521   - printf("* read_holding_registers: ");
522   - if (rc == -1 && errno == EMBBADDATA) {
523   - printf("OK\n");
524   - } else {
525   - printf("FAILED\n");
526   - goto close;
527   - }
528   - free(tab_rp_registers_bad);
  476 + rc = read_holding_registers(&mb_param, MODBUS_BROADCAST_ADDRESS,
  477 + UT_HOLDING_REGISTERS_ADDRESS,
  478 + UT_HOLDING_REGISTERS_NB_POINTS,
  479 + tab_rp_registers);
  480 + printf("2/3 Reply after a broadcast query: ");
  481 + if (rc == UT_HOLDING_REGISTERS_NB_POINTS) {
  482 + printf("OK\n");
  483 + } else {
  484 + printf("FAILED\n");
  485 + goto close;
  486 + }
  487 +
  488 + /* Save original timeout */
  489 + modbus_get_timeout_begin(&mb_param, &timeout_begin_old);
  490 +
  491 + /* Define a new and too short timeout */
  492 + timeout_begin_new.tv_sec = 0;
  493 + timeout_begin_new.tv_usec = 0;
  494 + modbus_set_timeout_begin(&mb_param, &timeout_begin_new);
  495 +
  496 + rc = read_holding_registers(&mb_param, SERVER_ID,
  497 + UT_HOLDING_REGISTERS_ADDRESS,
  498 + UT_HOLDING_REGISTERS_NB_POINTS,
  499 + tab_rp_registers);
  500 + printf("3/3 Too short timeout: ");
  501 + if (rc == -1 && errno == ETIMEDOUT) {
  502 + printf("OK\n");
  503 + } else {
  504 + printf("FAILED\n");
  505 + goto close;
  506 + }
  507 +
  508 + /* Restore original timeout */
  509 + modbus_set_timeout_begin(&mb_param, &timeout_begin_old);
  510 +
  511 + /** BAD RESPONSE **/
  512 + printf("\nTEST BAD RESPONSE ERROR:\n");
  513 +
  514 + /* Allocate only the required space */
  515 + tab_rp_registers_bad = (uint16_t *) malloc(
  516 + UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL * sizeof(uint16_t));
  517 + rc = read_holding_registers(&mb_param, SERVER_ID,
  518 + UT_HOLDING_REGISTERS_ADDRESS,
  519 + UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL,
  520 + tab_rp_registers_bad);
  521 + printf("* read_holding_registers: ");
  522 + if (rc == -1 && errno == EMBBADDATA) {
  523 + printf("OK\n");
  524 + } else {
  525 + printf("FAILED\n");
  526 + goto close;
  527 + }
  528 + free(tab_rp_registers_bad);
529 529  
530   - printf("\nALL TESTS PASS WITH SUCCESS.\n");
  530 + printf("\nALL TESTS PASS WITH SUCCESS.\n");
531 531  
532 532 close:
533   - /* Free the memory */
534   - free(tab_rp_status);
535   - free(tab_rp_registers);
  533 + /* Free the memory */
  534 + free(tab_rp_status);
  535 + free(tab_rp_registers);
536 536  
537   - /* Close the connection */
538   - modbus_close(&mb_param);
  537 + /* Close the connection */
  538 + modbus_close(&mb_param);
539 539  
540   - return 0;
  540 + return 0;
541 541 }
... ...
tests/unit-test-slave.c
... ... @@ -26,72 +26,72 @@
26 26  
27 27 int main(void)
28 28 {
29   - int socket;
30   - modbus_param_t mb_param;
31   - modbus_mapping_t mb_mapping;
32   - int rc;
33   - int i;
  29 + int socket;
  30 + modbus_param_t mb_param;
  31 + modbus_mapping_t mb_mapping;
  32 + int rc;
  33 + int i;
34 34  
35   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
36   - modbus_set_debug(&mb_param, TRUE);
37   - modbus_set_error_recovery(&mb_param, TRUE);
  35 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
  36 + modbus_set_debug(&mb_param, TRUE);
  37 + modbus_set_error_recovery(&mb_param, TRUE);
38 38  
39   - rc = modbus_mapping_new(&mb_mapping,
40   - UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS,
41   - UT_INPUT_STATUS_ADDRESS + UT_INPUT_STATUS_NB_POINTS,
42   - UT_HOLDING_REGISTERS_ADDRESS + UT_HOLDING_REGISTERS_NB_POINTS,
43   - UT_INPUT_REGISTERS_ADDRESS + UT_INPUT_REGISTERS_NB_POINTS);
44   - if (rc == -1) {
45   - fprintf(stderr, "Failed to allocate the mapping: %s\n",
46   - modbus_strerror(errno));
47   - return -1;
48   - }
  39 + rc = modbus_mapping_new(&mb_mapping,
  40 + UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS,
  41 + UT_INPUT_STATUS_ADDRESS + UT_INPUT_STATUS_NB_POINTS,
  42 + UT_HOLDING_REGISTERS_ADDRESS + UT_HOLDING_REGISTERS_NB_POINTS,
  43 + UT_INPUT_REGISTERS_ADDRESS + UT_INPUT_REGISTERS_NB_POINTS);
  44 + if (rc == -1) {
  45 + fprintf(stderr, "Failed to allocate the mapping: %s\n",
  46 + modbus_strerror(errno));
  47 + return -1;
  48 + }
49 49  
50   - /* Examples from PI_MODBUS_300.pdf.
51   - Only the read-only input values are assigned. */
  50 + /* Examples from PI_MODBUS_300.pdf.
  51 + Only the read-only input values are assigned. */
52 52  
53   - /** INPUT STATUS **/
54   - set_bits_from_bytes(mb_mapping.tab_input_status,
55   - UT_INPUT_STATUS_ADDRESS, UT_INPUT_STATUS_NB_POINTS,
56   - UT_INPUT_STATUS_TAB);
  53 + /** INPUT STATUS **/
  54 + set_bits_from_bytes(mb_mapping.tab_input_status,
  55 + UT_INPUT_STATUS_ADDRESS, UT_INPUT_STATUS_NB_POINTS,
  56 + UT_INPUT_STATUS_TAB);
57 57  
58   - /** INPUT REGISTERS **/
59   - for (i=0; i < UT_INPUT_REGISTERS_NB_POINTS; i++) {
60   - mb_mapping.tab_input_registers[UT_INPUT_REGISTERS_ADDRESS+i] =
61   - UT_INPUT_REGISTERS_TAB[i];;
62   - }
  58 + /** INPUT REGISTERS **/
  59 + for (i=0; i < UT_INPUT_REGISTERS_NB_POINTS; i++) {
  60 + mb_mapping.tab_input_registers[UT_INPUT_REGISTERS_ADDRESS+i] =
  61 + UT_INPUT_REGISTERS_TAB[i];;
  62 + }
63 63  
64   - socket = modbus_slave_listen_tcp(&mb_param, 1);
65   - modbus_slave_accept_tcp(&mb_param, &socket);
  64 + socket = modbus_slave_listen_tcp(&mb_param, 1);
  65 + modbus_slave_accept_tcp(&mb_param, &socket);
66 66  
67   - for (;;) {
68   - uint8_t query[MAX_MESSAGE_LENGTH];
  67 + for (;;) {
  68 + uint8_t query[MAX_MESSAGE_LENGTH];
69 69  
70   - rc = modbus_slave_receive(&mb_param, -1, query);
71   - if (rc > 0) {
72   - if (((query[HEADER_LENGTH_TCP + 3] << 8) + query[HEADER_LENGTH_TCP + 4])
73   - == UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL) {
74   - /* Change the number of values (offset
75   - TCP = 6) */
76   - query[HEADER_LENGTH_TCP + 3] = 0;
77   - query[HEADER_LENGTH_TCP + 4] = UT_HOLDING_REGISTERS_NB_POINTS;
78   - }
  70 + rc = modbus_slave_receive(&mb_param, -1, query);
  71 + if (rc > 0) {
  72 + if (((query[HEADER_LENGTH_TCP + 3] << 8) + query[HEADER_LENGTH_TCP + 4])
  73 + == UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL) {
  74 + /* Change the number of values (offset
  75 + TCP = 6) */
  76 + query[HEADER_LENGTH_TCP + 3] = 0;
  77 + query[HEADER_LENGTH_TCP + 4] = UT_HOLDING_REGISTERS_NB_POINTS;
  78 + }
79 79  
80   - rc = modbus_slave_manage(&mb_param, query, rc, &mb_mapping);
81   - if (rc == -1) {
82   - return -1;
83   - }
84   - } else {
85   - /* Connection closed by the client or error */
86   - break;
87   - }
  80 + rc = modbus_slave_manage(&mb_param, query, rc, &mb_mapping);
  81 + if (rc == -1) {
  82 + return -1;
  83 + }
  84 + } else {
  85 + /* Connection closed by the client or error */
  86 + break;
88 87 }
  88 + }
89 89  
90   - printf("Quit the loop: %s\n", modbus_strerror(errno));
  90 + printf("Quit the loop: %s\n", modbus_strerror(errno));
91 91  
92   - close(socket);
93   - modbus_mapping_free(&mb_mapping);
94   - modbus_close(&mb_param);
  92 + close(socket);
  93 + modbus_mapping_free(&mb_mapping);
  94 + modbus_close(&mb_param);
95 95  
96   - return 0;
  96 + return 0;
97 97 }
... ...
tests/version.c
... ... @@ -20,12 +20,12 @@
20 20  
21 21 int main(void)
22 22 {
23   - printf("Compiled with libmodbus version %s\n", LIBMODBUS_VERSION_STRING);
24   - printf("Linked with libmodbus version %d.%d.%d\n",
25   - libmodbus_version_major, libmodbus_version_minor, libmodbus_version_micro);
  23 + printf("Compiled with libmodbus version %s\n", LIBMODBUS_VERSION_STRING);
  24 + printf("Linked with libmodbus version %d.%d.%d\n",
  25 + libmodbus_version_major, libmodbus_version_minor, libmodbus_version_micro);
26 26  
27   - if (LIBMODBUS_VERSION_CHECK(2, 1, 0)) {
28   - printf("The functions to read/write float values are available.\n");
29   - }
30   - return 0;
  27 + if (LIBMODBUS_VERSION_CHECK(2, 1, 0)) {
  28 + printf("The functions to read/write float values are available.\n");
  29 + }
  30 + return 0;
31 31 }
... ...