You need to sign in before continuing.

Commit f410aea2f72fb1205803b10e5cec4a322601a82b

Authored by Stéphane Raimbault
1 parent 50fa79da

Isolate RTU and TCP headers and simplify Win32 detection

- move termios header in RTU backend
- move TCP headers in TCP backend
- use native serial on Win32 for Cygwin
- avoid too many defines
configure.ac
@@ -47,15 +47,13 @@ LIBMODBUS_LT_VERSION_INFO=$LIBMODBUS_LD_CURRENT:$LIBMODBUS_LD_REVISION:$LIBMODBU @@ -47,15 +47,13 @@ LIBMODBUS_LT_VERSION_INFO=$LIBMODBUS_LD_CURRENT:$LIBMODBUS_LD_REVISION:$LIBMODBU
47 AC_SUBST(LIBMODBUS_LT_VERSION_INFO) 47 AC_SUBST(LIBMODBUS_LT_VERSION_INFO)
48 48
49 # Check whether we are building for Win32 49 # Check whether we are building for Win32
50 -build_win32="false"  
51 -case "${host}" in 50 +os_win32="false"
  51 +case "${target}" in
52 *mingw32) 52 *mingw32)
53 - AC_DEFINE([BUILD_WIN32], [], [Build libmodbus for Win32])  
54 - build_win32="true" 53 + os_win32="true"
55 ;; 54 ;;
56 esac 55 esac
57 -  
58 -AM_CONDITIONAL(BUILD_WIN32, test "$build_win32" = "true") 56 +AM_CONDITIONAL(OS_WIN32, test "$os_win32" = "true")
59 57
60 # Checks for programs. 58 # Checks for programs.
61 AC_PROG_CC 59 AC_PROG_CC
src/Makefile.am
@@ -11,7 +11,8 @@ libmodbus_la_SOURCES = \ @@ -11,7 +11,8 @@ libmodbus_la_SOURCES = \
11 modbus-tcp.h \ 11 modbus-tcp.h \
12 modbus-tcp-private.h \ 12 modbus-tcp-private.h \
13 modbus-version.h 13 modbus-version.h
14 -if BUILD_WIN32 14 +
  15 +if OS_WIN32
15 libmodbus_la_LIBADD = -lwsock32 16 libmodbus_la_LIBADD = -lwsock32
16 endif 17 endif
17 18
src/modbus-rtu-private.h
@@ -19,7 +19,12 @@ @@ -19,7 +19,12 @@
19 #define _MODBUS_RTU_PRIVATE_H_ 19 #define _MODBUS_RTU_PRIVATE_H_
20 20
21 #include <stdint.h> 21 #include <stdint.h>
  22 +
  23 +#if defined(_WIN32)
  24 +#include <windows.h>
  25 +#else
22 #include <termios.h> 26 #include <termios.h>
  27 +#endif
