167 lines
No EOL
4.4 KiB
Text
167 lines
No EOL
4.4 KiB
Text
/*@!Encoding:1252*/
|
||
includes
|
||
{
|
||
#include "Common.cin"
|
||
#include "TcpUdpCommon.cin"
|
||
}
|
||
|
||
variables
|
||
{
|
||
long gPacket;
|
||
msTimer gtArp;
|
||
|
||
byte gLocalMac[6];
|
||
byte gRemoteMac[6];
|
||
dword gLocalIP = 0xC0A80101;
|
||
}
|
||
|
||
|
||
word EilConnectTo(char Remote_IP[], word remotePort)
|
||
{
|
||
dword remoteIp;
|
||
|
||
// Convert IP string to Number
|
||
remoteIp = IpGetAddressAsNumber(Remote_IP);
|
||
if (remoteIp == INVALID_IP)
|
||
{
|
||
writeDbg(ConnError, "EilConnectTo: invalid server Ip address!");
|
||
OnModbusClientPanics(ConnectionError);
|
||
return ipGetLastError();
|
||
}
|
||
|
||
return EilConnectTo(remoteIp, remotePort);
|
||
}
|
||
|
||
word EilConnectTo(dword remoteIp, word remotePort)
|
||
{
|
||
long error;
|
||
byte broadcastMac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||
|
||
if (EthGetMacId(gLocalMac) != 0)
|
||
{
|
||
gSocketState = ERROR;
|
||
error = EthGetLastError();
|
||
writeDbg(ConnError, "EthGetMacId: Could not get local MAC! %d", error);
|
||
OnModbusClientPanics(ConnectionError);
|
||
return error;
|
||
}
|
||
|
||
// TCP/IP API gives IP in little endian but EIL uses big endian
|
||
gRemotePort = remotePort;
|
||
gRemoteIP = (remoteIp >> 24) | (remoteIp >> 8) & 0x0000FF00 | (remoteIp << 8) & 0x00FF0000 | (remoteIp << 24);
|
||
|
||
if (gPacket != 0)
|
||
ModbusDisconnect();
|
||
// Try to create an ARP packet that gets the MAC from remote server
|
||
gPacket = EthInitPacket("arp");
|
||
if (gPacket == 0)
|
||
{
|
||
gSocketState = ERROR;
|
||
error = EthGetLastError();
|
||
writeDbg(ConnError, "EthInitPacket: Could not create ARP package! %d", error);
|
||
OnModbusClientPanics(ConnectionError);
|
||
return error;
|
||
}
|
||
|
||
EthSetTokenData(gPacket, "eth", "source" , elCount(gLocalMac), gLocalMac);
|
||
EthSetTokenData(gPacket, "eth", "destination" , elCount(broadcastMac), broadcastMac);
|
||
EthSetTokenInt(gPacket, "arp", "hwType" , 1); // Ethernet
|
||
EthSetTokenInt(gPacket, "arp", "protType" , 0x0800); // IPv4
|
||
EthSetTokenInt(gPacket, "arp", "hwSize" , 6); // Ethernet addr size
|
||
EthSetTokenInt(gPacket, "arp", "protSize" , 4); // IP addr size
|
||
EthSetTokenInt(gPacket, "arp", "operation" , 1);
|
||
EthSetTokenData(gPacket, "arp", "hwSourceAddr" , elCount(gLocalMac), gLocalMac);
|
||
EthSetTokenInt(gPacket, "arp", "protSourceAddr" , gLocalIP);
|
||
//EthSetTokenData(gPacket, "arp", "hwDestinationAddr" , elCount(gLocalMac), gLocalMac);
|
||
EthSetTokenInt(gPacket, "arp", "protDestinationAddr" , gRemoteIP);
|
||
|
||
EthReceivePacket("OnEthReceivePacket");
|
||
|
||
EthCompletePacket(gPacket);
|
||
EthOutputPacket(gPacket);
|
||
EthReleasePacket(gPacket);
|
||
gSocketState = NULL;
|
||
gtArp.set(@sysvar::Config::Modbus::RequestTimeout);
|
||
return 0;
|
||
}
|
||
|
||
void EilConnectTo2()
|
||
{
|
||
gPacket = EthInitPacket("udp");
|
||
if (gPacket == 0)
|
||
{
|
||
gSocketState = ERROR;
|
||
writeDbg(ConnError, "EthInitPacket: Could not create UDP packet: %d", EthGetLastError());
|
||
OnModbusClientPanics(ConnectionError);
|
||
return;
|
||
}
|
||
|
||
EthSetTokenData(gPacket, "eth", "source" , elCount(gLocalMac), gLocalMac);
|
||
EthSetTokenData(gPacket, "eth", "destination" , elCount(gRemoteMac), gRemoteMac);
|
||
EthSetTokenInt(gPacket, "ipv4", "source" , gLocalIP);
|
||
EthSetTokenInt(gPacket, "ipv4", "destination" , gRemoteIP);
|
||
EthSetTokenInt(gPacket, "udp", "source" , 23456);
|
||
EthSetTokenInt(gPacket, "udp", "destination" , 502);
|
||
|
||
gSocketState = OK;
|
||
}
|
||
|
||
void EilDisconnect()
|
||
{
|
||
if (gPacket != 0)
|
||
{
|
||
EthReleasePacket(gPacket);
|
||
gPacket = 0;
|
||
}
|
||
gSocketState = CLOSED;
|
||
}
|
||
|
||
|
||
void EilRecv()
|
||
{
|
||
}
|
||
|
||
byte EilSnd(byte buffer[], word length)
|
||
{
|
||
char str[20*3];
|
||
|
||
switch (gSocketState)
|
||
{
|
||
case CLOSED:
|
||
EilConnectTo(gRemoteIP, gRemotePort);
|
||
if (gSocketState != OK)
|
||
{
|
||
writeDbg(ConnWarning, "EilSnd: Reconnecting failed! Doing nothing.");
|
||
return 1;
|
||
}
|
||
case OK:
|
||
break;
|
||
default:
|
||
writeDbg(ConnWarning, "EilSnd: Socket status is not OK! Doing nothing.");
|
||
return 1;
|
||
}
|
||
|
||
bin_to_strhex(buffer, str);
|
||
writeDbg(ConnDebug, "EilSnd: %s (L<>nge: %d)", str, length);
|
||
|
||
EthResizeToken(gPacket, "udp", "data" , length*8);
|
||
EthSetTokenData(gPacket, "udp", "data" , length, buffer);
|
||
|
||
EthCompletePacket(gPacket);
|
||
EthOutputPacket(gPacket);
|
||
|
||
return 0;
|
||
}
|
||
|
||
long EilGetLastConnectionError(char string[])
|
||
{
|
||
EthGetLastErrorText(elCount(string), string);
|
||
return EthGetLastError();
|
||
}
|
||
|
||
on timer gtArp
|
||
{
|
||
gSocketState = ERROR;
|
||
writeDbg(ConnError, "No (valid) ARP response detected. The host seems to be offline!");
|
||
OnModbusClientPanics(ConnectionError);
|
||
} |