private void Run() { try { string workingBuffer = string.Empty; while (true) { int bytesToRead = _port.BytesToRead; if (bytesToRead > 0) { byte[] buffer = new byte[bytesToRead]; _port.Read(buffer, 0, buffer.Length); string text = new string(Encoding.UTF8.GetChars(buffer)); workingBuffer += text.ToString(); int sentenceEndIndex; while ((sentenceEndIndex = workingBuffer.IndexOf(CrLf)) != -1) { string sentence = workingBuffer.Substring(0, sentenceEndIndex); if (sentence.IndexOf('$') != -1) { IGPSMessage message = GPSMessageParser.Parse(sentence); if (message != null) { if (message is FixedDataMessage) { GPSPosition position = ParsePosition(message as FixedDataMessage); if (PositionReceived != null) { PositionReceived(this, position); } } } } if (sentenceEndIndex + CrLf.Length == workingBuffer.Length) { workingBuffer = string.Empty; } else { workingBuffer = workingBuffer.Substring(sentenceEndIndex + CrLf.Length, workingBuffer.Length - sentenceEndIndex - CrLf.Length); } sentenceEndIndex = workingBuffer.IndexOf(CrLf); } Thread.Sleep(100); } } } catch (ThreadAbortException) { } }
public static IGPSMessage Parse(string sentence) { IGPSMessage message = null; int checksumIndex = sentence.IndexOf("*"); if (checksumIndex == -1) { throw new Exception("No checksum found"); } if (checksumIndex == sentence.Length - 1) { throw new Exception("No checksum after marker"); } string checksum = sentence.Substring(checksumIndex + 1, sentence.Length - checksumIndex - 1); sentence = sentence.Substring(0, checksumIndex); string[] messageFields = sentence.Split(new char[] { ',' }); if (messageFields == null || messageFields.Length == 0) { throw new Exception("No fields in the message"); } switch (messageFields[0]) { case "$GPGGA": { FixedDataMessage fdMessage = new FixedDataMessage(); fdMessage.Timestamp = ParseTime(messageFields[1]); fdMessage.Latitude = messageFields[2]; fdMessage.NSIndicator = ParseChar(messageFields[3]); fdMessage.Longitude = messageFields[4]; fdMessage.EWIndicator = ParseChar(messageFields[5]); fdMessage.PositionFix = ParsePositionFixIndicator(messageFields[6]); fdMessage.SatallitesUsed = messageFields[7]; ParseDouble(messageFields[8], out fdMessage.HDOP, out fdMessage.IsHDOPValid); ParseDouble(messageFields[9], out fdMessage.MSLAltitude, out fdMessage.IsMSLAltitudeValid); fdMessage.MSLAltitudeUnits = ParseChar(messageFields[10], out fdMessage.IsMSLAltitudeUnitsValid); ParseDouble(messageFields[11], out fdMessage.GeoidSeperation, out fdMessage.IsGeoidSeperationValid); fdMessage.GeoidSeperationUnits = ParseChar(messageFields[12], out fdMessage.IsGeoidSeperationUnitsValid); ParseInt(messageFields[13], out fdMessage.AgeOfDifferentialCorrection, out fdMessage.IsAgeOfDifferentialCorrectionValid); fdMessage.DifferentialReferenceStationId = messageFields[14]; message = fdMessage; break; } } return(message); }