using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO.Ports; using System.Threading; using System.Diagnostics; using System.Collections.ObjectModel; //***************************************************************************** // Copyright 2020 Sensus GmbH Ludwigshafen. All rights reserved. // Author: Venkat, Rajeshwar //***************************************************************************** namespace Sensus.iPerl.NfcHandler { public class SERIAL_Driver { public string ErrorMessage { get; private set; } public Collection SerialPortReadBuffer = new Collection(); private SerialPort _serialPort; private List _binMessages = new List(); private bool _isReading; private Parity Parity { get; set; } private StopBits StopBits { get; set; } public SERIAL_Driver() { _serialPort = new SerialPort(); } public bool OpenConnection(string comPort, int baudrate, int dataBits, Parity parity, StopBits stopbits, int readTimeout=1000, int writeTimeout = 1000) { lock (this) { if ((_serialPort != null) && (_serialPort.IsOpen)) { _serialPort.DataReceived -= DataReceivedHandler; _serialPort.Close(); _serialPort.Dispose(); _serialPort = null; } try { ErrorMessage = ""; //_serialPort = new SerialPort(comPort, 57600, Parity.None, 8, StopBits.Two); _serialPort = new SerialPort(comPort, baudrate, parity, dataBits, stopbits); _serialPort.ReadTimeout = readTimeout; _serialPort.WriteTimeout = writeTimeout; _serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); _serialPort.Open(); } catch (Exception ex) { ErrorMessage = String.Format("COM error: Open failed {0}.{1}", comPort, ex.Message); return false; } if (!_serialPort.IsOpen) { ErrorMessage = String.Format("COM error: Can't Open {0}.", comPort); return false; } }//End Lock return true; } public bool SendMessage(byte[] sendDataBytes, int length, int readTimeout = 1000, int writeTimeout=1000) { if (!isOpen()) return false; if (sendDataBytes.Length == 0) return true; // nothing to send - no error try { PrepareReading(); //clear read buffer etc. _serialPort.WriteTimeout = writeTimeout; _serialPort.ReadTimeout = readTimeout; _serialPort.Write(sendDataBytes, 0, length); _isReading = true; Thread.Sleep(100); var stopWatch = Stopwatch.StartNew(); //start stop watch for data recevie timeout while (_isReading) //wait until reading finishes or timeout occur { if (stopWatch.ElapsedMilliseconds > readTimeout) { stopWatch.Stop(); ErrorMessage = "COM error: Receive timeout"; return false; } } } catch (Exception ex) { ErrorMessage = String.Format("COM error: Transmit timeout {0}.{1}", _serialPort.PortName, ex.Message); return false; // Exception in send function } return true; } private void PrepareReading() { _serialPort.DiscardInBuffer(); if(_binMessages != null) _binMessages.Clear(); _isReading = true; } public byte[] GetRawData() { try { return _binMessages[0].ToArray(); } catch(Exception) { byte[] err = { 0xFF }; return err; } } private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { if (!_serialPort.IsOpen) return; lock (this) { Thread.Sleep(100); SerialPortReadBuffer = new Collection(); while (_serialPort.BytesToRead > 0) { SerialPortReadBuffer.Add((byte)_serialPort.ReadByte()); } _binMessages.Add(SerialPortReadBuffer.ToArray()); _isReading = false; } } public void Close() { if (isOpen()) { _serialPort.Close(); } } public void Dispose() { if (_serialPort != null) { _serialPort.Dispose(); } } public bool isOpen() { if(_serialPort != null) return _serialPort.IsOpen; return false; } } }