Jelajahi Sumber

add modbus tcp

chenbin 4 tahun lalu
induk
melakukan
9f696fbb13

+ 22 - 2
inc/small_modbus_base.h

@@ -1,8 +1,9 @@
-/*
+/*
  * Change Logs:
  * Date           Author       Notes
  * 2020-08-21     chenbin      small modbus the first version
  * 2021-06-02     chenbin      small modbus
+ * 2021-08-06     chenbin      small modbus
  */
 #ifndef _SMALL_MODBUS_BASE_H_
 #define _SMALL_MODBUS_BASE_H_
@@ -78,6 +79,21 @@ enum portType
 	MODBUS_PORT_SOCKET		= 2
 };
 
+enum deviceType
+{
+	MODBUS_DEVICE_NONE	= 0,
+	MODBUS_DEVICE_SLAVE		= 1,
+	MODBUS_DEVICE_MASTER	= 2
+};
+
+enum modbusMagic
+{
+	MODBUS_MAGIC				= 0x4243424D,  //"MBCB"
+	MODBUS_CORE_MAGIC		= 0x4343424D,  //"MBCC"
+	MODBUS_PORT_MAGIC		= 0x5050424D,  //"MBPP"
+};
+
+
 #define MODBUS_BROADCAST_ADDRESS    0
 
 /* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 1 page 12)
@@ -143,6 +159,7 @@ typedef struct _small_modbus_port   small_modbus_port_t; //modbus port (rtthread
 
 struct _small_modbus_core
 {
+	const uint32_t magic;
 	const uint16_t type;
 	const uint16_t len_header;
 	const uint16_t len_checksum;
@@ -156,6 +173,7 @@ struct _small_modbus_core
 
 struct _small_modbus_port
 {
+	const uint32_t magic;
 	const uint32_t type;
 	int (*open)(small_modbus_t *smb);
 	int (*close)(small_modbus_t *smb);
@@ -167,9 +185,11 @@ struct _small_modbus_port
 
 struct _small_modbus
 {
-	uint8_t			mode;
+	uint32_t		modbus_magic;
+	uint16_t 		device_mode;
 	uint8_t     slave_addr;
 	uint8_t     debug_level;
+	
 	uint16_t    transfer_id;
 	uint16_t    protocol_id;
 	

+ 44 - 26
inc/small_modbus_port_rtthread.h

@@ -16,42 +16,45 @@
 int modbus_init(small_modbus_t* smb, uint8_t core_type, void* port);
 small_modbus_t* modbus_create(uint8_t core_type, void* port);
 
-
 /*
-*modbus port device
+*modbus port rtthread device
 */
 #if SMALL_MODBUS_RTTHREAD_USE_DEVICDE
 
 #include <rtthread.h>
 #include <rtdevice.h>
 
-typedef struct _small_modbus_port_rtdevice   small_modbus_port_rtdevice_t;
+typedef struct small_modbus_port_rtdevice   small_modbus_port_rtdevice_t;
 
-struct _small_modbus_port_rtdevice
+struct small_modbus_port_rtdevice
 {
 	struct _small_modbus_port 	base;
-    struct serial_configure     serial_config;
+  struct serial_configure     serial_config;
 	const char                  *device_name;
 	struct rt_device            *device;
 	struct rt_semaphore         rx_sem;
 	rt_size_t                   rx_size;
 	int                         oflag;
-    int                         (*rts_set)(int on);
+	int                         (*rts_set)(int on);
 };
 
+small_modbus_port_rtdevice_t *modbus_port_rtdevice_get(small_modbus_t *smb);
+
 int modbus_port_rtdevice_init(small_modbus_port_rtdevice_t *port,const char *device_name);
+int modbus_port_rtdevice_deinit(small_modbus_port_rtdevice_t *port);
+
 small_modbus_port_rtdevice_t *modbus_port_rtdevice_create(const char *device_name);
-small_modbus_port_rtdevice_t *modbus_port_rtdevice_get(small_modbus_t *smb);
+int modbus_port_rtdevice_delete(void *port);
 
