public static NmeaSentence From(string sentence)
        {
            NmeaSentence nmeaSentence = new NmeaSentence();
            int          length1      = !string.IsNullOrEmpty(sentence) ? sentence.LastIndexOf('*') : throw new ArgumentException("Empty sentence. Nothing to parse.");
            string       str1         = length1 > 0 ? sentence.Substring(length1 + 1) : throw new ArgumentException("No checksum found. Invalid data.");
            string       str2         = sentence.Substring(0, length1);
            byte         num1         = ChecksumCalculator.XOR(str2.Substring(1));
            byte         num2;

            try
            {
                num2 = byte.Parse(str1.Trim());//, 16);
            }
            catch (Exception ex)
            {
                throw new ArgumentException("Checksum failed to parse, error: " + ex.Message);
            }
            if ((int)num1 != (int)num2)
            {
                throw new ArgumentException("Checksum does not match data. Invalid data.");
            }
            int length2    = str2.IndexOf(',') - 1 == 5 ? 2 : 1;
            int startIndex = length2 == 2 ? 3 : 2;

            nmeaSentence.StartingDelimiter = str2.Substring(0, 1);
            nmeaSentence.TalkerID          = str2.Substring(1, length2);
            nmeaSentence.Prefix            = str2.Substring(startIndex, 3);
            var span1 = str2.Split(',');//new string[]{((M0[]) );

            if (span1.Length <= 0)
            {
                throw new ArgumentException("No data in sentence.");
            }
            nmeaSentence.DataElements.Clear();
            ArrayList dataElements = nmeaSentence.DataElements;
            var       span2        = new string[span1.Length - 1];

            for (int i = 1; i < span1.Length; i++)
            {
                span2[i - 1] = span1[i];
            }

            for (int i = 0; i < span2.Length; i++)
            {
                dataElements.Add(span2[i]);
            }
            return(nmeaSentence);
        }
Example #2
0
        private static (byte[] tag, RfidValidationStatus status) GetValidatedRfidTag(Span <byte> data)
        {
            // Valid format is as follows:
            // STX, 0-F x10 tag, 0-F x2 checksum, CR, LF, ETX
            // example:
            // STX 7 C 0 0 5 5 F 8 C 4 1 5 CR LF ETX
            const int validLength       = 16;
            const int startByte         = 0;
            const int endByte           = 15;
            const int tagStartByte      = 1;
            const int tagLength         = 10;
            const int checksumStartByte = 11;
            const int checksumLength    = 2;


            if (data.Length != validLength)
            {
                Debug.WriteLine(
                    $"Serial data is not of expected length for RFID tag format. Expected {validLength}, actual {data.Length}");
                return(tag : null, status : RfidValidationStatus.InvalidDataFormat);
            }

            if (data[startByte] != StartToken)
            {
                Debug.WriteLine(
                    $"Invalid start byte in serial data for RFID tag format. Expected '{StartToken}', actual '{data[startByte]}'");
                return(tag : null, status : RfidValidationStatus.InvalidDataFormat);
            }

            if (data[endByte] != EndToken)
            {
                Debug.WriteLine(
                    $"Invalid end byte in serial data for RFID tag format. Expected '{EndToken}', actual '{data[endByte]}'");
                return(tag : null, status : RfidValidationStatus.InvalidDataFormat);
            }

            // verify tag is hexadecimal
            var tagSlice = data.Slice(tagStartByte, tagLength);

            if (!IsHexChars(tagSlice))
            {
                Debug.WriteLine(
                    "Invalid end byte in serial data for RFID tag format. Expected hex ASCII character (48-57, 65-70)");
                return(tag : null, status : RfidValidationStatus.InvalidDataFormat);
            }

            // verify checksum is hexadecimal
            var checksumSlice = data.Slice(checksumStartByte, checksumLength);

            if (!IsHexChars(checksumSlice))
            {
                Debug.WriteLine(
                    "Invalid end byte in serial data for RFID tag format. Expected hex ASCII character (48-57, 65-70)");
                return(tag : null, status : RfidValidationStatus.InvalidDataFormat);
            }

            var tag      = AsciiHexByteArrayToBytes(tagSlice);
            var checkSum = AsciiHexByteArrayToBytes(checksumSlice)[0];

            return((ChecksumCalculator.XOR(tag) == checkSum)
                ? (tag, status : RfidValidationStatus.Ok)
                   : (tag, status : RfidValidationStatus.ChecksumFailed));
        }
        public override string ToString()
        {
            string dataString = this.GetDataString();

            return(dataString + "*" + ChecksumCalculator.XOR(dataString).ToString());
        }