added errormessages (in method MCI_TxRequest_RxResponse, for better NFC error analysis) CRC check included. If the meter CRC doesn't match the calculated CRC an error is returned. removed method MCI_Raw_Read/write (same as MCI_Read/Write, which autoselects the correct password) Refactoring more detailed errorcodes(no more unidentified, separated host (>=20) and Meter messages (0..8))
156 lines
5.3 KiB
C#
156 lines
5.3 KiB
C#
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<byte> SerialPortReadBuffer = new Collection<byte>();
|
|
private SerialPort _serialPort;
|
|
|
|
private List<byte[]> _binMessages = new List<byte[]>();
|
|
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<byte>();
|
|
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;
|
|
}
|
|
}
|
|
}
|