コード例 #1
0
 /// <summary>
 /// A standard filter rule. When the filter matches
 /// </summary>
 /// <param name="sourceName">Name of the source (Nmea stream name) for which the filter applies or * for all</param>
 /// <param name="talkerId">TalkerId for which the rule applies or <see cref="TalkerId.Any"/></param>
 /// <param name="sentenceId">SentenceId for which the rule applies or <see cref="SentenceId.Any"/></param>
 /// <param name="sinks">Where to send the message when the filter matches</param>
 /// <param name="rawMessagesOnly">The filter matches raw messages only. This is the default, because otherwise known message
 /// types would be implicitly duplicated on forwarding</param>
 /// <param name="continueAfterMatch">True to continue processing after a match, false to stop processing this message</param>
 public FilterRule(string sourceName, TalkerId talkerId, SentenceId sentenceId, IEnumerable <string> sinks, bool rawMessagesOnly = true,
                   bool continueAfterMatch = false)
 {
     _rawMessagesOnly   = rawMessagesOnly;
     SourceName         = sourceName;
     TalkerId           = talkerId;
     SentenceId         = sentenceId;
     Sinks              = sinks;
     ContinueAfterMatch = continueAfterMatch;
 }
コード例 #2
0
ファイル: QuerySentence.cs プロジェクト: dotnet/iot
        /// <summary>
        /// Reads NMEA0183 query sentence from provided string
        /// </summary>
        /// <param name="sentence">NMEA0183 query sentence</param>
        /// <returns>QuerySentence instance</returns>
        /// <remarks><paramref name="sentence"/> does not include new line characters</remarks>
        public static QuerySentence FromSentenceString(string sentence)
        {
            // http://www.tronico.fi/OH6NT/docs/NMEA0183.pdf
            // page 3
            // $XXYYY ...
            const int SentenceLength = 6;

            if (sentence == null)
            {
                throw new ArgumentNullException(nameof(sentence));
            }

            if (sentence.Length != SentenceLength)
            {
                throw new ArgumentException($"Sentence length must be exactly {SentenceLength} characters", nameof(sentence));
            }

            if (sentence[0] != '$')
            {
                throw new ArgumentException("Sentence must start with '$'", nameof(sentence));
            }

            TalkerId requesterId = new TalkerId(sentence[1], sentence[2]);
            TalkerId deviceId    = new TalkerId(sentence[3], sentence[4]);

            if (sentence[5] != 'Q')
            {
                throw new ArgumentException("Valid query sentence must have character 'Q' at index 5");
            }

            if (sentence[6] != ',')
            {
                throw new ArgumentException("Valid query sentence must have character ',' at index 6");
            }

            SentenceId requestedSentence = new SentenceId(sentence[7], sentence[8], sentence[9]);

            return(new QuerySentence(requesterId, deviceId, requestedSentence));
        }
コード例 #3
0
 /// <summary>
 /// Constructs NMEA0183 talker identifier
 /// </summary>
 /// <param name="talkerId">NMEA0183 talker identifier of the device sending the sentence</param>
 /// <param name="sentenceId">NMEA0183 sentence identifier</param>
 /// <param name="fields">fields related to the sentence</param>
 public TalkerSentence(TalkerId talkerId, SentenceId sentenceId, IEnumerable <string> fields)
 {
     TalkerId = talkerId;
     Id       = sentenceId;
     _fields  = fields.ToArray();
 }
コード例 #4
0
        /// <summary>
        /// Reads NMEA0183 talker sentence from provided string
        /// </summary>
        /// <param name="sentence">NMEA0183 talker sentence</param>
        /// <param name="expectedTalkerId">If this is not TalkerId.Any, only messages with this talker id are parsed,
        /// all others are ignored. This reduces workload if a source acts as repeater, but the repeated messages are not needed.</param>
        /// <param name="errorCode">Returns an error code, if the parsing failed</param>
        /// <returns>TalkerSentence instance, or null in case of an error</returns>
        /// <remarks><paramref name="sentence"/> does not include new line characters</remarks>
        public static TalkerSentence?FromSentenceString(string sentence, TalkerId expectedTalkerId, out NmeaError errorCode)
        {
            // $XXY, ...
            const int sentenceHeaderMinLength = 4;

            // http://www.tronico.fi/OH6NT/docs/NMEA0183.pdf page 2
            // defines this as 80 + 1 (for $), but we don't really care if it is something within a reasonable limit.
            const int MaxSentenceLength = 256;

            if (sentence == null)
            {
                throw new ArgumentNullException(nameof(sentence));
            }

            if (sentence.Length < sentenceHeaderMinLength)
            {
                errorCode = NmeaError.MessageToShort;
                return(null);
            }

            if (sentence.Length > MaxSentenceLength)
            {
                errorCode = NmeaError.MessageToLong;
                return(null);
            }

            if (sentence[0] != '$' && sentence[0] != '!')
            {
                // Valid sentences start with $ or ! (for the AIS sentences)
                errorCode = NmeaError.NoSyncByte;
                return(null);
            }

            TalkerId talkerId = new TalkerId(sentence[1], sentence[2]);

            if (expectedTalkerId != TalkerId.Any && expectedTalkerId != talkerId)
            {
                errorCode = NmeaError.None;
                return(null);
            }

            int firstComma = sentence.IndexOf(',', 1);

            if (firstComma == -1)
            {
                errorCode = NmeaError.MessageToShort;
                return(null);
            }

            string sentenceIdString = sentence.Substring(3, firstComma - 3);

            SentenceId sentenceId = new SentenceId(sentenceIdString);

            string[] fields       = sentence.Substring(firstComma + 1).Split(',');
            int      lastFieldIdx = fields.Length - 1;

            // This returns null as the checksum if there was none, or a very big number if the checksum couldn't be parsed
            (int?checksum, string lastField) = GetChecksumAndLastField(fields[lastFieldIdx]);
            fields[lastFieldIdx]             = lastField;

            TalkerSentence result = new TalkerSentence(talkerId, sentenceId, fields);

            if (checksum.HasValue)
            {
                byte realChecksum = CalculateChecksumFromSentenceString(sentence.AsSpan());

                if (realChecksum != checksum.Value)
                {
                    errorCode = NmeaError.InvalidChecksum;
                    return(null);
                }
            }

            errorCode = NmeaError.None;
            return(result);
        }
コード例 #5
0
ファイル: QuerySentence.cs プロジェクト: dotnet/iot
 /// <summary>
 /// Constructs NMEA0183 query sentence
 /// </summary>
 /// <param name="requesterId">Talker identifier of the requester</param>
 /// <param name="deviceId">Talker identifier of the device</param>
 /// <param name="requestedSentence">Requested sentence</param>
 public QuerySentence(TalkerId requesterId, TalkerId deviceId, SentenceId requestedSentence)
 {
     RequesterId       = requesterId;
     DeviceId          = deviceId;
     RequestedSentence = requestedSentence;
 }