Implemented UDP
Implemented TCP/UDP abstraction layer
This commit is contained in:
		
							parent
							
								
									c863dbd443
								
							
						
					
					
						commit
						f82756e670
					
				
					 8 changed files with 374 additions and 174 deletions
				
			
		|  | @ -1,4 +1,5 @@ | ||||||
| /*@!Encoding:1252*/ | /*@!Encoding:1252*/ | ||||||
|  | 
 | ||||||
| void bin_to_strhex(byte bin[], char result[]) | void bin_to_strhex(byte bin[], char result[]) | ||||||
| { | { | ||||||
| 	char hex_str[17]= "0123456789ABCDEF"; | 	char hex_str[17]= "0123456789ABCDEF"; | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| /*@!Encoding:1252*/ | /*@!Encoding:1252*/ | ||||||
|  | // Additionally include ModbusTcpCommon.cin or ModbusUdpCommon.cin | ||||||
| includes | includes | ||||||
| { | { | ||||||
| 	#include "TcpCommon.cin" |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| variables | variables | ||||||
|  | @ -35,7 +35,7 @@ variables | ||||||
| 
 | 
 | ||||||
| void ModbusInit(char Remote_IP[], word Remote_Port) | void ModbusInit(char Remote_IP[], word Remote_Port) | ||||||
| { | { | ||||||
| 	TcpConnectTo("192.168.1.3", 502); | 	ModbusConnectTo("192.168.1.3", 502); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ModbusMakeHeader(struct ModbusApHeader mbap, byte length) | void ModbusMakeHeader(struct ModbusApHeader mbap, byte length) | ||||||
|  | @ -63,8 +63,8 @@ void ModbusReadBits(word address, word count) | ||||||
| 	mbr.Count = count;				// [2] Number of items; 1:max 2000=0x7D0 | 	mbr.Count = count;				// [2] Number of items; 1:max 2000=0x7D0 | ||||||
| 	 | 	 | ||||||
| 	memcpy_h2n(buffer, mbr); | 	memcpy_h2n(buffer, mbr); | ||||||
| 	TcpSnd(buffer); | 	ModbusSend(buffer); | ||||||
| 	TcpRecv(); | 	ModbusRecv(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void OnModbusReceiveBits(byte response[], dword size) | void OnModbusReceiveBits(byte response[], dword size) | ||||||
|  | @ -86,8 +86,8 @@ void ModbusReadRegisters(word address, word count)	// 16 bit | ||||||
| 	mbr.Count = count;				// [2] Number of items; 1:max 2000=0x7D0 | 	mbr.Count = count;				// [2] Number of items; 1:max 2000=0x7D0 | ||||||
| 	 | 	 | ||||||
| 	memcpy_h2n(buffer, mbr); | 	memcpy_h2n(buffer, mbr); | ||||||
| 	TcpSnd(buffer); | 	ModbusSend(buffer); | ||||||
| 	TcpRecv(); | 	ModbusRecv(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void OnModbusReceiveRegisters(byte response[], dword size) | void OnModbusReceiveRegisters(byte response[], dword size) | ||||||
|  | @ -112,8 +112,8 @@ void ModbusWriteBit(word address, byte value) | ||||||
| 	mbw.Value = value << 8;			// [2] Output value (0x0000: Off, 0xFF00: On) | 	mbw.Value = value << 8;			// [2] Output value (0x0000: Off, 0xFF00: On) | ||||||
| 	 | 	 | ||||||
| 	memcpy_h2n(buffer, mbw); | 	memcpy_h2n(buffer, mbw); | ||||||
| 	TcpSnd(buffer); | 	ModbusSend(buffer); | ||||||
| 	TcpRecv(); | 	ModbusRecv(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void OnModbusConfirmBit(byte response[], dword size) | void OnModbusConfirmBit(byte response[], dword size) | ||||||
|  | @ -135,8 +135,8 @@ void ModbusWriteRegister(word address, word value) | ||||||
| 	mbw.Value = value;				// [2] Output value | 	mbw.Value = value;				// [2] Output value | ||||||
| 	 | 	 | ||||||
| 	memcpy_h2n(buffer, mbw); | 	memcpy_h2n(buffer, mbw); | ||||||
| 	TcpSnd(buffer); | 	ModbusSend(buffer); | ||||||
| 	TcpRecv(); | 	ModbusRecv(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void OnModbusConfirmRegister(byte response[], dword size) | void OnModbusConfirmRegister(byte response[], dword size) | ||||||
|  | @ -165,8 +165,8 @@ void ModbusWriteBits(word address, word count, byte values[]) | ||||||
| 	{ | 	{ | ||||||
| 		buffer[i+13] = values[i]; | 		buffer[i+13] = values[i]; | ||||||
| 	} | 	} | ||||||
| 	TcpSnd(buffer); | 	ModbusSend(buffer); | ||||||
| 	TcpRecv(); | 	ModbusRecv(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ModbusWriteBitsB(word address, word count, byte values[]) | void ModbusWriteBitsB(word address, word count, byte values[]) | ||||||
|  | @ -235,8 +235,8 @@ void ModbusWriteRegisters(word address, word count, word values[]) | ||||||
| 		buffer[i+13] = values[i] >> 8; | 		buffer[i+13] = values[i] >> 8; | ||||||
| 		buffer[i+14] = values[i] & 0xFF; | 		buffer[i+14] = values[i] & 0xFF; | ||||||
| 	} | 	} | ||||||
| 	TcpSnd(buffer); | 	ModbusSend(buffer); | ||||||
| 	TcpRecv(); | 	ModbusRecv(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void OnModbusConfirmRegisters(byte response[], dword size) | void OnModbusConfirmRegisters(byte response[], dword size) | ||||||
|  | @ -249,34 +249,6 @@ void OnModbusConfirmRegisters(byte response[], dword size) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void OnTcpReceive(dword socket, long result, dword address, dword port, byte buffer[], dword size) |  | ||||||
| { |  | ||||||
| 	if (result == 0) |  | ||||||
| 	{ |  | ||||||
| 		if (size == 0) |  | ||||||
| 		{ |  | ||||||
| 			// Size of zero indicates that the socket was closed by the communication peer. |  | ||||||
| 			writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive: Socket closed by peer"); |  | ||||||
| 			g_%NODE_NAME%_Socket.Close(); |  | ||||||
| 			g_%NODE_NAME%_TcpState = CLOSED; |  | ||||||
| 		} |  | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			// Sucessfully received some bytes over the TCP/IP connection. |  | ||||||
| 			OnModbusReceive(buffer, size); |  | ||||||
| 			TcpRecv(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		gIpLastErr = g_%NODE_NAME%_Socket.GetLastSocketError(); |  | ||||||
| 		g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); |  | ||||||
| 		writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr); |  | ||||||
| 		g_%NODE_NAME%_Socket.Close(); |  | ||||||
| 		g_%NODE_NAME%_TcpState = CLOSED; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void OnModbusReceive(byte buffer[], dword size) | void OnModbusReceive(byte buffer[], dword size) | ||||||
| { | { | ||||||
| 	// Test transaction identifier? | 	// Test transaction identifier? | ||||||
|  |  | ||||||
							
								
								
									
										50
									
								
								Modbus/ModbusTcpCommon.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								Modbus/ModbusTcpCommon.cin
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,50 @@ | ||||||
|  | /*@!Encoding:1252*/ | ||||||
|  | 
 | ||||||
|  | includes | ||||||
|  | { | ||||||
|  | 	#include "TcpCommon.cin" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ModbusConnectTo(char Remote_IP[], word Remote_Port) | ||||||
|  | { | ||||||
|  | 	TcpConnectTo("192.168.1.3", 502); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ModbusSend(byte buffer[]) | ||||||
|  | { | ||||||
|  | 	TcpSnd(buffer); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ModbusRecv() | ||||||
|  | { | ||||||
|  | 	TcpRecv(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void OnTcpReceive(dword socket, long result, dword address, dword port, byte buffer[], dword size) | ||||||
|  | { | ||||||
|  | 	if (result == 0) | ||||||
|  | 	{ | ||||||
|  | 		if (size == 0) | ||||||
|  | 		{ | ||||||
|  | 			// Size of zero indicates that the socket was closed by the communication peer. | ||||||
|  | 			writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive: Socket closed by peer"); | ||||||
|  | 			g_%NODE_NAME%_Socket.Close(); | ||||||
|  | 			g_%NODE_NAME%_SocketState = CLOSED; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			// Sucessfully received some bytes over the TCP/IP connection. | ||||||
|  | 			OnModbusReceive(buffer, size); | ||||||
|  | 			TcpRecv(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		gIpLastErr = g_%NODE_NAME%_Socket.GetLastSocketError(); | ||||||
|  | 		g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); | ||||||
|  | 		writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr); | ||||||
|  | 		g_%NODE_NAME%_Socket.Close(); | ||||||
|  | 		g_%NODE_NAME%_SocketState = CLOSED; | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										50
									
								
								Modbus/ModbusUdpCommon.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								Modbus/ModbusUdpCommon.cin
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,50 @@ | ||||||
|  | /*@!Encoding:1252*/ | ||||||
|  | 
 | ||||||
|  | includes | ||||||
|  | { | ||||||
|  | 	#include "UdpCommon.cin" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ModbusConnectTo(char Remote_IP[], word Remote_Port) | ||||||
|  | { | ||||||
|  | 	UdpConnectTo("192.168.1.3", 502); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ModbusSend(byte buffer[]) | ||||||
|  | { | ||||||
|  | 	UdpSnd(buffer); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void ModbusRecv() | ||||||
|  | { | ||||||
|  | 	UdpRecv(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void OnUdpReceiveFrom(dword socket, long result, dword address, dword port, byte buffer[], dword size) | ||||||
|  | { | ||||||
|  | 	if (result == 0) | ||||||
|  | 	{ | ||||||
|  | 		if (size == 0) | ||||||
|  | 		{ | ||||||
|  | 			// Size of zero indicates that the socket was closed by the communication peer. | ||||||
|  | 			writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive: Socket closed by peer"); | ||||||
|  | 			g_%NODE_NAME%_Socket.Close(); | ||||||
|  | 			g_%NODE_NAME%_SocketState = CLOSED; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			// Sucessfully received some bytes over the TCP/IP connection. | ||||||
|  | 			OnModbusReceive(buffer, size); | ||||||
|  | 			UdpRecv(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		gIpLastErr = g_%NODE_NAME%_Socket.GetLastSocketError(); | ||||||
|  | 		g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); | ||||||
|  | 		writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr); | ||||||
|  | 		g_%NODE_NAME%_Socket.Close(); | ||||||
|  | 		g_%NODE_NAME%_SocketState = CLOSED; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -2,102 +2,17 @@ | ||||||
| includes | includes | ||||||
| { | { | ||||||
| 	#include "Common.cin" | 	#include "Common.cin" | ||||||
|  | 	#include "TcpUdpCommon.cin" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| variables | variables | ||||||
| { | { | ||||||
| 	const long	WSA_IO_PENDING		= 997; |  | ||||||
| 	const long	WSAEWOULDBLOCK		= 10035; |  | ||||||
| 	const dword INVALID_IP			= 0xffffffff; |  | ||||||
| 	 |  | ||||||
| 	long gIpLastErr					= 0; |  | ||||||
| 	char gIpLastErrStr[512]			= ""; |  | ||||||
| 	TcpSocket g_%NODE_NAME%_Socket; | 	TcpSocket g_%NODE_NAME%_Socket; | ||||||
| 
 | 
 | ||||||
| 	dword g_%NODE_NAME%_RemoteIP		= INVALID_IP; | 	byte gRxBuffer[8192]; | ||||||
| 	word g_%NODE_NAME%_RemotePort	= 0; |  | ||||||
| 	 |  | ||||||
| 	enum TcpState { NULL, OK, ERROR, CLOSED }; |  | ||||||
| 	enum TcpState g_%NODE_NAME%_TcpState = NULL; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	byte gTcpRxBuffer[8192]; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| dword TcpSetupIp(char Local_IP[]) |  | ||||||
| { |  | ||||||
| 	int			adapterIndex; |  | ||||||
| 	const int	size = 512; |  | ||||||
| 	char		text[size] = ""; |  | ||||||
| 	dword		addresses[1]; |  | ||||||
| 	dword		address; |  | ||||||
| 	word		adapterCount; |  | ||||||
| 	word		i; |  | ||||||
| 
 |  | ||||||
| 	adapterCount = IpGetAdapterCount(); |  | ||||||
| 	adapterIndex = @sysvar::TCPIP::AdapterIndex; |  | ||||||
| 
 |  | ||||||
| 	switch (adapterCount) |  | ||||||
| 	{ |  | ||||||
| 		case 0: |  | ||||||
| 			writeLineEx(0, 3, "<%BASE_FILE_NAME%> Error: There is no network interface available!"); |  | ||||||
| 			stop(); |  | ||||||
| 			return INVALID_IP; |  | ||||||
| 		break; |  | ||||||
| 		case 1: |  | ||||||
| 			writeLineEx(0, 1, "<%BASE_FILE_NAME%> Info: There is 1 network interface available!"); |  | ||||||
| 			if (adapterIndex != 1) |  | ||||||
| 			{ |  | ||||||
| 				writeLineEx(0, 3, "<%BASE_FILE_NAME%> Error: You have not selected the first adapter!"); |  | ||||||
| 				stop(); |  | ||||||
| 				return INVALID_IP; |  | ||||||
| 			} |  | ||||||
| 			break; |  | ||||||
| 		default: |  | ||||||
| 			writeLineEx(0, 1, "<%BASE_FILE_NAME%> Info: There are %d network interfaces available!", adapterCount); |  | ||||||
| 			// // // // TEST \\ \\ \\ \\ |  | ||||||
| 			for (i = 1; i <= adapterCount; i++) |  | ||||||
| 			{ |  | ||||||
| 				IpGetAdapterDescription(i, text, size); |  | ||||||
| 				writeLineEx(0, 1, "<%BASE_FILE_NAME%> Info: Interface %d: %s", i, text); |  | ||||||
| 			} |  | ||||||
| 			break; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (IpGetAdapterAddress(adapterIndex, addresses, 1) != 0) |  | ||||||
| 	{ |  | ||||||
| 		writeLineEx(0, 3, "<%BASE_FILE_NAME%> Error: Could not retrieve IP address!"); |  | ||||||
| 		stop(); |  | ||||||
| 		return INVALID_IP; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	address = addresses[0]; // the interface used |  | ||||||
| 
 |  | ||||||
| 	if (address == INVALID_IP) |  | ||||||
| 	{ |  | ||||||
| 		writeLineEx(0, 3, "<%BASE_FILE_NAME%> Error: IP address to be used is invalid!"); |  | ||||||
| 		stop(); |  | ||||||
| 		return INVALID_IP; |  | ||||||
| 	} |  | ||||||
|   |  | ||||||
| 	IpGetAdapterDescription(adapterIndex, text, size); |  | ||||||
| 	writeLineEx(0, 1, "<%BASE_FILE_NAME%> Interface: %s", text); |  | ||||||
| 	writeLineEx(0, 1, "<%BASE_FILE_NAME%>    Wrong interface? Change sysvar::TCPIP::AdapterIndex"); |  | ||||||
| 
 |  | ||||||
| 	IpGetAdapterAddressAsString(adapterIndex, text, size); |  | ||||||
| 	writeLineEx(0, 1, "<%BASE_FILE_NAME%> Ip address: %s", text); |  | ||||||
| 	strncpy(Local_IP, text, 16); |  | ||||||
| 
 |  | ||||||
| 	IpGetAdapterMaskAsString(adapterIndex, text, size); |  | ||||||
| 	writeLineEx(0, 1, "<%BASE_FILE_NAME%> Subnet mask: %s", text); |  | ||||||
| 
 |  | ||||||
| 	IpGetAdapterGatewayAsString(adapterIndex, text, size); |  | ||||||
| 	writeLineEx(0, 1, "<%BASE_FILE_NAME%> Gateway address: %s", text); |  | ||||||
| 	 |  | ||||||
| 	return address; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| word TcpOpenSocket() | word TcpOpenSocket() | ||||||
| { | { | ||||||
| 	char Local_IP[16]; | 	char Local_IP[16]; | ||||||
|  | @ -106,7 +21,7 @@ word TcpOpenSocket() | ||||||
| 	dword i = 0; | 	dword i = 0; | ||||||
| 	CHAR errorText[200]; | 	CHAR errorText[200]; | ||||||
| 
 | 
 | ||||||
| 	localIp = TcpSetupIp(Local_IP); | 	localIp = SetupIp(Local_IP); | ||||||
| 	localPort = random(65535-10240)+10240; | 	localPort = random(65535-10240)+10240; | ||||||
| 
 | 
 | ||||||
| 	if (localIp == INVALID_IP) | 	if (localIp == INVALID_IP) | ||||||
|  | @ -161,7 +76,7 @@ word TcpConnectTo(dword remoteIp, word remotePort) | ||||||
| 	fehler = TcpOpenSocket(); | 	fehler = TcpOpenSocket(); | ||||||
| 	if (fehler != 0) | 	if (fehler != 0) | ||||||
| 	{ | 	{ | ||||||
| 		g_%NODE_NAME%_TcpState = ERROR; | 		g_%NODE_NAME%_SocketState = ERROR; | ||||||
| 		return fehler; | 		return fehler; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -177,7 +92,7 @@ word TcpConnectTo(dword remoteIp, word remotePort) | ||||||
| 		if (fehler != WSAEWOULDBLOCK)		// OnTcpConnect will be called otherwise | 		if (fehler != WSAEWOULDBLOCK)		// OnTcpConnect will be called otherwise | ||||||
| 		{ | 		{ | ||||||
| 			write("<%BASE_FILE_NAME%> No Port-Connection: %d", fehler); | 			write("<%BASE_FILE_NAME%> No Port-Connection: %d", fehler); | ||||||
| 			g_%NODE_NAME%_TcpState = ERROR; | 			g_%NODE_NAME%_SocketState = ERROR; | ||||||
| 			return fehler; | 			return fehler; | ||||||
| 		} | 		} | ||||||
| 		return 0; | 		return 0; | ||||||
|  | @ -185,7 +100,7 @@ word TcpConnectTo(dword remoteIp, word remotePort) | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		writeLineEx(0, 1, "<%BASE_FILE_NAME%> Successfully connected to server"); | 		writeLineEx(0, 1, "<%BASE_FILE_NAME%> Successfully connected to server"); | ||||||
| 		g_%NODE_NAME%_TcpState = OK; | 		g_%NODE_NAME%_SocketState = OK; | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | @ -196,13 +111,13 @@ void OnTcpConnect(dword socket, long result) | ||||||
| 	{ | 	{ | ||||||
| 		g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); | 		g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); | ||||||
| 		writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpConnect error (%d): %s", g_%NODE_NAME%_Socket.GetLastSocketError(), gIpLastErrStr); | 		writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpConnect error (%d): %s", g_%NODE_NAME%_Socket.GetLastSocketError(), gIpLastErrStr); | ||||||
| 		g_%NODE_NAME%_TcpState = ERROR; | 		g_%NODE_NAME%_SocketState = ERROR; | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		writeLineEx(0, 1, "<%BASE_FILE_NAME%> Successfully connected to server"); | 		writeLineEx(0, 1, "<%BASE_FILE_NAME%> Successfully connected to server"); | ||||||
| 		g_%NODE_NAME%_TcpState = OK; | 		g_%NODE_NAME%_SocketState = OK; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -210,13 +125,13 @@ void TcpRecv() | ||||||
| { | { | ||||||
| 	int result; | 	int result; | ||||||
| 
 | 
 | ||||||
| 	if (g_%NODE_NAME%_TcpState != OK) | 	if (g_%NODE_NAME%_SocketState != OK) | ||||||
| 	{ | 	{ | ||||||
| 		writeLineEx(0, 2, "TcpRecv: Socket status is not OK!"); | 		writeLineEx(0, 2, "TcpRecv: Socket status is not OK!"); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	result = g_%NODE_NAME%_Socket.Receive(gTcpRxBuffer, elcount(gTcpRxBuffer)); | 	result = g_%NODE_NAME%_Socket.Receive(gRxBuffer, elcount(gRxBuffer)); | ||||||
| 
 | 
 | ||||||
| 	if (result != 0)	// Calling OnTcpReceive otherwise | 	if (result != 0)	// Calling OnTcpReceive otherwise | ||||||
| 	{ | 	{ | ||||||
|  | @ -227,54 +142,22 @@ void TcpRecv() | ||||||
| 			g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); | 			g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); | ||||||
| 			writeLineEx(0, 2, "<%BASE_FILE_NAME%> TcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr); | 			writeLineEx(0, 2, "<%BASE_FILE_NAME%> TcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr); | ||||||
| 			g_%NODE_NAME%_Socket.Close(); | 			g_%NODE_NAME%_Socket.Close(); | ||||||
| 			g_%NODE_NAME%_TcpState = CLOSED; | 			g_%NODE_NAME%_SocketState = CLOSED; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* |  | ||||||
| void OnTcpReceive(dword socket, long result, dword address, dword port, char buffer[], dword size) |  | ||||||
| { |  | ||||||
| 	char str[20*3]; |  | ||||||
| 
 |  | ||||||
| 	if (result == 0) |  | ||||||
| 	{ |  | ||||||
| 		if (size == 0) |  | ||||||
| 		{ |  | ||||||
| 			// Size of zero indicates that the socket was closed by the communication peer. |  | ||||||
| 			writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive: Socket closed by peer"); |  | ||||||
| 			g_%NODE_NAME%_Socket.Close(); |  | ||||||
| 			g_%NODE_NAME%_TcpState = CLOSED; |  | ||||||
| 		} |  | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			// Sucessfully received some bytes over the TCP/IP connection. |  | ||||||
| 			bin_to_strhex(gTcpRxBuffer, str); |  | ||||||
| 			writeLineEx(0, 1, "<%BASE_FILE_NAME%> OnTcpReceive: %s", str); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		gIpLastErr = g_%NODE_NAME%_Socket.GetLastSocketError(); |  | ||||||
| 		g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); |  | ||||||
| 		writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr); |  | ||||||
| 		g_%NODE_NAME%_Socket.Close(); |  | ||||||
| 		g_%NODE_NAME%_TcpState = CLOSED; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| void TcpSnd(byte buffer[]) | void TcpSnd(byte buffer[]) | ||||||
| { | { | ||||||
| 	char str[20*3]; | 	char str[20*3]; | ||||||
| 
 | 
 | ||||||
| 	switch (g_%NODE_NAME%_TcpState) | 	switch (g_%NODE_NAME%_SocketState) | ||||||
| 	{ | 	{ | ||||||
| 		case CLOSED: | 		case CLOSED: | ||||||
| 			TcpConnectTo(g_%NODE_NAME%_RemoteIP, g_%NODE_NAME%_RemotePort); | 			TcpConnectTo(g_%NODE_NAME%_RemoteIP, g_%NODE_NAME%_RemotePort); | ||||||
| 			if (g_%NODE_NAME%_TcpState != OK) | 			if (g_%NODE_NAME%_SocketState != OK) | ||||||
| 			{ | 			{ | ||||||
| 				writeLineEx(0, 2, "TcpSnd: Reconnecting failed!"); | 				writeLineEx(0, 2, "TcpSnd: Reconnecting failed!"); | ||||||
| 				return; | 				return; | ||||||
|  | @ -298,7 +181,7 @@ void TcpSnd(byte buffer[]) | ||||||
| 			g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); | 			g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); | ||||||
| 			writeLineEx(0, 2, "<%BASE_FILE_NAME%> TcpSnd error (%d): %s", gIpLastErr, gIpLastErrStr); | 			writeLineEx(0, 2, "<%BASE_FILE_NAME%> TcpSnd error (%d): %s", gIpLastErr, gIpLastErrStr); | ||||||
| 			g_%NODE_NAME%_Socket.Close(); | 			g_%NODE_NAME%_Socket.Close(); | ||||||
| 			g_%NODE_NAME%_TcpState = CLOSED; | 			g_%NODE_NAME%_SocketState = CLOSED; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
							
								
								
									
										92
									
								
								Modbus/TcpUdpCommon.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								Modbus/TcpUdpCommon.cin
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,92 @@ | ||||||
|  | /*@!Encoding:1252*/ | ||||||
|  | 
 | ||||||
|  | variables | ||||||
|  | { | ||||||
|  | 	const long	WSA_IO_PENDING		= 997; | ||||||
|  | 	const long	WSAEWOULDBLOCK		= 10035; | ||||||
|  | 	const dword INVALID_IP			= 0xffffffff; | ||||||
|  | 	 | ||||||
|  | 	long gIpLastErr					= 0; | ||||||
|  | 	char gIpLastErrStr[512]			= ""; | ||||||
|  | 
 | ||||||
|  | 	enum SocketState { NULL, OK, ERROR, CLOSED }; | ||||||
|  | 	enum SocketState g_%NODE_NAME%_SocketState = NULL; | ||||||
|  | 
 | ||||||
|  | 	dword g_%NODE_NAME%_RemoteIP	= INVALID_IP; | ||||||
|  | 	word g_%NODE_NAME%_RemotePort	= 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | dword SetupIp(char Local_IP[]) | ||||||
|  | { | ||||||
|  | 	int			adapterIndex; | ||||||
|  | 	const int	size = 512; | ||||||
|  | 	char		text[size] = ""; | ||||||
|  | 	dword		addresses[1]; | ||||||
|  | 	dword		address; | ||||||
|  | 	word		adapterCount; | ||||||
|  | 	word		i; | ||||||
|  | 
 | ||||||
|  | 	adapterCount = IpGetAdapterCount(); | ||||||
|  | 	adapterIndex = @sysvar::TCPIP::AdapterIndex; | ||||||
|  | 
 | ||||||
|  | 	switch (adapterCount) | ||||||
|  | 	{ | ||||||
|  | 		case 0: | ||||||
|  | 			writeLineEx(0, 3, "<%BASE_FILE_NAME%> Error: There is no network interface available!"); | ||||||
|  | 			stop(); | ||||||
|  | 			return INVALID_IP; | ||||||
|  | 		break; | ||||||
|  | 		case 1: | ||||||
|  | 			writeLineEx(0, 1, "<%BASE_FILE_NAME%> Info: There is 1 network interface available!"); | ||||||
|  | 			if (adapterIndex != 1) | ||||||
|  | 			{ | ||||||
|  | 				writeLineEx(0, 3, "<%BASE_FILE_NAME%> Error: You have not selected the first adapter!"); | ||||||
|  | 				stop(); | ||||||
|  | 				return INVALID_IP; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			writeLineEx(0, 1, "<%BASE_FILE_NAME%> Info: There are %d network interfaces available!", adapterCount); | ||||||
|  | 			// // // // TEST \\ \\ \\ \\ | ||||||
|  | 			for (i = 1; i <= adapterCount; i++) | ||||||
|  | 			{ | ||||||
|  | 				IpGetAdapterDescription(i, text, size); | ||||||
|  | 				writeLineEx(0, 1, "<%BASE_FILE_NAME%> Info: Interface %d: %s", i, text); | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (IpGetAdapterAddress(adapterIndex, addresses, 1) != 0) | ||||||
|  | 	{ | ||||||
|  | 		writeLineEx(0, 3, "<%BASE_FILE_NAME%> Error: Could not retrieve IP address!"); | ||||||
|  | 		stop(); | ||||||
|  | 		return INVALID_IP; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	address = addresses[0]; // the interface used | ||||||
|  | 
 | ||||||
|  | 	if (address == INVALID_IP) | ||||||
|  | 	{ | ||||||
|  | 		writeLineEx(0, 3, "<%BASE_FILE_NAME%> Error: IP address to be used is invalid!"); | ||||||
|  | 		stop(); | ||||||
|  | 		return INVALID_IP; | ||||||
|  | 	} | ||||||
|  |   | ||||||
|  | 	IpGetAdapterDescription(adapterIndex, text, size); | ||||||
|  | 	writeLineEx(0, 1, "<%BASE_FILE_NAME%> Interface: %s", text); | ||||||
|  | 	writeLineEx(0, 1, "<%BASE_FILE_NAME%>    Wrong interface? Change sysvar::TCPIP::AdapterIndex"); | ||||||
|  | 
 | ||||||
|  | 	IpGetAdapterAddressAsString(adapterIndex, text, size); | ||||||
|  | 	writeLineEx(0, 1, "<%BASE_FILE_NAME%> Ip address: %s", text); | ||||||
|  | 	strncpy(Local_IP, text, 16); | ||||||
|  | 
 | ||||||
|  | 	IpGetAdapterMaskAsString(adapterIndex, text, size); | ||||||
|  | 	writeLineEx(0, 1, "<%BASE_FILE_NAME%> Subnet mask: %s", text); | ||||||
|  | 
 | ||||||
|  | 	IpGetAdapterGatewayAsString(adapterIndex, text, size); | ||||||
|  | 	writeLineEx(0, 1, "<%BASE_FILE_NAME%> Gateway address: %s", text); | ||||||
|  | 	 | ||||||
|  | 	return address; | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										152
									
								
								Modbus/UdpCommon.cin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								Modbus/UdpCommon.cin
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,152 @@ | ||||||
|  | /*@!Encoding:1252*/ | ||||||
|  | includes | ||||||
|  | { | ||||||
|  | 	#include "Common.cin" | ||||||
|  | 	#include "TcpUdpCommon.cin" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | variables | ||||||
|  | { | ||||||
|  | 	UdpSocket g_%NODE_NAME%_Socket; | ||||||
|  | 
 | ||||||
|  | 	byte gRxBuffer[8192]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | word UdpOpenSocket() | ||||||
|  | { | ||||||
|  | 	char Local_IP[16]; | ||||||
|  | 	dword localIp; | ||||||
|  | 	word localPort; | ||||||
|  | 	dword i = 0; | ||||||
|  | 	CHAR errorText[200]; | ||||||
|  | 
 | ||||||
|  | 	localIp = SetupIp(Local_IP); | ||||||
|  | 	localPort = random(65535-10240)+10240; | ||||||
|  | 
 | ||||||
|  | 	if (localIp == INVALID_IP) | ||||||
|  | 		return INVALID_IP; | ||||||
|  | 
 | ||||||
|  | 	// Try to open socket | ||||||
|  | 	do | ||||||
|  | 	{ | ||||||
|  | 		g_%NODE_NAME%_Socket = UdpSocket::Open(localIp, localPort); | ||||||
|  | 		if (g_%NODE_NAME%_Socket.GetLastSocketError() != 0) | ||||||
|  | 		{ | ||||||
|  | 			g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(errorText, elcount(errorText)); | ||||||
|  | 			writeLineEx(0, 1, "<%BASE_FILE_NAME%> Error: could not open Udp socket on %s:%d, %s (%d)!", Local_IP, localPort, errorText, g_%NODE_NAME%_Socket.GetLastSocketError()); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	while (g_%NODE_NAME%_Socket.GetLastSocketError() != 0 && i++ < 9); | ||||||
|  | 	 | ||||||
|  | 	if (g_%NODE_NAME%_Socket.GetLastSocketError() != 0) | ||||||
|  | 	{ | ||||||
|  | 		writeLineEx(0, 1, "<%BASE_FILE_NAME%> Error: could not open Udp socket!"); | ||||||
|  | 		return g_%NODE_NAME%_Socket.GetLastSocketError(); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		writeLineEx(0, 1, "<%BASE_FILE_NAME%> Udp socket opened on %s:%d.", Local_IP, localPort); | ||||||
|  | 	} | ||||||
|  | 	return 0; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | word UdpConnectTo(char Remote_IP[], word remotePort) | ||||||
|  | { | ||||||
|  | 	dword remoteIp; | ||||||
|  | 
 | ||||||
|  | 	// Convert IP string to Number | ||||||
|  | 	remoteIp = IpGetAddressAsNumber(Remote_IP); | ||||||
|  | 	if (remoteIp == INVALID_IP) | ||||||
|  | 	{ | ||||||
|  | 		writeLineEx(0, 1, "<%BASE_FILE_NAME%> Error: invalid server Ip address!"); | ||||||
|  | 		 | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return UdpConnectTo(remoteIp, remotePort); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | word UdpConnectTo(dword remoteIp, word remotePort) | ||||||
|  | { | ||||||
|  | 	long fehler; | ||||||
|  | 
 | ||||||
|  | 	// Try to open a socket | ||||||
|  | 	fehler = UdpOpenSocket(); | ||||||
|  | 	if (fehler != 0) | ||||||
|  | 	{ | ||||||
|  | 		g_%NODE_NAME%_SocketState = ERROR; | ||||||
|  | 		return fehler; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	g_%NODE_NAME%_RemoteIP = remoteIp; | ||||||
|  | 	g_%NODE_NAME%_RemotePort = remotePort; | ||||||
|  | 	g_%NODE_NAME%_SocketState = OK; | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UdpRecv() | ||||||
|  | { | ||||||
|  | 	int result; | ||||||
|  | 
 | ||||||
|  | 	if (g_%NODE_NAME%_SocketState != OK) | ||||||
|  | 	{ | ||||||
|  | 		writeLineEx(0, 2, "UdpRecv: Socket status is not OK!"); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	result = g_%NODE_NAME%_Socket.ReceiveFrom(gRxBuffer, elcount(gRxBuffer)); | ||||||
|  | 
 | ||||||
|  | 	if (result != 0)	// Calling OnUdpReceive otherwise | ||||||
|  | 	{ | ||||||
|  | 		gIpLastErr = g_%NODE_NAME%_Socket.GetLastSocketError(); | ||||||
|  | 
 | ||||||
|  | 		if (gIpLastErr != WSA_IO_PENDING)	// Calling OnUdpReceive otherwise | ||||||
|  | 		{ | ||||||
|  | 			g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); | ||||||
|  | 			writeLineEx(0, 2, "<%BASE_FILE_NAME%> UdpRecv Error (%d): %s", gIpLastErr, gIpLastErrStr); | ||||||
|  | 			g_%NODE_NAME%_Socket.Close(); | ||||||
|  | 			g_%NODE_NAME%_SocketState = CLOSED; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UdpSnd(byte buffer[]) | ||||||
|  | { | ||||||
|  | 	char str[20*3]; | ||||||
|  | 
 | ||||||
|  | 	switch (g_%NODE_NAME%_SocketState) | ||||||
|  | 	{ | ||||||
|  | 		case CLOSED: | ||||||
|  | 			UdpConnectTo(g_%NODE_NAME%_RemoteIP, g_%NODE_NAME%_RemotePort); | ||||||
|  | 			if (g_%NODE_NAME%_SocketState != OK) | ||||||
|  | 			{ | ||||||
|  | 				writeLineEx(0, 2, "UdpSnd: Reconnecting failed!"); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 		case OK: | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			writeLineEx(0, 2, "UdpSnd: Socket status is not OK!"); | ||||||
|  | 			return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	bin_to_strhex(buffer, str); | ||||||
|  | 	writeLineEx(0, 1, "<%BASE_FILE_NAME%> UdpSnd: %s (Länge: %d)", str, elCount(buffer)); | ||||||
|  | 	 | ||||||
|  | 	if (g_%NODE_NAME%_Socket.SendTo(g_%NODE_NAME%_RemoteIP, g_%NODE_NAME%_RemotePort, buffer, elCount(buffer)) != 0) | ||||||
|  | 	{ | ||||||
|  | 		gIpLastErr = g_%NODE_NAME%_Socket.GetLastSocketError(); | ||||||
|  | 
 | ||||||
|  | 		if (gIpLastErr != WSA_IO_PENDING) | ||||||
|  | 		{ | ||||||
|  | 			g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); | ||||||
|  | 			writeLineEx(0, 2, "<%BASE_FILE_NAME%> UdpSnd error (%d): %s", gIpLastErr, gIpLastErrStr); | ||||||
|  | 			g_%NODE_NAME%_Socket.Close(); | ||||||
|  | 			g_%NODE_NAME%_SocketState = CLOSED; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
| includes | includes | ||||||
| { | { | ||||||
| 	#include "ModbusCommon.cin" | 	#include "ModbusCommon.cin" | ||||||
| 	#include "ModbusTcpCommon.cin" | 	#include "ModbusUdpCommon.cin" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| variables | variables | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue