| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 | using System;using System.IO.Ports;using Aitex.Core.RT.Event;using Aitex.Core.RT.Log;namespace MECF.Framework.Common.Communications{    public abstract class SerialPortConnectionBase : IConnection    {        public string Address        {            get { return _address; }        }        public bool IsConnected        {            get { return _port.IsOpen(); }        }        public bool Connect()        {            return _port.Open();        }        public bool Disconnect()        {            _port.Close();            return true;        }        public bool IsBusy        {            get { return _activeHandler != null; }        }        public bool IsCommunicationError { get; private set; }        public string LastCommunicationError { get; private set; }        private AsyncSerialPort _port;        protected HandlerBase _activeHandler; //set, control,         private object _lockerActiveHandler = new object();        private string _address;        private bool _isAsciiMode;        public SerialPortConnectionBase(string port, int baudRate=9600, int dataBits=8, Parity parity = Parity.None, StopBits stopBits = StopBits.One, string newline = "\r", bool isAsciiMode = true)        {            _address = port;            _isAsciiMode = isAsciiMode;            _port = new AsyncSerialPort(port, baudRate, dataBits, parity, stopBits, newline, isAsciiMode);            _port.OnDataChanged += _port_OnAsciiDataReceived;            _port.OnBinaryDataChanged += _port_OnBinaryDataChanged;            _port.OnErrorHappened += _port_OnErrorHappened;        }        public void SetPortAddress(string portName)        {            _port.PortName = portName;        }        private void _port_OnErrorHappened(string obj)        {            //LOG.Error(obj);        }        public virtual bool SendMessage(string message)        {            if (_port != null && _port.IsOpen())                return _port.Write(message);            //LOG.Error($"No connection writing message {message}");            return false;        }        public virtual bool SendMessage(byte[] message)        {            if (_port != null && _port.IsOpen())                return _port.Write(message);             //LOG.Error($"No connection writing message {string.Join(" ", Array.ConvertAll(message, x => x.ToString("X2")))}");            return false;        }        public void Execute(HandlerBase handler)        {            if (_activeHandler != null)                return;            if (handler == null)                return;            if (_port.IsOpen())            {                lock (_lockerActiveHandler)                {                    _activeHandler = handler;                    _activeHandler.SetState(EnumHandlerState.Sent);                }                bool sendResult = _isAsciiMode ? SendMessage(handler.SendText) : SendMessage(handler.SendBinary);                if (!sendResult)                 {                    lock (_lockerActiveHandler)                    {                        _activeHandler = null;                    }                }             }        }        protected virtual MessageBase ParseResponse(string rawMessage)        {            return null;        }        protected virtual MessageBase ParseResponse(byte[] rawMessage)        {            return null;        }        protected virtual void OnEventArrived(MessageBase msg)        {        }        protected virtual void ActiveHandlerProceedMessage(MessageBase msg)        {            lock (_lockerActiveHandler)            {                if (_activeHandler != null)                {                    if (msg.IsFormatError || (_activeHandler.HandleMessage(msg, out bool transactionComplete) && transactionComplete))                    {                        _activeHandler = null;                    }                }            }        }        private void ProceedTransactionMessage(MessageBase msg)        {            if (msg == null || msg.IsFormatError)            {                SetCommunicationError(true, "received invalid response message.");                return;            }            if (msg.IsEvent)            {                OnEventArrived(msg);                return;            }            //当前活动交互会话,继续执行            ActiveHandlerProceedMessage(msg);        }        private void _port_OnBinaryDataChanged(byte[] binaryData)        {            MessageBase msg = ParseResponse(binaryData);            ProceedTransactionMessage(msg);        }        private void _port_OnAsciiDataReceived(string oneLineMessage)        {            MessageBase msg = ParseResponse(oneLineMessage);            ProceedTransactionMessage(msg);        }        public HandlerBase MonitorTimeout()        {            HandlerBase result = null;            lock (_lockerActiveHandler)            {                if (_activeHandler!=null && _activeHandler.CheckTimeout())                {                    result = _activeHandler;                    _activeHandler = null;                    SetCommunicationError(true, "receive response timeout");                }            }            return result;        }        public void SetCommunicationError(bool isError, string reason)        {            IsCommunicationError = isError;            LastCommunicationError = reason;        }    }}
 |