Added hbin_to_strhex and dbin_to_strhex ModbusClientCommon.cin Introduced timers to watch for timeouts Enhanced OnModbusReceive Added exception handling Added ModbusReadWriteRegisters and ModbusWriteMasks
		
			
				
	
	
		
			187 lines
		
	
	
		
			No EOL
		
	
	
		
			4 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			No EOL
		
	
	
		
			4 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
/*@!Encoding:1252*/
 | 
						||
includes
 | 
						||
{
 | 
						||
	#include "Common.cin"
 | 
						||
	#include "TcpUdpCommon.cin"
 | 
						||
}
 | 
						||
 | 
						||
variables
 | 
						||
{
 | 
						||
	TcpSocket gSocket;
 | 
						||
 | 
						||
	byte gRxBuffer[8192];
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
word TcpOpenSocket()
 | 
						||
{
 | 
						||
	char Local_IP[16];
 | 
						||
	dword localIp;
 | 
						||
	word localPort;
 | 
						||
	dword i = 0;
 | 
						||
	CHAR errorText[200];
 | 
						||
 | 
						||
	localIp = SetupIp(Local_IP);
 | 
						||
 | 
						||
	if (localIp == INVALID_IP)
 | 
						||
		return INVALID_IP;
 | 
						||
 | 
						||
	// Try to open socket
 | 
						||
	do
 | 
						||
	{
 | 
						||
		localPort = random(65536-10240)+10240;
 | 
						||
		gSocket = TcpSocket::Open(localIp, localPort);
 | 
						||
		if (gSocket.GetLastSocketError() != 0)
 | 
						||
		{
 | 
						||
			gSocket.GetLastSocketErrorAsString(errorText, elcount(errorText));
 | 
						||
			writeLineEx(0, 1, "<%BASE_FILE_NAME%> Error: could not open Tcp socket on %s:%d, %s (%d)!", Local_IP, localPort, errorText, gSocket.GetLastSocketError());
 | 
						||
		}
 | 
						||
	}
 | 
						||
	while (gSocket.GetLastSocketError() != 0 && i++ < 9);
 | 
						||
	
 | 
						||
	if (gSocket.GetLastSocketError() != 0)
 | 
						||
	{
 | 
						||
		writeLineEx(0, 1, "<%BASE_FILE_NAME%> Error: could not open Tcp socket!");
 | 
						||
		return gSocket.GetLastSocketError();
 | 
						||
	}
 | 
						||
	else
 | 
						||
	{
 | 
						||
		writeLineEx(0, 1, "<%BASE_FILE_NAME%> Tcp socket opened on %s:%d.", Local_IP, localPort);
 | 
						||
	}
 | 
						||
	return 0;
 | 
						||
 | 
						||
}
 | 
						||
 | 
						||
word TcpConnectTo(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 TcpConnectTo(remoteIp, remotePort);
 | 
						||
}
 | 
						||
 | 
						||
word TcpConnectTo(dword remoteIp, word remotePort)
 | 
						||
{
 | 
						||
	long fehler;
 | 
						||
 | 
						||
	// Try to open a socket
 | 
						||
	fehler = TcpOpenSocket();
 | 
						||
	if (fehler != 0)
 | 
						||
	{
 | 
						||
		gSocketState = ERROR;
 | 
						||
		return fehler;
 | 
						||
	}
 | 
						||
 | 
						||
	gRemoteIP = remoteIp;
 | 
						||
	gRemotePort = remotePort;
 | 
						||
 | 
						||
 | 
						||
	// Connect to Server
 | 
						||
	if (gSocket.Connect(remoteIp, remotePort) != 0)
 | 
						||
	{
 | 
						||
		fehler = gSocket.GetLastSocketError();
 | 
						||
 | 
						||
		if (fehler != WSAEWOULDBLOCK)		// OnTcpConnect will be called otherwise
 | 
						||
		{
 | 
						||
			write("<%BASE_FILE_NAME%> No Port-Connection: %d", fehler);
 | 
						||
			gSocketState = ERROR;
 | 
						||
			return fehler;
 | 
						||
		}
 | 
						||
		return 0;
 | 
						||
	}
 | 
						||
	else
 | 
						||
	{
 | 
						||
		writeLineEx(0, 1, "<%BASE_FILE_NAME%> Successfully connected to server");
 | 
						||
		gSocketState = OK;
 | 
						||
		return 0;
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
void OnTcpConnect(dword socket, long result)
 | 
						||
{
 | 
						||
	if (result != 0)
 | 
						||
	{
 | 
						||
		gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr));
 | 
						||
		writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpConnect error (%d): %s", gSocket.GetLastSocketError(), gIpLastErrStr);
 | 
						||
		gSocketState = ERROR;
 | 
						||
		return;
 | 
						||
	}
 | 
						||
	else
 | 
						||
	{
 | 
						||
		writeLineEx(0, 1, "<%BASE_FILE_NAME%> Successfully connected to server");
 | 
						||
		gSocketState = OK;
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
void TcpRecv()
 | 
						||
{
 | 
						||
	int result;
 | 
						||
 | 
						||
	if (gSocketState != OK)
 | 
						||
	{
 | 
						||
		writeLineEx(0, 2, "TcpRecv: Socket status is not OK!");
 | 
						||
		return;
 | 
						||
	}
 | 
						||
	
 | 
						||
	result = gSocket.Receive(gRxBuffer, elcount(gRxBuffer));
 | 
						||
 | 
						||
	if (result != 0)	// Calling OnTcpReceive otherwise
 | 
						||
	{
 | 
						||
		gIpLastErr = gSocket.GetLastSocketError();
 | 
						||
 | 
						||
		if (gIpLastErr != WSA_IO_PENDING)	// Calling OnTcpReceive otherwise
 | 
						||
		{
 | 
						||
			gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr));
 | 
						||
			writeLineEx(0, 2, "<%BASE_FILE_NAME%> TcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr);
 | 
						||
			gSocket.Close();
 | 
						||
			gSocketState = CLOSED;
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	return;
 | 
						||
}
 | 
						||
 | 
						||
void TcpSnd(byte buffer[], word length)
 | 
						||
{
 | 
						||
	//char str[20*3];
 | 
						||
 | 
						||
	switch (gSocketState)
 | 
						||
	{
 | 
						||
		case CLOSED:
 | 
						||
			TcpConnectTo(gRemoteIP, gRemotePort);
 | 
						||
			if (gSocketState != OK)
 | 
						||
			{
 | 
						||
				writeLineEx(0, 2, "<%BASE_FILE_NAME%> TcpSnd: Reconnecting failed!");
 | 
						||
				return;
 | 
						||
			}
 | 
						||
		case OK:
 | 
						||
			break;
 | 
						||
		default:
 | 
						||
			writeLineEx(0, 2, "<%BASE_FILE_NAME%> TcpSnd: Socket status is not OK!");
 | 
						||
			return;
 | 
						||
	}
 | 
						||
 | 
						||
	//bin_to_strhex(buffer, str);
 | 
						||
	//writeLineEx(0, 1, "<%BASE_FILE_NAME%> TcpSnd: %s (L<>nge: %d)", str, length);
 | 
						||
	
 | 
						||
	if (gSocket.Send(buffer, length) != 0)
 | 
						||
	{
 | 
						||
		gIpLastErr = gSocket.GetLastSocketError();
 | 
						||
 | 
						||
		if (gIpLastErr != WSA_IO_PENDING)
 | 
						||
		{
 | 
						||
			gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr));
 | 
						||
			writeLineEx(0, 2, "<%BASE_FILE_NAME%> TcpSnd error (%d): %s", gIpLastErr, gIpLastErrStr);
 | 
						||
			gSocket.Close();
 | 
						||
			gSocketState = CLOSED;
 | 
						||
		}
 | 
						||
	}
 | 
						||
} |