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