ConnectionBase.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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. private void ProceedTransactionMessage(MessageBase msg)
  116. {
  117. if (msg == null || msg.IsFormatError)
  118. {
  119. SetCommunicationError(true, "received invalid response message.");
  120. return;
  121. }
  122. if (msg.IsEvent)
  123. {
  124. OnEventArrived(msg);
  125. return;
  126. }
  127. //当前活动交互会话,继续执行
  128. ActiveHandlerProceedMessage(msg);
  129. }
  130. private void _port_OnBinaryDataChanged(byte[] binaryData)
  131. {
  132. MessageBase msg = ParseResponse(binaryData);
  133. ProceedTransactionMessage(msg);
  134. }
  135. private void _port_OnAsciiDataReceived(string oneLineMessage)
  136. {
  137. MessageBase msg = ParseResponse(oneLineMessage);
  138. ProceedTransactionMessage(msg);
  139. }
  140. public HandlerBase MonitorTimeout()
  141. {
  142. HandlerBase result = null;
  143. lock (_lockerActiveHandler)
  144. {
  145. if (_activeHandler!=null && _activeHandler.CheckTimeout())
  146. {
  147. result = _activeHandler;
  148. _activeHandler = null;
  149. SetCommunicationError(true, "receive response timeout");
  150. }
  151. }
  152. return result;
  153. }
  154. public void SetCommunicationError(bool isError, string reason)
  155. {
  156. IsCommunicationError = isError;
  157. LastCommunicationError = reason;
  158. }
  159. }
  160. }