Ejemplo n.º 1
0
 public void AddSendTelegram(Telegram t)
 {
     t.Build();
     lock (_lockSendTelegram)
         SendTelegrams.Add(t);
     _newSendTelegram.Set();
 }
Ejemplo n.º 2
0
 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()})");
     }
 }
Ejemplo n.º 3
0
 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);
     }
 }
Ejemplo n.º 4
0
        // 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;
            }
        }
Ejemplo n.º 5
0
        // 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);
                }
            }