public static void Receive(TcpState tcps) { try { // Begin receiving the data from the remote device. // tcps.workSocket.BeginReceive(tcps.recvBuffer, 0, Iec61850State.recvBufferSize, 0, new AsyncCallback(ReceiveCallback), tcps); } catch (Exception e) { StopClient(tcps); tcps.logger.LogError(e.ToString()); } }
public static void Send(TcpState tcps) //Socket client, byte[] data) { try { // Begin sending the data to the remote device. if (tcps.workSocket != null) { tcps.workSocket.BeginSend(tcps.sendBuffer, 0, tcps.sendBytes, 0, new AsyncCallback(SendCallback), tcps); } } catch (Exception e) { tcps.logger.LogError(e.ToString()); } }
private static void ReceiveCallback(IAsyncResult ar) { // Retrieve the socket from the state object. TcpState tcps = (TcpState)ar.AsyncState; try { // Complete the connection. if (tcps.workSocket != null) { if (tcps.workSocket.Poll(5000, SelectMode.SelectRead) && tcps.workSocket.Available == 0) { //socket not connected, close it if it's still running tcps.workSocket.Close(); tcps.workSocket = null; tcps.logger.LogError("Socket disconnected (detected in ReceiveCallback)"); tcps.tstate = TcpProtocolState.TCP_STATE_SHUTDOWN; } else { try { tcps.recvBytes = tcps.workSocket.EndReceive(ar); //Console.WriteLine("ReceiveCallback: Data received {0}", // tcps.recvBytes.ToString()); } catch (Exception e) { tcps.logger.LogError(e.Message); } try { IsoTpkt.Parse(tcps); } catch (Exception e) { tcps.logger.LogError(e.Message); } // Signal that the data has been received. tcps.receiveDone.Set(); } } } catch (Exception e) { // StopClient(tcps); // tcps.logger.LogInfo(e.ToString()); } }
private static void SendCallback(IAsyncResult ar) { TcpState tcps = (TcpState)ar.AsyncState; try { // Retrieve the socket from the state object. // Complete sending the data to the remote device. int bytesSent = tcps.workSocket.EndSend(ar); tcps.logger.LogDebug(String.Format("Sent {0} bytes to server.", bytesSent)); // Signal that all bytes have been sent. tcps.sendDone.Set(); } catch (Exception e) { tcps.logger.LogError(e.ToString()); } }
private static void ConnectCallback(IAsyncResult ar) { // Retrieve the socket from the state object. TcpState tcps = (TcpState)ar.AsyncState; try { // Complete the connection. tcps.workSocket.EndConnect(ar); tcps.logger.LogInfo(String.Format("ConnectCallback: Socket connected to {0}", tcps.workSocket.RemoteEndPoint.ToString())); // Signal that the connection has been made. tcps.tstate = TcpProtocolState.TCP_CONNECTED; tcps.connectDone.Set(); } catch (Exception e) { StopClient(tcps); tcps.logger.LogError(e.ToString()); } }
/// <summary> /// Parsing of data from socket into TPKT datagrams /// </summary> /// <param name="iecs">Global protocol state structure</param> public static void Parse(TcpState tcps) { Iec61850State iecs = (Iec61850State)tcps; for (int i = 0; i < iecs.recvBytes; i++) { if (iecs.kstate == IsoTpktState.TPKT_RECEIVE_ERROR) { iecs.kstate = IsoTpktState.TPKT_RECEIVE_START; tcps.logger.LogError("iec61850tpktState.IEC61850_RECEIVE_ERROR\n"); break; } switch (iecs.kstate) { case IsoTpktState.TPKT_RECEIVE_START: if (iecs.recvBuffer[i] == TPKT_START) { iecs.kstate = IsoTpktState.TPKT_RECEIVE_RES; iecs.dataBufferIndex = 0; } else { tcps.logger.LogError("Synchronization lost: TPKT START / VERSION!\n"); iecs.kstate = IsoTpktState.TPKT_RECEIVE_ERROR; } break; case IsoTpktState.TPKT_RECEIVE_RES: if (iecs.recvBuffer[i] == TPKT_RES) { iecs.kstate = IsoTpktState.TPKT_RECEIVE_LEN1; } else { tcps.logger.LogError("Synchronization lost: TPKT RES!\n"); iecs.kstate = IsoTpktState.TPKT_RECEIVE_ERROR; } break; case IsoTpktState.TPKT_RECEIVE_LEN1: iecs.TpktLen = iecs.recvBuffer[i] << 8; iecs.kstate = IsoTpktState.TPKT_RECEIVE_LEN2; break; case IsoTpktState.TPKT_RECEIVE_LEN2: iecs.TpktLen |= iecs.recvBuffer[i]; if (iecs.TpktLen <= TPKT_MAXLEN) { iecs.kstate = IsoTpktState.TPKT_RECEIVE_DATA_COPY; } else { tcps.logger.LogError("Synchronization lost: TPKT TPDU too long!\n"); iecs.kstate = IsoTpktState.TPKT_RECEIVE_ERROR; } break; case IsoTpktState.TPKT_RECEIVE_DATA_COPY: // OPTIMIZE!!! //iecs.dataBuffer[iecs.dataBufferIndex++] = iecs.recvBuffer[i]; int copylen = Math.Min(/*available*/ iecs.recvBytes - i, /*wanted*/ iecs.TpktLen - TPKT_SIZEOF - iecs.dataBufferIndex); Array.Copy(iecs.recvBuffer, i, iecs.dataBuffer, iecs.dataBufferIndex, copylen); i += copylen - 1; // i will be incremented in 'for' cycle, so we must decrement here iecs.dataBufferIndex += copylen; if (iecs.dataBufferIndex == iecs.TpktLen - TPKT_SIZEOF) { iecs.kstate = IsoTpktState.TPKT_RECEIVE_START; // Call OSI Layer tcps.logger.LogDebug("TPKT sent to OSI"); iecs.iso.Receive(iecs); } break; default: tcps.logger.LogError("iecs.tstate: unknown state!\n"); break; } // switch } // for }