diff --git a/OBD.NET/OBD.NET.Common/Communication/SerialConnection.cs b/OBD.NET/OBD.NET.Common/Communication/SerialConnection.cs
index c25571f..d5934cf 100644
--- a/OBD.NET/OBD.NET.Common/Communication/SerialConnection.cs
+++ b/OBD.NET/OBD.NET.Common/Communication/SerialConnection.cs
@@ -29,13 +29,13 @@ namespace OBD.NET.Communication
///
/// Connects the serial port.
///
- bool Connect();
+ void Connect();
///
/// Connects the serial port async
///
///
- Task ConnectAsync();
+ Task ConnectAsync();
///
diff --git a/OBD.NET/OBD.NET.Common/Devices/ELM327.cs b/OBD.NET/OBD.NET.Common/Devices/ELM327.cs
index 4921712..2fe0f18 100644
--- a/OBD.NET/OBD.NET.Common/Devices/ELM327.cs
+++ b/OBD.NET/OBD.NET.Common/Devices/ELM327.cs
@@ -80,51 +80,11 @@ namespace OBD.NET.Devices
}
}
- public override async Task InitializeAsync()
- {
- await base.InitializeAsync();
-
- Logger?.WriteLine("Initializing ...", OBDLogLevel.Debug);
-
- try
- {
- Logger?.WriteLine("Resetting Device ...", OBDLogLevel.Debug);
- await SendCommandAsync(ATCommand.ResetDevice);
- Logger?.WriteLine("Turning Echo Off ...", OBDLogLevel.Debug);
- await SendCommandAsync(ATCommand.EchoOff);
-
- Logger?.WriteLine("Turning Linefeeds Off ...", OBDLogLevel.Debug);
- await SendCommandAsync(ATCommand.LinefeedsOff);
-
- Logger?.WriteLine("Turning Headers Off ...", OBDLogLevel.Debug);
- await SendCommandAsync(ATCommand.HeadersOff);
-
- Logger?.WriteLine("Turning Spaced Off ...", OBDLogLevel.Debug);
- await SendCommandAsync(ATCommand.PrintSpacesOff);
-
- Logger?.WriteLine("Setting the Protocol to 'Auto' ...", OBDLogLevel.Debug);
- await SendCommandAsync(ATCommand.SetProtocolAuto); //TODO rewrite
-
-
- }
- // DarthAffe 21.02.2017: This seems to happen sometimes, i don't know why - just retry.
- catch
- {
- Logger?.WriteLine("Failed to initialize the device!", OBDLogLevel.Error);
- throw;
- }
- }
-
public virtual void SendCommand(ATCommand command)
{
SendCommand(command.Command);
}
-
- public virtual async Task SendCommandAsync(ATCommand command)
- {
- await SendCommandAsync(command.Command);
- }
-
+
public virtual void RequestData()
where T : class, IOBDData, new()
{
@@ -134,27 +94,12 @@ namespace OBD.NET.Devices
RequestData(pid);
}
- public virtual async Task RequestDataAsync()
- where T : class, IOBDData, new()
- {
- Logger?.WriteLine("Requesting Type " + typeof(T).Name + " ...", OBDLogLevel.Debug);
-
- byte pid = ResolvePid();
- await RequestDataAsync(pid);
- }
-
protected virtual void RequestData(byte pid)
{
Logger?.WriteLine("Requesting PID " + pid.ToString("X2") + " ...", OBDLogLevel.Debug);
SendCommand(((byte)Mode).ToString("X2") + pid.ToString("X2"));
}
- protected virtual async Task RequestDataAsync(byte pid)
- {
- Logger?.WriteLine("Requesting PID " + pid.ToString("X2") + " ...", OBDLogLevel.Debug);
- await SendCommandAsync(((byte)Mode).ToString("X2") + pid.ToString("X2"));
- }
-
protected override void ProcessMessage(string message)
{
DateTime timestamp = DateTime.Now;
diff --git a/OBD.NET/OBD.NET.Common/Devices/SerialDevice.cs b/OBD.NET/OBD.NET.Common/Devices/SerialDevice.cs
index eb1c656..efeffc5 100644
--- a/OBD.NET/OBD.NET.Common/Devices/SerialDevice.cs
+++ b/OBD.NET/OBD.NET.Common/Devices/SerialDevice.cs
@@ -4,6 +4,9 @@ using OBD.NET.Exceptions;
using OBD.NET.Logging;
using System.Threading.Tasks;
using OBD.NET.Common.Communication.EventArgs;
+using System.Text;
+using System.Threading;
+using System.Collections.Concurrent;
namespace OBD.NET.Devices
{
@@ -12,8 +15,15 @@ namespace OBD.NET.Devices
///
public abstract class SerialDevice : IDisposable
{
- private System.Collections.Generic.Queue commandQueue;
+ private BlockingCollection commandQueue;
+ private readonly StringBuilder _lineBuffer = new StringBuilder();
+
+ private readonly AutoResetEvent commandFinishedEvent = new AutoResetEvent(true);
+
+ private Task commandWorkerTask;
+ private CancellationTokenSource commandCancellationToken;
+
///
/// Logger instance
///
@@ -34,7 +44,7 @@ namespace OBD.NET.Devices
private SerialDevice()
{
- commandQueue = new System.Collections.Generic.Queue();
+ commandQueue = new BlockingCollection();
}
protected SerialDevice(ISerialConnection connection, char terminator = '\r', IOBDLogger logger = null)
@@ -49,12 +59,7 @@ namespace OBD.NET.Devices
#endregion
-
- private void OnDataReceived(object sender, DataReceivedEventArgs e)
- {
-
- }
-
+
#region Methods
@@ -63,22 +68,21 @@ namespace OBD.NET.Devices
///
public virtual void Initialize()
{
-
Connection.Connect();
- CheckConnection();
+ CheckConnectionAndStartWorker();
}
///
- /// Initializes the device async
+ /// Initializes the device asynchronously
///
///
public virtual async Task InitializeAsync()
{
await Connection.ConnectAsync();
- CheckConnection();
+ CheckConnectionAndStartWorker();
}
- private void CheckConnection()
+ private void CheckConnectionAndStartWorker()
{
if (!Connection.IsOpen)
{
@@ -86,23 +90,37 @@ namespace OBD.NET.Devices
throw new SerialException("Failed to open Serial-Connection.");
}
else
+ {
Logger?.WriteLine("Opened Serial-Connection!", OBDLogLevel.Debug);
+ }
+
+ commandWorkerTask = Task.Factory.StartNew(CommandWorker);
}
-
+ private void CommandWorker()
+ {
+ while (!commandCancellationToken.IsCancellationRequested)
+ {
+ string command = null;
+ commandQueue.TryTake(out command, Timeout.Infinite, commandCancellationToken.Token);
+ Logger?.WriteLine("Writing Command: '" + command.Replace('\r', '\'') + "'", OBDLogLevel.Verbose);
+ Connection.Write(Encoding.ASCII.GetBytes(command));
+
+ //wait for command to finish
+ commandFinishedEvent.WaitOne();
+ }
+ }
protected virtual void SendCommand(string command)
{
if (!Connection.IsOpen)
{
throw new InvalidOperationException("Not connected");
- }
+ }
command = PrepareCommand(command);
Logger?.WriteLine("Queuing Command: '" + command.Replace('\r', '\'') + "'", OBDLogLevel.Verbose);
- commandQueue.Enqueue(command);
-// Logger?.WriteLine("Writing Command: '" + command.Replace('\r', '\'') + "'", OBDLogLevel.Verbose);
- // Connection.Write(command);
+ commandQueue.Add(command);
}
///
@@ -120,6 +138,40 @@ namespace OBD.NET.Devices
return command;
}
+ private void OnDataReceived(object sender, DataReceivedEventArgs e)
+ {
+ for (int i = 0; i < e.Count; i++)
+ {
+ char c = (char)e.Data[i];
+ switch (c)
+ {
+ case '\r':
+ FinishLine();
+ break;
+
+ case '>':
+ commandFinishedEvent.Set();
+ break;
+
+ case '\n':
+ case (char)0x00:
+ break; // ignore
+
+ default:
+ _lineBuffer.Append(c);
+ break;
+ }
+ }
+ }
+
+ private void FinishLine()
+ {
+ string line = _lineBuffer.ToString();
+ _lineBuffer.Clear();
+ ProcessMessage(line);
+ }
+
+
private void SerialMessageReceived(object sender, string message)
{
if (string.IsNullOrWhiteSpace(message)) return;
diff --git a/OBD.NET/OBD.NET.Common/Logging/TraceLogger.cs b/OBD.NET/OBD.NET.Common/Logging/TraceLogger.cs
new file mode 100644
index 0000000..7ee9adf
--- /dev/null
+++ b/OBD.NET/OBD.NET.Common/Logging/TraceLogger.cs
@@ -0,0 +1,20 @@
+using OBD.NET.Logging;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+
+namespace OBD.NET.Common.Logging
+{
+ ///
+ /// Simple debug logger
+ ///
+ ///
+ public class OBDDebugLogger : IOBDLogger
+ {
+ public void WriteLine(string text, OBDLogLevel level)
+ {
+ Debug.WriteLine($"{level}: {text}");
+ }
+ }
+}
diff --git a/OBD.NET/OBD.NET.Universal/Communication/BluetoothSerialConnection.cs b/OBD.NET/OBD.NET.Universal/Communication/BluetoothSerialConnection.cs
index cd48f14..72b826d 100644
--- a/OBD.NET/OBD.NET.Universal/Communication/BluetoothSerialConnection.cs
+++ b/OBD.NET/OBD.NET.Universal/Communication/BluetoothSerialConnection.cs
@@ -3,6 +3,7 @@ using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using OBD.NET.Common.Communication.EventArgs;
using Windows.Devices.Bluetooth.Rfcomm;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
@@ -16,8 +17,7 @@ namespace OBD.NET.Communication
private DataWriter _writer;
private readonly byte[] _readBuffer = new byte[1024];
- private readonly StringBuilder _lineBuffer = new StringBuilder();
-
+
private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
private Task _readerTask;
@@ -32,7 +32,7 @@ namespace OBD.NET.Communication
///
/// Occurs when a full line was received
///
- public event EventHandler MessageReceived;
+ public event EventHandler DataReceived;
///
/// Connects the serial port.
@@ -74,7 +74,7 @@ namespace OBD.NET.Communication
///
/// The text.
/// Synchronous operations not supported
- public void Write(string text)
+ public void Write(byte[] data)
{
throw new NotImplementedException("Synchronous operations not supported");
}
@@ -84,9 +84,9 @@ namespace OBD.NET.Communication
///
/// The text.
///
- public async Task WriteAsync(string text)
+ public async Task WriteAsync(byte[] data)
{
- _writer.WriteString(text);
+ _writer.WriteBytes(data);
await _writer.StoreAsync();
await _writer.FlushAsync();
}
@@ -107,38 +107,10 @@ namespace OBD.NET.Communication
private void SerialPortOnDataReceived(IBuffer buffer)
{
-
- for (uint i = 0; i < buffer.Length; i++)
- {
- char c = (char)buffer.GetByte(i);
- switch (c)
- {
- case '\r':
- FinishLine();
- break;
-
- case '>':
- continue; //ignore
-
- 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);
+ DataReceived?.Invoke(this, new DataReceivedEventArgs((int)buffer.Length, _readBuffer));
}
+
public void Dispose()
{
_cancellationTokenSource?.Cancel();
@@ -146,6 +118,5 @@ namespace OBD.NET.Communication
_socket?.Dispose();
}
-
}
}
diff --git a/OBD.NET/ODB.NET.Desktop/Communication/SerialConnection.cs b/OBD.NET/ODB.NET.Desktop/Communication/SerialConnection.cs
index 23ad33d..76941f1 100644
--- a/OBD.NET/ODB.NET.Desktop/Communication/SerialConnection.cs
+++ b/OBD.NET/ODB.NET.Desktop/Communication/SerialConnection.cs
@@ -3,6 +3,7 @@ using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using OBD.NET.Common.Communication.EventArgs;
namespace OBD.NET.Communication
{
@@ -24,7 +25,7 @@ namespace OBD.NET.Communication
#region Events
- public event EventHandler MessageReceived;
+ public event EventHandler DataReceived;
#endregion
@@ -52,53 +53,15 @@ namespace OBD.NET.Communication
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);
+ DataReceived?.Invoke(this,new DataReceivedEventArgs(count, _readBuffer));
}
+
public void Dispose()
{
_serialPort?.Dispose();
@@ -109,11 +72,19 @@ namespace OBD.NET.Communication
throw new NotSupportedException("Asynchronous operations not supported");
}
- public Task WriteAsync(string text)
+ public Task WriteAsync(byte[] data)
{
throw new NotSupportedException("Asynchronous operations not supported");
}
+
+ public void Write(byte[] data)
+ {
+ _serialPort.Write(data, 0, data.Length);
+ }
+
+
+
#endregion
}
}