-int modbus_set_rts(small_modbus_t *smb,int (*rts_set)(int on));
-int modbus_set_serial_config(small_modbus_t *smb,struct serial_configure *serial_config);
-int modbus_set_oflag(small_modbus_t *smb,int oflag);
+int modbus_rtu_set_serial_rts(small_modbus_t *smb,int (*rts_set)(int on));
+int modbus_rtu_set_serial_name(small_modbus_t *smb,const char *device_name);
+int modbus_rtu_set_serial_config(small_modbus_t *smb,struct serial_configure *serial_config);
+int modbus_rtu_set_oflag(small_modbus_t *smb,int oflag);
 
 #endif
 
-
 /*
-*modbus port socket
+*modbus port rtthread socket
 */
 #if SMALL_MODBUS_RTTHREAD_USE_SOCKET
 
@@ -77,25 +80,40 @@ int modbus_set_oflag(small_modbus_t *smb,int oflag);
 
 #include "ipc/ringbuffer.h"
 
-typedef struct _small_modbus_port_rtsocket   small_modbus_port_rtsocket_t;
+typedef struct small_modbus_port_rtsocket   small_modbus_port_rtsocket_t;
 
-struct _small_modbus_port_rtsocket
+struct small_modbus_port_rtsocket
 {
-	struct _small_modbus_port base;
-	int32_t     socket_fd;
-	const char *hostname;
-	const char *hostport;
+	struct _small_modbus_port 	base;
+	int32_t     								socket_fd;
+	int													devicemode;
+	const char *								hostname;
+	const char *								hostport;
 	
-	struct rt_ringbuffer rx_ringbuff;
-	uint8_t 			rx_ringbuff_pool[256];
-	uint8_t 			rx_temp[256];
-//	char				hostname[128];
-//	char				hostport[16];
+	struct rt_ringbuffer 			rx_ringbuff;
+	uint8_t 									rx_temp[256];
+	uint8_t 									rx_ringbuff_pool[256];
 };
 
-int modbus_port_rtsocket_init(small_modbus_port_rtsocket_t*port,char *hostname,char *hostport);
-small_modbus_port_rtsocket_t *modbus_port_rtsocket_create(char *hostname,char *hostport);
-small_modbus_port_rtsocket_t *modbus_port_socket_get(small_modbus_t *smb);
+
+int modbus_tcp_status(small_modbus_t *smb);
+int modbus_tcp_disconnect(small_modbus_t *smb);
+int modbus_tcp_connect(small_modbus_t *smb);
+int modbus_tcp_listen(small_modbus_t *smb, int max_connection);
+int modbus_tcp_accept(small_modbus_t *smb,int socket_fd);
+
+int modbus_tcp_get_socket(small_modbus_t *smb);
+int modbus_tcp_set_socket(small_modbus_t *smb,int socket);
+int modbus_tcp_set_socket_block(small_modbus_t *smb,int isblock);
+
+
+small_modbus_port_rtsocket_t * modbus_port_rtsocket_get(small_modbus_t *smb);
+
+int modbus_port_rtsocket_init(small_modbus_port_rtsocket_t *port,int devicemode,char *hostname,char *hostport);
+int modbus_port_rtsocket_deinit(small_modbus_port_rtsocket_t *port);
+
+small_modbus_port_rtsocket_t *modbus_port_rtsocket_create(int devicemode, char *hostname, char *hostport);
+int modbus_port_rtsocket_delete(void *port);
 
 #endif
 

+ 4 - 2
src/small_modbus_base.c

