mirror of
https://github.com/DarthAffe/OBD.NET.git
synced 2025-12-13 01:08:30 +00:00
changed common to NetStandard-1.4
added desktop implementation of serial port (needs full Framework)
This commit is contained in:
parent
9dd42cba6f
commit
f9b25b4965
@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard1.6</TargetFramework>
|
<TargetFramework>netstandard1.4</TargetFramework>
|
||||||
<Authors>Wyrez / Roman Lumetsberger</Authors>
|
<Authors>Wyrez / Roman Lumetsberger</Authors>
|
||||||
<Company>-</Company>
|
<Company>-</Company>
|
||||||
<Product>OBD.NET</Product>
|
<Product>OBD.NET</Product>
|
||||||
|
|||||||
@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.26403.7
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OBD.NET.Common", "OBD.NET.Common\OBD.NET.Common.csproj", "{D985B70E-CDF3-4CF1-AB5D-8D19C7FE7B31}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OBD.NET.Common", "OBD.NET.Common\OBD.NET.Common.csproj", "{D985B70E-CDF3-4CF1-AB5D-8D19C7FE7B31}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ODB.NET.Desktop", "ODB.NET.Desktop\ODB.NET.Desktop.csproj", "{14CB98E1-95DE-4923-8896-FDF5171AA49E}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -15,6 +17,10 @@ Global
|
|||||||
{D985B70E-CDF3-4CF1-AB5D-8D19C7FE7B31}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D985B70E-CDF3-4CF1-AB5D-8D19C7FE7B31}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{D985B70E-CDF3-4CF1-AB5D-8D19C7FE7B31}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D985B70E-CDF3-4CF1-AB5D-8D19C7FE7B31}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D985B70E-CDF3-4CF1-AB5D-8D19C7FE7B31}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D985B70E-CDF3-4CF1-AB5D-8D19C7FE7B31}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{14CB98E1-95DE-4923-8896-FDF5171AA49E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{14CB98E1-95DE-4923-8896-FDF5171AA49E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{14CB98E1-95DE-4923-8896-FDF5171AA49E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{14CB98E1-95DE-4923-8896-FDF5171AA49E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
163
OBD.NET/ODB.NET.Desktop/Communication/EnhancedSerialPort.cs
Normal file
163
OBD.NET/ODB.NET.Desktop/Communication/EnhancedSerialPort.cs
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
// 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;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
#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);
|
||||||
|
_fd = (int)fieldInfo.GetValue(BaseStream);
|
||||||
|
_disposedFieldInfo = BaseStream.GetType().GetField("disposed", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
fieldInfo = typeof(SerialPort).GetField("data_received", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
_dataReceived = fieldInfo.GetValue(this);
|
||||||
|
|
||||||
|
new System.Threading.Thread(EventThreadFunction).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");
|
||||||
|
int error;
|
||||||
|
|
||||||
|
bool pollResult = poll_serial(_fd, out 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
|
||||||
|
}
|
||||||
|
}
|
||||||
108
OBD.NET/ODB.NET.Desktop/Communication/SerialConnection.cs
Normal file
108
OBD.NET/ODB.NET.Desktop/Communication/SerialConnection.cs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
54
OBD.NET/ODB.NET.Desktop/ODB.NET.Desktop.csproj
Normal file
54
OBD.NET/ODB.NET.Desktop/ODB.NET.Desktop.csproj
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{14CB98E1-95DE-4923-8896-FDF5171AA49E}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>ODB.NET.Desktop</RootNamespace>
|
||||||
|
<AssemblyName>ODB.NET.Desktop</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Communication\EnhancedSerialPort.cs" />
|
||||||
|
<Compile Include="Communication\SerialConnection.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\OBD.NET.Common\OBD.NET.Common.csproj">
|
||||||
|
<Project>{d985b70e-cdf3-4cf1-ab5d-8d19c7fe7b31}</Project>
|
||||||
|
<Name>OBD.NET.Common</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
36
OBD.NET/ODB.NET.Desktop/Properties/AssemblyInfo.cs
Normal file
36
OBD.NET/ODB.NET.Desktop/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("ODB.NET.Desktop")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("ODB.NET.Desktop")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("14cb98e1-95de-4923-8896-fdf5171aa49e")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
Loading…
x
Reference in New Issue
Block a user