/*@!Encoding:1252*/ includes { #include "Common.cin" } 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; dword g_%NODE_NAME%_RemoteIP = INVALID_IP; 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() { char Local_IP[16]; dword localIp; word localPort; dword i = 0; CHAR errorText[200]; localIp = TcpSetupIp(Local_IP); localPort = random(65535-10240)+10240; if (localIp == INVALID_IP) return INVALID_IP; // Try to open socket do { g_%NODE_NAME%_Socket = TcpSocket::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 Tcp 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 Tcp socket!"); return g_%NODE_NAME%_Socket.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) { g_%NODE_NAME%_TcpState = ERROR; return fehler; } g_%NODE_NAME%_RemoteIP = remoteIp; g_%NODE_NAME%_RemotePort = remotePort; // Connect to Server if (g_%NODE_NAME%_Socket.Connect(remoteIp, remotePort) != 0) { fehler = g_%NODE_NAME%_Socket.GetLastSocketError(); if (fehler != WSAEWOULDBLOCK) // OnTcpConnect will be called otherwise { write("<%BASE_FILE_NAME%> No Port-Connection: %d", fehler); g_%NODE_NAME%_TcpState = ERROR; return fehler; } return 0; } else { writeLineEx(0, 1, "<%BASE_FILE_NAME%> Successfully connected to server"); g_%NODE_NAME%_TcpState = OK; return 0; } } void OnTcpConnect(dword socket, long result) { if (result != 0) { g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpConnect error (%d): %s", g_%NODE_NAME%_Socket.GetLastSocketError(), gIpLastErrStr); g_%NODE_NAME%_TcpState = ERROR; return; } else { writeLineEx(0, 1, "<%BASE_FILE_NAME%> Successfully connected to server"); g_%NODE_NAME%_TcpState = OK; } } void TcpRecv() { int result; if (g_%NODE_NAME%_TcpState != OK) { writeLineEx(0, 2, "TcpRecv: Socket status is not OK!"); return; } result = g_%NODE_NAME%_Socket.Receive(gTcpRxBuffer, elcount(gTcpRxBuffer)); if (result != 0) // Calling OnTcpReceive otherwise { gIpLastErr = g_%NODE_NAME%_Socket.GetLastSocketError(); if (gIpLastErr != WSA_IO_PENDING) // Calling OnTcpReceive otherwise { g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); writeLineEx(0, 2, "<%BASE_FILE_NAME%> TcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr); g_%NODE_NAME%_Socket.Close(); g_%NODE_NAME%_TcpState = CLOSED; } } 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[]) { char str[20*3]; switch (g_%NODE_NAME%_TcpState) { case CLOSED: TcpConnectTo(g_%NODE_NAME%_RemoteIP, g_%NODE_NAME%_RemotePort); if (g_%NODE_NAME%_TcpState != OK) { writeLineEx(0, 2, "TcpSnd: Reconnecting failed!"); return; } case OK: break; default: writeLineEx(0, 2, "TcpSnd: Socket status is not OK!"); return; } bin_to_strhex(buffer, str); writeLineEx(0, 1, "<%BASE_FILE_NAME%> TcpSnd: %s (Länge: %d)", str, elCount(buffer)); if (g_%NODE_NAME%_Socket.Send(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%> TcpSnd error (%d): %s", gIpLastErr, gIpLastErrStr); g_%NODE_NAME%_Socket.Close(); g_%NODE_NAME%_TcpState = CLOSED; } } }