@@ -1,4 +1,4 @@
-/*
+/*
  * Change Logs:
  * Date           Author       Notes
  * 2020-08-21     chenbin      small modbus the first version
@@ -10,9 +10,11 @@ int _modbus_init(small_modbus_t *smb)
 {
 	if(smb != NULL)
 	{
+		smb->modbus_magic = MODBUS_MAGIC;
+		smb->device_mode = MODBUS_DEVICE_SLAVE;
 		smb->transfer_id = 0;
 		smb->protocol_id = 0;
-		smb->debug_level = 0;
+		smb->debug_level = 1;  //log level info
 		if(smb->timeout_frame==0)
 		{
 				smb->timeout_frame = 100;

+ 301 - 87
src/small_modbus_port_rtthread.c

@@ -34,8 +34,8 @@ int _modbus_debug(small_modbus_t *smb,int level,const char *fmt, ...)
 */
 int modbus_init(small_modbus_t* smb, uint8_t core_type, void* port)
 {
-    small_modbus_port_t* smb_port;
-    if (smb && core_type && port)
+    small_modbus_port_t* smb_port = port;
+    if (smb && core_type && smb_port)
     {
         _modbus_init(smb);
         if ((core_type == MODBUS_CORE_RTU) || (core_type == MODBUS_CORE_TCP))  // check core type
@@ -53,7 +53,6 @@ int modbus_init(small_modbus_t* smb, uint8_t core_type, void* port)
         {
             return 0;
         }
-        smb_port = port;
         if ((smb_port->type == MODBUS_PORT_DEVICE) || (smb_port->type == MODBUS_PORT_SOCKET))  // check port type
         {
             smb->port = smb_port;
@@ -131,17 +130,21 @@ static int _modbus_rtdevice_close(small_modbus_t *smb)
 static int _modbus_rtdevice_write(small_modbus_t *smb,uint8_t *data,uint16_t length)
 {
 	small_modbus_port_rtdevice_t *smb_port_device = (small_modbus_port_rtdevice_t*)smb->port;
-	rt_enter_critical();
+	//rt_enter_critical();
 	
 	if(smb_port_device->rts_set)
 			smb_port_device->rts_set(1);
-		
+	
+	rt_enter_critical();
+	
 	rt_device_write(smb_port_device->device,0,data,length);
 	
+	rt_exit_critical();
+	
 	if(smb_port_device->rts_set)
 			smb_port_device->rts_set(0);
 	
-	rt_exit_critical();
+	//rt_exit_critical();
 	return length;
 }
 
@@ -179,11 +182,20 @@ static int _modbus_rtdevice_wait(small_modbus_t *smb,int timeout)
 	return rc;
 }
 
+
+small_modbus_port_rtdevice_t * modbus_port_rtdevice_get(small_modbus_t *smb)
+{
+	if( (smb->port->type == MODBUS_PORT_DEVICE) && (smb->port->magic == MODBUS_PORT_MAGIC) )
+	{
+		return (small_modbus_port_rtdevice_t*)smb->port;
+	}
+	return NULL;
+}
+
 int modbus_port_rtdevice_init(small_modbus_port_rtdevice_t *port,const char *device_name)
 {
-	//rt_memcpy(&port->base,&_port_device_default,sizeof(small_modbus_port_t));
-	
 	(*(uint32_t *)&(port->base.type)) = MODBUS_PORT_DEVICE;
+	(*(uint32_t *)&(port->base.magic)) = MODBUS_PORT_MAGIC;
 	port->base.open = _modbus_rtdevice_open;
 	port->base.close = _modbus_rtdevice_close;
 	port->base.read = _modbus_rtdevice_read;
@@ -200,6 +212,15 @@ int modbus_port_rtdevice_init(small_modbus_port_rtdevice_t *port,const char *dev
 	return 0;
 }
 
+int modbus_port_rtdevice_deinit(small_modbus_port_rtdevice_t *port)
+{
+	if(port->device)
+	{
+		rt_device_close(port->device);
+	}
+	return 0;
+}
+
 small_modbus_port_rtdevice_t *modbus_port_rtdevice_create(const char *device_name)
 {
 	small_modbus_port_rtdevice_t *smb_port_device = rt_malloc_align(sizeof(small_modbus_port_rtdevice_t),4);
@@ -212,16 +233,18 @@ small_modbus_port_rtdevice_t *modbus_port_rtdevice_create(const char *device_nam
 	return NULL;
 }
 
-small_modbus_port_rtdevice_t * modbus_port_rtdevice_get(small_modbus_t *smb)
+int modbus_port_rtdevice_delete(void *port)
 {
-	if(smb->port->type == MODBUS_PORT_DEVICE)
+	small_modbus_port_rtdevice_t *port_device = port;
+	if( port_device && (port_device->base.type == MODBUS_PORT_DEVICE) && (port_device->base.magic == MODBUS_PORT_MAGIC))
 	{
-		return (small_modbus_port_rtdevice_t*)smb->port;
+		modbus_port_rtdevice_deinit(port_device);
+		rt_free_align(port_device);
 	}
-	return NULL;
+	return 0;
 }
 
-int modbus_set_rts(small_modbus_t *smb,int (*rts_set)(int on))
+int modbus_rtu_set_serial_rts(small_modbus_t *smb,int (*rts_set)(int on))
 {
 	small_modbus_port_rtdevice_t *smb_port_device = modbus_port_rtdevice_get(smb);
 	if(smb_port_device)
@@ -230,7 +253,18 @@ int modbus_set_rts(small_modbus_t *smb,int (*rts_set)(int on))
 	}
 	return 0;
 }
-int modbus_set_serial_config(small_modbus_t *smb,struct serial_configure *serial_config)
+
+int modbus_rtu_set_serial_name(small_modbus_t *smb,const char *device_name)
+{
+	small_modbus_port_rtdevice_t *smb_port_device = modbus_port_rtdevice_get(smb);
+	if(smb_port_device)
+	{
+		modbus_port_rtdevice_init(smb_port_device,device_name);
+	}
+	return 0;
+}
+
+int modbus_rtu_set_serial_config(small_modbus_t *smb,struct serial_configure *serial_config)
 {
 	small_modbus_port_rtdevice_t *smb_port_device = modbus_port_rtdevice_get(smb);
 	if(smb_port_device)
@@ -242,7 +276,7 @@ int modbus_set_serial_config(small_modbus_t *smb,struct serial_configure *serial
 	}
 	return 0;
 }
-int modbus_set_oflag(small_modbus_t *smb,int oflag)
+int modbus_rtu_set_oflag(small_modbus_t *smb,int oflag)
 {
 	small_modbus_port_rtdevice_t *smb_port_device = modbus_port_rtdevice_get(smb);
 	if(smb_port_device)
@@ -279,69 +313,14 @@ int modbus_set_oflag(small_modbus_t *smb,int oflag)
 #include <lwip/sockets.h>
 #endif /* RT_USING_SAL */
 
-
 static int _modbus_rtsocket_open(small_modbus_t *smb)
 {
-	small_modbus_port_rtsocket_t *smb_port_socket = (small_modbus_port_rtsocket_t *)smb->port;
-	
-	int ret = 0;
-	unsigned long mode = 0;
-	struct addrinfo hints, *addr_list, *cur;
-	struct timeval timeout;
-	
-	if(smb_port_socket->socket_fd < 0)
-	{
-		/* Do name resolution with both IPv6 and IPv4 */
-		memset(&hints, 0, sizeof(hints));
-		hints.ai_family = AF_INET;
-		hints.ai_socktype = SOCK_STREAM;
-		hints.ai_protocol = IPPROTO_TCP;
-		//hints.ai_protocol = PROTOCOL_TLS;
-
-		ret = getaddrinfo(smb_port_socket->hostname, smb_port_socket->hostport, &hints, &addr_list);
-		if (ret != 0)
-		{
-				rt_kprintf("modbus rtsocket getaddrinfo fail [%d]\n",ret);
-				return ret;
-		}
-		for (cur = addr_list; cur != NULL; cur = cur->ai_next)
-		{
-			smb_port_socket->socket_fd = socket(cur->ai_family,SOCK_STREAM, IPPROTO_TCP);
-			if (smb_port_socket->socket_fd < 0)
-			{
-				continue;
-			}
-			mode = 0;
-			ioctlsocket(smb_port_socket->socket_fd, FIONBIO, &mode);
-			
-			ret = connect(smb_port_socket->socket_fd, cur->ai_addr, cur->ai_addrlen);
-			rt_kprintf("net connect socket:%d  ret:%d\n",smb_port_socket->socket_fd,ret);
-			if (ret == 0)
-			{
-				break;//连接成功
-			}
-			closesocket(smb_port_socket->socket_fd);
-		}
-		freeaddrinfo(addr_list);
-		
-		timeout.tv_sec = smb->timeout_frame /1000;
-		timeout.tv_usec = (smb->timeout_frame%1000)*1000;
-		
-		setsockopt(smb_port_socket->socket_fd, SOL_SOCKET, SO_RCVTIMEO, (void *) &timeout,sizeof(timeout));
-		
-		setsockopt(smb_port_socket->socket_fd, SOL_SOCKET, SO_SNDTIMEO, (void *) &timeout,sizeof(timeout));
-	}
-	return 0;
+	return modbus_tcp_connect(smb);
 }
 
 static int _modbus_rtsocket_close(small_modbus_t *smb)
 {
-	small_modbus_port_rtsocket_t *smb_port_socket = (small_modbus_port_rtsocket_t *)smb->port;
-	if(smb_port_socket->socket_fd >= 0)
-	{
-		closesocket( smb_port_socket->socket_fd );
-	}
-	return 0;
+	return modbus_tcp_disconnect(smb);
 }
 
 static int _modbus_rtsocket_write(small_modbus_t *smb,uint8_t *data,uint16_t length)
@@ -394,6 +373,8 @@ static int _modbus_rtsocket_flush(small_modbus_t *smb)
 static int _modbus_rtsocket_wait(small_modbus_t *smb,int timeout)
 {
 	int rc = -1;
+	int socket_status = 0;
+	socklen_t slen;
 	small_modbus_port_rtsocket_t *smb_port_socket = (small_modbus_port_rtsocket_t *)smb->port;
 	
 	struct timeval tv = {
@@ -405,18 +386,20 @@ static int _modbus_rtsocket_wait(small_modbus_t *smb,int timeout)
 			tv.tv_sec = 0;
 			tv.tv_usec = 1000*10;
 	}
-	setsockopt(smb_port_socket->socket_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
+	setsockopt(smb_port_socket->socket_fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(struct timeval));
 
 	rc = recv(smb_port_socket->socket_fd, smb_port_socket->rx_temp, sizeof(smb_port_socket->rx_temp), 0);
 	if(rc <= 0)
 	{
-		if(!(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN))
+		getsockopt(smb_port_socket->socket_fd, SOL_SOCKET, SO_ERROR, (void *)&socket_status , &slen );
+		
+		if(!(socket_status == EINTR || socket_status == EWOULDBLOCK || socket_status == EAGAIN))
 		{
-				//rt_kprintf("net recv err :%d\n",rc);
+				modbus_debug_error(smb,"rtsocket[%d] recv err(%d)\n", smb_port_socket->socket_fd, socket_status);
 				rc = MODBUS_ERROR_READ;
 		}else
 		{
-				//rt_kprintf("net recv timeout :%d\n",rc);
+				//rt_kprintf("rtsocket timeout :%d\n",rc);
 				rc = MODBUS_TIMEOUT;
 		}
 	}else
@@ -427,9 +410,19 @@ static int _modbus_rtsocket_wait(small_modbus_t *smb,int timeout)
 }
 
 
-int modbus_port_socket_init(small_modbus_port_rtsocket_t *port,char *hostname,char *hostport)
+small_modbus_port_rtsocket_t * modbus_port_rtsocket_get(small_modbus_t *smb)
 {
-	(*(uint32_t *)&(port->base.type)) = MODBUS_PORT_DEVICE;
+	if( (smb->port->type == MODBUS_PORT_SOCKET) && (smb->port->magic == MODBUS_PORT_MAGIC))
+	{
+		return (small_modbus_port_rtsocket_t*)smb->port;
+	}
+	return NULL;
+}
+
+int modbus_port_rtsocket_init(small_modbus_port_rtsocket_t *port,int devicemode,char *hostname,char *hostport)
+{
+	(*(uint32_t *)&(port->base.type)) = MODBUS_PORT_SOCKET;
+	(*(uint32_t *)&(port->base.magic)) = MODBUS_PORT_MAGIC;
 	port->base.open = _modbus_rtsocket_open;
 	port->base.close = _modbus_rtsocket_close;
 	port->base.read = _modbus_rtsocket_read;
@@ -439,8 +432,6 @@ int modbus_port_socket_init(small_modbus_port_rtsocket_t *port,char *hostname,ch
 	
 	rt_ringbuffer_init( &(port->rx_ringbuff) ,port->rx_ringbuff_pool, sizeof(port->rx_ringbuff_pool) );  //static init ringbuff
 	
-//	rt_strncpy(port->hostname,hostname, rt_strnlen(hostname,sizeof(port->hostname)));  //copy hostname
-//	rt_strncpy(port->hostport,hostport, rt_strnlen(hostport,sizeof(port->hostport)));  //copy hostport
 	if(hostname)
 	{
 		port->hostname = hostname;
@@ -449,30 +440,253 @@ int modbus_port_socket_init(small_modbus_port_rtsocket_t *port,char *hostname,ch
 	{
 		port->hostport = hostport;
 	}
-	
+	port->devicemode = devicemode;
 	port->socket_fd = -1;
 	return 0;
 }
 
-small_modbus_port_rtsocket_t *modbus_port_rtsocket_create(char *hostname,char *hostport)
+int modbus_port_rtsocket_deinit(small_modbus_port_rtsocket_t *port)
+{
+	if(port->socket_fd >= 0)
+	{
+		closesocket( port->socket_fd );
+		port->socket_fd = -1;
+	}
+	return 0;
+}
+
+small_modbus_port_rtsocket_t *modbus_port_rtsocket_create(int devicemode, char *hostname, char *hostport)
 {
 	small_modbus_port_rtsocket_t *port_socket = rt_malloc_align(sizeof(small_modbus_port_rtsocket_t),4);
 	if(port_socket)
 	{
 		rt_memset(port_socket,0,sizeof(small_modbus_port_rtsocket_t));
-		modbus_port_socket_init(port_socket,hostname,hostport);
+		modbus_port_rtsocket_init(port_socket, devicemode, hostname, hostport);
 		return port_socket;
 	}
 	return NULL;
 }
 
-small_modbus_port_rtsocket_t * modbus_port_rtsocket_get(small_modbus_t *smb)
+int modbus_port_rtsocket_delete(void *port)
 {
-	if(smb->port->type == MODBUS_PORT_SOCKET)
+	small_modbus_port_rtsocket_t *port_socket = port;
+	if( port_socket && (port_socket->base.type == MODBUS_PORT_SOCKET) && (port_socket->base.magic == MODBUS_PORT_MAGIC))
 	{
-		return (small_modbus_port_rtsocket_t*)smb->port;
+		modbus_port_rtsocket_deinit(port_socket);
+		rt_free_align(port_socket);
 	}
-	return NULL;
+	return 0;
+}
+
+
+/*
+* modbus tcp api
+*/
+int modbus_tcp_status(small_modbus_t *smb)
+{
+	small_modbus_port_rtsocket_t *port_socket = (small_modbus_port_rtsocket_t *)smb->port;
+	
+	int socket_status = 0;
+	socklen_t slen;
+	
+	if( (port_socket) && (port_socket->socket_fd >= 0) )
+	{
+		getsockopt(port_socket->socket_fd, SOL_SOCKET, SO_ERROR, (void *)&socket_status , &slen );
+	}
+	return socket_status;
+}
+
+
+int modbus_tcp_disconnect(small_modbus_t *smb)
+{
+	small_modbus_port_rtsocket_t *port_socket = (small_modbus_port_rtsocket_t *)smb->port;
+	if( (port_socket) && (port_socket->socket_fd >= 0) )
+	{
+		closesocket( port_socket->socket_fd );
+		port_socket->socket_fd = -1;
+	}
+	return 0;
+}
+
+int modbus_tcp_connect(small_modbus_t *smb)
+{
+	small_modbus_port_rtsocket_t *port_socket = modbus_port_rtsocket_get(smb);
+	if( (port_socket) && (port_socket->socket_fd < 0) )
+	{
+		int ret = 0;
+		unsigned long mode = 0;
+		struct addrinfo hints, *addr_list, *cur;
+		struct timeval timeout;
+		
+		struct sockaddr_in * socket_addr;
+		char addr_str[64];
+		
+		/* Do name resolution with both IPv6 and IPv4 */
+		memset(&hints, 0, sizeof(hints));
+		hints.ai_family = AF_INET;
+		hints.ai_socktype = SOCK_STREAM;
+		hints.ai_protocol = IPPROTO_TCP;
+		//hints.ai_protocol = PROTOCOL_TLS;
+
+		ret = getaddrinfo(port_socket->hostname, port_socket->hostport, &hints, &addr_list);
+		if (ret != 0)
+		{
+				modbus_debug_info(smb,"rtsocket getaddrinfo fail [%d]\n",ret);
+				return ret;
+		}
+		for (cur = addr_list; cur != NULL; cur = cur->ai_next)
+		{
+			port_socket->socket_fd = socket(cur->ai_family,SOCK_STREAM, IPPROTO_TCP);
+			if (port_socket->socket_fd < 0)
+			{
+				continue;
+			}
+			mode = 0;
+			ioctlsocket(port_socket->socket_fd, FIONBIO, &mode);
+			
+			ret = connect(port_socket->socket_fd, cur->ai_addr, cur->ai_addrlen);
+		
+			socket_addr = (struct sockaddr_in *)(cur->ai_addr);
+			
+			inet_ntoa_r(socket_addr->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
+			
+			modbus_debug_info(smb,"rtsocket[%d] connect: %s:%d  ret:%d\n", port_socket->socket_fd, addr_str ,ntohs(socket_addr->sin_port),ret);
+			if (ret == 0)
+			{
+				break;//连接成功
+			}
+			closesocket(port_socket->socket_fd);
+		}
+		freeaddrinfo(addr_list);
+		
+		timeout.tv_sec = smb->timeout_frame /1000;
+		timeout.tv_usec = (smb->timeout_frame%1000)*1000;
+		
+		setsockopt(port_socket->socket_fd, SOL_SOCKET, SO_RCVTIMEO, (void *) &timeout,sizeof(timeout));
+		
+		setsockopt(port_socket->socket_fd, SOL_SOCKET, SO_SNDTIMEO, (void *) &timeout,sizeof(timeout));
+	}
+	return port_socket->socket_fd;
+}
+
+int modbus_tcp_listen(small_modbus_t *smb, int max_connection)
+{
+	small_modbus_port_rtsocket_t *port_socket = modbus_port_rtsocket_get(smb);
+	if( (port_socket) && (port_socket->socket_fd < 0) )
+	{
+		int ret = 0;
+		unsigned long mode = 0;
+		struct addrinfo hints, *addr_list, *cur;
+		
+		struct sockaddr_in * socket_addr;
+		char addr_str[64];
+		
+		/* Do name resolution with both IPv6 and IPv4 */
+		memset(&hints, 0, sizeof(hints));
+		hints.ai_family = AF_INET;
+		hints.ai_socktype = SOCK_STREAM;
+		hints.ai_protocol = IPPROTO_TCP;
+		//hints.ai_protocol = PROTOCOL_TLS;
+
+		ret = getaddrinfo(port_socket->hostname, port_socket->hostport, &hints, &addr_list);
+		if (ret != 0)
+		{
+				modbus_debug_info(smb,"rtsocket getaddrinfo fail [%d]\n",ret);
+				return ret;
+		}
+		for (cur = addr_list; cur != NULL; cur = cur->ai_next)
+		{
+			port_socket->socket_fd = socket(cur->ai_family,SOCK_STREAM, IPPROTO_TCP);
+			if (port_socket->socket_fd < 0)
+			{
+				continue;
+			}
+			mode = 0;
+			ioctlsocket(port_socket->socket_fd, FIONBIO, &mode);
+			mode = 1;
+			setsockopt(port_socket->socket_fd, SOL_SOCKET, SO_REUSEADDR,(void *)&mode, sizeof (mode));
+			
+			ret = bind(port_socket->socket_fd, cur->ai_addr, cur->ai_addrlen);
+			if(ret == 0)
+			{
+				ret = listen(port_socket->socket_fd, max_connection);
+				
+				socket_addr = (struct sockaddr_in *)(cur->ai_addr);
+				inet_ntoa_r(socket_addr->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
+				
+				modbus_debug_info(smb,"rtsocket[%d] listen: %s:%d  ret:%d\n", port_socket->socket_fd, addr_str ,ntohs(socket_addr->sin_port),ret);
+				if (ret == 0)
+				{
+					break;//连接成功
+				}
+			}else
+			{
+				modbus_debug_info(smb,"rtsocket[%d] bind:err ret:%d\n", port_socket->socket_fd, ret);
+			}
+			closesocket(port_socket->socket_fd);
+		}
+		freeaddrinfo(addr_list);
+	}
+	return port_socket->socket_fd;
+}
+
+int modbus_tcp_accept(small_modbus_t *smb,int socket_fd)
+{
+	small_modbus_port_rtsocket_t *port_socket = modbus_port_rtsocket_get(smb);
+	
+	struct sockaddr_storage addr;
+  socklen_t addrlen;
+	int ret_socket = -1;
+	
+	if( (port_socket) && (socket_fd >= 0) )
+	{
+		ret_socket = accept( socket_fd, (struct sockaddr *)&addr, &addrlen);
+		if(ret_socket < 0)
+		{
+			closesocket(ret_socket);
+		}
+	}
+	return ret_socket;
+}
+
+
+
+int modbus_tcp_get_socket(small_modbus_t *smb)
+{
+	small_modbus_port_rtsocket_t *port_socket = modbus_port_rtsocket_get(smb);
+	if(port_socket)
+	{
+		return port_socket->socket_fd;
+	}
+	return 0;
+}
+
+int modbus_tcp_set_socket(small_modbus_t *smb,int socket)
+{
+	small_modbus_port_rtsocket_t *port_socket = modbus_port_rtsocket_get(smb);
+	if(port_socket)
+	{
+		port_socket->socket_fd = socket;
+	}
+	return 0;
+}
+
+int modbus_tcp_set_socket_block(small_modbus_t *smb,int isblock)
+{
+	small_modbus_port_rtsocket_t *port_socket = modbus_port_rtsocket_get(smb);
+	unsigned long mode = 0;
+	if(port_socket)
+	{
+		if(isblock)
+		{	
+			mode = 0;
+		}else
+		{
+			mode = 1;
+		}
+		ioctlsocket(port_socket->socket_fd, FIONBIO, &mode);
+	}
+	return 0;
 }
 
 #endif

+ 7 - 5
src/small_modbus_rtu.c

@@ -26,11 +26,12 @@ static int _rtu_build_response_header(small_modbus_t *smb,uint8_t *buff,int slav
     buff[1] = fun;
     return _MODBUS_RTU_PRESET_RSP_LENGTH;
 }
-
+#if (SMALL_MODBUS_CRC_BYTE_SWAP)
 static inline uint16_t bswap_16(uint16_t x)
 {
     return (x >> 8) | (x << 8);
 }
+#endif
 
 static int _rtu_check_send_pre(small_modbus_t *smb,uint8_t *buff,int length)
 {
@@ -85,14 +86,15 @@ static int _rtu_check_wait_response(small_modbus_t *smb,uint8_t *buff,int length
 
 const small_modbus_core_t _modbus_rtu_core =
 {
-    .type           = MODBUS_CORE_RTU,
+    .magic     = MODBUS_CORE_MAGIC,
+    .type      = MODBUS_CORE_RTU,
     .len_header     = _MODBUS_RTU_HEADER_LENGTH,
     .len_checksum   = _MODBUS_RTU_CHECKSUM_LENGTH,
     .len_adu_max    = _MODBUS_RTU_MAX_ADU_LENGTH,
     .build_request_header   = _rtu_build_request_header,
     .build_response_header  = _rtu_build_response_header,
-    .check_send_pre     = _rtu_check_send_pre,
-    .check_wait_request   = _rtu_check_wait_request,
-    .check_wait_response   = _rtu_check_wait_response
+    .check_send_pre    			= _rtu_check_send_pre,
+    .check_wait_request   	= _rtu_check_wait_request,
+    .check_wait_response   	= _rtu_check_wait_response
 };
 

+ 5 - 4
src/small_modbus_tcp.c

@@ -120,15 +120,16 @@ static int _tcp_check_wait_response(small_modbus_t *smb,uint8_t *buff,int length
 
 const small_modbus_core_t _modbus_tcp_core =
 {
-    .type           = MODBUS_CORE_TCP,
+    .magic     = MODBUS_CORE_MAGIC,
+    .type      = MODBUS_CORE_TCP,
     .len_header     = _MODBUS_TCP_HEADER_LENGTH,
     .len_checksum   = _MODBUS_TCP_CHECKSUM_LENGTH,
     .len_adu_max    = _MODBUS_TCP_MAX_ADU_LENGTH,
     .build_request_header   = _tcp_build_request_header,
     .build_response_header  = _tcp_build_response_header,
-    .check_send_pre     = _tcp_check_send_pre,
-    .check_wait_request    = _tcp_check_wait_request,
-    .check_wait_response   = _tcp_check_wait_response
+    .check_send_pre     		= _tcp_check_send_pre,
+    .check_wait_request    	= _tcp_check_wait_request,
+    .check_wait_response   	= _tcp_check_wait_response
 };