/// <summary> /// Обработчик события возникновения ошибки при работе порта /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void EventHandler_SerialPort_ErrorReceived( object sender, SerialErrorReceivedEventArgs e) { //Ошибка. Создать служебное сообщение об ошибке ErrorCode code = ErrorCode.UnknownError; switch (e.EventType) { case SerialError.Frame: { code = ErrorCode.ErrorSerialPortFrame; break; } case SerialError.Overrun: { code = ErrorCode.ErrorSerialPortOverrun; break; } case SerialError.RXOver: { code = ErrorCode.ErrorSerialPortRXOver; break; } case SerialError.RXParity: { code = ErrorCode.ErrorSerialPortRXParity; break; } case SerialError.TXFull: { code = ErrorCode.ErrorSerialPortTXFull; break; } default: { code = ErrorCode.UnknownError; break; } } var errMessage = new ServiceErrorMessage() { SpecificErrorCode = ErrorCode.ErrorSerialPortFrame, Description = "Ошибка COM-порта", ExecutionTime = DateTime.Now }; _InputBuffer.Enqueue(errMessage); OnMessageReceived(); }
/// <summary> /// Обработчик срабатываения таймера межкадрового интервала /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void EventHandler_TimerInterFrameDelay_Elapsed( object sender, ElapsedEventArgs e) { DataMessage message; ServiceErrorMessage errMessage; // Если сработал межкадровый таймер, значит сообщение полностью // принято. List<Byte> list = new List<byte>(); // Получаем массив байт принятого сообщения while(_serialPort.BytesToRead != 0) { list.Add((Byte)_serialPort.ReadByte()); } // Проверяем форат сообщения // Минимальная длина сообщения 1 байт: // [ADDR: 4 байта] + [CMD: 1 байт] + [DATA: 0 байт] + [CRC16: 2 байта] = 7 байт if (list.Count < 7) { //TODO: Ошибка. Создать служебное сообщение об ошибке errMessage = new ServiceErrorMessage { SpecificErrorCode = ErrorCode.IncorrectMessageLength, Description = "Неправильная длина сообщения", ExecutionTime = DateTime.Now }; _InputBuffer.Enqueue(errMessage); OnMessageReceived(); return; } // Проверяем CRC16 var array = new Byte[list.Count - 2]; list.CopyTo(0, array, 0, array.Length); if (!CRC16.CheckCRC16(list.ToArray())) { errMessage = new ServiceErrorMessage { SpecificErrorCode = ErrorCode.IncorrectCRC, Description = "Неправильная контрольная сумма", ExecutionTime = DateTime.Now }; _InputBuffer.Enqueue(errMessage); OnMessageReceived(); return; } // Получаем данные сообщения array = new Byte[list.Count - 7]; // 7 = 5 [adr:4 cmd: 1] + 2 [crc16: 2] list.CopyTo(5, array, 0, array.Length); // Получаем адрес устройства UInt32 adr = 0; //adr |= ((UInt32)list[3] << 24); //adr |= ((UInt32)list[2] << 16); //adr |= ((UInt32)list[1] << 8); //adr |= list[0]; var arrayAdr = new Byte[4]; list.CopyTo(0, arrayAdr, 0, 4); if (BitConverter.IsLittleEndian) Array.Reverse(arrayAdr); adr = BitConverter.ToUInt32(arrayAdr, 0); message = new DataMessage(array) { MessageType = MessageType.IncomingMessage, Address = adr, CmdCode = list[4], ExecutionTime = DateTime.Now }; // Формируем сообщение и сохраняем его в буфер _InputBuffer.Enqueue(message); OnMessageReceived(); }