123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- using Aitex.Core.RT.Event;
- using Aitex.Core.RT.Log;
- using MECF.Framework.Common.Communications;
- using MECF.Framework.Common.Equipment;
- using System;
- using System.Collections.Generic;
- namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes
- {
- public class RorzeEfemMessage : AsciiMessage
- {
- public ModuleName TargetModule { get; set; }
- public RorzeEfemMessageType MessageType { get; set; }
- public RorzeEfemBasicMessage BasicMessage { get; set; }
- public string Parameter { get; set; }
- public string NakFactor { get; set; }
- public bool WaitAck { get; set; }
- public bool WaitInf { get; set; }
- //ABS : Message* | ERROR / Parameter1 / Parameter2 ;
- //ERROR / Parameter1 / Parameter2
- public string AbsError { get; set; }
- //CAN : Message* | Factor / Place ;
- //Factor / Place
- public string CanError { get; set; }
- }
- public class RorzeEfemConnection : FsmConnection
- {
- private string _cachedBuffer = string.Empty;
- private object _lockerHandler = new object();
- private IConnectionContext _config;
- List<HandlerBase> _handlers = new List<HandlerBase>();
- private Dictionary<RorzeEfemBasicMessage, HandlerBase> _eventHandler = new Dictionary<RorzeEfemBasicMessage, HandlerBase>();
- public RorzeEfemConnection(IConnectionContext config)
- {
- _config = config;
- }
- public bool IsBusy(int mutexId)
- {
- lock (_lockerHandler)
- {
- foreach (var handlerBase in _handlers)
- {
- if (handlerBase.MutexId == mutexId)
- {
- return true;
- }
- }
- }
- return false;
- }
- public void AddEventHandler(RorzeEfemBasicMessage type, RorzeEfemHandler handler)
- {
- System.Diagnostics.Debug.Assert(!_eventHandler.ContainsKey(type));
- _eventHandler[type] = handler;
- }
- public void Initialize()
- {
- base.Initialize(100, new SocketClient(_config), _config);
- }
- protected override void OnConnect()
- {
- }
- protected override void OnDisconnect()
- {
- lock (_lockerHandler)
- {
- _cachedBuffer = string.Empty;
- _handlers.Clear();
- }
- }
- protected override void OnConnectMonitor()
- {
- MonitorTimeout();
- base.OnConnectMonitor();
- }
- private HandlerBase MonitorTimeout()
- {
- HandlerBase result = null;
- lock (_lockerHandler)
- {
- foreach (var handlerBase in _handlers)
- {
- if (handlerBase.CheckTimeout())
- {
- EV.PostWarningLog("System", $"execute {handlerBase.Name} timeout");
- result = handlerBase;
- break;
- }
- }
- if (result != null)
- {
- _handlers.Remove(result);
- }
- }
- return result;
- }
- public bool Execute(HandlerBase handler, out string reason)
- {
- lock (_lockerHandler)
- {
- foreach (var handlerBase in _handlers)
- {
- if (handlerBase.MutexId == handler.MutexId && handler.MutexId!=-1)
- {
- reason = $"Can not execute {handler.Name} while execute {handlerBase.Name}";
- return false;
- }
- }
- _handlers.Add(handler);
- handler.SetState(EnumHandlerState.Sent);
- if (_config.IsAscii)
- {
- InvokeSendData(handler.SendText);
- }
- else
- {
- InvokeSendData(handler.SendBinary);
- }
- }
- reason = string.Empty;
- return true;
- }
- public void Reset()
- {
- InvokeReset();
- }
- protected override void OnReceiveData(string message)
- {
- _cachedBuffer += message;
- int enderIndex = _cachedBuffer.IndexOf(";\r");
- while (enderIndex != -1)
- {
- if (enderIndex > 0)
- {
- ProceedResponse(_cachedBuffer.Substring(0, enderIndex));
- }
- _cachedBuffer = _cachedBuffer.Remove(0, enderIndex + 2);
- enderIndex = _cachedBuffer.IndexOf(";\r");
- }
- }
- private void AckInfo(string message)
- {
- if (message.StartsWith("INF:"))
- {
- InvokeSendData(message.Replace("INF:", "ACK:") + ";\r");
- }
- else if (message.StartsWith("ABS:"))
- {
- InvokeSendData(message.Replace("ABS:", "ACK:") + ";\r");
- }
- else if (message.StartsWith("NAK:"))
- {
- InvokeSendData(message.Replace("NAK:", "ACK:") + ";\r");
- }
- else if (message.StartsWith("CAN:"))
- {
- InvokeSendData(message.Replace("CAN:", "ACK:") + ";\r");
- }
- }
- protected void ProceedResponse(string rawMessage)
- {
- RorzeEfemMessage msg = new RorzeEfemMessage();
- msg.RawMessage = rawMessage;
- if (rawMessage == "INF:READY/COMM")
- {
- _eventHandler[RorzeEfemBasicMessage.READY].HandleMessage(msg, out _);
- AckInfo(rawMessage);
- return;
- }
- string[] words = rawMessage.Split(new char[5] { ':', '/', '>', '|', ';' }, StringSplitOptions.RemoveEmptyEntries);
- msg.MessagePart = words;
- if (!Enum.TryParse<RorzeEfemMessageType>(words[0], out RorzeEfemMessageType type))
- {
- LOG.Write($"{rawMessage} is not a valid EFEM message format");
- return;
- }
- if (type == RorzeEfemMessageType.MOV || type == RorzeEfemMessageType.GET ||
- type == RorzeEfemMessageType.SET)
- {
- LOG.Write($"{rawMessage} is not a valid EFEM message format, {type} is TO EFEM");
- return;
- }
- msg.MessageType = type;
- msg.IsEvent = msg.MessageType == RorzeEfemMessageType.EVT;
- int messageIndex = msg.MessageType == RorzeEfemMessageType.NAK ? 2 : 1;
- if (words.Length <= messageIndex || !Enum.TryParse<RorzeEfemBasicMessage>(words[messageIndex], out RorzeEfemBasicMessage basicMessage))
- {
- LOG.Write($"{rawMessage} is not a valid EFEM message format");
- return;
- }
- msg.BasicMessage = basicMessage;
- if (msg.MessageType == RorzeEfemMessageType.NAK)
- {
- msg.NakFactor = words[1];
- msg.Parameter = rawMessage.Substring(rawMessage.IndexOf('/') + 1);
- }
- else if (msg.MessageType == RorzeEfemMessageType.CAN)
- {
- msg.CanError = rawMessage.Substring(rawMessage.IndexOf('|'));
- msg.Parameter = rawMessage.Substring(rawMessage.IndexOf('/') + 1, rawMessage.IndexOf('|') - rawMessage.IndexOf('/'));
- }
- else if (msg.MessageType == RorzeEfemMessageType.ABS)
- {
- msg.AbsError = rawMessage.Substring(rawMessage.IndexOf('|'));
- msg.Parameter = rawMessage.Substring(rawMessage.IndexOf('/') + 1, rawMessage.IndexOf('|') - rawMessage.IndexOf('/'));
- }
- else
- {
- msg.Parameter = rawMessage.Substring(rawMessage.IndexOf('/') + 1);
- }
- if (msg.IsEvent)
- {
- ProceedEvent(msg);
- return;
- }
- //Report of ERROR
- if (msg.MessageType == RorzeEfemMessageType.INF && words.Length>=2 && words[1].ToUpper() == "ERROR")
- {
- AckInfo(rawMessage);
- return;
- }
- ProceedMessage(msg);
- }
- private void ProceedMessage(RorzeEfemMessage msg)
- {
- lock (_lockerHandler)
- {
- HandlerBase handlerDone = null;
- bool matchMessage = false;
- foreach (var handler in _handlers)
- {
- matchMessage = handler.HandleMessage(msg, out bool completed);
- if (completed)
- {
- handlerDone = handler;
- AckInfo(msg.RawMessage);
- break;
- }
- if (matchMessage)
- break;
- }
- if (!matchMessage)
- {
- LOG.Write($"No handler for message, {msg.RawMessage}");
- return;
- }
- _handlers.Remove(handlerDone);
- }
- }
- private void ProceedEvent(RorzeEfemMessage msg)
- {
- if (_eventHandler.ContainsKey(msg.BasicMessage))
- {
- _eventHandler[msg.BasicMessage].HandleMessage(msg, out _);
- }
- else
- {
- LOG.Write($"No handler for event {msg.RawMessage}");
- }
- }
- }
- }
|