ConnectionBase.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. using System;
  2. using System.IO.Ports;
  3. using Aitex.Core.RT.Event;
  4. using Aitex.Core.RT.Log;
  5. namespace MECF.Framework.Common.Communications
  6. {
  7. public abstract class SerialPortConnectionBase : IConnection
  8. {
  9. public string Address
  10. {
  11. get { return _address; }
  12. }
  13. public bool IsConnected
  14. {
  15. get { return _port.IsOpen(); }
  16. }
  17. public bool Connect()
  18. {
  19. return _port.Open();
  20. }
  21. public bool Disconnect()
  22. {
  23. _port.Close();
  24. return true;
  25. }
  26. public bool IsBusy
  27. {
  28. get { return _activeHandler != null; }
  29. }
  30. public bool IsCommunicationError { get; private set; }
  31. public string LastCommunicationError { get; private set; }
  32. private AsyncSerialPort _port;
  33. protected HandlerBase _activeHandler; //set, control,
  34. private object _lockerActiveHandler = new object();
  35. private string _address;
  36. private bool _isAsciiMode;
  37. public SerialPortConnectionBase(string port, int baudRate=9600, int dataBits=8, Parity parity = Parity.None, StopBits stopBits = StopBits.One, string newline = "\r", bool isAsciiMode = true)
  38. {
  39. _address = port;
  40. _isAsciiMode = isAsciiMode;
  41. _port = new AsyncSerialPort(port, baudRate, dataBits, parity, stopBits, newline, isAsciiMode);
  42. _port.OnDataChanged += _port_OnAsciiDataReceived;
  43. _port.OnBinaryDataChanged += _port_OnBinaryDataChanged;
  44. _port.OnErrorHappened += _port_OnErrorHappened;
  45. }
  46. public void SetPortAddress(string portName)
  47. {
  48. _port.PortName = portName;
  49. }
  50. private void _port_OnErrorHappened(string obj)
  51. {
  52. LOG.Error(obj);
  53. }
  54. public virtual bool SendMessage(string message)
  55. {
  56. if (_port != null && _port.IsOpen())
  57. return _port.Write(message);
  58. LOG.Error($"No connection writing message {message}");
  59. return false;
  60. }
  61. public virtual bool SendMessage(byte[] message)
  62. {
  63. if (_port != null && _port.IsOpen())
  64. return _port.Write(message);
  65. LOG.Error($"No connection writing message {string.Join(" ", Array.ConvertAll(message, x => x.ToString("X2")))}");
  66. return false;
  67. }
  68. public void Execute(HandlerBase handler)
  69. {
  70. if (_activeHandler != null)
  71. return;
  72. if (handler == null)
  73. return;
  74. if (_port.IsOpen())
  75. {
  76. lock (_lockerActiveHandler)
  77. {
  78. _activeHandler = handler;
  79. _activeHandler.SetState(EnumHandlerState.Sent);
  80. }
  81. bool sendResult = _isAsciiMode ? SendMessage(handler.SendText) : SendMessage(handler.SendBinary);
  82. if (!sendResult)
  83. {
  84. lock (_lockerActiveHandler)
  85. {
  86. _activeHandler = null;
  87. }
  88. }
  89. }
  90. }
  91. protected virtual MessageBase ParseResponse(string rawMessage)
  92. {
  93. return null;
  94. }
  95. protected virtual MessageBase ParseResponse(byte[] rawMessage)
  96. {
  97. return null;
  98. }
  99. protected virtual void OnEventArrived(MessageBase msg)
  100. {
  101. }
  102. protected virtual void ActiveHandlerProceedMessage(MessageBase msg)
  103. {
  104. lock (_lockerActiveHandler)
  105. {
  106. if (_activeHandler != null)
  107. {
  108. if (msg.IsFormatError || (_activeHandler.HandleMessage(msg, out bool transactionComplete) && transactionComplete))
  109. {
  110. _activeHandler = null;
  111. }
  112. }
  113. }
  114. }
  115. public void EnableLog(bool enable)
  116. {
  117. _port.EnableLog = enable;
  118. }
  119. private void ProceedTransactionMessage(MessageBase msg)
  120. {
  121. if (msg == null || msg.IsFormatError)
  122. {
  123. SetCommunicationError(true, "received invalid response message.");
  124. return;
  125. }
  126. if (msg.IsEvent)
  127. {
  128. OnEventArrived(msg);
  129. return;
  130. }
  131. //当前活动交互会话,继续执行
  132. ActiveHandlerProceedMessage(msg);
  133. }
  134. private void _port_OnBinaryDataChanged(byte[] binaryData)
  135. {
  136. MessageBase msg = ParseResponse(binaryData);
  137. ProceedTransactionMessage(msg);
  138. }
  139. private void _port_OnAsciiDataReceived(string oneLineMessage)
  140. {
  141. MessageBase msg = ParseResponse(oneLineMessage);
  142. ProceedTransactionMessage(msg);
  143. }
  144. public HandlerBase MonitorTimeout()
  145. {
  146. HandlerBase result = null;
  147. lock (_lockerActiveHandler)
  148. {
  149. if (_activeHandler!=null && _activeHandler.CheckTimeout())
  150. {
  151. result = _activeHandler;
  152. _activeHandler = null;
  153. SetCommunicationError(true, "receive response timeout");
  154. }
  155. }
  156. return result;
  157. }
  158. public void SetCommunicationError(bool isError, string reason)
  159. {
  160. IsCommunicationError = isError;
  161. LastCommunicationError = reason;
  162. }
  163. }
  164. }