public void AddSendTelegram(Telegram t) { t.Build(); lock (_lockSendTelegram) SendTelegrams.Add(t); _newSendTelegram.Set(); }
override public void AddSendTelegram(Telegram t) { lock (_lockSendTelegrams) { t.Build(); SendTelegrams.Enqueue(t); if (!_newSendTelegram.Task.IsCompleted) { _newSendTelegram.SetResult(SendTelegrams.First()); } Log.AddLog(Log.Severity.EVENT, Name, $"SendTelegrams.Enqueue({t.ToString()})"); } }
public bool LongTelegramSendWait(Telegram t) { try { if (CurrentSendTelegram == null) { return(false); } t.Sequence = CurrentSendTelegram.Sequence; t.CommSendStatus = CurrentSendTelegram.CommSendStatus; t.Build(); CurrentSendTelegram.SetCRC(); return(t.CRC == CurrentSendTelegram.CRC); } catch (Exception ex) { Log?.AddLog(Log.Severity.EXCEPTION, Name, "ServiceCommunicator.LongTelegramSendWait failed", ex.Message); return(false); } }
// Main thread for sending telegrams public async Task <Telegram> Send(Telegram tel) { try { if (!Connected) { await MyConnect().ConfigureAwait(false); } TelegramACK telAck = null; LastSendTime = DateTime.Now; tel.Sequence = Sequence; tel.Build(); // Log?.AddLog(Log.Severity.EVENT, Name, "Communication.SendThread", String.Format("Start sending {0}", tel.ToString())); await MyWrite(tel.ByteBuffer, 0, tel.Length).ConfigureAwait(false); Log.AddLog(Log.Severity.EVENT, Name, $"Socket written {tel.ToString()}"); tel.CommSendStatus = Telegram.CommSendStatusEnum.WaitACK; telAck = new TelegramACK(); await MyRead(telAck.ByteBuffer, 0, telAck.DesignLength()).ConfigureAwait(false); telAck.ReadBuffer(); telAck.Validate(); if (telAck.Sequence != tel.Sequence) { Log.AddLog(Log.Severity.EXCEPTION, Name, $"Sequence does not correspond"); throw new TelegramException("Sequence does not correspond"); } Sequence = (Sequence < 99) ? (short)(Sequence + 1) : (short)0; Log.AddLog(Log.Severity.EVENT, Name, $"Send finished : {tel.ToString()}"); return(tel); } catch (Exception ex) { Log.AddLog(Log.Severity.EXCEPTION, Name, ex.Message); throw; } }
// Main thread for sending telegrams public override void SendThreading() { TelegramACK telAck = null; try { lock (_lockSendTelegram) { SendTelegrams.RemoveAll(p => p.CommSendStatus >= Telegram.CommSendStatusEnum.Ack); } LastSendTime = DateTime.Now; Telegram tel = null; Telegram telNew = null; while (Thread.CurrentThread.ThreadState == ThreadState.Background) { try { if (tel == null) { lock (_lockSendTelegram) { tel = SendTelegrams.FirstOrDefault(prop => prop.CommSendStatus < Telegram.CommSendStatusEnum.Ack); CurrentSendTelegram = tel; } } if (DateTime.Now - LastSendTime > SendTimeOut) { InitSendSocket(); if (tel != null) { tel.CommSendStatus = Telegram.CommSendStatusEnum.None; } LastSendTime = DateTime.Now; Retry = 0; Log?.AddLog(Log.Severity.EXCEPTION, Name, "Communicator.SendThread", "Send timeout, SendSocket reinitialized!"); } else if (DateTime.Now - LastSendTime > KeepALifeTime && tel == null) { Telegram tRes = null; lock (_lockSendTelegram) tRes = SendTelegrams.FirstOrDefault(prop => prop.CommSendStatus < Telegram.CommSendStatusEnum.Ack); if (tRes == null) { if (KeepALifeTelegram != null) { Telegram t = Activator.CreateInstance(KeepALifeTelegram.GetType()) as Telegram; t.Sender = MFCS_ID; t.Receiver = PLC_ID; t.Build(); tel = t; Log?.AddLog(Log.Severity.EVENT, Name, "Communicator.SendThread", String.Format("Adding KeepALife telegram")); } } } else if (!SendSocket.Connected) { InitSendSocket(); ConnectSendPartner(); } else if (tel != null) { switch (tel.CommSendStatus) { case (Telegram.CommSendStatusEnum.None): CurrentSendTelegram = tel; tel.Sequence = Sequence; tel.Build(); // Log?.AddLog(Log.Severity.EVENT, Name, "Communication.SendThread", String.Format("Start sending {0}", tel.ToString())); SendSocket.Send(tel.ByteBuffer, tel.Length, SocketFlags.None); Log?.AddLog(Log.Severity.EVENT, Name, "Communicator.SendThread", String.Format("Socket written {0}", tel.ToString())); tel.CommSendStatus = Telegram.CommSendStatusEnum.WaitACK; telAck = new TelegramACK(); SendTime = DateTime.Now; break; case (Telegram.CommSendStatusEnum.WaitACK): int numRead = 0; int crRead = 0; do { crRead = SendSocket.Receive(telAck.ByteBuffer, numRead, telAck.ByteBuffer.Length - numRead, SocketFlags.None); if (crRead == 0) { throw new TelegramException("Receive bytes is 0."); } numRead += crRead; } while (numRead < telAck.ByteBuffer.Length); telAck.ReadBuffer(); Log?.AddLog(Log.Severity.EVENT, Name, "Communication.SendThread", String.Format("Received ACK {0}", telAck.ToString())); if (telAck.Validate() && telAck.Sequence == tel.Sequence) { tel.CommSendStatus = Telegram.CommSendStatusEnum.Ack; LastSendTime = DateTime.Now; Retry = 0; if (Sequence < 99) { Sequence++; } else { Sequence = 0; } Log?.AddLog(Log.Severity.EVENT, Name, "Communicator.SendThreading", String.Format("Send finished : {0}", tel.ToString())); NotifySend(tel); lock (_lockSendTelegram) telNew = SendTelegrams.FirstOrDefault(prop => prop.CommSendStatus < Telegram.CommSendStatusEnum.Ack); tel = null; } else { // tel.CommSendStatus = Telegram.CommSendStatusEnum.None; Retry++; Log?.AddLog(Log.Severity.EXCEPTION, Name, "Communicator.SendThreading", String.Format("Retry increased - {0}", Retry)); } break; default: break; } } else { WaitHandle.WaitAny(new WaitHandle[] { _newSendTelegram }, 100, true); } } catch (SocketException ex) { Log?.AddLog(Log.Severity.EXCEPTION, Name, "Communicator.SendThread::SocketException", ex.Message); Thread.Sleep(1000); } } catch (TelegramException ex) { Log?.AddLog(Log.Severity.EXCEPTION, Name, "Communicator.SendThread::TelegramException", ex.Message); Thread.Sleep(1000); } catch (ThreadAbortException ex) { Log?.AddLog(Log.Severity.EXCEPTION, Name, "Communicator.RcvThreading::ThreadAbortException", ex.Message); return; } catch (CommunicationException ex) { Log?.AddLog(Log.Severity.EXCEPTION, Name, "Communicator.SendThread::CommunicationException", ex.Message); Thread.Sleep(1000); } catch (Exception ex) { Log?.AddLog(Log.Severity.EXCEPTION, Name, "Communicator.SendThread::Exception", ex.Message); Thread.Sleep(1000); } }