From 1065b3f7900980c63aaf6385fa9569970c5ffed1 Mon Sep 17 00:00:00 2001 From: Villuton Date: Wed, 26 Mar 2025 16:14:43 +0300 Subject: [PATCH] fix --- Inc/Nmea0183Parser_General.h | 15 +- Inc/Nmea0183Parser_Private.h | 5 +- Src/Nmea0183Parser.c | 320 ----------------------------------- Src/Nmea0183Parser_General.c | 72 ++------ 4 files changed, 25 insertions(+), 387 deletions(-) diff --git a/Inc/Nmea0183Parser_General.h b/Inc/Nmea0183Parser_General.h index 53f23fe..882f338 100644 --- a/Inc/Nmea0183Parser_General.h +++ b/Inc/Nmea0183Parser_General.h @@ -7,17 +7,10 @@ #include -typedef struct { - uint8_t hour; - uint8_t minute; - uint8_t second; - uint16_t millisecond; -} tNmeaTime; +uint8_t Nmea0183CheckSum(const char *str, size_t len); -typedef struct { - uint8_t day; - uint8_t month; - uint8_t year; -} tNmeaDate; +bool Nmea0183CheckIsNmeaStr(const char *str, size_t len); + +bool Nmea0183IsValidString(char *str, size_t len); #endif //NMEA0183PARSER_GENERAL_H diff --git a/Inc/Nmea0183Parser_Private.h b/Inc/Nmea0183Parser_Private.h index e335ddc..e9200ff 100644 --- a/Inc/Nmea0183Parser_Private.h +++ b/Inc/Nmea0183Parser_Private.h @@ -21,16 +21,17 @@ #define Nmea0183SkipToChar(STR, STR_END, SYMBOL) xAsciiStringSeekChar(STR,STR_END,SYMBOL) -#define Nmea0183ParseNextPortion(BEGIN, DIV, STR_END) iAsciiStringMoveToNextParsingBlock(BEGIN,DIV,STR_END,',') +#define Nmea0183ParseNextPortion(BEGIN, DIV, STR_END) iAsciiStringMoveToNextParsingBlock(BEGIN,DIV,STR_END,Nmea0183FieldDelimiter) #define Nmea0183ParseStartPosition(BEGIN, DIV, STR_END) iAsciiStringMoveToNextParsingBlock(BEGIN,DIV,STR_END,Nmea0183StartDelimiter) #define Nmea0183ParseCheckSumPosition(BEGIN, DIV, STR_END) iAsciiStringMoveToNextParsingBlock(BEGIN,DIV,STR_END,Nmea0183CheckSumDelimiter) #define Nmea0183SkipToStartDelimiter(STR, STR_END) Nmea0183SkipToChar(STR,STR_END,Nmea0183StartDelimiter) -#define Nmea0183SkipToStartCheckSumDelimiter(STR, STR_END) Nmea0183SkipToChar(STR,STR_END,Nmea0183CheckSumDelimiter) +#define Nmea0183SkipToCheckSumDelimiter(STR, STR_END) Nmea0183SkipToChar(STR,STR_END,Nmea0183CheckSumDelimiter) +#define NMEA_ASSERT(x) if(!(x)){return 0;}; #define Nmea0183ParseHexByte(STR) iAsciiStringParseHexByte(STR) diff --git a/Src/Nmea0183Parser.c b/Src/Nmea0183Parser.c index 7215523..837281c 100644 --- a/Src/Nmea0183Parser.c +++ b/Src/Nmea0183Parser.c @@ -7,323 +7,3 @@ #include "time.h" #include -#define Nmea0183ParseShortCharsDecimalNumber(STR, LEN) (uint16_t) iAsciiStringParseUnsignedLongDecimalNumber(STR,((STR)+(LEN))) - -#define Nmea0183ParseDouble(STR, LEN) dAsciiStringParseDouble(STR,((STR)+(LEN))) - -#define Nmea0183SkipSpace(STR, STR_END) xAsciiStringSkipSpace(STR,STR_END) - -#define Nmea0183SkipToChar(STR, STR_END, SYMBOL) xAsciiStringSeekChar(STR,STR_END,SYMBOL) - -#define Nmea0183ParseNextPortion(BEGIN, DIV, STR_END) iAsciiStringMoveToNextParsingBlock(BEGIN,DIV,STR_END,',') - -#define Nmea0183ParseHexByte(STR) iAsciiStringParseHexByte(STR) - -bool Nmea0183ParseTime(char *utcString, char const *utcStringEnd, tNmeaTimeRmc *time) { - - uint32_t len = utcStringEnd - utcString; - uint8_t charsLeft = len - 7; - - if (len > 10 || len < 9) { - return false; - } - - if (utcString[6] != '.') { - return false; - } - - time->hour = Nmea0183ParseShortCharsDecimalNumber(utcString + 0, 2); - time->minute = Nmea0183ParseShortCharsDecimalNumber(utcString + 2, 2); - time->second = Nmea0183ParseShortCharsDecimalNumber(utcString + 4, 2); - - time->millisecond = Nmea0183ParseShortCharsDecimalNumber(utcString + 7, charsLeft); - - charsLeft = 3 - charsLeft; - - while (charsLeft) { - time->millisecond *= 10; - --charsLeft; - } - - return true; -} - -bool Nmea0183ParseDate(char *utcString, char const *utcStringEnd, tNmeaDateRmc *date) { - - uint32_t len = utcStringEnd - utcString; - - if (len != 6) { - return false; - } - - date->day = Nmea0183ParseShortCharsDecimalNumber(utcString + 0, 2); - date->month = Nmea0183ParseShortCharsDecimalNumber(utcString + 2, 2); - date->year = Nmea0183ParseShortCharsDecimalNumber(utcString + 4, 2); - - return true; -} - -uint8_t uNmea0183Checksum(const char *str, size_t len) { - char *end = (char *) (str + len); - - unsigned char result; - result = 0; - str++; - - while ((str != end) && (*str != '*') && (*str != '\0')) - result ^= *str++; - - return result; -} - - -void vNmea0183Sign(char *str, size_t *strLen) { - uint8_t crc = uNmea0183Checksum(str, *strLen); - vAsciiStringAddChar(str, strLen, '*'); - vAsciiStringAddByteAsHex(str, strLen, crc); -} - -bool bNmea0183IsRmcString(char *nmeaString, size_t len) { - if (nmeaString[0] != '$') { - return false; - } - - return strnstr(nmeaString, "RMC", len); -} - -uint32_t iNmea0183TimestampFromRmc(tNmeaRmc *env) { - struct tm time; - time.tm_hour = env->time.hour; - time.tm_min = env->time.minute; - time.tm_sec = env->time.second; - - time.tm_mday = env->date.day; - time.tm_mon = env->date.month - 1; - if(env->date.year>60){ - time.tm_year = (1900 - 1900) + env->date.year; - }else{ - time.tm_year = (2000 - 1900) + env->date.year; - } - - return mktime(&time); -} - -static double nmeaLocationToDeg(double dec) { - double _dec = dec; - int deg = (int) (_dec / 100); - int min = (int) (_dec) - (deg * 100); - - double sec = (double) (_dec - min - 100 * deg) * 60.0; - - return deg + min / 60.0 + sec / 3600.0; -} - - -tLocationPointInDegDouble iNmea0183_DegLocationDoubleFromRmc(tNmeaRmc *env) { - tLocationPointInDegDouble result; - result.lat = nmeaLocationToDeg(env->location.latitude); - result.lon = nmeaLocationToDeg(env->location.longitude); - - if (env->location.nsIndicator == 'S' || env->location.nsIndicator == 's') { - result.lat *= -1.0; - } - - if (env->location.ewIndicator == 'W' || env->location.ewIndicator == 'w') { - result.lon *= -1.0; - } - return result; -} - -tLocationPointInDeg iNmea0183_DegLocationFromRmc(tNmeaRmc *env) { - tLocationPointInDeg result; - result.lat = (float) nmeaLocationToDeg(env->location.latitude); - result.lon = (float) nmeaLocationToDeg(env->location.longitude); - - if (env->location.nsIndicator == 'S' || env->location.nsIndicator == 's') { - result.lat *= -1.0f; - } - - if (env->location.ewIndicator == 'W' || env->location.ewIndicator == 'w') { - result.lon *= -1.0f; - } - return result; -} - - -bool bNmea0183IsValidString(char *nmeaString, size_t len) { - char *dataEndPos = strnstr((char *) nmeaString, "*", len); - uint8_t checksumCalculated = uNmea0183Checksum(nmeaString, dataEndPos - nmeaString); - ++dataEndPos; - uint8_t checksumInString = Nmea0183ParseHexByte(dataEndPos); - return checksumCalculated == checksumInString; -} - -bool bNmea0183ParseRMC(char *rmcString, size_t len, tNmeaRmc *result) { - - char *end = rmcString + len; - char *front = rmcString; - char *nextDivider = front - 1; - - result->status = 'V'; - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - if (!Nmea0183ParseTime(front, nextDivider, &result->time)) { - return false; - } - } else { - result->time.second = 0; - result->time.minute = 0; - result->time.hour = 0; - result->time.millisecond = 0; - } - - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->status = *front; - } else { - result->status = 0; - } - - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->location.latitude = Nmea0183ParseDouble(front, nextDivider - front); - } else { - result->location.latitude = 0; - } - - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->location.nsIndicator = *front; - } else { - result->location.nsIndicator = 0; - } - - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->location.longitude = Nmea0183ParseDouble(front, nextDivider - front); - } else { - result->location.longitude = 0; - } - - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->location.ewIndicator = *front; - } else { - result->location.ewIndicator = 0; - } - - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->knotVelocity = Nmea0183ParseDouble(front, nextDivider - front); - } else { - result->knotVelocity = 0; - } - - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->headingAngle = Nmea0183ParseDouble(front, nextDivider - front); - } else { - result->headingAngle = 0; - } - - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - if (!Nmea0183ParseDate(front, nextDivider, &result->date)) { - return false; - } - } else { - result->date.year = 0; - result->date.month = 0; - result->date.day = 0; - } - - - return true; -} - -bool bNmea0183IsGgaString(char *nmeaString, size_t len) { - if (nmeaString[0] != '$') { - return false; - } - - return strnstr(nmeaString, "GGA", len); -} - -bool bNmea0183ParseGGA(char *ggaString, size_t len, tNmeaGga *result){ - char *end = ggaString + len; - char *front = ggaString; - char *nextDivider = front-1; - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - if (!Nmea0183ParseTime(front, nextDivider, &result->time)) { - return false; - } - } else { - result->time.second = 0; - result->time.minute = 0; - result->time.hour = 0; - result->time.millisecond = 0; - } - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->location.latitude = Nmea0183ParseDouble(front, nextDivider - front); - } else { - result->location.latitude = 0; - } - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->location.nsIndicator = *front; - } else { - result->location.nsIndicator = 0; - } - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->location.longitude = Nmea0183ParseDouble(front, nextDivider - front); - } else { - result->location.longitude = 0; - } - - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->location.ewIndicator = *front; - } else { - result->location.ewIndicator = 0; - } - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->qual = Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front); - } else { - result->qual = 0; - } - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->sats = Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front); - } else { - result->sats = 0; - } - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->hdop = Nmea0183ParseDouble(front,nextDivider - front); - } else { - result->hdop = 0; - } - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->altitude = Nmea0183ParseDouble(front,nextDivider - front); - } else { - result->altitude = 0; - } - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->altitudeUnit = *front; - } else { - result->altitude = 0; - } - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->undulation = Nmea0183ParseDouble(front,nextDivider - front); - } else { - result->undulation = 0; - } - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->undulationUnit = *front; - } else { - result->undulationUnit = 0; - } - if(result->qual == DIFF){ - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->ageSec = Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front); - } else { - result->ageSec = 0; - } - if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) { - result->stnID = Nmea0183ParseShortCharsDecimalNumber(front,nextDivider - front); - } else { - result->stnID = 0; - } - } else{ - result->ageSec = 0; - result->stnID = 0; - } - return true; -} \ No newline at end of file diff --git a/Src/Nmea0183Parser_General.c b/Src/Nmea0183Parser_General.c index 1e73fcd..a194e8b 100644 --- a/Src/Nmea0183Parser_General.c +++ b/Src/Nmea0183Parser_General.c @@ -13,31 +13,45 @@ * @param len * @return XOR checksum */ -uint8_t uNmea0183CheckSum(const char *str, size_t len) { +uint8_t Nmea0183CheckSum(const char *str, size_t len) { char *end = (char *) (str + len); unsigned char result; result = 0; + switch (*str) { + case : + + } while (str != end) result ^= *str++; return result; } +/** + * Check string of a NMEA string + * @param str + * @param len + * @return Check start delimiter result + */ +bool Nmea0183CheckIsNmeaStr(const char *str, size_t len){ + return ((str[0] == Nmea0183StartDelimiter)); +} + /** * Checking string validity NMEA 0183 * @param str * @param len * @return Checksum comparison result */ -bool bNmea0183IsValidString(char *str, size_t len) { +bool Nmea0183IsValidString(char *str, size_t len) { char *end = str + len; char *front = str; char *nextDivider = front - 1; char *dataStartPos = Nmea0183SkipToStartDelimiter(front,end); - char *dataEndPos = Nmea0183SkipToStartCheckSumDelimiter(front,end); - uint8_t checksumCalculated = uNmea0183CheckSum(dataStartPos, dataEndPos - dataStartPos); + char *dataEndPos = Nmea0183SkipToCheckSumDelimiter(front, end); + uint8_t checksumCalculated = Nmea0183CheckSum(dataStartPos, dataEndPos - dataStartPos); if(Nmea0183ParseCheckSumPosition(&front,&nextDivider,end) > 0){ uint8_t checksumInString = Nmea0183ParseHexByte(nextDivider); return checksumCalculated == checksumInString; @@ -45,53 +59,3 @@ bool bNmea0183IsValidString(char *str, size_t len) { return false; } -#define NMEA_HourStrLen 2 -#define NMEA_MinuteStrLen 2 -#define NMEA_SecondStrLen 2 - -#define NMEA_HourStrOffset 0 -#define NMEA_MinuteStrOffset (NMEA_HourStrOffset + NMEA_HourStrLen) -#define NMEA_SecondStrOffset (NMEA_MinuteStrOffset + NMEA_MinuteStrLen) -#define NMEA_UTC_PointStrOffset 1 -#define NMEA_DecimalSecondStrOffset (NMEA_SecondStrOffset + NMEA_SecondStrLen + NMEA_UTC_PointStrOffset) - -bool Nmea0183ParseTime(char *utcString, char const *utcStringEnd, tNmeaTime *time) { - - uint32_t len = utcStringEnd - utcString; - uint8_t decimalPortion = len - NMEA_HourStrLen+NMEA_MinuteStrLen+NMEA_SecondStrLen+NMEA_UTC_PointStrOffset; - - if (len > 10 || len < 9) { - return false; - } - - if (utcString[6] != '.') { - return false; - } - - time->hour = Nmea0183ParseShortCharsDecimalNumber(utcString + NMEA_HourStrOffset, NMEA_HourStrLen); - time->minute = Nmea0183ParseShortCharsDecimalNumber(utcString + NMEA_MinuteStrOffset, NMEA_MinuteStrLen); - time->second = Nmea0183ParseShortCharsDecimalNumber(utcString + NMEA_SecondStrOffset, NMEA_SecondStrLen); - - time->millisecond = Nmea0183ParseShortCharsDecimalNumber(utcString + NMEA_DecimalSecondStrOffset, decimalPortion); - while (decimalPortion) { - time->millisecond *= 10; - --decimalPortion; - } - - return true; -} - -bool Nmea0183ParseDate(char *utcString, char const *utcStringEnd, tNmeaDate *date) { - - uint32_t len = utcStringEnd - utcString; - - if (len != 6) { - return false; - } - - date->day = Nmea0183ParseShortCharsDecimalNumber(utcString + 0, 2); - date->month = Nmea0183ParseShortCharsDecimalNumber(utcString + 2, 2); - date->year = Nmea0183ParseShortCharsDecimalNumber(utcString + 4, 2); - - return true; -} \ No newline at end of file