some basic work

This commit is contained in:
Daniel Schick 2022-10-05 19:25:19 +02:00
parent 13cfead3c9
commit ac84f46ae8
13 changed files with 381 additions and 4 deletions

29
AIS/ReadMe.md Normal file
View File

@ -0,0 +1,29 @@
# AIS Service
___
## Übersicht
### Architektur Entwurf
![Übersichtsbild der geplanten Architektur](architektur.jpg "Architektur")
## Stand Sep/Okt.22
Entscheidung, den leidlich laufenden AIS Service zu verbessern, da aktiv nicht mehr an WETRIS weitergearbeitet wird. Aufgaben:
* Prüfen und Debuggen des aktuellen Stands (sinnvoll?)
* Anlage einer neuen, effizienteren Datenbankstruktur (kein SQL Server!)
* Vollständige Implementierung aller Telegramm-Arten
* verbesserte Architektur (s.u. Bild)
* Webservice-Endpunkt, der aktuelle Lage als Liste liefert
* Zonen Alarm
* Einfaches Frontend zur Einrichtung von Zonen
* (Backup) Evaluierung alternativer Datenquellen
## Referenzen
* [NMEA 0183](https://de.wikipedia.org/wiki/NMEA_0183)
* [AIS Wikipedia](https://en.wikipedia.org/wiki/Automatic_identification_system)
* [AIVDM/AIVDO protocol decoding](https://gpsd.gitlab.io/gpsd/AIVDM.html)
* [AIS Documentation (PDF)](itu-m.1371-4-201004.pdf)

BIN
AIS/architektur.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

View File

@ -1,4 +1,8 @@
namespace bsmd.AIS2Service // Copyright (c) 2022- schick Informatik
// Description: Windows Service Main File
//
namespace bsmd.AIS2Service
{ {
partial class AIS2_Service partial class AIS2_Service
{ {
@ -28,8 +32,11 @@
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
components = new System.ComponentModel.Container(); //
this.ServiceName = "Service1"; // AIS2_Service
//
this.ServiceName = "BSMD AIS Service";
} }
#endregion #endregion

View File

@ -7,11 +7,14 @@ using System.Linq;
using System.ServiceProcess; using System.ServiceProcess;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using log4net;
namespace bsmd.AIS2Service namespace bsmd.AIS2Service
{ {
public partial class AIS2_Service : ServiceBase public partial class AIS2_Service : ServiceBase
{ {
private readonly ILog _log = LogManager.GetLogger(typeof(AIS2_Service));
public AIS2_Service() public AIS2_Service()
{ {
InitializeComponent(); InitializeComponent();
@ -19,10 +22,19 @@ namespace bsmd.AIS2Service
protected override void OnStart(string[] args) protected override void OnStart(string[] args)
{ {
this.EventLog.Source = this.ServiceName;
this.EventLog.Log = "Application";
this.EventLog.WriteEntry("BSMD AIS Service started.", EventLogEntryType.Information);
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
string version = fvi.FileVersion;
_log.InfoFormat("Starting AIS2 Service. v.{0} -------------- ", version);
} }
protected override void OnStop() protected override void OnStop()
{ {
_log.Info("AIS2 Service stopped.");
} }
} }
} }

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View File

@ -1,6 +1,21 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<configuration> <configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="bsmd.AIS2Service.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" /> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup> </startup>
<applicationSettings>
<bsmd.AIS2Service.Properties.Settings>
<setting name="DataSourceHost" serializeAs="String">
<value>192.168.2.24</value>
</setting>
<setting name="DataSourcePort" serializeAs="String">
<value>0</value>
</setting>
</bsmd.AIS2Service.Properties.Settings>
</applicationSettings>
</configuration> </configuration>

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bsmd.AIS2Service
{
internal interface IAISThread
{
/// <summary>
/// regular start request
/// </summary>
void Start();
/// <summary>
/// regular stop request
/// </summary>
void Stop();
/// <summary>
/// if this happens the whole show must be stopped
/// </summary>
event EventHandler FatalErrorOccurred;
}
}

View File

@ -0,0 +1,44 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace bsmd.AIS2Service.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.3.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("192.168.2.24")]
public string DataSourceHost {
get {
return ((string)(this["DataSourceHost"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
public uint DataSourcePort {
get {
return ((uint)(this["DataSourcePort"]));
}
}
}
}

View File

@ -0,0 +1,12 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="bsmd.AIS2Service.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="DataSourceHost" Type="System.String" Scope="Application">
<Value Profile="(Default)">192.168.2.24</Value>
</Setting>
<Setting Name="DataSourcePort" Type="System.UInt32" Scope="Application">
<Value Profile="(Default)">0</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -0,0 +1,80 @@
using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace bsmd.AIS2Service
{
internal class SerialTCPReader : IAISThread
{
private readonly string _host;
private readonly uint _port;
private NetworkStream tcpStream;
private TcpClient tcpSocket;
private Thread _thread;
private static readonly ILog _log = LogManager.GetLogger(typeof(SerialTCPReader));
public SerialTCPReader(string host, uint port)
{
_host = host; _port = port;
}
private void ReadData()
{
try
{
while (true)
{
if (this.tcpSocket == null || !this.tcpSocket.Connected) this.Connect();
}
}
catch(Exception ex)
{
_log.ErrorFormat("Something bad has happened: {0}", ex.Message);
if(this.FatalErrorOccurred != null)
this.FatalErrorOccurred(this, new EventArgs());
}
}
private void Connect()
{
this.tcpSocket = new TcpClient(_host, (int)_port);
this.tcpStream = tcpSocket.GetStream();
_log.InfoFormat("TCP stream connected ({0}:{1})", _host, _port);
}
#region IAISThread implementation
public event EventHandler FatalErrorOccurred;
public void Start()
{
if (_thread != null) return; // may not run twice
ThreadStart runReader = new ThreadStart(this.ReadData);
_thread = new Thread(runReader);
}
public void Stop()
{
}
#endregion
}
}

View File

@ -33,8 +33,13 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
@ -50,11 +55,31 @@
<Compile Include="AIS2_Service.Designer.cs"> <Compile Include="AIS2_Service.Designer.cs">
<DependentUpon>AIS2_Service.cs</DependentUpon> <DependentUpon>AIS2_Service.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="IAISThread.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="SerialTCPReader.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="Parser\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="AIS2_Service.resx">
<DependentUpon>AIS2_Service.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.15" targetFramework="net48" />
</packages>

BIN
AIS/itu-m.1371-4-201004.pdf Normal file

Binary file not shown.