private bool HandleMessage(byte[] buffer, int msgSize) { long currentTime = SystemUtils.currentTimeMillis(); if ((buffer [2] & 1) == 0) { if (msgSize < 7) { DebugLog("I msg too small!"); return(false); } if (firstIMessageReceived == false) { firstIMessageReceived = true; lastConfirmationTime = currentTime; /* start timeout T2 */ } int frameSendSequenceNumber = ((buffer [3] * 0x100) + (buffer [2] & 0xfe)) / 2; int frameRecvSequenceNumber = ((buffer [5] * 0x100) + (buffer [4] & 0xfe)) / 2; DebugLog("Received I frame: N(S) = " + frameSendSequenceNumber + " N(R) = " + frameRecvSequenceNumber); /* check the receive sequence number N(R) - connection will be closed on an unexpected value */ if (frameSendSequenceNumber != receiveCount) { DebugLog("Sequence error: Close connection!"); return(false); } if (CheckSequenceNumber(frameRecvSequenceNumber) == false) { DebugLog("Sequence number check failed"); return(false); } receiveCount = (receiveCount + 1) % 32768; unconfirmedReceivedIMessages++; if (isActive) { try { ASDU asdu = new ASDU(parameters, buffer, 6, msgSize); // push to handler thread for processing DebugLog("Enqueue received I-message for processing"); receivedASDUs.Enqueue(asdu); } catch (ASDUParsingException e) { DebugLog("ASDU parsing failed: " + e.Message); return(false); } } else { // connection not activated --> skip message DebugLog("Connection not activated. Skip I message"); } } // Check for TESTFR_ACT message else if ((buffer [2] & 0x43) == 0x43) { DebugLog("Send TESTFR_CON"); socketStream.Write(TESTFR_CON_MSG, 0, TESTFR_CON_MSG.Length); } // Check for STARTDT_ACT message else if ((buffer [2] & 0x07) == 0x07) { DebugLog("Send STARTDT_CON"); this.isActive = true; this.server.Activated(this); socketStream.Write(STARTDT_CON_MSG, 0, TESTFR_CON_MSG.Length); } // Check for STOPDT_ACT message else if ((buffer [2] & 0x13) == 0x13) { DebugLog("Send STOPDT_CON"); this.isActive = false; socketStream.Write(STOPDT_CON_MSG, 0, TESTFR_CON_MSG.Length); } // Check for TESTFR_CON message else if ((buffer [2] & 0x83) == 0x83) { DebugLog("Recv TESTFR_CON"); outStandingTestFRConMessages = 0; } // S-message else if (buffer [2] == 0x01) { int seqNo = (buffer[4] + buffer[5] * 0x100) / 2; DebugLog("Recv S(" + seqNo + ") (own sendcounter = " + sendCount + ")"); if (CheckSequenceNumber(seqNo) == false) { return(false); } } else { DebugLog("Unknown message"); } ResetT3Timeout(); return(true); }
private void HandleConnection() { byte[] bytes = new byte[300]; try { try { running = true; if (tlsSecInfo != null) { DebugLog("Setup TLS"); SslStream sslStream = new SslStream(socketStream, true, RemoteCertificateValidationCallback); bool authenticationSuccess = false; try { sslStream.AuthenticateAsServer(tlsSecInfo.OwnCertificate, true, System.Security.Authentication.SslProtocols.Tls, false); if (sslStream.IsAuthenticated == true) { socketStream = sslStream; authenticationSuccess = true; } } catch (IOException e) { if (e.GetBaseException() != null) { DebugLog("TLS authentication error: " + e.GetBaseException().Message); } else { DebugLog("TLS authentication error: " + e.Message); } } if (authenticationSuccess == true) { socketStream = sslStream; } else { DebugLog("TLS authentication failed"); running = false; } } if (running) { socketStream.ReadTimeout = 50; callbackThread = new Thread(ProcessASDUs); callbackThread.Start(); ResetT3Timeout(); } while (running) { try { // Receive the response from the remote device. int bytesRec = receiveMessage(bytes); if (bytesRec > 0) { DebugLog("RCVD: " + BitConverter.ToString(bytes, 0, bytesRec)); if (HandleMessage(bytes, bytesRec) == false) { /* close connection on error */ running = false; } if (unconfirmedReceivedIMessages >= parameters.W) { lastConfirmationTime = SystemUtils.currentTimeMillis(); unconfirmedReceivedIMessages = 0; SendSMessage(); } } else if (bytesRec == -1) { running = false; } } catch (System.IO.IOException) { running = false; } if (handleTimeouts() == false) { running = false; } if (running) { if (isActive) { SendWaitingASDUs(); } Thread.Sleep(1); } } isActive = false; DebugLog("CLOSE CONNECTION!"); // Release the socket. socket.Shutdown(SocketShutdown.Both); socket.Close(); socketStream.Dispose(); socket.Dispose(); DebugLog("CONNECTION CLOSED!"); } catch (ArgumentNullException ane) { DebugLog("ArgumentNullException : " + ane.ToString()); } catch (SocketException se) { DebugLog("SocketException : " + se.ToString()); } catch (Exception e) { DebugLog("Unexpected exception : " + e.ToString()); } } catch (Exception e) { DebugLog(e.ToString()); } // unmark unconfirmed messages in server queue if k-buffer not empty if (oldestSentASDU != -1) { server.UnmarkAllASDUs(); } server.Remove(this); if (callbackThreadRunning) { callbackThreadRunning = false; callbackThread.Join(); } DebugLog("Connection thread finished"); }
private void ResetT3Timeout() { nextT3Timeout = (UInt64)SystemUtils.currentTimeMillis() + (UInt64)(parameters.T3 * 1000); }
private void HandleConnection() { byte[] bytes = new byte[300]; try { try { running = true; ResetT3Timeout(); while (running) { try { // Receive the response from the remote device. int bytesRec = receiveMessage(socket, bytes); if (bytesRec != 0) { DebugLog("RCVD: " + BitConverter.ToString(bytes, 0, bytesRec)); if (HandleMessage(socket, bytes, bytesRec) == false) { /* close connection on error */ running = false; } if (unconfirmedReceivedIMessages >= parameters.W) { lastConfirmationTime = SystemUtils.currentTimeMillis(); unconfirmedReceivedIMessages = 0; SendSMessage(); } } } catch (SocketException) { running = false; } if (handleTimeouts() == false) { running = false; } if (running) { if (isActive) { SendWaitingASDUs(); } Thread.Sleep(1); } } isActive = false; DebugLog("CLOSE CONNECTION!"); // Release the socket. socket.Shutdown(SocketShutdown.Both); socket.Close(); DebugLog("CONNECTION CLOSED!"); } catch (ArgumentNullException ane) { DebugLog("ArgumentNullException : " + ane.ToString()); } catch (SocketException se) { DebugLog("SocketException : " + se.ToString()); } catch (Exception e) { DebugLog("Unexpected exception : " + e.ToString()); } } catch (Exception e) { DebugLog(e.ToString()); } callbackThreadRunning = false; // unmark unconfirmed messages in server queue if k-buffer not empty if (oldestSentASDU != -1) { server.UnmarkAllASDUs(); } server.Remove(this); callbackThread.Join(); DebugLog("Connection thread finished"); }
/// <summary> /// 信息检查,按说每收到一条信息都要来这里检查。。。 /// </summary> /// <param name="socket"></param> /// <param name="buffer"></param> /// <param name="msgSize"></param> /// <returns></returns> private bool checkMessage(Socket socket, byte[] buffer, int msgSize) { //这里检测I帧和U帧,不知道为什么不检测S帧,难道是S帧已经处理过了? //update:似乎他这里只需要发送S帧,不主动监测S帧。。。 if ((buffer[2] & 1) == 0) { /* I format frame */ if (debugOutput) { Console.WriteLine("Received I frame"); } if (msgSize < 7) { if (debugOutput) { Console.WriteLine("I msg too small!"); } return(false); } receiveCount++; unconfirmedMessages++; long currentTime = SystemUtils.currentTimeMillis(); if ((unconfirmedMessages > parameters.W) || checkConfirmTimeout(currentTime)) { //未确认消息超过W,或者t2超时,则发送S帧 lastConfirmationTime = currentTime; unconfirmedMessages = 0; sendSMessage(); } //新建一个ASDU,准备解析 ASDU asdu = new ASDU(parameters, buffer, msgSize); //解析ASDU if (asduReceivedHandler != null) { asduReceivedHandler(asduReceivedHandlerParameter, asdu); } } else if ((buffer[2] & 0x03) == 0x03) { /* U format frame */ if (buffer[2] == 0x43) { // Check for TESTFR_ACT message //收到了测试命令,回复测试确认 socket.Send(TESTFR_CON_MSG); } else if (buffer[2] == 0x07) { /* STARTDT ACT */ //收到了开启命令,回复开启命令确认 socket.Send(STARTDT_CON_MSG); } else if (buffer[2] == 0x0b) { /* STARTDT_CON */ //收到了开启确认,处理[已连接]事件 if (connectionHandler != null) { connectionHandler(connectionHandlerParameter, ConnectionEvent.STARTDT_CON_RECEIVED); } } else if (buffer[2] == 0x23) { /* STOPDT_CON */ //收到了停止确认,处理[已断开]事件 if (connectionHandler != null) { connectionHandler(connectionHandlerParameter, ConnectionEvent.STOPDT_CON_RECEIVED); } } } return(true); }
private bool checkMessage(Socket socket, byte[] buffer, int msgSize) { long currentTime = SystemUtils.currentTimeMillis(); if ((buffer [2] & 1) == 0) /* I format frame */ { if (firstIMessageReceived == false) { firstIMessageReceived = true; lastConfirmationTime = currentTime; /* start timeout T2 */ } if (msgSize < 7) { DebugLog("I msg too small!"); return(false); } int frameSendSequenceNumber = ((buffer [3] * 0x100) + (buffer [2] & 0xfe)) / 2; int frameRecvSequenceNumber = ((buffer [5] * 0x100) + (buffer [4] & 0xfe)) / 2; DebugLog("Received I frame: N(S) = " + frameSendSequenceNumber + " N(R) = " + frameRecvSequenceNumber); /* check the receive sequence number N(R) - connection will be closed on an unexpected value */ if (frameSendSequenceNumber != receiveSequenceNumber) { DebugLog("Sequence error: Close connection!"); return(false); } if (CheckSequenceNumber(frameRecvSequenceNumber) == false) { return(false); } receiveSequenceNumber = (receiveSequenceNumber + 1) % 32768; unconfirmedReceivedIMessages++; try { ASDU asdu = new ASDU(parameters, buffer, 6, msgSize); if (asduReceivedHandler != null) { asduReceivedHandler(asduReceivedHandlerParameter, asdu); } } catch (ASDUParsingException e) { DebugLog("ASDU parsing failed: " + e.Message); return(false); } } else if ((buffer [2] & 0x03) == 0x01) /* S format frame */ { int seqNo = (buffer[4] + buffer[5] * 0x100) / 2; DebugLog("Recv S(" + seqNo + ") (own sendcounter = " + sendSequenceNumber + ")"); if (CheckSequenceNumber(seqNo) == false) { return(false); } } else if ((buffer [2] & 0x03) == 0x03) /* U format frame */ { uMessageTimeout = 0; if (buffer [2] == 0x43) // Check for TESTFR_ACT message { statistics.RcvdTestFrActCounter++; DebugLog("RCVD TESTFR_ACT"); DebugLog("SEND TESTFR_CON"); socket.Send(TESTFR_CON_MSG); statistics.SentMsgCounter++; } else if (buffer [2] == 0x83) /* TESTFR_CON */ { DebugLog("RCVD TESTFR_CON"); statistics.RcvdTestFrConCounter++; outStandingTestFRConMessages = 0; } else if (buffer [2] == 0x07) /* STARTDT ACT */ { DebugLog("RCVD STARTDT_ACT"); socket.Send(STARTDT_CON_MSG); statistics.SentMsgCounter++; } else if (buffer [2] == 0x0b) /* STARTDT_CON */ { DebugLog("RCVD STARTDT_CON"); if (connectionHandler != null) { connectionHandler(connectionHandlerParameter, ConnectionEvent.STARTDT_CON_RECEIVED); } } else if (buffer [2] == 0x23) /* STOPDT_CON */ { DebugLog("RCVD STOPDT_CON"); if (connectionHandler != null) { connectionHandler(connectionHandlerParameter, ConnectionEvent.STOPDT_CON_RECEIVED); } } } else { DebugLog("Unknown message type"); return(false); } ResetT3Timeout(); return(true); }
private void HandleConnection() { byte[] bytes = new byte[300]; try { try { connecting = true; try { // Connect to a remote device. ConnectSocketWithTimeout(); DebugLog("Socket connected to " + socket.RemoteEndPoint.ToString()); if (autostart) { socket.Send(STARTDT_ACT_MSG); statistics.SentMsgCounter++; } running = true; socketError = false; connecting = false; if (connectionHandler != null) { connectionHandler(connectionHandlerParameter, ConnectionEvent.OPENED); } } catch (SocketException se) { DebugLog("SocketException: " + se.ToString()); running = false; socketError = true; lastException = se; } if (running) { bool loopRunning = running; while (loopRunning) { bool suspendThread = true; try { // Receive a message from from the remote device. int bytesRec = receiveMessage(socket, bytes); if (bytesRec > 0) { DebugLog("RCVD: " + BitConverter.ToString(bytes, 0, bytesRec)); statistics.RcvdMsgCounter++; bool handleMessage = true; if (rawMessageHandler != null) { handleMessage = rawMessageHandler(rawMessageHandlerParameter, bytes, bytesRec); } if (handleMessage) { if (checkMessage(socket, bytes, bytesRec) == false) { /* close connection on error */ loopRunning = false; } } if (unconfirmedReceivedIMessages >= parameters.W) { lastConfirmationTime = SystemUtils.currentTimeMillis(); unconfirmedReceivedIMessages = 0; SendSMessage(); } suspendThread = false; } else if (bytesRec == -1) { loopRunning = false; } if (handleTimeouts() == false) { loopRunning = false; } if (isConnected() == false) { loopRunning = false; } if (useSendMessageQueue) { if (SendNextWaitingASDU() == true) { suspendThread = false; } } if (suspendThread) { Thread.Sleep(10); } } catch (SocketException) { loopRunning = false; } } DebugLog("CLOSE CONNECTION!"); // Release the socket. try { socket.Shutdown(SocketShutdown.Both); } catch (SocketException) { } socket.Close(); if (connectionHandler != null) { connectionHandler(connectionHandlerParameter, ConnectionEvent.CLOSED); } } } catch (ArgumentNullException ane) { connecting = false; DebugLog("ArgumentNullException: " + ane.ToString()); } catch (SocketException se) { DebugLog("SocketException: " + se.ToString()); } catch (Exception e) { DebugLog("Unexpected exception: " + e.ToString()); } } catch (Exception e) { Console.WriteLine(e.ToString()); } running = false; connecting = false; }
private bool handleTimeouts() { UInt64 currentTime = (UInt64)SystemUtils.currentTimeMillis(); if (currentTime > nextT3Timeout) { if (outStandingTestFRConMessages > 2) { DebugLog("Timeout for TESTFR_CON message"); // close connection return(false); } else { socket.Send(TESTFR_ACT_MSG); statistics.SentMsgCounter++; DebugLog("U message T3 timeout"); uMessageTimeout = (UInt64)currentTime + (UInt64)(parameters.T1 * 1000); outStandingTestFRConMessages++; ResetT3Timeout(); if (sentMessageHandler != null) { sentMessageHandler(sentMessageHandlerParameter, TESTFR_ACT_MSG, 6); } } } if (unconfirmedReceivedIMessages > 0) { if (checkConfirmTimeout((long)currentTime)) { lastConfirmationTime = (long)currentTime; unconfirmedReceivedIMessages = 0; SendSMessage(); /* send confirmation message */ } } if (uMessageTimeout != 0) { if (currentTime > uMessageTimeout) { DebugLog("U message T1 timeout"); throw new SocketException(10060); } } /* check if counterpart confirmed I messages */ lock (sentASDUs) { if (oldestSentASDU != -1) { if (((long)currentTime - sentASDUs [oldestSentASDU].sentTime) >= (parameters.T1 * 1000)) { return(false); } } } return(true); }