Beispiel #1
0
        /// <summary>
        /// </summary>
        /// <param name="sixState"></param>
        /// <exception cref="SixbitsExhaustedException"></exception>
        /// <exception cref="AisMessageException"></exception>
        public override void Parse(Sixbit sixState)
        {
            if (sixState.BitLength != 168)
            {
                throw new AisMessageException($"Message {MsgId} wrong length");
            }

            base.Parse(sixState);

            /* Parse the Message 1 */
            NavStatus = (int)sixState.Get(4);
            Rot       = (int)sixState.Get(8);
            Sog       = (int)sixState.Get(10);
            PosAcc    = (int)sixState.Get(1);

            Pos = new Position {
                Longitude = sixState.Get(28),
                Latitude  = sixState.Get(27)
            };

            Cog         = (int)sixState.Get(12);
            TrueHeading = (int)sixState.Get(9);
            UtcSec      = (int)sixState.Get(6);
            Regional    = (int)sixState.Get(4);
            Spare       = (int)sixState.Get(1);
            Raim        = (int)sixState.Get(1);
            SyncState   = (int)sixState.Get(2);
        }
Beispiel #2
0
        /// <summary>
        ///     Assemble AIVDM/VDO sentences
        ///     This function handles re-assembly and extraction of the 6-bit data
        ///     from AIVDM/AIVDO sentences.
        ///     Because the NMEA standard limits the length of a line to 80 characters
        ///     some AIS messages, such as message 5, are output as a multipart VDM
        ///     messages.
        ///     This routine collects the 6-bit encoded data from these parts and
        ///     returns a 1 when all pieces have been reassembled.
        ///     It expects the sentences to:
        ///     - Be in order, part 1, part 2, etc.
        ///     - Be from a single sequence
        ///     It will return an error if it receives a piece out of order or from
        ///     a new sequence before the previous one is finished.
        /// </summary>
        /// <returns>
        ///     - 0 Complete packet
        ///     - 1 Incomplete packet
        ///     - 2 NMEA 0183 checksum failed
        ///     - 3 Not an AIS message
        ///     - 4 Error with nmea_next_field
        ///     - 5 Out of sequence packet
        /// </returns>
        /// <exception cref="ChecksumFailedException"></exception>
        /// <exception cref="StartNotFoundException"></exception>
        /// <exception cref="VDMSentenceException"></exception>
        public VdmStatus Add(string str)
        {
            int total;
            int num;
            int sequence;

            if (Nmea.CheckChecksum(str) != 0)
            {
                throw new ChecksumFailedException();
            }
            var ptr = Nmea.FindStart(str);

            // Allow any sender type for VDM and VDO messages
            //if (!str.regionMatches(ptr + 3, "VDM", 0, 3) && !str.regionMatches(ptr + 3, "VDO", 0, 3))
            var tag = str.Substring(ptr + 3, 3);

            if (!tag.Equals("VDM") && !tag.Equals("VDO"))
            {
                throw new VDMSentenceException("Not a VDM or VDO message");
            }

            var fields = FieldSpliter.Split(str); //str.Split(",|\\*", true);

            if (fields.Length != 8)
            {
                throw new VDMSentenceException("Does not have 8 fields");
            }

            // Get the message info for multipart messages
            try {
                total = int.Parse(fields[1]);
                num   = int.Parse(fields[2]);
            } catch (FormatException) {
                throw new VDMSentenceException("total or num field is not an integer");
            }

            if (!int.TryParse(fields[3], out sequence))
            {
                sequence = 0;
            }

            // Are we looking for more message parts?
            if (Total > 0)
            {
                if (Sequence != sequence || Num != num - 1)
                {
                    Total    = 0;
                    Sequence = 0;
                    Num      = 0;
                    return((VdmStatus)5);
                    //throw new VDMSentenceException("Out of sequence sentence");
                }

                Num++;
            }
            else
            {
                Total    = total;
                Num      = num;
                Sequence = sequence;
                SixState = new Sixbit();
            }

            Channel = fields[4].FirstOrDefault();//[0];
            SixState.Add(fields[5]);

            if (total == 0 || Total == num)
            {
                Total    = 0;
                Num      = 0;
                Sequence = 0;
                // Get the message id
                try {
                    MsgId = (int)SixState.Get(6);
                } catch (SixbitsExhaustedException) {
                    throw new VDMSentenceException("Not enough bits for msgid");
                }

                // Adjust bit count
                SixState.PadBits(int.Parse(fields[6]));
                // Found a complete packet
                return(0);
            }

            // No complete message yet
            return((VdmStatus)1);
        }