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); }
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()); }