/// <summary> /// Provides validation that the sentence is a complete and valid NMEA sentence /// </summary> /// <param name="sentence">The sentence to be validated.</param> /// <returns>True if the sentence is a valid NMEA formated sentence.</returns> /// <remarks> /// NMEA sentences are of the form $GPRMC,11,22,33,44,55*CC /// A valid sentence starts with a $. /// Has comma seperated data values. /// Has a * indicating the end of the data and position of the checksum. /// The two checksum characters are correct. /// </remarks> public bool ValidateNMEASentence(string sentence) { // Does it begin with a dollar sign? if (!sentence.StartsWith("$", StringComparison.Ordinal)) { CNXLog.WarnFormat("NMEAClient Validation failed, no $."); return(false); } // make sure there are data fields if (sentence.IndexOf(",", StringComparison.Ordinal) == -1) { CNXLog.WarnFormat("NMEAClient Validation failed, no data fields."); return(false); } // Next, get the index of the asterisk int asteriskIndex = sentence.IndexOf("*", StringComparison.Ordinal); // Is an asterisk present? if (asteriskIndex == -1) { CNXLog.WarnFormat("NMEAClient Validation failed, no *."); return(false); } // The checksum is calculated over the command and data portion of the sentence byte checksum = (byte)sentence[1]; for (int index = 2; index < asteriskIndex; ++index) { checksum ^= (byte)sentence[index]; } // The checksum is the two-character hexadecimal value string calculatedChecksum = checksum.ToString("X2", NMEACultureInfo); string sentenceChecksum = sentence.Substring(asteriskIndex + 1, 2); if (!calculatedChecksum.Equals(sentenceChecksum, StringComparison.Ordinal)) { ++mChecksumErrors; CNXLog.WarnFormat("NMEAClient checksum errors {0}, sentence ratio {1}/{2}.", mChecksumErrors, mValidSentences, mSentencesRecieved); return(false); } return(true); }
/// <summary> /// Event firing method. /// </summary> /// <param name="frame">The CAN frame just received.</param> //protected virtual void OnRaiseFrameReceivedEvent(FrameReceivedEventArgs frameEvent) //{ // // copy the event handler to avoid mid process subscribe/un-subscribe // EventHandler<FrameReceivedEventArgs> handler = RaiseFrameReceivedEvent; // // Check if there are any Subscribers // if (handler != null) // // Call the Event // handler(this, frameEvent); //} private void ReceiveFrames() { byte[] buffer = new byte[13]; EndPoint ep = mRxEndPoint; CANFrame frame = new CANFrame(); while (mKeepReceiving) { try { if (mRxSocket.ReceiveFrom(buffer, ref ep) > 0) { CNXLog.Debug(BitConverter.ToString(buffer)); // populate a CAN frame frame.WireFormatArray = buffer; CNXLog.Debug(BitConverter.ToString(frame.Data)); CNXLog.Debug(frame.MailboxId.ToString("X")); OnRaiseFrameReceivedEvent(new FrameReceivedEventArgs(frame)); } } catch (SocketException se) { // may be OK to continue. CNXLog.WarnFormat("ReceiveFrames {0}.", se.Message); } catch (Exception e) { // stuffed. mKeepReceiving = false; CNXLog.ErrorFormat("ReceiveFrames {0}.", e.Message); break; } } mRxSocket.Close(); }