using System; using System.Collections.Generic; //using System.Linq; using System.Text; using System.Diagnostics; using System.IO.Ports; using System.Collections; using System.Threading; namespace IControls_FireManager { // // 시리얼통신 // public class _Serial { // 시리얼 포트 public SerialPort serial = new SerialPort(); // 수신 큐 public Queue RxQueue = new Queue(); // 발신 큐 public Queue TxQueue = new Queue(); // Critical Section public Object CS_TxQueue = new Object(); public Object CS_RxQueue = new Object(); // 타입 public PortInfo MyPortInfo = PortInfo.Receiver1; // // Queue // public void RxQueue_ADD(byte[] Data) { lock (CS_RxQueue) { RxQueue.Enqueue(Data); } } public void TxQueue_ADD(byte[] Data) { lock (CS_TxQueue) { TxQueue.Enqueue(Data); } } // // 생성 // public bool Serial_Create(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits, PortInfo info) { try { if (serial.IsOpen == true) serial.Close(); MyPortInfo = info; serial = new SerialPort(portName, baudRate, parity, dataBits, stopBits); serial.Open(); serial.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived); return true; } catch (Exception e) { _Event.DebugView_SendMessage_Write(MyPortInfo, serial.PortName + e.ToString()); return false; } } // // 종료 // public void Serial_Dispose() { serial.Close(); } // // 수신 // public int buffer_index = 0; public int buffer_max_size = 30; // 읽은 데이터 만큼 임시버퍼를 생성한다 public byte[] tempbuf = new byte[30]; public void buffer_cler() { for (int i = 0; i < buffer_max_size; i++) { tempbuf[i] = 0x00; } } public void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs evt) { SerialPort serial = (SerialPort)sender; // 시리얼 포트로 들어오는 패킷 최대 버퍼 사이즈는 36이다. byte[] raw_data = new byte[buffer_max_size]; int ReadByte_Cnt = 0; try { if (serial.IsOpen) { // 메세지 수신이 몇바이트가 된건지 체크 ReadByte_Cnt = serial.Read(raw_data, 0, buffer_max_size); if (ReadByte_Cnt > buffer_max_size) ReadByte_Cnt = buffer_max_size; else if (ReadByte_Cnt <= 0) return; // 비상방송에서 응답은 반드시 1바이트만 들어온다 // 만약 중복해서 들어온다면 어차피 상위단에서 양쪽으로 송신하게 되므로 1개만 처리하도록 하자 if (MyPortInfo == PortInfo.Emergency) { // 읽은 데이터를 모두 검색한다 for (int i = 0; i < ReadByte_Cnt; i++) { if (raw_data[i] == 0x06 || raw_data[i] == 0x15) // 2가지 중에 하나이다. { Thread.Sleep(50); // 늦게 쏜다 byte[] workbuf = new byte[1]; workbuf[0] = raw_data[i]; string log = "rx " + string.Format("{0:00} ", workbuf[0].ToString("X2")); _Event.DebugView_SendMessage_Write(MyPortInfo, log); RxQueue_ADD(workbuf); return; // 종료 } } } else { // 읽은 데이터를 모두 검색한다 for (int i = 0; i < ReadByte_Cnt; i++) { if (raw_data[i] == 0x02) // 5 바이트 혹은 12 바이트 등 시작은 0x02 { // 버퍼 초기화 buffer_index = 0; // 버퍼에 저장시작 tempbuf[buffer_index] = raw_data[i]; // 버퍼 인덱스 증가 buffer_index++; } else { // 버퍼 저장시작이였다면 계속 저장 if (buffer_index >= 1) tempbuf[buffer_index] = raw_data[i]; // 버퍼 인덱스 증가 (단, 인덱스 초과하면 처음부터) if (buffer_index > 12) buffer_index = 0; else buffer_index++; } } // 길이가 5 byte 이고 폴링데이터라면 if (buffer_index == 5 && tempbuf[0] == 0x02 && tempbuf[1] == 0x50 && tempbuf[2] == 0x4F && tempbuf[3] == 0x4C && tempbuf[4] == 0x03) { byte[] workbuf = new byte[5]; string log = "rx "; for (int i = 0; i < buffer_index; i++) { workbuf[i] = tempbuf[i]; log = log + string.Format("{0:00} ", workbuf[i].ToString("X2")); } _Event.DebugView_SendMessage_Write(MyPortInfo, log); RxQueue_ADD(workbuf); // 버퍼 초기화 buffer_index = 0; buffer_cler(); return; // 종료 } else if (buffer_index == 12) { // 체크섬 계산 int chksum = 0x00; for (int i = 0;i< 10;i++) chksum = chksum + tempbuf[i]; chksum = chksum + tempbuf[11]; chksum = (chksum % 16) + 0x30; if (chksum == tempbuf[10]) { byte[] workbuf = new byte[12]; string log = "rx "; for (int i = 0; i < buffer_index; i++) { workbuf[i] = tempbuf[i]; log = log + string.Format("{0:00} ", workbuf[i].ToString("X2")); } _Event.DebugView_SendMessage_Write(MyPortInfo, log); RxQueue_ADD(workbuf); } // 버퍼 초기화 buffer_index = 0; buffer_cler(); } } } } catch (Exception e) { buffer_index = 0; _Event.DebugView_SendMessage_Write(MyPortInfo, serial.PortName + e.ToString()); } } // // 발신 // public void Serial_Transmit(byte[] data) { try { if (serial.IsOpen) { serial.Write(data, 0, data.Length); string log = "tx "; for (int i = 0; i < data.Length; i++) { log = log + string.Format("{0:00} ", data[i].ToString("X2")); } _Event.DebugView_SendMessage_Write(MyPortInfo, log); } } catch (Exception e) { _Event.DebugView_SendMessage_Write(MyPortInfo, serial.PortName + e.ToString()); } } } }