23 28
24 #define _MODBUS_RTU_HEADER_LENGTH 1 29 #define _MODBUS_RTU_HEADER_LENGTH 1
25 #define _MODBUS_RTU_PRESET_REQ_LENGTH 6 30 #define _MODBUS_RTU_PRESET_REQ_LENGTH 6
@@ -27,11 +32,7 @@ @@ -27,11 +32,7 @@
27 32
28 #define _MODBUS_RTU_CHECKSUM_LENGTH 2 33 #define _MODBUS_RTU_CHECKSUM_LENGTH 2
29 34
30 -#ifdef NATIVE_WIN32  
31 -  
32 -#define WIN32_LEAN_AND_MEAN  
33 -#include <windows.h>  
34 - 35 +#if defined(_WIN32)
35 /* WIN32: struct containing serial handle and a receive buffer */ 36 /* WIN32: struct containing serial handle and a receive buffer */
36 #define PY_BUF_SIZE 512 37 #define PY_BUF_SIZE 512
37 struct win32_ser { 38 struct win32_ser {
@@ -42,7 +43,7 @@ struct win32_ser { @@ -42,7 +43,7 @@ struct win32_ser {
42 /* Received chars */ 43 /* Received chars */
43 DWORD n_bytes; 44 DWORD n_bytes;
44 }; 45 };
45 -#endif /* NATIVE_WIN32 */ 46 +#endif /* _WIN32 */
46 47
47 typedef struct _modbus_rtu { 48 typedef struct _modbus_rtu {
48 /* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*" on Mac OS X for 49 /* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*" on Mac OS X for
@@ -50,7 +51,7 @@ typedef struct _modbus_rtu { @@ -50,7 +51,7 @@ typedef struct _modbus_rtu {
50 as the directory+file name was bigger than 19 bytes. Making it 67 bytes 51 as the directory+file name was bigger than 19 bytes. Making it 67 bytes
51 for now, but OS X does support 256 byte file names. May become a problem 52 for now, but OS X does support 256 byte file names. May become a problem
52 in the future. */ 53 in the future. */
53 -#ifdef __APPLE_CC__ 54 +#if defined(__APPLE_CC__)
54 char device[64]; 55 char device[64];
55 #else 56 #else
56 char device[16]; 57 char device[16];
@@ -63,7 +64,7 @@ typedef struct _modbus_rtu { @@ -63,7 +64,7 @@ typedef struct _modbus_rtu {
63 uint8_t stop_bit; 64 uint8_t stop_bit;
64 /* Parity: 'N', 'O', 'E' */ 65 /* Parity: 'N', 'O', 'E' */
65 char parity; 66 char parity;
66 -#ifdef NATIVE_WIN32 67 +#if defined(_WIN32)
67 struct win32_ser w_ser; 68 struct win32_ser w_ser;
68 DCB old_dcb; 69 DCB old_dcb;
69 #else 70 #else
src/modbus-rtu.c
@@ -22,7 +22,6 @@ @@ -22,7 +22,6 @@
22 #include <string.h> 22 #include <string.h>
23 #include <unistd.h> 23 #include <unistd.h>
24 24
25 -#include "modbus.h"  
26 #include "modbus-private.h" 25 #include "modbus-private.h"
27 26
28 #include "modbus-rtu.h" 27 #include "modbus-rtu.h"
@@ -156,7 +155,7 @@ int _modbus_rtu_send_msg_pre(uint8_t *req, int req_length) @@ -156,7 +155,7 @@ int _modbus_rtu_send_msg_pre(uint8_t *req, int req_length)
156 return req_length; 155 return req_length;
157 } 156 }
158 157
159 -#ifdef NATIVE_WIN32 158 +#if defined(_WIN32)
160 /* This simple implementation is sort of a substitute of the select() call, working 159 /* This simple implementation is sort of a substitute of the select() call, working
161 * this way: the win32_ser_select() call tries to read some data from the serial port, 160 * this way: the win32_ser_select() call tries to read some data from the serial port,
162 * setting the timeout as the select() call would. Data read is stored into the 161 * setting the timeout as the select() call would. Data read is stored into the
@@ -233,7 +232,7 @@ static int win32_ser_read(struct win32_ser *ws, uint8_t *p_msg, unsigned int max @@ -233,7 +232,7 @@ static int win32_ser_read(struct win32_ser *ws, uint8_t *p_msg, unsigned int max
233 232
234 ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length) 233 ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length)
235 { 234 {
236 -#ifdef NATIVE_WIN32 235 +#if defined(_WIN32)
237 modbus_rtu_t *ctx_rtu = ctx->backend_data; 236 modbus_rtu_t *ctx_rtu = ctx->backend_data;
238 DWORD n_bytes = 0; 237 DWORD n_bytes = 0;
239 return (WriteFile(ctx_rtu->w_ser.fd, req, req_length, &n_bytes, NULL)) ? n_bytes : -1; 238 return (WriteFile(ctx_rtu->w_ser.fd, req, req_length, &n_bytes, NULL)) ? n_bytes : -1;
@@ -244,7 +243,7 @@ ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length) @@ -244,7 +243,7 @@ ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length)
244 243
245 ssize_t _modbus_rtu_recv(modbus_t *ctx, uint8_t *rsp, int rsp_length) 244 ssize_t _modbus_rtu_recv(modbus_t *ctx, uint8_t *rsp, int rsp_length)
246 { 245 {
247 -#ifdef NATIVE_WIN32 246 +#if defined(_WIN32)
248 return win32_ser_read(&((modbus_rtu_t *)ctx->backend_data)->w_ser, rsp, rsp_length); 247 return win32_ser_read(&((modbus_rtu_t *)ctx->backend_data)->w_ser, rsp, rsp_length);
249 #else 248 #else
250 return read(ctx->s, rsp, rsp_length); 249 return read(ctx->s, rsp, rsp_length);
@@ -283,7 +282,7 @@ int _modbus_rtu_check_integrity(modbus_t *ctx, uint8_t *msg, @@ -283,7 +282,7 @@ int _modbus_rtu_check_integrity(modbus_t *ctx, uint8_t *msg,
283 /* Sets up a serial port for RTU communications */ 282 /* Sets up a serial port for RTU communications */
284 static int _modbus_rtu_connect(modbus_t *ctx) 283 static int _modbus_rtu_connect(modbus_t *ctx)
285 { 284 {
286 -#ifdef NATIVE_WIN32 285 +#if defined(_WIN32)
287 DCB dcb; 286 DCB dcb;
288 #else 287 #else
289 struct termios tios; 288 struct termios tios;
@@ -297,7 +296,7 @@ static int _modbus_rtu_connect(modbus_t *ctx) @@ -297,7 +296,7 @@ static int _modbus_rtu_connect(modbus_t *ctx)
297 ctx_rtu->data_bit, ctx_rtu->stop_bit); 296 ctx_rtu->data_bit, ctx_rtu->stop_bit);
298 } 297 }
299 298
300 -#ifdef NATIVE_WIN32 299 +#if defined(_WIN32)
301 /* Some references here: 300 /* Some references here:
302 * http://msdn.microsoft.com/en-us/library/aa450602.aspx 301 * http://msdn.microsoft.com/en-us/library/aa450602.aspx
303 */ 302 */
@@ -681,7 +680,7 @@ void _modbus_rtu_close(modbus_t *ctx) @@ -681,7 +680,7 @@ void _modbus_rtu_close(modbus_t *ctx)
681 /* Closes the file descriptor in RTU mode */ 680 /* Closes the file descriptor in RTU mode */
682 modbus_rtu_t *ctx_rtu = ctx->backend_data; 681 modbus_rtu_t *ctx_rtu = ctx->backend_data;
683 682
684 -#ifdef NATIVE_WIN32 683 +#if defined(_WIN32)
685 /* Revert settings */ 684 /* Revert settings */
686 if (!SetCommState(ctx_rtu->w_ser.fd, &ctx_rtu->old_dcb)) 685 if (!SetCommState(ctx_rtu->w_ser.fd, &ctx_rtu->old_dcb))
687 fprintf(stderr, "ERROR Couldn't revert to configuration (LastError %d)\n", 686 fprintf(stderr, "ERROR Couldn't revert to configuration (LastError %d)\n",
@@ -698,7 +697,7 @@ void _modbus_rtu_close(modbus_t *ctx) @@ -698,7 +697,7 @@ void _modbus_rtu_close(modbus_t *ctx)
698 697
699 int _modbus_rtu_flush(modbus_t *ctx) 698 int _modbus_rtu_flush(modbus_t *ctx)
700 { 699 {
701 -#ifdef NATIVE_WIN32 700 +#if defined(_WIN32)
702 modbus_rtu_t *ctx_rtu = ctx->backend_data; 701 modbus_rtu_t *ctx_rtu = ctx->backend_data;
703 ctx_rtu->w_ser.n_bytes = 0; 702 ctx_rtu->w_ser.n_bytes = 0;
704 return ( FlushFileBuffers(ctx_rtu->w_ser.fd) == FALSE ); 703 return ( FlushFileBuffers(ctx_rtu->w_ser.fd) == FALSE );
@@ -730,7 +729,7 @@ int _modbus_rtu_accept(modbus_t *ctx, int *socket) @@ -730,7 +729,7 @@ int _modbus_rtu_accept(modbus_t *ctx, int *socket)
730 int _modbus_rtu_select(modbus_t *ctx, fd_set *rfds, struct timeval *tv, int msg_length_computed, int msg_length) 729 int _modbus_rtu_select(modbus_t *ctx, fd_set *rfds, struct timeval *tv, int msg_length_computed, int msg_length)
731 { 730 {
732 int s_rc; 731 int s_rc;
733 -#ifdef NATIVE_WIN32 732 +#if defined(_WIN32)
734 s_rc = win32_ser_select(&(((modbus_rtu_t*)ctx->backend_data)->w_ser), msg_length_computed, tv); 733 s_rc = win32_ser_select(&(((modbus_rtu_t*)ctx->backend_data)->w_ser), msg_length_computed, tv);
735 if (s_rc == 0) { 734 if (s_rc == 0) {
736 errno = ETIMEDOUT; 735 errno = ETIMEDOUT;
src/modbus-tcp.c
@@ -15,29 +15,44 @@ @@ -15,29 +15,44 @@
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 -#include "modbus.h"  
19 -#include "modbus-private.h"  
20 -  
21 #include <stdio.h> 18 #include <stdio.h>
22 #include <stdlib.h> 19 #include <stdlib.h>
23 #include <string.h> 20 #include <string.h>
24 #include <errno.h> 21 #include <errno.h>
25 #include <unistd.h> 22 #include <unistd.h>
26 -  
27 #include <sys/types.h> 23 #include <sys/types.h>
28 24
29 -#ifdef NATIVE_WIN32  
30 -#include <ws2tcpip.h> 25 +#if defined(_WIN32)
  26 +# define OS_WIN32
  27 +# include <winsock2.h>
  28 +# include <ws2tcpip.h>
  29 +# define SHUT_RDWR 2
31 #else 30 #else
32 -#include <sys/socket.h>  
33 -#include <sys/ioctl.h> 31 +# include <sys/socket.h>
  32 +# include <sys/ioctl.h>
  33 +
  34 +#if defined(OpenBSD) || (defined(__FreeBSD__) && __FreeBSD__ < 5)
  35 +# define OS_BSD
  36 +# include <netinet/in_systm.h>
  37 +#endif
  38 +
  39 +# include <netinet/in.h>
  40 +# include <netinet/ip.h>
  41 +# include <netinet/tcp.h>
  42 +# include <arpa/inet.h>
  43 +#endif
  44 +
  45 +#if !defined(MSG_NOSIGNAL)
  46 +#define MSG_NOSIGNAL 0
34 #endif 47 #endif
35 48
  49 +#include "modbus-private.h"
  50 +
36 #include "modbus-tcp.h" 51 #include "modbus-tcp.h"
37 #include "modbus-tcp-private.h" 52 #include "modbus-tcp-private.h"
38 53
39 -#ifdef NATIVE_WIN32  
40 -static int _modbus_tcp_init_win32() 54 +#ifdef OS_WIN32
  55 +static int _modbus_tcp_init_win32(void)
41 { 56 {
42 // Initialise Win32 Socket API 57 // Initialise Win32 Socket API
43 WORD wVersionRequested; 58 WORD wVersionRequested;
@@ -174,7 +189,7 @@ static int _modbus_tcp_connect(modbus_t *ctx) @@ -174,7 +189,7 @@ static int _modbus_tcp_connect(modbus_t *ctx)
174 struct sockaddr_in addr; 189 struct sockaddr_in addr;
175 modbus_tcp_t *ctx_tcp = ctx->backend_data; 190 modbus_tcp_t *ctx_tcp = ctx->backend_data;
176 191
177 -#ifdef NATIVE_WIN32 192 +#ifdef OS_WIN32
178 if (_modbus_tcp_init_win32() == -1) { 193 if (_modbus_tcp_init_win32() == -1) {
179 return -1; 194 return -1;
180 } 195 }
@@ -195,7 +210,7 @@ static int _modbus_tcp_connect(modbus_t *ctx) @@ -195,7 +210,7 @@ static int _modbus_tcp_connect(modbus_t *ctx)
195 return -1; 210 return -1;
196 } 211 }
197 212
198 -#ifndef NATIVE_WIN32 213 +#ifndef OS_WIN32
199 /** 214 /**
200 * Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's 215 * Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's
201 * necessary to workaround that problem. 216 * necessary to workaround that problem.
@@ -241,7 +256,7 @@ int _modbus_tcp_flush(modbus_t *ctx) @@ -241,7 +256,7 @@ int _modbus_tcp_flush(modbus_t *ctx)
241 do { 256 do {
242 /* Extract the garbage from the socket */ 257 /* Extract the garbage from the socket */
243 char devnull[MODBUS_TCP_MAX_ADU_LENGTH]; 258 char devnull[MODBUS_TCP_MAX_ADU_LENGTH];
244 -#ifndef NATIVE_WIN32 259 +#ifndef OS_WIN32
245 rc = recv(ctx->s, devnull, MODBUS_TCP_MAX_ADU_LENGTH, MSG_DONTWAIT); 260 rc = recv(ctx->s, devnull, MODBUS_TCP_MAX_ADU_LENGTH, MSG_DONTWAIT);
246 #else 261 #else
247 /* On Win32, it's a bit more complicated to not wait */ 262 /* On Win32, it's a bit more complicated to not wait */
@@ -275,7 +290,7 @@ int _modbus_tcp_listen(modbus_t *ctx, int nb_connection) @@ -275,7 +290,7 @@ int _modbus_tcp_listen(modbus_t *ctx, int nb_connection)
275 struct sockaddr_in addr; 290 struct sockaddr_in addr;
276 modbus_tcp_t *ctx_tcp = ctx->backend_data; 291 modbus_tcp_t *ctx_tcp = ctx->backend_data;
277 292
278 -#ifdef NATIVE_WIN32 293 +#ifdef OS_WIN32
279 if (_modbus_tcp_init_win32() == -1) { 294 if (_modbus_tcp_init_win32() == -1) {
280 return -1; 295 return -1;
281 } 296 }
src/modbus-tcp.h
@@ -20,6 +20,15 @@ @@ -20,6 +20,15 @@
20 20
21 #include "modbus.h" 21 #include "modbus.h"
22 22
  23 +#if defined(_WIN32) && !defined(__CYGWIN__)
  24 +/* Win32 with MinGW, supplement to <errno.h> */
  25 +#include <winsock2.h>
  26 +#define ECONNRESET WSAECONNRESET
  27 +#define ECONNREFUSED WSAECONNREFUSED
  28 +#define ETIMEDOUT WSAETIMEDOUT
  29 +#define ENOPROTOOPT WSAENOPROTOOPT
  30 +#endif
  31 +
23 #define MODBUS_TCP_DEFAULT_PORT 502 32 #define MODBUS_TCP_DEFAULT_PORT 502
24 #define MODBUS_TCP_SLAVE 0xFF 33 #define MODBUS_TCP_SLAVE 0xFF
25 34
src/modbus.h
@@ -20,35 +20,12 @@ @@ -20,35 +20,12 @@
20 20
21 #include <config.h> 21 #include <config.h>
22 22
23 -/* If win32 and no cygwin, suppose it's MinGW or any other native windows compiler. */  
24 -#if defined(WIN32) && !defined(__CYGWIN__)  
25 -#define NATIVE_WIN32  
26 -#define MSG_NOSIGNAL 0  
27 -#define ECONNRESET WSAECONNRESET  
28 -#define ECONNREFUSED WSAECONNREFUSED  
29 -#define ETIMEDOUT WSAETIMEDOUT  
30 -#define ENOPROTOOPT WSAENOPROTOOPT  
31 -#define SHUT_RDWR 2  
32 -#include <winsock2.h>  
33 -#endif /* win32 and no cygwin */  
34 -  
35 /* Add this for macros that defined unix flavor */ 23 /* Add this for macros that defined unix flavor */
36 #if (defined(__unix__) || defined(unix)) && !defined(USG) 24 #if (defined(__unix__) || defined(unix)) && !defined(USG)
37 #include <sys/param.h> 25 #include <sys/param.h>
38 #endif 26 #endif
39 -#include <stdint.h>  
40 -#ifndef NATIVE_WIN32  
41 -  
42 -#include <termios.h>  
43 27
44 -#if defined(OpenBSD) || (defined(__FreeBSD__) && __FreeBSD__ < 5)  
45 -#include <netinet/in_systm.h>  
46 -#endif  
47 -#include <netinet/in.h>  
48 -#include <netinet/ip.h>  
49 -#include <netinet/tcp.h>  
50 -#include <arpa/inet.h>  
51 -#endif 28 +#include <stdint.h>
52 #include <sys/time.h> 29 #include <sys/time.h>
53 30
54 #include "modbus-version.h" 31 #include "modbus-version.h"
tests/bandwidth-server-many-up.c
@@ -24,8 +24,10 @@ @@ -24,8 +24,10 @@
24 24
25 #include <modbus.h> 25 #include <modbus.h>
26 26
27 -#ifdef NATIVE_WIN32 27 +#if defined(_WIN32)
28 #include <ws2tcpip.h> 28 #include <ws2tcpip.h>
  29 +#else
  30 +#include <netinet/in.h>
29 #endif 31 #endif
30 32
31 #define NB_CONNECTION 5 33 #define NB_CONNECTION 5