mirror of
https://github.com/DarthAffe/OBD.NET.git
synced 2025-12-12 16:58:30 +00:00
Merge pull request #2 from romanlum/master
Refactored command handling and added uwp implementation
This commit is contained in:
commit
ea2ac35046
@ -0,0 +1,29 @@
|
|||||||
|
namespace OBD.NET.Common.Communication.EventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event args for receiving serial data
|
||||||
|
/// </summary>
|
||||||
|
public class DataReceivedEventArgs:System.EventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="DataReceivedEventArgs"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="count">The count.</param>
|
||||||
|
/// <param name="data">The data.</param>
|
||||||
|
public DataReceivedEventArgs(int count, byte[] data)
|
||||||
|
{
|
||||||
|
Count = count;
|
||||||
|
Data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Count of valid data bytes in the buffer
|
||||||
|
/// </summary>
|
||||||
|
public int Count { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Data buffer holding the bytes
|
||||||
|
/// </summary>
|
||||||
|
public byte[] Data { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
59
OBD.NET/OBD.NET.Common/Communication/ISerialConnection.cs
Normal file
59
OBD.NET/OBD.NET.Common/Communication/ISerialConnection.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
using OBD.NET.Common.Communication.EventArgs;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace OBD.NET.Communication
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Serial connection interface
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="System.IDisposable" />
|
||||||
|
public interface ISerialConnection : IDisposable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this instance is open.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <c>true</c> if this instance is open; otherwise, <c>false</c>.
|
||||||
|
/// </value>
|
||||||
|
bool IsOpen { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this instance uses asynchronous IO
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Has to be set to true if asynchronous IO is supported.
|
||||||
|
/// If true async methods have to be implemented
|
||||||
|
/// </remarks>
|
||||||
|
bool IsAsync { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a full line was received
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<DataReceivedEventArgs> DataReceived;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Connects the serial port.
|
||||||
|
/// </summary>
|
||||||
|
void Connect();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Connects the serial port asynchronous
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task ConnectAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes the specified data to the serial connection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text">The text.</param>
|
||||||
|
void Write(byte[] data);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes the specified data to the serial connection asynchronous
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text">The text.</param>
|
||||||
|
Task WriteAsync(byte[] data);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
27
OBD.NET/OBD.NET.Common/Devices/Command.cs
Normal file
27
OBD.NET/OBD.NET.Common/Devices/Command.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OBD.NET.Common.Devices
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class used for queued command
|
||||||
|
/// </summary>
|
||||||
|
public class QueuedCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="commandText"></param>
|
||||||
|
public QueuedCommand(string commandText)
|
||||||
|
{
|
||||||
|
CommandResult = new CommandResult();
|
||||||
|
CommandText = commandText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CommandText { get; set; }
|
||||||
|
|
||||||
|
public CommandResult CommandResult { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
18
OBD.NET/OBD.NET.Common/Devices/CommandResult.cs
Normal file
18
OBD.NET/OBD.NET.Common/Devices/CommandResult.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using OBD.NET.Util;
|
||||||
|
|
||||||
|
namespace OBD.NET.Common.Devices
|
||||||
|
{
|
||||||
|
public class CommandResult
|
||||||
|
{
|
||||||
|
public CommandResult()
|
||||||
|
{
|
||||||
|
WaitHandle = new AsyncManualResetEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Result { get; set; }
|
||||||
|
public AsyncManualResetEvent WaitHandle { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,6 +9,7 @@ using OBD.NET.Events.EventArgs;
|
|||||||
using OBD.NET.Extensions;
|
using OBD.NET.Extensions;
|
||||||
using OBD.NET.Logging;
|
using OBD.NET.Logging;
|
||||||
using OBD.NET.OBDData;
|
using OBD.NET.OBDData;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace OBD.NET.Devices
|
namespace OBD.NET.Devices
|
||||||
{
|
{
|
||||||
@ -22,7 +23,7 @@ namespace OBD.NET.Devices
|
|||||||
protected static Dictionary<byte, Type> DataTypeCache { get; } = new Dictionary<byte, Type>();
|
protected static Dictionary<byte, Type> DataTypeCache { get; } = new Dictionary<byte, Type>();
|
||||||
|
|
||||||
protected Mode Mode { get; set; } = Mode.ShowCurrentData; //TODO DarthAffe 26.06.2016: Implement different modes
|
protected Mode Mode { get; set; } = Mode.ShowCurrentData; //TODO DarthAffe 26.06.2016: Implement different modes
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
@ -36,7 +37,7 @@ namespace OBD.NET.Devices
|
|||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
public ELM327(SerialConnection connection, IOBDLogger logger = null)
|
public ELM327(ISerialConnection connection, IOBDLogger logger = null)
|
||||||
: base(connection, logger: logger)
|
: base(connection, logger: logger)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -44,17 +45,26 @@ namespace OBD.NET.Devices
|
|||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
|
public override async Task InitializeAsync()
|
||||||
|
{
|
||||||
|
await base.InitializeAsync();
|
||||||
|
InternalInitialize();
|
||||||
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
InternalInitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InternalInitialize()
|
||||||
|
{
|
||||||
Logger?.WriteLine("Initializing ...", OBDLogLevel.Debug);
|
Logger?.WriteLine("Initializing ...", OBDLogLevel.Debug);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger?.WriteLine("Resetting Device ...", OBDLogLevel.Debug);
|
Logger?.WriteLine("Resetting Device ...", OBDLogLevel.Debug);
|
||||||
SendCommand(ATCommand.ResetDevice);
|
SendCommand(ATCommand.ResetDevice);
|
||||||
Thread.Sleep(1000);
|
|
||||||
|
|
||||||
Logger?.WriteLine("Turning Echo Off ...", OBDLogLevel.Debug);
|
Logger?.WriteLine("Turning Echo Off ...", OBDLogLevel.Debug);
|
||||||
SendCommand(ATCommand.EchoOff);
|
SendCommand(ATCommand.EchoOff);
|
||||||
@ -71,7 +81,6 @@ namespace OBD.NET.Devices
|
|||||||
Logger?.WriteLine("Setting the Protocol to 'Auto' ...", OBDLogLevel.Debug);
|
Logger?.WriteLine("Setting the Protocol to 'Auto' ...", OBDLogLevel.Debug);
|
||||||
SendCommand(ATCommand.SetProtocolAuto);
|
SendCommand(ATCommand.SetProtocolAuto);
|
||||||
|
|
||||||
Thread.Sleep(1000);
|
|
||||||
}
|
}
|
||||||
// DarthAffe 21.02.2017: This seems to happen sometimes, i don't know why - just retry.
|
// DarthAffe 21.02.2017: This seems to happen sometimes, i don't know why - just retry.
|
||||||
catch
|
catch
|
||||||
@ -81,11 +90,20 @@ namespace OBD.NET.Devices
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends the AT command.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command">The command.</param>
|
||||||
public virtual void SendCommand(ATCommand command)
|
public virtual void SendCommand(ATCommand command)
|
||||||
{
|
{
|
||||||
SendCommand(command.Command);
|
SendCommand(command.Command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Requests the data and calls the handler
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
public virtual void RequestData<T>()
|
public virtual void RequestData<T>()
|
||||||
where T : class, IOBDData, new()
|
where T : class, IOBDData, new()
|
||||||
{
|
{
|
||||||
@ -101,13 +119,33 @@ namespace OBD.NET.Devices
|
|||||||
SendCommand(((byte)Mode).ToString("X2") + pid.ToString("X2"));
|
SendCommand(((byte)Mode).ToString("X2") + pid.ToString("X2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ProcessMessage(string message)
|
/// <summary>
|
||||||
|
/// Requests the data asynchronous and return the data when available
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual async Task<T> RequestDataAsync<T>()
|
||||||
|
where T : class, IOBDData, new()
|
||||||
|
{
|
||||||
|
Logger?.WriteLine("Requesting Type " + typeof(T).Name + " ...", OBDLogLevel.Debug);
|
||||||
|
byte pid = ResolvePid<T>();
|
||||||
|
Logger?.WriteLine("Requesting PID " + pid.ToString("X2") + " ...", OBDLogLevel.Debug);
|
||||||
|
var result = SendCommand(((byte)Mode).ToString("X2") + pid.ToString("X2"));
|
||||||
|
|
||||||
|
await result.WaitHandle.WaitAsync();
|
||||||
|
return result.Result as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected override object ProcessMessage(string message)
|
||||||
{
|
{
|
||||||
DateTime timestamp = DateTime.Now;
|
DateTime timestamp = DateTime.Now;
|
||||||
|
|
||||||
RawDataReceived?.Invoke(this, new RawDataReceivedEventArgs(message, timestamp));
|
RawDataReceived?.Invoke(this, new RawDataReceivedEventArgs(message, timestamp));
|
||||||
|
|
||||||
if (message.Length > 4)
|
if (message.Length > 4)
|
||||||
|
{
|
||||||
if (message[0] == '4')
|
if (message[0] == '4')
|
||||||
{
|
{
|
||||||
byte mode = (byte)message[1].GetHexVal();
|
byte mode = (byte)message[1].GetHexVal();
|
||||||
@ -119,13 +157,17 @@ namespace OBD.NET.Devices
|
|||||||
{
|
{
|
||||||
IOBDData obdData = (IOBDData)Activator.CreateInstance(dataType);
|
IOBDData obdData = (IOBDData)Activator.CreateInstance(dataType);
|
||||||
obdData.Load(message.Substring(4, message.Length - 4));
|
obdData.Load(message.Substring(4, message.Length - 4));
|
||||||
|
|
||||||
IDataEventManager dataEventManager;
|
IDataEventManager dataEventManager;
|
||||||
if (_dataReceivedEventHandlers.TryGetValue(dataType, out dataEventManager))
|
if (_dataReceivedEventHandlers.TryGetValue(dataType, out dataEventManager))
|
||||||
dataEventManager.RaiseEvent(this, obdData, timestamp);
|
dataEventManager.RaiseEvent(this, obdData, timestamp);
|
||||||
|
|
||||||
|
return obdData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual byte ResolvePid<T>()
|
protected virtual byte ResolvePid<T>()
|
||||||
@ -155,12 +197,11 @@ namespace OBD.NET.Devices
|
|||||||
if (sendCloseProtocol)
|
if (sendCloseProtocol)
|
||||||
{
|
{
|
||||||
SendCommand(ATCommand.CloseProtocol);
|
SendCommand(ATCommand.CloseProtocol);
|
||||||
Thread.Sleep(500);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
_dataReceivedEventHandlers = null;
|
_dataReceivedEventHandlers.Clear();
|
||||||
|
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
}
|
}
|
||||||
@ -9,7 +9,7 @@ namespace OBD.NET.Devices
|
|||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
public STN1170(SerialConnection connection, IOBDLogger logger = null)
|
public STN1170(ISerialConnection connection, IOBDLogger logger = null)
|
||||||
: base(connection, logger)
|
: base(connection, logger)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
256
OBD.NET/OBD.NET.Common/Devices/SerialDevice.cs
Normal file
256
OBD.NET/OBD.NET.Common/Devices/SerialDevice.cs
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
using System;
|
||||||
|
using OBD.NET.Communication;
|
||||||
|
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;
|
||||||
|
using OBD.NET.Common.Devices;
|
||||||
|
|
||||||
|
namespace OBD.NET.Devices
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base class used for communicating with the device
|
||||||
|
/// </summary>
|
||||||
|
public abstract class SerialDevice : IDisposable
|
||||||
|
{
|
||||||
|
private BlockingCollection<QueuedCommand> commandQueue;
|
||||||
|
|
||||||
|
private readonly StringBuilder _lineBuffer = new StringBuilder();
|
||||||
|
|
||||||
|
private readonly AutoResetEvent commandFinishedEvent = new AutoResetEvent(false);
|
||||||
|
|
||||||
|
private Task commandWorkerTask;
|
||||||
|
|
||||||
|
private CancellationTokenSource commandCancellationToken;
|
||||||
|
|
||||||
|
protected QueuedCommand currentCommand;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Logger instance
|
||||||
|
/// </summary>
|
||||||
|
protected IOBDLogger Logger { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Low level connection
|
||||||
|
/// </summary>
|
||||||
|
protected ISerialConnection Connection { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Terminator of the protocol message
|
||||||
|
/// </summary>
|
||||||
|
protected char Terminator { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Prevents a default instance of the <see cref="SerialDevice"/> class from being created.
|
||||||
|
/// </summary>
|
||||||
|
private SerialDevice()
|
||||||
|
{
|
||||||
|
commandQueue = new BlockingCollection<QueuedCommand>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SerialDevice"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connection">connection.</param>
|
||||||
|
/// <param name="terminator">terminator used for terminating the command message</param>
|
||||||
|
/// <param name="logger">logger instance</param>
|
||||||
|
protected SerialDevice(ISerialConnection connection, char terminator = '\r', IOBDLogger logger = null)
|
||||||
|
:this()
|
||||||
|
{
|
||||||
|
Connection = connection;
|
||||||
|
Terminator = terminator;
|
||||||
|
Logger = logger;
|
||||||
|
|
||||||
|
connection.DataReceived += OnDataReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the device
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Initialize()
|
||||||
|
{
|
||||||
|
Connection.Connect();
|
||||||
|
CheckConnectionAndStartWorker();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the device
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task InitializeAsync()
|
||||||
|
{
|
||||||
|
await Connection.ConnectAsync();
|
||||||
|
CheckConnectionAndStartWorker();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks the connection and starts background worker which is sending the commands
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="SerialException">Failed to open Serial-Connection.</exception>
|
||||||
|
private void CheckConnectionAndStartWorker()
|
||||||
|
{
|
||||||
|
if (!Connection.IsOpen)
|
||||||
|
{
|
||||||
|
Logger?.WriteLine("Failed to open Serial-Connection.", OBDLogLevel.Error);
|
||||||
|
throw new SerialException("Failed to open Serial-Connection.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger?.WriteLine("Opened Serial-Connection!", OBDLogLevel.Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
commandCancellationToken = new CancellationTokenSource();
|
||||||
|
commandWorkerTask = Task.Factory.StartNew(CommandWorker);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends the command.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command">command string</param>
|
||||||
|
/// <exception cref="System.InvalidOperationException">Not connected</exception>
|
||||||
|
protected virtual CommandResult SendCommand(string command)
|
||||||
|
{
|
||||||
|
if (!Connection.IsOpen)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Not connected");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
command = PrepareCommand(command);
|
||||||
|
Logger?.WriteLine("Queuing Command: '" + command.Replace('\r', '\'') + "'", OBDLogLevel.Verbose);
|
||||||
|
|
||||||
|
var cmd = new QueuedCommand(command);
|
||||||
|
commandQueue.Add(cmd);
|
||||||
|
return cmd.CommandResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Prepares the command
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected virtual string PrepareCommand(string command)
|
||||||
|
{
|
||||||
|
if (command == null) throw new ArgumentNullException(nameof(command));
|
||||||
|
|
||||||
|
if (!command.EndsWith(Terminator.ToString(), StringComparison.Ordinal))
|
||||||
|
command += Terminator;
|
||||||
|
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when data is received from the serial device
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender.</param>
|
||||||
|
/// <param name="e">The <see cref="DataReceivedEventArgs"/> instance containing the event data.</param>
|
||||||
|
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 '>':
|
||||||
|
currentCommand.CommandResult.WaitHandle.Set();
|
||||||
|
commandFinishedEvent.Set();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\n':
|
||||||
|
case (char)0x00:
|
||||||
|
break; // ignore
|
||||||
|
|
||||||
|
default:
|
||||||
|
_lineBuffer.Append(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Signals a final message
|
||||||
|
/// </summary>
|
||||||
|
private void FinishLine()
|
||||||
|
{
|
||||||
|
string line = _lineBuffer.ToString().Trim();
|
||||||
|
_lineBuffer.Clear();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(line)) return;
|
||||||
|
Logger?.WriteLine("Response: '" + line + "'", OBDLogLevel.Verbose);
|
||||||
|
|
||||||
|
InternalProcessMessage(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Process message and sets the result
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message.</param>
|
||||||
|
private void InternalProcessMessage(string message)
|
||||||
|
{
|
||||||
|
var data = ProcessMessage(message);
|
||||||
|
currentCommand.CommandResult.Result = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processes the message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">message received</param>
|
||||||
|
/// <returns>result data</returns>
|
||||||
|
protected abstract object ProcessMessage(string message);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Worker method for sending commands
|
||||||
|
/// </summary>
|
||||||
|
private async void CommandWorker()
|
||||||
|
{
|
||||||
|
while (!commandCancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
currentCommand = null;
|
||||||
|
if(commandQueue.TryTake(out currentCommand, Timeout.Infinite, commandCancellationToken.Token))
|
||||||
|
{
|
||||||
|
Logger?.WriteLine("Writing Command: '" + currentCommand.CommandText.Replace('\r', '\'') + "'", OBDLogLevel.Verbose);
|
||||||
|
|
||||||
|
if (Connection.IsAsync)
|
||||||
|
{
|
||||||
|
await Connection.WriteAsync(Encoding.ASCII.GetBytes(currentCommand.CommandText));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Connection.Write(Encoding.ASCII.GetBytes(currentCommand.CommandText));
|
||||||
|
|
||||||
|
}
|
||||||
|
//wait for command to finish
|
||||||
|
commandFinishedEvent.WaitOne();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Dispose()
|
||||||
|
{
|
||||||
|
commandCancellationToken?.Cancel();
|
||||||
|
commandWorkerTask?.Wait();
|
||||||
|
Connection?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace OBD.NET.Exceptions
|
namespace OBD.NET.Exceptions
|
||||||
{
|
{
|
||||||
@ -17,10 +16,7 @@ namespace OBD.NET.Exceptions
|
|||||||
public SerialException(string message, Exception innerException)
|
public SerialException(string message, Exception innerException)
|
||||||
: base(message, innerException)
|
: base(message, innerException)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
protected SerialException(SerializationInfo info, StreamingContext context)
|
|
||||||
: base(info, context)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace OBD.NET.Exceptions
|
namespace OBD.NET.Exceptions
|
||||||
{
|
{
|
||||||
@ -34,13 +33,7 @@ namespace OBD.NET.Exceptions
|
|||||||
this.Result = result;
|
this.Result = result;
|
||||||
this.ExpectedResult = expectedResult;
|
this.ExpectedResult = expectedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected UnexpectedResultException(SerializationInfo info, StreamingContext context, string result, string expectedResult)
|
|
||||||
: base(info, context)
|
|
||||||
{
|
|
||||||
this.Result = result;
|
|
||||||
this.ExpectedResult = expectedResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
17
OBD.NET/OBD.NET.Common/Logging/OBDDebugLogger.cs
Normal file
17
OBD.NET/OBD.NET.Common/Logging/OBDDebugLogger.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using OBD.NET.Logging;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace OBD.NET.Common.Logging
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Simple debug logger
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="OBD.NET.Logging.IOBDLogger" />
|
||||||
|
public class OBDDebugLogger : IOBDLogger
|
||||||
|
{
|
||||||
|
public void WriteLine(string text, OBDLogLevel level)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"{level}: {text}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
OBD.NET/OBD.NET.Common/OBD.NET.Common.csproj
Normal file
17
OBD.NET/OBD.NET.Common/OBD.NET.Common.csproj
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard1.4</TargetFramework>
|
||||||
|
<Authors>Wyrez / Roman Lumetsberger</Authors>
|
||||||
|
<Company>-</Company>
|
||||||
|
<Product>OBD.NET</Product>
|
||||||
|
<Description>C#-Library to read/write data from/to a car through an ELM327-/STN1170-Adapter</Description>
|
||||||
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
|
<Version>1.1.0</Version>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Properties\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user