1
0
mirror of https://github.com/DarthAffe/OBD.NET.git synced 2025-12-13 01:08:30 +00:00
Roman Lumetsberger f9b25b4965 changed common to NetStandard-1.4
added desktop implementation of serial port (needs full Framework)
2017-05-07 09:30:05 +02:00

109 lines
2.8 KiB
C#

using System;
using System.IO.Ports;
using System.Text;
using System.Threading;
namespace OBD.NET.Communication
{
public class SerialConnection : ISerialConnection
{
#region Properties & Fields
private readonly EnhancedSerialPort _serialPort;
private readonly int _timeout;
public bool IsOpen => _serialPort?.IsOpen ?? false;
private readonly byte[] _readBuffer = new byte[1024];
private readonly StringBuilder _lineBuffer = new StringBuilder();
private readonly AutoResetEvent _hasPrompt = new AutoResetEvent(true);
#endregion
#region Events
public event EventHandler<string> MessageReceived;
#endregion
#region Constructors
public SerialConnection(string port, int baudRate = 38400, Parity parity = Parity.None, StopBits stopBits = StopBits.One,
Handshake handshake = Handshake.None, int timeout = 5000)
{
this._timeout = timeout;
_serialPort = new EnhancedSerialPort(port, baudRate, parity)
{
StopBits = stopBits,
Handshake = handshake,
ReadTimeout = timeout,
WriteTimeout = timeout
};
_serialPort.DataReceived += SerialPortOnDataReceived;
}
#endregion
#region Methods
public void Connect()
{
_serialPort.Open();
Thread.Sleep(5000);
Write("\r");
}
public void Write(string text)
{
if (!_hasPrompt.WaitOne(_timeout))
throw new TimeoutException("No prompt received");
_serialPort.Write(text);
}
private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
{
int count = _serialPort.Read(_readBuffer, 0, _serialPort.BytesToRead);
for (int i = 0; i < count; i++)
{
char c = (char)_readBuffer[i];
switch (c)
{
case '\r':
FinishLine();
break;
case '>':
_hasPrompt.Set();
break;
case '\n':
case (char)0x00:
break; // ignore
default:
_lineBuffer.Append(c);
break;
}
}
}
private void FinishLine()
{
string line = _lineBuffer.ToString();
_lineBuffer.Clear();
MessageReceived?.Invoke(this, line);
}
public void Dispose()
{
_serialPort?.Dispose();
}
#endregion
}
}