예제 #1
0
 public void AddSendTelegram(Telegram t)
 {
     t.Build();
     lock (_lockSendTelegram)
         SendTelegrams.Add(t);
     _newSendTelegram.Set();
 }
예제 #2
0
        // Main thread for sending telegrams
        public override async Task SendThreading(CancellationToken ct)
        {
            while (!ct.IsCancellationRequested)
            {
                try
                {
                    using (WCF_SendTelProxyClient sendTel = new WCF_SendTelProxyClient())
                    {
                        await sendTel.InitAsync(Name, SendIPEndPoint.Address.ToString(), SendIPEndPoint.Port, SendTimeOutSeconds, Version);

                        while (!ct.IsCancellationRequested)
                        {
                            Task longSilence = Task.Delay(KeepALifeTime);
                            lock (_lockSendTelegrams)
                                if (SendTelegrams.Count > 0 && !_newSendTelegram.Task.IsCompleted)
                                {
                                    _newSendTelegram.SetResult(SendTelegrams.First());
                                }
                            Task task = await Task.WhenAny(_newSendTelegram.Task, longSilence).ConfigureAwait(false);

                            await task.ConfigureAwait(false);

                            if (_newSendTelegram.Task.IsCompleted)
                            {
                                Telegram t = _newSendTelegram.Task.Result;
                                await sendTel.SendAsync(t).ConfigureAwait(false);

                                SendTime = DateTime.Now;
                                NotifySend(t);
                                Log.AddLog(Log.Severity.EVENT, Name, $"NotifySend({t.ToString()})");
                                lock (_lockSendTelegrams)
                                {
                                    _newSendTelegram = new TaskCompletionSource <Telegram>();
                                    SendTelegrams.Dequeue();
                                }
                            }
                            else if (task == longSilence)
                            {
                                KeepALifeTelegram.Sender   = MFCS_ID;
                                KeepALifeTelegram.Receiver = PLC_ID;
                                AddSendTelegram(KeepALifeTelegram);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.AddLog(Log.Severity.EXCEPTION, Name, ex.Message);
                    await Task.Delay(1000).ConfigureAwait(false);
                }
            }
        }
예제 #3
0
        public override void SendThreading()
        {
            LastSendTime = DateTime.Now;
            Telegram tel = null;

            while (Thread.CurrentThread.ThreadState == ThreadState.Background)
            {
                try
                {
                    lock (_lockSendTelegram)
                        tel = SendTelegrams.FirstOrDefault(prop => prop.CommSendStatus < Telegram.CommSendStatusEnum.Ack);
                    if (tel != null)
                    {
                        if (INotifyTelegramCallBack == null)
                        {
                            throw new TelegramException(String.Format("Callback for {0} is not registered.", Name));
                        }
                        INotifyTelegramCallBack?.Invoke(tel);
                        Log?.AddLog(Log.Severity.EVENT, Name, "MFCSCommunicator.SendThreading Telegram written", tel.ToString());
                        do
                        {
                            WaitHandle.WaitAny(new WaitHandle[] { _newSendNotifyTelegram }, (int)SendTimeOut.TotalMilliseconds, true); // TODO it is a long time
                            Telegram tel1 = null;
                            lock (_lockSendNotifyTelegram)
                                tel1 = SendNotifyTelegrams.FirstOrDefault();
                            if (tel1 == null)
                            {
                                if (!INotifyLongWait.Invoke(tel))
                                {
                                    throw new TelegramException("Long wait without knowledge of service communicator...");
                                }
                            }
                            if (tel1 != null)
                            {
                                // check if both telegrams are completely identical
                                tel.Sequence        = tel1.Sequence;
                                tel1.CommSendStatus = tel.CommSendStatus;
                                tel.SetCRC();
                                tel1.SetCRC();
                                if (tel.CRC != tel1.CRC)
                                {
                                    Log?.AddLog(Log.Severity.EXCEPTION, Name, "MFCSCommunicator.SendThreadind:tel={0}", tel.ToString());
                                    Log?.AddLog(Log.Severity.EXCEPTION, Name, "MFCSCommunicator.SendThreadind:tel1={0}", tel1.ToString());
                                    throw new TelegramException(String.Format("SendNotify telegram CRC does not match ({0},{1})", tel.CRC, tel1.CRC));
                                }
                                lock (_lockSendTelegram)
                                    SendTelegrams.Remove(tel);
                                lock (_lockSendNotifyTelegram)
                                    SendNotifyTelegrams.Remove(tel1);
                                Log?.AddLog(Log.Severity.EVENT, Name, "MFCSCommunicator.SendThreading send phase finished", tel.ToString());
                                tel = null;
                            }
                        } while (tel != null);
                    }
                    else
                    {
                        WaitHandle.WaitAny(new WaitHandle[] { _newSendTelegram, _newSendNotifyTelegram }, 100, true);
                    }
                }
                catch (TelegramException ex)
                {
                    Log?.AddLog(Log.Severity.EXCEPTION, Name, "MFCSCommunicator.SendThread::TelegramException", ex.Message);
                    Thread.Sleep(1000);
                }
            }
예제 #4
0
        // Main thread for sending telegrams
        private void SendThreading()
        {
            TelegramACK telAck = null;

            try
            {
                if (SimulateMFCS)
                {
                    SendListener = new TcpListener(SendIPEndPoint);
                    Log.AddLog(Log.Severity.EVENT, Name, "Communication.SendThreading", SendIPEndPoint.ToString());
                    SendListener.Start();
                }

                lock (_lockSendTelegram)
                {
                    SendTelegrams.RemoveAll(p => p.CommSendStatus >= Telegram.CommSendStatusEnum.Ack);
                }

                LastSendTime = DateTime.Now;

                while (Thread.CurrentThread.ThreadState == ThreadState.Background)
                {
                    try
                    {
                        Telegram tel = null;
                        lock (_lockSendTelegram)
                            tel = SendTelegrams.FirstOrDefault(prop => prop.CommSendStatus < Telegram.CommSendStatusEnum.Ack);
                        if (DateTime.Now - LastSendTime > SendTimeOut)
                        {
                            InitSendSocket();
                            if (tel != null)
                            {
                                tel.CommSendStatus = Telegram.CommSendStatusEnum.None;
                            }
                            LastSendTime = DateTime.Now;
                            Retry        = 0;
                            Log.AddLog(Log.Severity.EVENT, Name, "Communication.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();
                                    AddSendTelegram(t);
                                    Log.AddLog(Log.Severity.EVENT, Name, "Communication.SendThread", String.Format("Adding KeepALife telegram"));
                                }
                            }
                        }
                        else if (!SendSocket.Connected)
                        {
                            InitSendSocket();
                            ConnectSendPartner();
                        }
                        else if (tel != null)
                        {
                            switch (tel.CommSendStatus)
                            {
                            case (Telegram.CommSendStatusEnum.None):
                                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, "Communication.SendThread", String.Format("Sended {0}", tel.ToString()));
                                tel.CommSendStatus = Telegram.CommSendStatusEnum.WaitACK;
                                telAck             = new TelegramACK();
                                SendTime           = DateTime.Now;
                                break;

                            case (Telegram.CommSendStatusEnum.WaitACK):
                                int numRead = 0;
                                do
                                {
                                    numRead += SendSocket.Receive(telAck.ByteBuffer, numRead, telAck.ByteBuffer.Length - numRead, SocketFlags.None);
                                } 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, "Communication.SendThreading", String.Format("Send Finished : {0}", tel.ToString()));
                                    NotifySend(tel);
                                }
                                else
                                {
                                    //                                      tel.CommSendStatus = Telegram.CommSendStatusEnum.None;
                                    Retry++;
                                    Log.AddLog(Log.Severity.EVENT, Name, "Communication.SendThreading", String.Format("Retry increased - {0}", Retry));
                                }
                                break;

                            default:
                                break;
                            }
                        }
                        else
                        {
                            Thread.Sleep(100);
                        }
                    }
                    catch (SocketException ex)
                    {
                        Log.AddLog(Log.Severity.EXCEPTION, Name, "Communication.SendThread::SocketException", ex.Message);
                        Thread.Sleep(1000);
                    }
                }
                catch (TelegramException ex)
                {
                    Log.AddLog(Log.Severity.EXCEPTION, Name, "Communication.SendThread::TelegramException", ex.Message);
                    Thread.Sleep(1000);
                }
                catch (ThreadAbortException ex)
                {
                    Log.AddLog(Log.Severity.EXCEPTION, Name, "Communication.RcvThreading::Communication", ex.Message);
                    return;
                }
                catch (CommunicationException ex)
                {
                    Log.AddLog(Log.Severity.EXCEPTION, Name, "Communication.SendThread::CommunicationException", ex.Message);
                    Thread.Sleep(1000);
                }
            }