1
0
mirror of https://github.com/DarthAffe/OBD.NET.git synced 2025-12-13 01:08:30 +00:00

refactoring

This commit is contained in:
Roman Lumetsberger 2017-05-08 21:14:51 +02:00
parent 34ca0d5a4f
commit 2ca0e8a899
6 changed files with 144 additions and 59 deletions

View File

@ -1,21 +1,29 @@
using System; namespace OBD.NET.Common.Communication.EventArgs
using System.Collections.Generic;
using System.Text;
namespace OBD.NET.Common.Communication.EventArgs
{ {
/// <summary> /// <summary>
/// Event args on receiving serial data /// Event args for receiving serial data
/// </summary> /// </summary>
public class DataReceivedEventArgs:System.EventArgs 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) public DataReceivedEventArgs(int count, byte[] data)
{ {
Count = count; Count = count;
Data = data; Data = data;
} }
/// <summary>
/// Count of valid data bytes in the buffer
/// </summary>
public int Count { get; private set; } public int Count { get; private set; }
/// <summary>
/// Data buffer holding the bytes
/// </summary>
public byte[] Data { get; private set; } public byte[] Data { get; private set; }
} }
} }

View File

@ -1,7 +1,5 @@
using OBD.NET.Common.Communication.EventArgs; using OBD.NET.Common.Communication.EventArgs;
using System; using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OBD.NET.Communication namespace OBD.NET.Communication
@ -23,9 +21,10 @@ namespace OBD.NET.Communication
/// <summary> /// <summary>
/// Gets a value indicating whether this instance uses asynchronous IO /// Gets a value indicating whether this instance uses asynchronous IO
/// </summary> /// </summary>
/// <value> /// <remarks>
/// <c>true</c> if this instance is asynchronous; otherwise, <c>false</c>. /// Has to be set to true if asynchronous IO is supported.
/// </value> /// If true async methods have to be implemented
/// </remarks>
bool IsAsync { get; } bool IsAsync { get; }
/// <summary> /// <summary>
@ -43,8 +42,7 @@ namespace OBD.NET.Communication
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
Task ConnectAsync(); Task ConnectAsync();
/// <summary> /// <summary>
/// Writes the specified data to the serial connection /// Writes the specified data to the serial connection
/// </summary> /// </summary>

View File

@ -45,12 +45,22 @@ 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);
@ -58,7 +68,7 @@ namespace OBD.NET.Devices
Logger?.WriteLine("Turning Echo Off ...", OBDLogLevel.Debug); Logger?.WriteLine("Turning Echo Off ...", OBDLogLevel.Debug);
SendCommand(ATCommand.EchoOff); SendCommand(ATCommand.EchoOff);
Logger?.WriteLine("Turning Linefeeds Off ...", OBDLogLevel.Debug); Logger?.WriteLine("Turning Linefeeds Off ...", OBDLogLevel.Debug);
SendCommand(ATCommand.LinefeedsOff); SendCommand(ATCommand.LinefeedsOff);

View File

