From e8a3e6de16ba8604c7631a66716c83ef0d4139d1 Mon Sep 17 00:00:00 2001 From: Daniel Schick Date: Sun, 9 Oct 2022 22:19:52 +0200 Subject: [PATCH] =?UTF-8?q?alles=20tut=20soweit,=20SQLite=20Tabelle=20f?= =?UTF-8?q?=C3=BCr=20Speicherung=20angelegt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AIS/SQL/ais_initial.db | Bin 0 -> 16384 bytes AIS/bsmd.AIS2Service/AISClass.cs | 27 +- AIS/bsmd.AIS2Service/AISDecoder.cs | 2 +- AIS/bsmd.AIS2Service/AISManager.cs | 1 + AIS/bsmd.AIS2Service/AIS_BaseStationReport.cs | 103 ++++++ AIS/bsmd.AIS2Service/AIS_Target.cs | 318 ++++++++++++++++++ AIS/bsmd.AIS2Service/bsmd.AIS2Service.csproj | 14 + AIS/bsmd.AIS2Service/packages.config | 2 + 8 files changed, 461 insertions(+), 6 deletions(-) create mode 100644 AIS/SQL/ais_initial.db create mode 100644 AIS/bsmd.AIS2Service/AIS_BaseStationReport.cs create mode 100644 AIS/bsmd.AIS2Service/AIS_Target.cs diff --git a/AIS/SQL/ais_initial.db b/AIS/SQL/ais_initial.db new file mode 100644 index 0000000000000000000000000000000000000000..76d1989699662b4689c7d26e793b10020b4ddd52 GIT binary patch literal 16384 zcmeI#(Q4Z;6b4|sDJv~o8SEmLbq#}rcDvaNEE}eTrD>PBuv`sARvm#Yxt1K(+l}oV z#$I5LxuZ6Tt90xE!f!CPj%4ZRJHFAUk0WVCbgk=>+2~F1JP5}^Gn2a{y76zb8`ZkWE##6og^c*(w2wJ^di6RcU2&#gZr z?N2J&p-Xp_NoF_ZDUDoz6^$>_XnZvqxtw{yjG3+bTxeDcmf5)%D}>57Lc+3kK|W_H z7g-xeRrr7!#6X5n7<=qUX0;%?4Ln_5)5w(FN2Z=QG^zc0U}jVz1iVcjMC&mP4V zu0)Mlf9ND@?QK5hI`{g`Mw@Zo)QsPHg9@#3X`9TiXh9W!6r5Axr1ICW^v6+ZW!2WE zX0r5_;F@+u>3d6fr6Q4NaFt#R#{_qtj8iI`JDby?9~T55009U<00Izz00bZa0SG_< z0$VJA^ZynX7h8h>1Rwwb2tWV=5P$##AOHafECq1>$FBeZ2tWV=5P$##AOHafKmY;| H*nWY(xHJU{ literal 0 HcmV?d00001 diff --git a/AIS/bsmd.AIS2Service/AISClass.cs b/AIS/bsmd.AIS2Service/AISClass.cs index 76185a1a..5c9ae54c 100644 --- a/AIS/bsmd.AIS2Service/AISClass.cs +++ b/AIS/bsmd.AIS2Service/AISClass.cs @@ -1,4 +1,5 @@ -using System; +using log4net; +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -66,6 +67,7 @@ namespace bsmd.AIS2Service private AISType _type = AISType.AIS_NONE; protected int _mmsi; protected string _data; + private static readonly ILog _log = LogManager.GetLogger(typeof(AISClass)); #endregion @@ -92,8 +94,7 @@ namespace bsmd.AIS2Service #region static methods internal static AISClass Decode(string data, ref Status status) - { - AISClass result = null; + { if (data == null || data.Length == 0) { @@ -104,7 +105,7 @@ namespace bsmd.AIS2Service BitArray bits = AISClass.DecodeChar(data[0]); int type = AISClass.GetInt(bits, 0, 5); - result = AISClass.CreateMessage(type); + AISClass result = AISClass.CreateMessage(type); if (result != null) { result._data = data; @@ -139,7 +140,10 @@ namespace bsmd.AIS2Service result = new AIS_PosReport(); result._type = AISType.POSITION_REPORT_SPECIAL; break; - + case 4: + result = new AIS_BaseStationReport(); + result._type = AISType.BASE_STATION_REPORT; + break; case 5: result = new AIS_StaticData(); result._type = AISType.STATIC_VOYAGE_DATA; @@ -161,6 +165,7 @@ namespace bsmd.AIS2Service break; default: + _log.InfoFormat("No decoder for AIS class {0}", (AISType)type); break; } @@ -221,6 +226,18 @@ namespace bsmd.AIS2Service return result; } + protected static uint GetUInt(BitArray bits, int lo, int hi) + { + uint result = 0; + uint test = 1; + + for (int i = hi; i >= lo; i--, test <<= 1) + { + if (bits[i]) result |= test; + } + return result; + } + protected static char GetAISChar(int val) { if (val < 32) return Convert.ToChar(val + 64); diff --git a/AIS/bsmd.AIS2Service/AISDecoder.cs b/AIS/bsmd.AIS2Service/AISDecoder.cs index d7b84809..2bc5ee33 100644 --- a/AIS/bsmd.AIS2Service/AISDecoder.cs +++ b/AIS/bsmd.AIS2Service/AISDecoder.cs @@ -119,7 +119,7 @@ namespace bsmd.AIS2Service if(aisStatus == AISClass.Status.OK) { _outputAISClasses.Enqueue(decodedClass); - _log.InfoFormat("Enqueuing AIS message for MMSI {0}", decodedClass.MMSI); + _log.DebugFormat("Enqueuing {0} message for MMSI {1}", decodedClass.MessageType, decodedClass.MMSI); } else { diff --git a/AIS/bsmd.AIS2Service/AISManager.cs b/AIS/bsmd.AIS2Service/AISManager.cs index 0748fbd8..739a8ee1 100644 --- a/AIS/bsmd.AIS2Service/AISManager.cs +++ b/AIS/bsmd.AIS2Service/AISManager.cs @@ -14,6 +14,7 @@ namespace bsmd.AIS2Service private static readonly ConcurrentQueue _inputLines = new ConcurrentQueue(); private static readonly ConcurrentQueue _decodedClasses = new ConcurrentQueue(); private static readonly ILog _log = LogManager.GetLogger(typeof(AISManager)); + private static readonly List _sitRepList = new List(); public static void Start() { diff --git a/AIS/bsmd.AIS2Service/AIS_BaseStationReport.cs b/AIS/bsmd.AIS2Service/AIS_BaseStationReport.cs new file mode 100644 index 00000000..4d3fb972 --- /dev/null +++ b/AIS/bsmd.AIS2Service/AIS_BaseStationReport.cs @@ -0,0 +1,103 @@ +using log4net; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Remoting.Metadata.W3cXsd2001; +using System.Text; +using System.Threading.Tasks; + +namespace bsmd.AIS2Service +{ + internal class AIS_BaseStationReport : AISClass + { + + #region enums + + public enum EPFDType + { + UNDEFINED, + GPS, + GLONASS, + COMBINED_GPS_GLONASS, + LORAN_C, + CHAYKA, + INTEGR_NAV_SYSTEM, + SURVEYED, + GALILEO + } + + #endregion + + #region fields + + private uint _repeatIndicator; + private DateTime? _utcTimestamp; + private bool _accuracy; + private int _latitude; + private int _longitude; + private EPFDType _epfdType; + bool _raim; + private uint _radio; + + private static readonly ILog _log = LogManager.GetLogger(typeof(AIS_BaseStationReport)); + + #endregion + + #region Properties + + public uint RepeatIndicator { get { return _repeatIndicator; } } + + public DateTime? UTCTimestamp { get { return _utcTimestamp; } } + + public bool Accuracy { get { return _accuracy; } } + + public int Latitude { get { return _latitude; } } + + public int Longitude { get { return _longitude; } } + + public EPFDType EPFD { get { return _epfdType; } } + + public bool Raim { get { return _raim; } } + + public uint Radio { get { return _radio; } } + + #endregion + + #region abstract class implementation + + protected override Status Decode() + { + Status result = Status.OK; + BitArray bits = DecodeBinary(_data); + + try + { + _repeatIndicator = GetUInt(bits, 6, 7); + _mmsi = GetInt(bits, 8, 37); + uint year = GetUInt(bits, 38, 51); + uint month = GetUInt(bits, 52, 55); + uint day = GetUInt(bits, 56, 60); + uint hour = GetUInt(bits, 61, 65); + uint minute = GetUInt(bits, 66, 71); + uint second = GetUInt(bits, 72, 77); + _utcTimestamp = new DateTime((int) year, (int) month, (int) day, (int) hour, (int) minute, (int) second, DateTimeKind.Utc); + _accuracy = GetInt(bits, 78, 78) == 1; + _longitude = GetInt(bits, 79, 106); + _latitude = GetInt(bits, 107, 133); + int epfd = GetInt(bits, 134, 137); + _epfdType = (EPFDType) epfd; + _raim = GetInt(bits, 148, 148) == 1; + _radio = GetUInt(bits, 149, 167); + } + catch (Exception e) + { + _log.WarnFormat("Error decoding AIS base station report: {0}", e.Message); + result = Status.PARSE_ERROR; + } + + return result; + } + #endregion + } +} diff --git a/AIS/bsmd.AIS2Service/AIS_Target.cs b/AIS/bsmd.AIS2Service/AIS_Target.cs new file mode 100644 index 00000000..99bb284b --- /dev/null +++ b/AIS/bsmd.AIS2Service/AIS_Target.cs @@ -0,0 +1,318 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace bsmd.AIS2Service +{ + public class AIS_Target + { + + #region private members + + public static TimeSpan dbUpdateInterval = new TimeSpan(0, 2, 0); // neue Position in DB schreiben (min Interval) + private int mmsi; + private bool isClassB = false; + private bool? isWatchkeeper = null; + private DateTime? lastUpdate; + private bool updateDB = false; + private string name; + private string station; + private string lastDBName; + private string callSign; + private bool selected = false; + + private AISClass staticInfo; + private AISClass posReport; + private AISClass lastAdditionalData; + + private AIS_Target.Type type = Type.OTHER; + private AIS_Target.NavStatus navStatus = AIS_Target.NavStatus.UNKNOWN; + + #endregion + + #region public defs + + public enum Type + { + PASSENGER, + CARGO, + TANKER, + HSC, + WIG, + TUG, + YACHT, + OTHER + } + + /// + /// vereinfacht + /// + public enum NavStatus + { + UNKNOWN, + UNDERWAY, + MOORED + } + + #endregion + + #region Construction + + public AIS_Target(int mmsi) + { + this.mmsi = mmsi; + } + + #endregion + + #region Properties + + public int MMSI + { + get { return this.mmsi; } + } + + public DateTime? LastUpdate + { + get { return this.lastUpdate; } + } + + public string Name + { + get { + if ((this.name == null) || (this.name.Length == 0)) + return this.LastDBName; + return this.name; + } + set { this.name = value; } + } + + public string Callsign + { + get { return this.callSign; } + set { this.callSign = value; } + } + + public string LastDBName + { + get { return this.lastDBName; } + set { this.lastDBName = value; } + } + + public string ReceivedFrom + { + get { return this.station; } + } + + internal AISClass LastPosReport + { + get { return this.posReport; } + } + + internal AISClass LastStaticData + { + get { return this.staticInfo; } + } + + public double? Latitude + { + get + { + if (this.LastPosReport == null) return null; + if (this.LastPosReport is AIS_PosReport) + return ((AIS_PosReport)this.LastPosReport).Latitude; + if (this.LastPosReport is AIS_ClassB) + return ((AIS_ClassB)this.LastPosReport).Latitude; + if (this.LastPosReport is AIS_ClassBExt) + return ((AIS_ClassBExt)this.LastPosReport).Latitude; + return null; + } + } + + public Type TargetType + { + get { return this.type; } + set { this.type = value; } + } + + public NavStatus TargetNavStatus + { + get { return this.navStatus; } + } + + public double? Longitude + { + get + { + if (this.LastPosReport == null) return null; + if (this.LastPosReport is AIS_PosReport) + return ((AIS_PosReport)this.LastPosReport).Longitude; + if (this.LastPosReport is AIS_ClassB) + return ((AIS_ClassB)this.LastPosReport).Longitude; + if (this.LastPosReport is AIS_ClassBExt) + return ((AIS_ClassBExt)this.LastPosReport).Longitude; + return null; + } + } + + public bool? IsClassB + { + get + { + return this.isClassB; + } + } + + public int? Heading + { + get + { + if (this.LastPosReport == null) return null; + if (this.LastPosReport is AIS_PosReport) + return ((AIS_PosReport)this.LastPosReport).TrueHeading; + if (this.LastPosReport is AIS_ClassB) + return ((AIS_ClassB)this.LastPosReport).TrueHeading; + if (this.LastPosReport is AIS_ClassBExt) + return ((AIS_ClassBExt)this.LastPosReport).TrueHeading; + return null; + } + } + + public int? COG + { + get + { + if (this.LastPosReport == null) return null; + if (this.LastPosReport is AIS_PosReport) + return (int)((AIS_PosReport)this.LastPosReport).COG; + if (this.LastPosReport is AIS_ClassB) + return (int)((AIS_ClassB)this.LastPosReport).Cog; + if (this.LastPosReport is AIS_ClassBExt) + return (int) ((AIS_ClassBExt)this.LastPosReport).Cog; + return null; + } + } + + public bool? IsWatchkeeperShip + { + get { return this.isWatchkeeper; } + set { this.isWatchkeeper = value; } + } + + public bool Selected + { + get { return this.selected; } + set { this.selected = value; } + } + + public string Station + { + get { return this.station; } + set { this.station = value; } + } + + #endregion + + #region public methods + + public static AIS_Target.NavStatus GetCurrentNavstatus(int status) + { + AIS_Target.NavStatus result = NavStatus.UNKNOWN; + switch (status) + { + case 0: + case 8: + result = NavStatus.UNDERWAY; + break; + default: + result = NavStatus.MOORED; + break; + } + return result; + } + + internal void Update(AISClass message) + { + + switch (message.MessageType) + { + case AISClass.AISType.POSITION_REPORT: + case AISClass.AISType.POSITION_REPORT_ASSIGNED: + case AISClass.AISType.POSITION_REPORT_SPECIAL: + if ((this.lastUpdate.HasValue && + (((AIS_PosReport)message).Timestamp - this.lastUpdate.Value) > AIS_Target.dbUpdateInterval) + || (!this.lastUpdate.HasValue)) + { + this.updateDB = true; + this.lastUpdate = ((AIS_PosReport)message).Timestamp; + } + this.posReport = message; + this.navStatus = AIS_Target.GetCurrentNavstatus(((AIS_PosReport)message).NavStatusVal); + // System.Diagnostics.Trace.WriteLine(string.Format("pos report at {0}", this.lastUpdate)); + break; + case AISClass.AISType.POSITION_REPORT_B_EQUIP: + if ((this.lastUpdate.HasValue && + (((AIS_ClassB)message).Timestamp - this.lastUpdate.Value) > AIS_Target.dbUpdateInterval) + || (!this.lastUpdate.HasValue)) + { + this.updateDB = true; + this.lastUpdate = ((AIS_ClassB)message).Timestamp; + this.isClassB = true; + this.type = Type.YACHT; + this.navStatus = NavStatus.UNDERWAY; + } + this.posReport = message; + break; + case AISClass.AISType.POSITION_REPORT_B_EQUIP_EXT: + if ((this.lastUpdate.HasValue && + (((AIS_ClassBExt)message).Timestamp - this.lastUpdate.Value) > AIS_Target.dbUpdateInterval) + || (!this.lastUpdate.HasValue)) + { + this.updateDB = true; + this.lastUpdate = ((AIS_ClassBExt)message).Timestamp; + this.isClassB = true; + this.type = Type.YACHT; + this.navStatus = NavStatus.UNDERWAY; + } + this.posReport = message; + break; + case AISClass.AISType.STATIC_VOYAGE_DATA: + this.staticInfo = message; + this.name = ((AIS_StaticData)message).Name; + this.callSign = ((AIS_StaticData)message).Callsign; + //this.type = AIS_StaticData.GetShipTypeSimple(((AIS_StaticData)message).ShipTypeVal); + + break; + case AISClass.AISType.CLASS_B_STATIC_DATA: + if (((AIS_ClassBStatic)message).IsPartA) + { + this.name = ((AIS_ClassBStatic)message).Name; + } + else + { + this.callSign = ((AIS_ClassBStatic)message).Callsign; + } + this.staticInfo = message; + this.type = Type.YACHT; + this.isClassB = true; + break; + default: + this.lastAdditionalData = message; + break; + } + + } + + #endregion + + #region overrides + + public override string ToString() + { + return string.Format("{0} [{1}]", this.Name, this.MMSI); + } + + #endregion + + } +} diff --git a/AIS/bsmd.AIS2Service/bsmd.AIS2Service.csproj b/AIS/bsmd.AIS2Service/bsmd.AIS2Service.csproj index 462f2444..59647bfb 100644 --- a/AIS/bsmd.AIS2Service/bsmd.AIS2Service.csproj +++ b/AIS/bsmd.AIS2Service/bsmd.AIS2Service.csproj @@ -12,6 +12,8 @@ 512 true true + + AnyCPU @@ -39,6 +41,9 @@ + + packages\Stub.System.Data.SQLite.Core.NetFramework.1.0.116.0\lib\net46\System.Data.SQLite.dll + @@ -58,11 +63,13 @@ + + @@ -91,4 +98,11 @@ + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + \ No newline at end of file diff --git a/AIS/bsmd.AIS2Service/packages.config b/AIS/bsmd.AIS2Service/packages.config index 4ec372e3..ee2c1118 100644 --- a/AIS/bsmd.AIS2Service/packages.config +++ b/AIS/bsmd.AIS2Service/packages.config @@ -1,4 +1,6 @@  + + \ No newline at end of file