e5e2d71a59c1f01679a04976d80c1218e5751417.svn-base 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. using System;
  2. using System.Collections.Generic;
  3. //using System.Linq;
  4. using System.Text;
  5. using System.Diagnostics;
  6. using System.IO.Ports;
  7. using System.Collections;
  8. using System.Threading;
  9. namespace IControls_FireManager
  10. {
  11. //
  12. // 시리얼통신
  13. //
  14. public class _Serial
  15. {
  16. // 시리얼 포트
  17. public SerialPort serial = new SerialPort();
  18. // 수신 큐
  19. public Queue RxQueue = new Queue();
  20. // 발신 큐
  21. public Queue TxQueue = new Queue();
  22. // Critical Section
  23. public Object CS_TxQueue = new Object();
  24. public Object CS_RxQueue = new Object();
  25. // 타입
  26. public PortInfo MyPortInfo = PortInfo.Receiver1;
  27. //
  28. // Queue
  29. //
  30. public void RxQueue_ADD(byte[] Data)
  31. {
  32. lock (CS_RxQueue)
  33. {
  34. RxQueue.Enqueue(Data);
  35. }
  36. }
  37. public void TxQueue_ADD(byte[] Data)
  38. {
  39. lock (CS_TxQueue)
  40. {
  41. TxQueue.Enqueue(Data);
  42. }
  43. }
  44. //
  45. // 생성
  46. //
  47. public bool Serial_Create(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits, PortInfo info)
  48. {
  49. try
  50. {
  51. if (serial.IsOpen == true)
  52. serial.Close();
  53. MyPortInfo = info;
  54. serial = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
  55. serial.Open();
  56. serial.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);
  57. return true;
  58. }
  59. catch (Exception e)
  60. {
  61. _Event.DebugView_SendMessage_Write(MyPortInfo, serial.PortName + e.ToString());
  62. return false;
  63. }
  64. }
  65. //
  66. // 종료
  67. //
  68. public void Serial_Dispose()
  69. {
  70. serial.Close();
  71. }
  72. //
  73. // 수신
  74. //
  75. public int buffer_index = 0;
  76. public int buffer_max_size = 30;
  77. // 읽은 데이터 만큼 임시버퍼를 생성한다
  78. public byte[] tempbuf = new byte[30];
  79. public void buffer_cler()
  80. {
  81. for (int i = 0; i < buffer_max_size; i++)
  82. {
  83. tempbuf[i] = 0x00;
  84. }
  85. }
  86. public void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs evt)
  87. {
  88. SerialPort serial = (SerialPort)sender;
  89. // 시리얼 포트로 들어오는 패킷 최대 버퍼 사이즈는 36이다.
  90. byte[] raw_data = new byte[buffer_max_size];
  91. int ReadByte_Cnt = 0;
  92. try
  93. {
  94. if (serial.IsOpen)
  95. {
  96. // 메세지 수신이 몇바이트가 된건지 체크
  97. ReadByte_Cnt = serial.Read(raw_data, 0, buffer_max_size);
  98. if (ReadByte_Cnt > buffer_max_size)
  99. ReadByte_Cnt = buffer_max_size;
  100. else if (ReadByte_Cnt <= 0)
  101. return;
  102. // 비상방송에서 응답은 반드시 1바이트만 들어온다
  103. // 만약 중복해서 들어온다면 어차피 상위단에서 양쪽으로 송신하게 되므로 1개만 처리하도록 하자
  104. if (MyPortInfo == PortInfo.Emergency)
  105. {
  106. // 읽은 데이터를 모두 검색한다
  107. for (int i = 0; i < ReadByte_Cnt; i++)
  108. {
  109. if (raw_data[i] == 0x06 || raw_data[i] == 0x15) // 2가지 중에 하나이다.
  110. {
  111. Thread.Sleep(50); // 늦게 쏜다
  112. byte[] workbuf = new byte[1];
  113. workbuf[0] = raw_data[i];
  114. string log = "rx " + string.Format("{0:00} ", workbuf[0].ToString("X2"));
  115. _Event.DebugView_SendMessage_Write(MyPortInfo, log);
  116. RxQueue_ADD(workbuf);
  117. return; // 종료
  118. }
  119. }
  120. }
  121. else
  122. {
  123. // 읽은 데이터를 모두 검색한다
  124. for (int i = 0; i < ReadByte_Cnt; i++)
  125. {
  126. if (raw_data[i] == 0x02) // 5 바이트 혹은 12 바이트 등 시작은 0x02
  127. {
  128. // 버퍼 초기화
  129. buffer_index = 0;
  130. // 버퍼에 저장시작
  131. tempbuf[buffer_index] = raw_data[i];
  132. // 버퍼 인덱스 증가
  133. buffer_index++;
  134. }
  135. else
  136. {
  137. // 버퍼 저장시작이였다면 계속 저장
  138. if (buffer_index >= 1)
  139. tempbuf[buffer_index] = raw_data[i];
  140. // 버퍼 인덱스 증가 (단, 인덱스 초과하면 처음부터)
  141. if (buffer_index > 12)
  142. buffer_index = 0;
  143. else
  144. buffer_index++;
  145. }
  146. }
  147. // 길이가 5 byte 이고 폴링데이터라면
  148. if (buffer_index == 5
  149. && tempbuf[0] == 0x02
  150. && tempbuf[1] == 0x50
  151. && tempbuf[2] == 0x4F
  152. && tempbuf[3] == 0x4C
  153. && tempbuf[4] == 0x03)
  154. {
  155. byte[] workbuf = new byte[5];
  156. string log = "rx ";
  157. for (int i = 0; i < buffer_index; i++)
  158. {
  159. workbuf[i] = tempbuf[i];
  160. log = log + string.Format("{0:00} ", workbuf[i].ToString("X2"));
  161. }
  162. _Event.DebugView_SendMessage_Write(MyPortInfo, log);
  163. RxQueue_ADD(workbuf);
  164. // 버퍼 초기화
  165. buffer_index = 0;
  166. buffer_cler();
  167. return; // 종료
  168. }
  169. else if (buffer_index == 12)
  170. {
  171. // 체크섬 계산
  172. int chksum = 0x00;
  173. for (int i = 0;i< 10;i++)
  174. chksum = chksum + tempbuf[i];
  175. chksum = chksum + tempbuf[11];
  176. chksum = (chksum % 16) + 0x30;
  177. if (chksum == tempbuf[10])
  178. {
  179. byte[] workbuf = new byte[12];
  180. string log = "rx ";
  181. for (int i = 0; i < buffer_index; i++)
  182. {
  183. workbuf[i] = tempbuf[i];
  184. log = log + string.Format("{0:00} ", workbuf[i].ToString("X2"));
  185. }
  186. _Event.DebugView_SendMessage_Write(MyPortInfo, log);
  187. RxQueue_ADD(workbuf);
  188. }
  189. // 버퍼 초기화
  190. buffer_index = 0;
  191. buffer_cler();
  192. }
  193. }
  194. }
  195. }
  196. catch (Exception e)
  197. {
  198. buffer_index = 0;
  199. _Event.DebugView_SendMessage_Write(MyPortInfo, serial.PortName + e.ToString());
  200. }
  201. }
  202. //
  203. // 발신
  204. //
  205. public void Serial_Transmit(byte[] data)
  206. {
  207. try
  208. {
  209. if (serial.IsOpen)
  210. {
  211. serial.Write(data, 0, data.Length);
  212. string log = "tx ";
  213. for (int i = 0; i < data.Length; i++)
  214. {
  215. log = log + string.Format("{0:00} ", data[i].ToString("X2"));
  216. }
  217. _Event.DebugView_SendMessage_Write(MyPortInfo, log);
  218. }
  219. }
  220. catch (Exception e)
  221. {
  222. _Event.DebugView_SendMessage_Write(MyPortInfo, serial.PortName + e.ToString());
  223. }
  224. }
  225. }
  226. }