@ -22,6 +22,7 @@ namespace OBD.NET.Devices
private readonly AutoResetEvent commandFinishedEvent = new AutoResetEvent(false); private readonly AutoResetEvent commandFinishedEvent = new AutoResetEvent(false);
private Task commandWorkerTask; private Task commandWorkerTask;
private CancellationTokenSource commandCancellationToken; private CancellationTokenSource commandCancellationToken;
/// <summary> /// <summary>
@ -38,15 +39,24 @@ namespace OBD.NET.Devices
/// Terminator of the protocol message /// Terminator of the protocol message
/// </summary> /// </summary>
protected char Terminator { get; set; } protected char Terminator { get; set; }
#region Constructors #region Constructors
/// <summary>
/// Prevents a default instance of the <see cref="SerialDevice"/> class from being created.
/// </summary>
private SerialDevice() private SerialDevice()
{ {
commandQueue = new BlockingCollection<string>(); commandQueue = new BlockingCollection<string>();
} }
/// <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) protected SerialDevice(ISerialConnection connection, char terminator = '\r', IOBDLogger logger = null)
:this() :this()
{ {
@ -66,19 +76,25 @@ namespace OBD.NET.Devices
/// <summary> /// <summary>
/// Initializes the device /// Initializes the device
/// </summary> /// </summary>
public virtual async void Initialize() public virtual void Initialize()
{ {
if (Connection.IsAsync) Connection.Connect();
{
await Connection.ConnectAsync();
}
else
{
Connection.Connect();
}
CheckConnectionAndStartWorker(); 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() private void CheckConnectionAndStartWorker()
{ {
if (!Connection.IsOpen) if (!Connection.IsOpen)
@ -95,29 +111,12 @@ namespace OBD.NET.Devices
commandWorkerTask = Task.Factory.StartNew(CommandWorker); commandWorkerTask = Task.Factory.StartNew(CommandWorker);
} }
private async 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);
if (Connection.IsAsync)
{
await Connection.WriteAsync(Encoding.ASCII.GetBytes(command));
}
else
{
Connection.Write(Encoding.ASCII.GetBytes(command));
}
//wait for command to finish
commandFinishedEvent.WaitOne();
}
}
/// <summary>
/// Sends the command.
/// </summary>
/// <param name="command">command string</param>
/// <exception cref="System.InvalidOperationException">Not connected</exception>
protected virtual void SendCommand(string command) protected virtual void SendCommand(string command)
{ {
if (!Connection.IsOpen) if (!Connection.IsOpen)
@ -145,6 +144,11 @@ namespace OBD.NET.Devices
return command; 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) private void OnDataReceived(object sender, DataReceivedEventArgs e)
{ {
for (int i = 0; i < e.Count; i++) for (int i = 0; i < e.Count; i++)
@ -171,6 +175,9 @@ namespace OBD.NET.Devices
} }
} }
/// <summary>
/// Signals a final message
/// </summary>
private void FinishLine() private void FinishLine()
{ {
string line = _lineBuffer.ToString().Trim(); string line = _lineBuffer.ToString().Trim();
@ -182,11 +189,45 @@ namespace OBD.NET.Devices
ProcessMessage(line); ProcessMessage(line);
} }
/// <summary>
/// Processes the message.
/// </summary>
/// <param name="message">message received</param>
protected abstract void ProcessMessage(string message); protected abstract void ProcessMessage(string message);
/// <summary>
/// Worker method for sending commands
/// </summary>
private async 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);
if (Connection.IsAsync)
{
await Connection.WriteAsync(Encoding.ASCII.GetBytes(command));
}
else
{
Connection.Write(Encoding.ASCII.GetBytes(command));
}
//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() public virtual void Dispose()
{ {
commandCancellationToken?.Cancel();
commandWorkerTask?.Wait();
Connection?.Dispose(); Connection?.Dispose();
} }

View File

@ -1,8 +1,5 @@
using OBD.NET.Logging; using OBD.NET.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Text;
namespace OBD.NET.Common.Logging namespace OBD.NET.Common.Logging
{ {

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Runtime.InteropServices.WindowsRuntime; using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using OBD.NET.Common.Communication.EventArgs; using OBD.NET.Common.Communication.EventArgs;
@ -10,6 +9,10 @@ using Windows.Storage.Streams;
namespace OBD.NET.Communication namespace OBD.NET.Communication
{ {
/// <summary>
/// Bluetooth OBD serial implementation
/// </summary>
/// <seealso cref="OBD.NET.Communication.ISerialConnection" />
public class BluetoothSerialConnection : ISerialConnection public class BluetoothSerialConnection : ISerialConnection
{ {
@ -20,15 +23,43 @@ namespace OBD.NET.Communication
private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
private Task _readerTask; private Task _readerTask;
private string device;
/// <summary> /// <summary>
/// Gets a value indicating whether this connection is open. /// Initializes a new instance of the <see cref="BluetoothSerialConnection"/> class.
/// </summary>
public BluetoothSerialConnection()
{
device = null;
}
/// <summary>
/// Initializes a new instance of the <see cref="BluetoothSerialConnection"/> class.
/// </summary>
/// <param name="deviceName">Name of the device.</param>
/// <param name="logger">The logger.</param>
public BluetoothSerialConnection(string deviceName)
{
device = deviceName;
}
/// <summary>
/// Gets a value indicating whether this instance is open.
/// </summary> /// </summary>
/// <value> /// <value>
/// <c>true</c> if this connection is open; otherwise, <c>false</c>. /// <c>true</c> if this instance is open; otherwise, <c>false</c>.
/// </value> /// </value>
public bool IsOpen { get; private set; } public bool IsOpen { get; private set; }
/// <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>
public bool IsAsync => true; public bool IsAsync => true;
/// <summary> /// <summary>
@ -42,7 +73,7 @@ namespace OBD.NET.Communication
/// <exception cref="System.NotSupportedException">Synchronous operations not supported</exception> /// <exception cref="System.NotSupportedException">Synchronous operations not supported</exception>
public void Connect() public void Connect()
{ {
throw new NotSupportedException("Synchronous operations not supported"); throw new NotSupportedException("Synchronous operations not supported on UWP platform");
} }
/// <summary> /// <summary>
@ -78,7 +109,7 @@ namespace OBD.NET.Communication
/// <exception cref="System.NotImplementedException">Synchronous operations not supported</exception> /// <exception cref="System.NotImplementedException">Synchronous operations not supported</exception>
public void Write(byte[] data) public void Write(byte[] data)
{ {
throw new NotImplementedException("Synchronous operations not supported"); throw new NotImplementedException("Synchronous operations not supported on UWP platform");
} }
/// <summary> /// <summary>