mirror of
https://github.com/DarthAffe/OBD.NET.git
synced 2025-12-12 16:58:30 +00:00
Readded EnhanvedSerialPort for .NET-Framework support
This commit is contained in:
parent
163f5eb3a3
commit
2136aaf0ca
@ -1,10 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TargetFramework>net4.8</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
using OBD.NET.Communication;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using OBD.NET.Communication;
|
||||
using OBD.NET.Devices;
|
||||
using OBD.NET.Extensions;
|
||||
using OBD.NET.Logging;
|
||||
@ -12,19 +15,19 @@ public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
if (args.Length < 1)
|
||||
{
|
||||
Console.WriteLine("Parameter ComPort needed.");
|
||||
//if (args.Length < 1)
|
||||
//{
|
||||
// Console.WriteLine("Parameter ComPort needed.");
|
||||
|
||||
IEnumerable<string> availablePorts = SerialConnection.GetAvailablePorts();
|
||||
// IEnumerable<string> availablePorts = SerialConnection.GetAvailablePorts();
|
||||
|
||||
Console.WriteLine("\nAvailable ports:");
|
||||
// Console.WriteLine("\nAvailable ports:");
|
||||
|
||||
foreach (string port in availablePorts)
|
||||
Console.WriteLine(port);
|
||||
// foreach (string port in availablePorts)
|
||||
// Console.WriteLine(port);
|
||||
|
||||
return;
|
||||
}
|
||||
// return;
|
||||
//}
|
||||
|
||||
string comPort = args[0];
|
||||
|
||||
|
||||
172
OBD.NET/OBD.NET/Communication/EnhancedSerialPort.cs
Normal file
172
OBD.NET/OBD.NET/Communication/EnhancedSerialPort.cs
Normal file
@ -0,0 +1,172 @@
|
||||
#if !NET5_0_OR_GREATER
|
||||
|
||||
// Copyright 2013 Antanas Veiverys www.veiverys.com
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
// Source: http://antanas.veiverys.com/mono-serialport-datareceived-event-workaround-using-a-derived-class/
|
||||
namespace OBD.NET.Communication;
|
||||
|
||||
[DesignerCategory("Code")]
|
||||
public class EnhancedSerialPort : SerialPort
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
// private member access via reflection
|
||||
private int _fd;
|
||||
private FieldInfo? _disposedFieldInfo;
|
||||
private object? _dataReceived;
|
||||
private Thread? _thread;
|
||||
|
||||
#endregion
|
||||
|
||||
#region DLLImports
|
||||
|
||||
[DllImport("MonoPosixHelper", SetLastError = true)]
|
||||
private static extern bool poll_serial(int fd, out int error, int timeout);
|
||||
|
||||
[DllImport("libc")]
|
||||
private static extern IntPtr strerror(int errnum);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public EnhancedSerialPort()
|
||||
: base()
|
||||
{ }
|
||||
|
||||
public EnhancedSerialPort(IContainer container)
|
||||
: base(container)
|
||||
{ }
|
||||
|
||||
public EnhancedSerialPort(string portName)
|
||||
: base(portName)
|
||||
{ }
|
||||
|
||||
public EnhancedSerialPort(string portName, int baudRate)
|
||||
: base(portName, baudRate)
|
||||
{ }
|
||||
|
||||
public EnhancedSerialPort(string portName, int baudRate, Parity parity)
|
||||
: base(portName, baudRate, parity)
|
||||
{ }
|
||||
|
||||
public EnhancedSerialPort(string portName, int baudRate, Parity parity, int dataBits)
|
||||
: base(portName, baudRate, parity, dataBits)
|
||||
{ }
|
||||
|
||||
public EnhancedSerialPort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits)
|
||||
: base(portName, baudRate, parity, dataBits, stopBits)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public new void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
if (!IsWindows)
|
||||
{
|
||||
FieldInfo? fieldInfo = BaseStream.GetType().GetField("fd", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
if (fieldInfo == null) throw new NotSupportedException("Unable to initialize SerialPort - 'fd'-field is missing.");
|
||||
_fd = (int)fieldInfo.GetValue(BaseStream)!;
|
||||
|
||||
_disposedFieldInfo = BaseStream.GetType().GetField("disposed", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new NotSupportedException("Unable to initialize SerialPort - 'disposed'-field is missing.");
|
||||
|
||||
fieldInfo = typeof(SerialPort).GetField("data_received", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
if (fieldInfo == null) throw new NotSupportedException("Unable to initialize SerialPort - 'data_received'-field is missing.");
|
||||
_dataReceived = fieldInfo.GetValue(this);
|
||||
|
||||
_thread = new Thread(EventThreadFunction);
|
||||
_thread.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsWindows
|
||||
{
|
||||
get
|
||||
{
|
||||
PlatformID id = Environment.OSVersion.Platform;
|
||||
return (id == PlatformID.Win32Windows) || (id == PlatformID.Win32NT); // WinCE not supported
|
||||
}
|
||||
}
|
||||
|
||||
private void EventThreadFunction()
|
||||
{
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
Stream? stream = BaseStream;
|
||||
if (stream == null)
|
||||
return;
|
||||
|
||||
if (Poll(stream, ReadTimeout))
|
||||
OnDataReceived(null!);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return;
|
||||
}
|
||||
} while (IsOpen);
|
||||
}
|
||||
|
||||
private void OnDataReceived(SerialDataReceivedEventArgs args)
|
||||
{
|
||||
SerialDataReceivedEventHandler? handler = Events[_dataReceived!] as SerialDataReceivedEventHandler;
|
||||
handler?.Invoke(this, args);
|
||||
}
|
||||
|
||||
private bool Poll(Stream stream, int timeout)
|
||||
{
|
||||
CheckDisposed(stream);
|
||||
if (IsOpen == false)
|
||||
throw new Exception("port is closed");
|
||||
|
||||
bool pollResult = poll_serial(_fd, out int error, ReadTimeout);
|
||||
if (error == -1)
|
||||
ThrowIOException();
|
||||
|
||||
return pollResult;
|
||||
}
|
||||
|
||||
private static void ThrowIOException()
|
||||
{
|
||||
int errnum = Marshal.GetLastWin32Error();
|
||||
string errorMessage = Marshal.PtrToStringAnsi(strerror(errnum))!;
|
||||
|
||||
throw new IOException(errorMessage);
|
||||
}
|
||||
|
||||
private void CheckDisposed(Stream stream)
|
||||
{
|
||||
bool disposed = (bool)_disposedFieldInfo!.GetValue(stream)!;
|
||||
if (disposed)
|
||||
throw new ObjectDisposedException(stream.GetType().FullName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1,4 +1,6 @@
|
||||
using OBD.NET.Communication.EventArgs;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using OBD.NET.Communication.EventArgs;
|
||||
|
||||
namespace OBD.NET.Communication;
|
||||
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
#if NET5_0_OR_GREATER
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Threading.Tasks;
|
||||
using OBD.NET.Communication.EventArgs;
|
||||
|
||||
namespace OBD.NET.Communication;
|
||||
@ -44,11 +47,78 @@ public class SerialConnection : ISerialConnection
|
||||
|
||||
#region Methods
|
||||
|
||||
public static IEnumerable<string> GetAvailablePorts()
|
||||
public static IEnumerable<string> GetAvailablePorts() => SerialPort.GetPortNames();
|
||||
|
||||
public void Connect() => _serialPort.Open();
|
||||
|
||||
private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
|
||||
{
|
||||
return SerialPort.GetPortNames();
|
||||
int count = _serialPort.Read(_readBuffer, 0, _serialPort.BytesToRead);
|
||||
DataReceived?.Invoke(this, new DataReceivedEventArgs(count, _readBuffer));
|
||||
}
|
||||
|
||||
public void Dispose() => _serialPort.Dispose();
|
||||
|
||||
public Task ConnectAsync() => throw new NotSupportedException("Asynchronous operations not supported");
|
||||
|
||||
public Task WriteAsync(byte[] data) => throw new NotSupportedException("Asynchronous operations not supported");
|
||||
|
||||
public void Write(byte[] data) => _serialPort.Write(data, 0, data.Length);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Threading.Tasks;
|
||||
using OBD.NET.Communication.EventArgs;
|
||||
|
||||
namespace OBD.NET.Communication;
|
||||
|
||||
public class SerialConnection : ISerialConnection
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private readonly EnhancedSerialPort _serialPort;
|
||||
|
||||
public bool IsOpen => _serialPort?.IsOpen ?? false;
|
||||
public bool IsAsync => false;
|
||||
|
||||
private readonly byte[] _readBuffer = new byte[1024];
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler<DataReceivedEventArgs>? DataReceived;
|
||||
|
||||
#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)
|
||||
{
|
||||
_serialPort = new EnhancedSerialPort(port, baudRate, parity)
|
||||
{
|
||||
StopBits = stopBits,
|
||||
Handshake = handshake,
|
||||
ReadTimeout = timeout,
|
||||
WriteTimeout = timeout
|
||||
};
|
||||
|
||||
_serialPort.DataReceived += SerialPortOnDataReceived;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public static IEnumerable<string> GetAvailablePorts() => SerialPort.GetPortNames();
|
||||
|
||||
public void Connect() => _serialPort.Open();
|
||||
|
||||
private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace OBD.NET.DataTypes;
|
||||
using System;
|
||||
|
||||
namespace OBD.NET.DataTypes;
|
||||
|
||||
public abstract class GenericData
|
||||
{
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using OBD.NET.Commands;
|
||||
using OBD.NET.Communication;
|
||||
using OBD.NET.Enums;
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using OBD.NET.Communication;
|
||||
using OBD.NET.Communication.EventArgs;
|
||||
using OBD.NET.Exceptions;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using OBD.NET.OBDData;
|
||||
using System;
|
||||
using OBD.NET.OBDData;
|
||||
|
||||
namespace OBD.NET.Events.EventArgs;
|
||||
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace OBD.NET.Events.EventArgs;
|
||||
using System;
|
||||
|
||||
namespace OBD.NET.Events.EventArgs;
|
||||
|
||||
public class RawDataReceivedEventArgs
|
||||
{
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using OBD.NET.Devices;
|
||||
using System;
|
||||
using OBD.NET.Devices;
|
||||
using OBD.NET.Events.EventArgs;
|
||||
using OBD.NET.OBDData;
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using OBD.NET.OBDData;
|
||||
using System;
|
||||
using OBD.NET.OBDData;
|
||||
|
||||
namespace OBD.NET.Events;
|
||||
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace OBD.NET.Exceptions;
|
||||
using System;
|
||||
|
||||
namespace OBD.NET.Exceptions;
|
||||
|
||||
public class SerialException : Exception
|
||||
{
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace OBD.NET.Exceptions;
|
||||
using System;
|
||||
|
||||
namespace OBD.NET.Exceptions;
|
||||
|
||||
public class UnexpectedResultException : Exception
|
||||
{
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
namespace OBD.NET.Extensions;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace OBD.NET.Extensions;
|
||||
|
||||
public static class HexExtension
|
||||
{
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace OBD.NET.Logging;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace OBD.NET.Logging;
|
||||
|
||||
|
||||
@ -1,66 +1,65 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<TargetFrameworks>net6.0;net5.0;netstandard1.4</TargetFrameworks>
|
||||
<LangVersion>10</LangVersion>
|
||||
<PropertyGroup>
|
||||
<Nullable>enable</Nullable>
|
||||
<TargetFrameworks>net6.0;net5.0;net4.8</TargetFrameworks>
|
||||
<LangVersion>10</LangVersion>
|
||||
|
||||
<Authors>Darth Affe / 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>
|
||||
<Version>1.2.0</Version>
|
||||
<Authors>Darth Affe / 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>
|
||||
<Version>1.2.0</Version>
|
||||
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<RepositoryType>Github</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/DarthAffe/OBD.NET</RepositoryUrl>
|
||||
<PackageProjectUrl>https://github.com/DarthAffe/OBD.NET</PackageProjectUrl>
|
||||
<PackageLicenseExpression>GPL-2.0-only</PackageLicenseExpression>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<RepositoryType>Github</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/DarthAffe/OBD.NET</RepositoryUrl>
|
||||
<PackageProjectUrl>https://github.com/DarthAffe/OBD.NET</PackageProjectUrl>
|
||||
<PackageLicenseExpression>GPL-2.0-only</PackageLicenseExpression>
|
||||
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IncludeSource>True</IncludeSource>
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<AssemblyName>OBD.NET</AssemblyName>
|
||||
<RootNamespace>OBD.NET</RootNamespace>
|
||||
<PackageId>OBD.NET</PackageId>
|
||||
</PropertyGroup>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IncludeSource>True</IncludeSource>
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<AssemblyName>OBD.NET</AssemblyName>
|
||||
<RootNamespace>OBD.NET</RootNamespace>
|
||||
<PackageId>OBD.NET</PackageId>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'net5.0'">
|
||||
<DefineConstants>NET5_0;NETFULL</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'net5.0'">
|
||||
<DefineConstants>NET5_0;NETFULL</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0'">
|
||||
<DefineConstants>NET6_0;NETFULL</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0'">
|
||||
<DefineConstants>NET6_0;NETFULL</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.4'">
|
||||
<DefineConstants>NETCORE;NETSTANDARD;NETSTANDARD1_4</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.4'">
|
||||
<DefineConstants>NETCORE;NETSTANDARD;NETSTANDARD1_4</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<DefineConstants>$(DefineConstants);TRACE;DEBUG</DefineConstants>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<DefineConstants>$(DefineConstants);TRACE;DEBUG</DefineConstants>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DebugType>portable</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>$(NoWarn);CS1591;CS1572;CS1573</NoWarn>
|
||||
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
|
||||
<DebugType>portable</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>$(NoWarn);CS1591;CS1572;CS1573</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
|
||||
<PackageReference Include="System.IO.Ports" Version="5.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
|
||||
<PackageReference Include="System.IO.Ports" Version="5.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
|
||||
<PackageReference Include="System.IO.Ports" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
|
||||
<PackageReference Include="System.IO.Ports" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace OBD.NET.OBDData._00_1F;
|
||||
using System;
|
||||
|
||||
namespace OBD.NET.OBDData._00_1F;
|
||||
|
||||
public class CommandedSecondaryAirStatus : AbstractOBDData
|
||||
{
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace OBD.NET.OBDData._00_1F;
|
||||
using System;
|
||||
|
||||
namespace OBD.NET.OBDData._00_1F;
|
||||
|
||||
public class FuelSystemStatus : AbstractOBDData
|
||||
{
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace OBD.NET.OBDData._00_1F;
|
||||
using System;
|
||||
|
||||
namespace OBD.NET.OBDData._00_1F;
|
||||
|
||||
public class OxygenSensorPresent : AbstractOBDData
|
||||
{
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace OBD.NET.OBDData._00_1F;
|
||||
using System;
|
||||
|
||||
namespace OBD.NET.OBDData._00_1F;
|
||||
|
||||
public class OxygenSensorPresent2 : AbstractOBDData
|
||||
{
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using OBD.NET.Extensions;
|
||||
using System;
|
||||
using OBD.NET.Extensions;
|
||||
|
||||
namespace OBD.NET.OBDData;
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OBD.NET.OBDData;
|
||||
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
namespace OBD.NET.Util;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OBD.NET.Util;
|
||||
|
||||
/// <summary>
|
||||
/// Notifies one or more waiting awaiters that an event has occurred
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user