From e931afd2ee2ec31d4ee06d30933d7d464b8823a7 Mon Sep 17 00:00:00 2001 From: Jeff Date: Sun, 17 Nov 2019 20:39:07 -0500 Subject: [PATCH 1/5] Add MessagePack definitions Update response behavior for unknown message types --- src/AisParser/AisMessage.cs | 6 +++++ src/AisParser/AisMessageFactory.cs | 3 ++- src/AisParser/AisParser.csproj | 7 +++++- .../Messages/AddressedSafetyRelatedMessage.cs | 10 +++++++- .../Messages/AidToNavigationReportMessage.cs | 22 ++++++++++++++++- .../Messages/BaseStationReportMessage.cs | 17 ++++++++++++- .../Messages/BinaryAcknowledgeMessage.cs | 13 +++++++++- .../Messages/BinaryAddressedMessage.cs | 11 ++++++++- .../Messages/BinaryBroadcastMessage.cs | 8 ++++++- .../Messages/DataLinkManagementMessage.cs | 21 +++++++++++++++- .../ExtendedClassBCsPositionReportMessage.cs | 24 ++++++++++++++++++- .../Messages/InterrogationMessage.cs | 12 +++++++++- .../PositionReportClassAMessageBase.cs | 15 ++++++++++++ ...onReportForLongRangeApplicationsMessage.cs | 13 +++++++++- .../SafetyRelatedAcknowledgementMessage.cs | 13 +++++++++- .../StandardClassBCsPositionReportMessage.cs | 21 +++++++++++++++- ...tandardSarAircraftPositionReportMessage.cs | 17 ++++++++++++- .../StaticAndVoyageRelatedDataMessage.cs | 22 ++++++++++++++++- .../Messages/StaticDataReportMessage.cs | 5 +++- .../Messages/StaticDataReportPartAMessage.cs | 6 ++++- .../Messages/StaticDataReportPartBMessage.cs | 15 +++++++++++- .../Messages/UtcAndDateInquiryMessage.cs | 7 +++++- .../Messages/UtcAndDateResponseMessage.cs | 17 ++++++++++++- 23 files changed, 284 insertions(+), 21 deletions(-) diff --git a/src/AisParser/AisMessage.cs b/src/AisParser/AisMessage.cs index 7f4f706..33e8250 100644 --- a/src/AisParser/AisMessage.cs +++ b/src/AisParser/AisMessage.cs @@ -1,9 +1,15 @@ +using MessagePack; + namespace AisParser { + [MessagePackObject] public abstract class AisMessage { + [Key(0)] public AisMessageType MessageType { get; } + [Key(1)] public uint Repeat { get; set; } + [Key(2)] public uint Mmsi { get; set; } protected AisMessage(AisMessageType messageType) diff --git a/src/AisParser/AisMessageFactory.cs b/src/AisParser/AisMessageFactory.cs index 3de6675..e531b3b 100644 --- a/src/AisParser/AisMessageFactory.cs +++ b/src/AisParser/AisMessageFactory.cs @@ -64,7 +64,8 @@ public AisMessage Create(Payload payload) //TODO: 51 //TODO: 57 default: - throw new AisMessageException($"Unrecognised message type: {payload.MessageType}"); + return null; + // throw new AisMessageException($"Unrecognised message type: {payload.MessageType}"); } } } diff --git a/src/AisParser/AisParser.csproj b/src/AisParser/AisParser.csproj index b24e083..8e9d417 100644 --- a/src/AisParser/AisParser.csproj +++ b/src/AisParser/AisParser.csproj @@ -5,7 +5,7 @@ Copyright Chris Richards 1.0.0 Chris Richards - netstandard2.0 + netcoreapp2.0 7.3 AisParser AisParser @@ -18,4 +18,9 @@ 1.0.0 + + + + + diff --git a/src/AisParser/Messages/AddressedSafetyRelatedMessage.cs b/src/AisParser/Messages/AddressedSafetyRelatedMessage.cs index ac5e474..25e101f 100644 --- a/src/AisParser/Messages/AddressedSafetyRelatedMessage.cs +++ b/src/AisParser/Messages/AddressedSafetyRelatedMessage.cs @@ -1,11 +1,19 @@ -namespace AisParser.Messages +using MessagePack; + +namespace AisParser.Messages { + [MessagePackObject] public class AddressedSafetyRelatedMessage : AisMessage { + [Key(3)] public uint SequenceNumber { get; set; } + [Key(4)] public uint DestinationMmsi { get; set; } + [Key(5)] public bool RetransmitFlag { get; set; } + [Key(6)] public uint Spare { get; set; } + [Key(7)] public string Text { get; set; } public AddressedSafetyRelatedMessage() diff --git a/src/AisParser/Messages/AidToNavigationReportMessage.cs b/src/AisParser/Messages/AidToNavigationReportMessage.cs index 274d406..08102af 100644 --- a/src/AisParser/Messages/AidToNavigationReportMessage.cs +++ b/src/AisParser/Messages/AidToNavigationReportMessage.cs @@ -1,24 +1,44 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class AidToNavigationReportMessage : AisMessage { + [Key(3)] public NavigationalAidType NavigationalAidType { get; set; } + [Key(4)] public string Name { get; set; } + [Key(5)] public PositionAccuracy PositionAccuracy { get; set; } + [Key(6)] public double Longitude { get; set; } + [Key(7)] public double Latitude { get; set; } + [Key(8)] public uint DimensionToBow { get; set; } + [Key(9)] public uint DimensionToStern { get; set; } + [Key(10)] public uint DimensionToPort { get; set; } + [Key(11)] public uint DimensionToStarboard { get; set; } + [Key(12)] public PositionFixType PositionFixType { get; set; } + [Key(13)] public uint Timestamp { get; set; } + [Key(14)] public bool OffPosition { get; set; } + [Key(15)] public uint RegionalReserved { get; set; } + [Key(16)] public Raim Raim { get; set; } + [Key(17)] public bool VirtualAid { get; set; } + [Key(18)] public bool Assigned { get; set; } + [Key(19)] public uint Spare { get; set; } + [Key(20)] public string NameExtension { get; set; } public AidToNavigationReportMessage() diff --git a/src/AisParser/Messages/BaseStationReportMessage.cs b/src/AisParser/Messages/BaseStationReportMessage.cs index a6855ff..5ee371d 100644 --- a/src/AisParser/Messages/BaseStationReportMessage.cs +++ b/src/AisParser/Messages/BaseStationReportMessage.cs @@ -1,19 +1,34 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class BaseStationReportMessage : AisMessage { + [Key(3)] public uint Year { get; set; } + [Key(4)] public uint Month { get; set; } + [Key(5)] public uint Day { get; set; } + [Key(6)] public uint Hour { get; set; } + [Key(7)] public uint Minute { get; set; } + [Key(8)] public uint Second { get; set; } + [Key(9)] public PositionAccuracy PositionAccuracy { get; set; } + [Key(10)] public double Longitude { get; set; } + [Key(11)] public double Latitude { get; set; } + [Key(12)] public PositionFixType PositionFixType { get; set; } + [Key(13)] public uint Spare { get; set; } + [Key(14)] public Raim Raim { get; set; } + [Key(15)] public uint RadioStatus { get; set; } public BaseStationReportMessage() diff --git a/src/AisParser/Messages/BinaryAcknowledgeMessage.cs b/src/AisParser/Messages/BinaryAcknowledgeMessage.cs index 4e5224a..93e95c4 100644 --- a/src/AisParser/Messages/BinaryAcknowledgeMessage.cs +++ b/src/AisParser/Messages/BinaryAcknowledgeMessage.cs @@ -1,15 +1,26 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class BinaryAcknowledgeMessage : AisMessage { + [Key(3)] public uint Spare { get; set; } + [Key(4)] public uint SequenceNumber1 { get; set; } + [Key(5)] public uint Mmsi1 { get; set; } + [Key(6)] public uint SequenceNumber2 { get; set; } + [Key(7)] public uint? Mmsi2 { get; set; } + [Key(8)] public uint SequenceNumber3 { get; set; } + [Key(9)] public uint? Mmsi3 { get; set; } + [Key(10)] public uint SequenceNumber4 { get; set; } + [Key(11)] public uint? Mmsi4 { get; set; } public BinaryAcknowledgeMessage() diff --git a/src/AisParser/Messages/BinaryAddressedMessage.cs b/src/AisParser/Messages/BinaryAddressedMessage.cs index 026d722..fde50a2 100644 --- a/src/AisParser/Messages/BinaryAddressedMessage.cs +++ b/src/AisParser/Messages/BinaryAddressedMessage.cs @@ -1,13 +1,22 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class BinaryAddressedMessage : AisMessage { + [Key(3)] public uint SequenceNumber { get; set; } + [Key(4)] public uint DestinationMmsi { get; set; } + [Key(5)] public bool RetransmitFlag { get; set; } + [Key(6)] public uint Spare { get; set; } + [Key(7)] public uint DesignatedAreaCode { get; set; } + [Key(8)] public uint FunctionalId { get; set; } + [Key(9)] public string Data { get; set; } public BinaryAddressedMessage() diff --git a/src/AisParser/Messages/BinaryBroadcastMessage.cs b/src/AisParser/Messages/BinaryBroadcastMessage.cs index 9ad4fab..e7aaf75 100644 --- a/src/AisParser/Messages/BinaryBroadcastMessage.cs +++ b/src/AisParser/Messages/BinaryBroadcastMessage.cs @@ -1,10 +1,16 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class BinaryBroadcastMessage : AisMessage { + [Key(3)] public uint Spare { get; set; } + [Key(4)] public uint DesignatedAreaCode { get; set; } + [Key(5)] public uint FunctionalId { get; set; } + [Key(6)] public string Data { get; set; } public BinaryBroadcastMessage() diff --git a/src/AisParser/Messages/DataLinkManagementMessage.cs b/src/AisParser/Messages/DataLinkManagementMessage.cs index bff7a37..42ed233 100644 --- a/src/AisParser/Messages/DataLinkManagementMessage.cs +++ b/src/AisParser/Messages/DataLinkManagementMessage.cs @@ -1,23 +1,42 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class DataLinkManagementMessage : AisMessage { + [Key(3)] public uint Spare { get; set; } + [Key(4)] public uint Offset1 { get; set; } + [Key(5)] public uint ReservedSlots1 { get; set; } + [Key(6)] public uint Timeout1 { get; set; } + [Key(7)] public uint Increment1 { get; set; } + [Key(8)] public uint Offset2 { get; set; } + [Key(9)] public uint ReservedSlots2 { get; set; } + [Key(10)] public uint Timeout2 { get; set; } + [Key(11)] public uint Increment2 { get; set; } + [Key(12)] public uint Offset3 { get; set; } + [Key(13)] public uint ReservedSlots3 { get; set; } + [Key(14)] public uint Timeout3 { get; set; } + [Key(15)] public uint Increment3 { get; set; } + [Key(16)] public uint Offset4 { get; set; } + [Key(17)] public uint ReservedSlots4 { get; set; } + [Key(18)] public uint Timeout4 { get; set; } + [Key(19)] public uint Increment4 { get; set; } public DataLinkManagementMessage() diff --git a/src/AisParser/Messages/ExtendedClassBCsPositionReportMessage.cs b/src/AisParser/Messages/ExtendedClassBCsPositionReportMessage.cs index e34432e..6047a50 100644 --- a/src/AisParser/Messages/ExtendedClassBCsPositionReportMessage.cs +++ b/src/AisParser/Messages/ExtendedClassBCsPositionReportMessage.cs @@ -1,26 +1,48 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class ExtendedClassBCsPositionReportMessage : AisMessage { + [Key(3)] public uint Reserved { get; set; } + [Key(4)] public double SpeedOverGround { get; set; } + [Key(5)] public PositionAccuracy PositionAccuracy { get; set; } + [Key(6)] public double Longitude { get; set; } + [Key(7)] public double Latitude { get; set; } + [Key(8)] public double CourseOverGround { get; set; } + [Key(9)] public uint? TrueHeading { get; set; } + [Key(10)] public uint Timestamp { get; set; } + [Key(11)] public uint RegionalReserved { get; set; } + [Key(12)] public string Name { get; set; } + [Key(13)] public ShipType ShipType { get; set; } + [Key(14)] public uint DimensionToBow { get; set; } + [Key(15)] public uint DimensionToStern { get; set; } + [Key(16)] public uint DimensionToPort { get; set; } + [Key(17)] public uint DimensionToStarboard { get; set; } + [Key(18)] public PositionFixType PositionFixType { get; set; } + [Key(19)] public Raim Raim { get; set; } + [Key(20)] public bool DataTerminalReady { get; set; } + [Key(21)] public bool Assigned { get; set; } + [Key(22)] public uint Spare { get; set; } public ExtendedClassBCsPositionReportMessage() diff --git a/src/AisParser/Messages/InterrogationMessage.cs b/src/AisParser/Messages/InterrogationMessage.cs index 3790864..2ec37f7 100644 --- a/src/AisParser/Messages/InterrogationMessage.cs +++ b/src/AisParser/Messages/InterrogationMessage.cs @@ -1,16 +1,26 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class InterrogationMessage: AisMessage { + [Key(3)] public uint InterrogatedMmsi { get; set; } + [Key(4)] public AisMessageType FirstMessageType { get; set; } + [Key(5)] public uint FirstSlotOffset { get; set; } + [Key(6)] public AisMessageType? SecondMessageType { get; set; } + [Key(7)] public uint? SecondSlotOffset { get; set; } + [Key(8)] public uint? SecondStationInterrogationMmsi { get; set; } + [Key(9)] public AisMessageType? SecondStationFirstMessageType { get; set; } + [Key(10)] public uint? SecondStationFirstSlotOffset { get; set; } diff --git a/src/AisParser/Messages/PositionReportClassAMessageBase.cs b/src/AisParser/Messages/PositionReportClassAMessageBase.cs index c1771a7..0463954 100644 --- a/src/AisParser/Messages/PositionReportClassAMessageBase.cs +++ b/src/AisParser/Messages/PositionReportClassAMessageBase.cs @@ -1,19 +1,34 @@ +using MessagePack; namespace AisParser.Messages { + [MessagePackObject] public abstract class PositionReportClassAMessageBase : AisMessage { + [Key(3)] public NavigationStatus NavigationStatus { get; set; } + [Key(4)] public int? RateOfTurn { get; set; } + [Key(5)] public double SpeedOverGround { get; set; } + [Key(6)] public PositionAccuracy PositionAccuracy { get; set; } + [Key(7)] public double Longitude { get; set; } + [Key(8)] public double Latitude { get; set; } + [Key(9)] public double CourseOverGround { get; set; } + [Key(10)] public uint? TrueHeading { get; set; } + [Key(11)] public uint Timestamp { get; set; } + [Key(12)] public ManeuverIndicator ManeuverIndicator { get; set; } + [Key(13)] public uint Spare { get; set; } + [Key(14)] public Raim Raim { get; set; } + [Key(15)] public uint RadioStatus { get; set; } protected PositionReportClassAMessageBase(AisMessageType messageType) diff --git a/src/AisParser/Messages/PositionReportForLongRangeApplicationsMessage.cs b/src/AisParser/Messages/PositionReportForLongRangeApplicationsMessage.cs index 266c60c..3fbf9f5 100644 --- a/src/AisParser/Messages/PositionReportForLongRangeApplicationsMessage.cs +++ b/src/AisParser/Messages/PositionReportForLongRangeApplicationsMessage.cs @@ -1,15 +1,26 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class PositionReportForLongRangeApplicationsMessage : AisMessage { + [Key(3)] public PositionAccuracy PositionAccuracy { get; set; } + [Key(4)] public Raim Raim { get; set; } + [Key(5)] public NavigationStatus NavigationStatus { get; set; } + [Key(6)] public double Longitude { get; set; } + [Key(7)] public double Latitude { get; set; } + [Key(8)] public double SpeedOverGround { get; set; } + [Key(9)] public double CourseOverGround { get; set; } + [Key(10)] public GnssPositionStatus GnssPositionStatus { get; set; } + [Key(11)] public uint Spare { get; set; } public PositionReportForLongRangeApplicationsMessage() diff --git a/src/AisParser/Messages/SafetyRelatedAcknowledgementMessage.cs b/src/AisParser/Messages/SafetyRelatedAcknowledgementMessage.cs index c6f7277..8062d89 100644 --- a/src/AisParser/Messages/SafetyRelatedAcknowledgementMessage.cs +++ b/src/AisParser/Messages/SafetyRelatedAcknowledgementMessage.cs @@ -1,15 +1,26 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class SafetyRelatedAcknowledgementMessage : AisMessage { + [Key(3)] public uint Spare { get; set; } + [Key(4)] public uint SequenceNumber1 { get; set; } + [Key(5)] public uint Mmsi1 { get; set; } + [Key(6)] public uint SequenceNumber2 { get; set; } + [Key(7)] public uint? Mmsi2 { get; set; } + [Key(8)] public uint SequenceNumber3 { get; set; } + [Key(9)] public uint? Mmsi3 { get; set; } + [Key(10)] public uint SequenceNumber4 { get; set; } + [Key(11)] public uint? Mmsi4 { get; set; } public SafetyRelatedAcknowledgementMessage() diff --git a/src/AisParser/Messages/StandardClassBCsPositionReportMessage.cs b/src/AisParser/Messages/StandardClassBCsPositionReportMessage.cs index 0267ae4..aa0bb77 100644 --- a/src/AisParser/Messages/StandardClassBCsPositionReportMessage.cs +++ b/src/AisParser/Messages/StandardClassBCsPositionReportMessage.cs @@ -1,23 +1,42 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class StandardClassBCsPositionReportMessage : AisMessage { + [Key(3)] public uint Reserved { get; set; } + [Key(4)] public double SpeedOverGround { get; set; } + [Key(5)] public PositionAccuracy PositionAccuracy { get; set; } + [Key(6)] public double Longitude { get; set; } + [Key(7)] public double Latitude { get; set; } + [Key(8)] public double CourseOverGround { get; set; } + [Key(9)] public uint? TrueHeading { get; set; } + [Key(10)] public uint Timestamp { get; set; } + [Key(11)] public uint RegionalReserved { get; set; } + [Key(12)] public bool IsCsUnit { get; set; } + [Key(13)] public bool HasDisplay { get; set; } + [Key(14)] public bool HasDscCapability { get; set; } + [Key(15)] public bool Band { get; set; } + [Key(16)] public bool CanAcceptMessage22 { get; set; } + [Key(17)] public bool Assigned { get; set; } + [Key(18)] public Raim Raim { get; set; } + [Key(19)] public uint RadioStatus { get; set; } public StandardClassBCsPositionReportMessage() diff --git a/src/AisParser/Messages/StandardSarAircraftPositionReportMessage.cs b/src/AisParser/Messages/StandardSarAircraftPositionReportMessage.cs index 5d04916..e611a22 100644 --- a/src/AisParser/Messages/StandardSarAircraftPositionReportMessage.cs +++ b/src/AisParser/Messages/StandardSarAircraftPositionReportMessage.cs @@ -1,19 +1,34 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class StandardSarAircraftPositionReportMessage : AisMessage { + [Key(3)] public uint Altitude { get; set; } + [Key(4)] public uint SpeedOverGround { get; set; } + [Key(5)] public PositionAccuracy PositionAccuracy { get; set; } + [Key(6)] public double Longitude { get; set; } + [Key(7)] public double Latitude { get; set; } + [Key(8)] public double CourseOverGround { get; set; } + [Key(9)] public uint Timestamp { get; set; } + [Key(10)] public uint Reserved { get; set; } + [Key(11)] public bool DataTerminalReady { get; set; } + [Key(12)] public uint Spare { get; set; } + [Key(13)] public bool Assigned { get; set; } + [Key(14)] public Raim Raim { get; set; } + [Key(15)] public uint RadioStatus { get; set; } public StandardSarAircraftPositionReportMessage() diff --git a/src/AisParser/Messages/StaticAndVoyageRelatedDataMessage.cs b/src/AisParser/Messages/StaticAndVoyageRelatedDataMessage.cs index 1da3703..b02937b 100644 --- a/src/AisParser/Messages/StaticAndVoyageRelatedDataMessage.cs +++ b/src/AisParser/Messages/StaticAndVoyageRelatedDataMessage.cs @@ -1,24 +1,44 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class StaticAndVoyageRelatedDataMessage : AisMessage { + [Key(3)] public uint AisVersion { get; set; } + [Key(4)] public uint ImoNumber { get; set; } + [Key(5)] public string CallSign { get; set; } + [Key(6)] public string ShipName { get; set; } + [Key(7)] public ShipType ShipType { get; set; } + [Key(8)] public uint DimensionToBow { get; set; } + [Key(9)] public uint DimensionToStern { get; set; } + [Key(10)] public uint DimensionToPort { get; set; } + [Key(11)] public uint DimensionToStarboard { get; set; } + [Key(12)] public PositionFixType PositionFixType { get; set; } + [Key(13)] public uint EtaMonth { get; set; } + [Key(14)] public uint EtaDay { get; set; } + [Key(15)] public uint EtaHour { get; set; } + [Key(16)] public uint EtaMinute { get; set; } + [Key(17)] public double Draught { get; set; } + [Key(18)] public string Destination { get; set; } + [Key(19)] public bool DataTerminalReady { get; set; } + [Key(20)] public uint Spare { get; set; } public StaticAndVoyageRelatedDataMessage() diff --git a/src/AisParser/Messages/StaticDataReportMessage.cs b/src/AisParser/Messages/StaticDataReportMessage.cs index 3e677cd..af13304 100644 --- a/src/AisParser/Messages/StaticDataReportMessage.cs +++ b/src/AisParser/Messages/StaticDataReportMessage.cs @@ -1,7 +1,10 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class StaticDataReportMessage : AisMessage { + [Key(3)] public uint PartNumber { get; } protected StaticDataReportMessage() diff --git a/src/AisParser/Messages/StaticDataReportPartAMessage.cs b/src/AisParser/Messages/StaticDataReportPartAMessage.cs index b42fdfc..d399481 100644 --- a/src/AisParser/Messages/StaticDataReportPartAMessage.cs +++ b/src/AisParser/Messages/StaticDataReportPartAMessage.cs @@ -1,8 +1,12 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class StaticDataReportPartAMessage : StaticDataReportMessage { + [Key(4)] public string ShipName { get; set; } + [Key(5)] public uint Spare { get; set; } public StaticDataReportPartAMessage() diff --git a/src/AisParser/Messages/StaticDataReportPartBMessage.cs b/src/AisParser/Messages/StaticDataReportPartBMessage.cs index fbe4634..64db088 100644 --- a/src/AisParser/Messages/StaticDataReportPartBMessage.cs +++ b/src/AisParser/Messages/StaticDataReportPartBMessage.cs @@ -1,17 +1,30 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class StaticDataReportPartBMessage : StaticDataReportMessage { + [Key(4)] public ShipType ShipType { get; set; } + [Key(5)] public string VendorId { get; set; } + [Key(6)] public uint UnitModelCode { get; set; } + [Key(7)] public uint SerialNumber { get; set; } + [Key(8)] public string CallSign { get; set; } + [Key(9)] public uint DimensionToBow { get; set; } + [Key(10)] public uint DimensionToStern { get; set; } + [Key(11)] public uint DimensionToPort { get; set; } + [Key(12)] public uint DimensionToStarboard { get; set; } + [Key(13)] public uint MothershipMmsi { get; set; } + [Key(14)] public uint Spare { get; set; } public StaticDataReportPartBMessage() diff --git a/src/AisParser/Messages/UtcAndDateInquiryMessage.cs b/src/AisParser/Messages/UtcAndDateInquiryMessage.cs index 4557909..6c4df64 100644 --- a/src/AisParser/Messages/UtcAndDateInquiryMessage.cs +++ b/src/AisParser/Messages/UtcAndDateInquiryMessage.cs @@ -1,9 +1,14 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class UtcAndDateInquiryMessage : AisMessage { + [Key(3)] public uint Spare1 { get; set; } + [Key(4)] public uint DestinationMmsi { get; set; } + [Key(5)] public uint Spare2 { get; set; } public UtcAndDateInquiryMessage() diff --git a/src/AisParser/Messages/UtcAndDateResponseMessage.cs b/src/AisParser/Messages/UtcAndDateResponseMessage.cs index f83e625..682b9dd 100644 --- a/src/AisParser/Messages/UtcAndDateResponseMessage.cs +++ b/src/AisParser/Messages/UtcAndDateResponseMessage.cs @@ -1,19 +1,34 @@ -namespace AisParser.Messages +using MessagePack; +namespace AisParser.Messages { + [MessagePackObject] public class UtcAndDateResponseMessage : AisMessage { + [Key(3)] public uint Year { get; set; } + [Key(4)] public uint Month { get; set; } + [Key(5)] public uint Day { get; set; } + [Key(6)] public uint Hour { get; set; } + [Key(7)] public uint Minute { get; set; } + [Key(8)] public uint Second { get; set; } + [Key(9)] public PositionAccuracy PositionAccuracy { get; set; } + [Key(10)] public double Longitude { get; set; } + [Key(11)] public double Latitude { get; set; } + [Key(12)] public PositionFixType PositionFixType { get; set; } + [Key(13)] public uint Spare { get; set; } + [Key(14)] public Raim Raim { get; set; } + [Key(15)] public uint RadioStatus { get; set; } public UtcAndDateResponseMessage() From 6f0115b93b0816866fb57e338f8e9a6cdc940549 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 8 Jan 2020 12:55:08 -0500 Subject: [PATCH 2/5] Convert to .net framework --- src/AisParser/AisParser.csproj | 2 +- test/AisParserTests/AisParserTests.csproj | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/AisParser/AisParser.csproj b/src/AisParser/AisParser.csproj index 8e9d417..a6f9b04 100644 --- a/src/AisParser/AisParser.csproj +++ b/src/AisParser/AisParser.csproj @@ -5,7 +5,7 @@ Copyright Chris Richards 1.0.0 Chris Richards - netcoreapp2.0 + net4.6.1 7.3 AisParser AisParser diff --git a/test/AisParserTests/AisParserTests.csproj b/test/AisParserTests/AisParserTests.csproj index 9299cb7..4801ad3 100644 --- a/test/AisParserTests/AisParserTests.csproj +++ b/test/AisParserTests/AisParserTests.csproj @@ -1,9 +1,15 @@  - netcoreapp2.1 + net4.6.1 false + + + + Library + + From 42d6a4ea88ab6511d04b8d3c430ab04018724554 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 8 Jan 2020 19:48:53 -0500 Subject: [PATCH 3/5] First run of message encoding, and only Position Report Class A is supported --- src/AisParser/AisMessage.cs | 5 ++ src/AisParser/AisMessageFactory.cs | 15 ++++ .../PositionReportClassAMessageBase.cs | 19 +++++ src/AisParser/Parser.cs | 59 +++++++++++++-- src/AisParser/Payload.cs | 72 +++++++++++++++++-- src/AisParser/PayloadDecoder.cs | 1 + src/AisParser/PayloadEncoder.cs | 44 ++++++++++++ 7 files changed, 206 insertions(+), 9 deletions(-) create mode 100644 src/AisParser/PayloadEncoder.cs diff --git a/src/AisParser/AisMessage.cs b/src/AisParser/AisMessage.cs index 33e8250..c109870 100644 --- a/src/AisParser/AisMessage.cs +++ b/src/AisParser/AisMessage.cs @@ -23,5 +23,10 @@ protected AisMessage(AisMessageType messageType, Payload payload) Repeat = payload.ReadUInt(6, 2); Mmsi = payload.ReadUInt(8, 30); } + public virtual void Encode(Payload payload) + { + payload.WriteUInt(Repeat, 2); + payload.WriteUInt(Mmsi, 30); + } } } \ No newline at end of file diff --git a/src/AisParser/AisMessageFactory.cs b/src/AisParser/AisMessageFactory.cs index e531b3b..c3a4b44 100644 --- a/src/AisParser/AisMessageFactory.cs +++ b/src/AisParser/AisMessageFactory.cs @@ -1,9 +1,24 @@ using AisParser.Messages; +using System; namespace AisParser { public class AisMessageFactory { + public Payload Encode(T message) where T : AisMessage + { + Payload payload = new Payload(); + switch (message) + { + case PositionReportClassAMessage t1: + t1.Encode(payload); + break; + default: + return null; + } + return payload; + } + public AisMessage Create(Payload payload) { switch (payload.MessageType) diff --git a/src/AisParser/Messages/PositionReportClassAMessageBase.cs b/src/AisParser/Messages/PositionReportClassAMessageBase.cs index 0463954..639ec18 100644 --- a/src/AisParser/Messages/PositionReportClassAMessageBase.cs +++ b/src/AisParser/Messages/PositionReportClassAMessageBase.cs @@ -55,5 +55,24 @@ protected PositionReportClassAMessageBase(AisMessageType messageType, Payload pa Raim = payload.ReadEnum(148, 1); RadioStatus = payload.ReadUInt(149, 19); } + + public override void Encode(Payload payload) + { + payload.WriteEnum(AisMessageType.PositionReportClassA, 6); + base.Encode(payload); + payload.WriteEnum(NavigationStatus, 4); + payload.WriteRateOfTurn((int)RateOfTurn, 8); + payload.WriteSpeedOverGround(SpeedOverGround, 10); + payload.WriteEnum(PositionAccuracy, 1); + payload.WriteLongitude(Longitude, 28); + payload.WriteLatitude(Latitude, 27); + payload.WriteCourseOverGround(CourseOverGround, 12); + payload.WriteTrueHeading((uint)TrueHeading, 9); + payload.WriteUInt(Timestamp, 6); + payload.WriteEnum(ManeuverIndicator, 2); + payload.WriteUInt(Spare, 3); + payload.WriteEnum(Raim, 1); + payload.WriteUInt(RadioStatus, 19); + } } } \ No newline at end of file diff --git a/src/AisParser/Parser.cs b/src/AisParser/Parser.cs index 056b352..69572ad 100644 --- a/src/AisParser/Parser.cs +++ b/src/AisParser/Parser.cs @@ -9,18 +9,20 @@ public class Parser { private readonly PayloadDecoder _payloadDecoder; private readonly AisMessageFactory _messageFactory; + private readonly PayloadEncoder _payloadEncoder; private readonly IDictionary _fragments = new ConcurrentDictionary(); public Parser() - : this(new PayloadDecoder(), new AisMessageFactory()) + : this(new PayloadDecoder(), new AisMessageFactory(), new PayloadEncoder()) { } - public Parser(PayloadDecoder payloadDecoder, AisMessageFactory messageFactory) + public Parser(PayloadDecoder payloadDecoder, AisMessageFactory messageFactory, PayloadEncoder payloadEncoder) { _payloadDecoder = payloadDecoder; _messageFactory = messageFactory; + _payloadEncoder = payloadEncoder; } public AisMessage Parse(string sentence) @@ -58,13 +60,62 @@ public AisMessage Parse(string sentence) return payload == null ? null : _messageFactory.Create(payload); } + public string Parse(T aisMessage) where T : AisMessage + { + string sentence = ""; + + // Example: !AIVDM,1,1,,A,B6CdCm0t3`tba35f@V9faHi7kP06,0*58 + //Field 1: Sentence Type + //Field 2: Count Of Fragments + //Field 3: Fragment Number + //Field 4: Sequential Messages ID for multi-sentence messages (blank for none) + //Field 5: Radio Channel Code (A or B) + //Field 6: Payload + //Field 7: 6 bit Boundary Padding (Zero seems to always be OK)? + + + string sentenceType = "AIVDM"; + int countOfFragments = 1; + int fragmentNumber = 1; + int sequentialMessageId = 0; + string radioChannel = "A"; + int boundaryPadding = 0; + + var payload = _messageFactory.Encode(aisMessage); + var payloadEncoded = _payloadEncoder.EncodeSixBitAis(payload); + + //Build the full sentence + sentence += "!"; + sentence += sentenceType; + sentence += ","; + sentence += countOfFragments.ToString("0"); + sentence += ","; + sentence += fragmentNumber.ToString("0"); + sentence += ","; + if(sequentialMessageId != 0) sentence += sequentialMessageId.ToString("0"); + sentence += ","; + sentence += radioChannel; + sentence += ","; + sentence += payloadEncoded; + sentence += ","; + sentence += boundaryPadding.ToString("0"); + + var calculatedChecksum = CalculateChecksum(sentence); + sentence += "*" + calculatedChecksum.ToString("00"); + + return sentence; + } + private Payload DecodePayload(string encodedPayload, string[] sentenceParts) { var numFragments = Convert.ToInt32(sentenceParts[1]); var numFillBits = Convert.ToInt32(sentenceParts[6]); - if (numFragments == 1) - return _payloadDecoder.Decode(encodedPayload, numFillBits); + if (numFragments == 1) + { + var decoded = _payloadDecoder.Decode(encodedPayload, numFillBits); + return decoded; + } var fragmentNumber = Convert.ToInt32(sentenceParts[2]); var messageId = Convert.ToInt32(sentenceParts[3]); diff --git a/src/AisParser/Payload.cs b/src/AisParser/Payload.cs index f7087df..5f56e2f 100644 --- a/src/AisParser/Payload.cs +++ b/src/AisParser/Payload.cs @@ -15,9 +15,9 @@ public Payload(string rawValue) MessageType = ReadEnum(0, 6); } - public string RawValue { get; } + public string RawValue; // { get; } - public AisMessageType MessageType { get; } + public AisMessageType MessageType; // { get; } public T ReadEnum(int startIndex, int length) where T : Enum { @@ -26,6 +26,11 @@ public T ReadEnum(int startIndex, int length) where T : Enum return (T) Enum.ToObject(typeof(T), value); } + public void WriteEnum(T var, int length) where T : Enum + { + WriteUInt(Convert.ToUInt32(var), length); + } + public AisMessageType? ReadNullableMessageType(int startIndex, int length) { var bitValue = Substring(startIndex, length); @@ -40,6 +45,10 @@ public uint ReadUInt(int startIndex, int length) var bitValue = Substring(startIndex, length); return Convert.ToUInt32(bitValue, 2); } + public void WriteUInt(uint var, int length) + { + RawValue += Convert.ToString(var, 2).PadLeft(length, '0'); + } public uint? ReadNullableUInt(int startIndex, int length) { @@ -61,7 +70,11 @@ public uint ReadUInt(int startIndex, int length) return null; return value; } - + public void WriteMmsi(uint var, int length) + { + WriteUInt(var,length); + } + public int ReadInt(int startIndex, int length) { var bitValue = Substring(startIndex, length); @@ -71,12 +84,20 @@ public int ReadInt(int startIndex, int length) return result; } + public void WriteInt(int var, int length) + { + RawValue += Convert.ToString(var, 2).PadLeft(length, '0'); + } public double ReadUnsignedDouble(int startIndex, int length) { var bitValue = Substring(startIndex, length); return Convert.ToUInt32(bitValue, 2); } + public void WriteUnsignedDouble(double var, int length) + { + RawValue += Convert.ToString((UInt32)var, 2).PadLeft(length, '0'); + } public double ReadDouble(int startIndex, int length) { @@ -88,38 +109,67 @@ public double ReadDouble(int startIndex, int length) return result; } + public void WriteDouble(double var, int length) + { + if (var < 0) + var = var + Math.Pow(2, length); + + RawValue += Convert.ToString((UInt32)var, 2).PadLeft(length, '0'); + } public int? ReadRateOfTurn(int startIndex, int length) { var rateOfTurn = ReadInt(startIndex, length); return rateOfTurn == -256 ? null : new int?(rateOfTurn); } + public void WriteRateOfTurn(int var, int length) + { + WriteInt(var, length); + } public uint? ReadTrueHeading(int startIndex, int length) { var trueHeading = ReadUInt(startIndex, length); return trueHeading == 511 ? null : new uint?(trueHeading); } - + public void WriteTrueHeading(uint var, int length) + { + WriteUInt(var, length); + } public double ReadLongitude(int startIndex, int length) { return ReadDouble(startIndex, length) / 600000; } + public void WriteLongitude(double var, int length) + { + WriteDouble(var * 600000, length); + } public double ReadLatitude(int startIndex, int length) { return ReadDouble(startIndex, length) / 600000; } + public void WriteLatitude(double var, int length) + { + WriteDouble(var * 600000, length); + } public double ReadSpeedOverGround(int startIndex, int length) { return ReadUnsignedDouble(startIndex, length) / 10; } - + public void WriteSpeedOverGround(double var, int length) + { + WriteUnsignedDouble(var * 10, length); + } public double ReadCourseOverGround(int startIndex, int length) { return ReadUnsignedDouble(startIndex, length) / 10; } + public void WriteCourseOverGround(double var, int length) + { + WriteUnsignedDouble(var * 10, length); + } public string ReadString(int startIndex, int length) { @@ -139,11 +189,19 @@ public string ReadString(int startIndex, int length) return value.Trim(); } + /*public void WriteString(string var, int length) + { + RawValue += Convert.ToString(var, 2).PadLeft(length, '0'); + }*/ public double ReadDraught(int startIndex, int length) { return ReadUnsignedDouble(startIndex, length) / 10; } + public void WriteDraught(double var, int length) + { + WriteUnsignedDouble(var * 10, length); + } public bool ReadDataTerminalReady(int startIndex, int length) { @@ -156,6 +214,10 @@ public bool ReadBoolean(int startIndex, int length) var bitValue = Substring(startIndex, length); return Convert.ToInt32(bitValue) == 1; } + public void WriteBoolean(bool var, int length) + { + RawValue += var.ToString(); + } private string Substring(int startIndex, int length) { diff --git a/src/AisParser/PayloadDecoder.cs b/src/AisParser/PayloadDecoder.cs index e686c13..118e3c9 100644 --- a/src/AisParser/PayloadDecoder.cs +++ b/src/AisParser/PayloadDecoder.cs @@ -33,5 +33,6 @@ public Payload Decode(string encodedPayload, int numFillBits) return new Payload(payload.ToString()); } + } } diff --git a/src/AisParser/PayloadEncoder.cs b/src/AisParser/PayloadEncoder.cs new file mode 100644 index 0000000..96ed7c1 --- /dev/null +++ b/src/AisParser/PayloadEncoder.cs @@ -0,0 +1,44 @@ +using System; +using System.Text; + +namespace AisParser +{ + public class PayloadEncoder + { + public string EncodeSixBitAis(Payload payload) + { + //Consume each 6 bits and making them 8 bits, with some value shifts + var value = payload.RawValue; + if (String.IsNullOrEmpty(value)) + return value; + + string ret = ""; + + for (int i = 0; i < value.Length / 6; ++i) + { + var b = value.Substring(6 * i, 6).PadLeft(8, '0'); + var c = (byte)ConvertBitsToChar(b); + + if (c < 40) + c += 48; + else + c += 56; + + ret += Convert.ToChar(c); + } + + return ret; + } + + private static Char ConvertBitsToChar(String value) + { + int result = 0; + + foreach (Char ch in value) + result = result * 2 + ch - '0'; + + return (Char)result; + } + + } +} From b88035a2fb95bdb7e97e90662d6e9e89d2561cc0 Mon Sep 17 00:00:00 2001 From: Jeff Date: Thu, 9 Jan 2020 11:25:47 -0500 Subject: [PATCH 4/5] Update checksum encoder for 16 bit value --- src/AisParser/Parser.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/AisParser/Parser.cs b/src/AisParser/Parser.cs index 69572ad..6dd4fc0 100644 --- a/src/AisParser/Parser.cs +++ b/src/AisParser/Parser.cs @@ -72,8 +72,7 @@ public string Parse(T aisMessage) where T : AisMessage //Field 5: Radio Channel Code (A or B) //Field 6: Payload //Field 7: 6 bit Boundary Padding (Zero seems to always be OK)? - - + string sentenceType = "AIVDM"; int countOfFragments = 1; int fragmentNumber = 1; @@ -100,8 +99,8 @@ public string Parse(T aisMessage) where T : AisMessage sentence += ","; sentence += boundaryPadding.ToString("0"); - var calculatedChecksum = CalculateChecksum(sentence); - sentence += "*" + calculatedChecksum.ToString("00"); + var calculatedChecksum = GenerateChecksum(sentence); + sentence += "*" + calculatedChecksum; return sentence; } @@ -138,6 +137,11 @@ private Payload DecodePayload(string encodedPayload, string[] sentenceParts) return _payloadDecoder.Decode(encodedPayload, numFillBits); } + public string GenerateChecksum(string sentence) + { + var checksum = CalculateChecksum(sentence); + return Convert.ToString(checksum, 16).ToUpper(); + } public int ExtractChecksum(string sentence, int checksumIndex) { var checksum = sentence.Substring(checksumIndex + 1); From 12e886a8310706ba37f802211048cba5c58905b3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Jan 2020 22:13:18 -0500 Subject: [PATCH 5/5] Revert "Convert to .net framework" This reverts commit 6f0115b93b0816866fb57e338f8e9a6cdc940549. --- src/AisParser/AisParser.csproj | 2 +- test/AisParserTests/AisParserTests.csproj | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/AisParser/AisParser.csproj b/src/AisParser/AisParser.csproj index a6f9b04..8e9d417 100644 --- a/src/AisParser/AisParser.csproj +++ b/src/AisParser/AisParser.csproj @@ -5,7 +5,7 @@ Copyright Chris Richards 1.0.0 Chris Richards - net4.6.1 + netcoreapp2.0 7.3 AisParser AisParser diff --git a/test/AisParserTests/AisParserTests.csproj b/test/AisParserTests/AisParserTests.csproj index 4801ad3..9299cb7 100644 --- a/test/AisParserTests/AisParserTests.csproj +++ b/test/AisParserTests/AisParserTests.csproj @@ -1,15 +1,9 @@  - net4.6.1 + netcoreapp2.1 false - - - - Library - -