From f3ff85be3d9502693ff98630778aefcfbca122a8 Mon Sep 17 00:00:00 2001 From: Villuton Date: Fri, 21 Mar 2025 17:42:42 +0300 Subject: [PATCH] 1019 --- Inc/Nmea0183Parser_Private.h | 15 +++++++ Src/Nmea0183Parser_General.c | 82 +++++++++++++++++++++++++++++++----- Tst/CMakeLists.txt | 8 ---- Tst/Src/test.c | 69 ------------------------------ Tst/modular.json | 16 ------- 5 files changed, 87 insertions(+), 103 deletions(-) delete mode 100644 Tst/CMakeLists.txt delete mode 100644 Tst/Src/test.c delete mode 100644 Tst/modular.json diff --git a/Inc/Nmea0183Parser_Private.h b/Inc/Nmea0183Parser_Private.h index 5c126fc..e335ddc 100644 --- a/Inc/Nmea0183Parser_Private.h +++ b/Inc/Nmea0183Parser_Private.h @@ -7,6 +7,12 @@ #include "AsciiStringParsingUtils.h" +#define Nmea0183StartEncapsulateSentenceDelimiter '!' +#define Nmea0183StartDelimiter '$' +#define Nmea0183CheckSumDelimiter '*' +#define Nmea0183FieldDelimiter ',' + + #define Nmea0183ParseShortCharsDecimalNumber(STR, LEN) (uint16_t) iAsciiStringParseUnsignedLongDecimalNumber(STR,((STR)+(LEN))) #define Nmea0183ParseDouble(STR, LEN) dAsciiStringParseDouble(STR,((STR)+(LEN))) @@ -17,6 +23,15 @@ #define Nmea0183ParseNextPortion(BEGIN, DIV, STR_END) iAsciiStringMoveToNextParsingBlock(BEGIN,DIV,STR_END,',') +#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 Nmea0183ParseHexByte(STR) iAsciiStringParseHexByte(STR) #endif //NMEA0183PARSER_PRIVATE_H diff --git a/Src/Nmea0183Parser_General.c b/Src/Nmea0183Parser_General.c index ba48e5a..1e73fcd 100644 --- a/Src/Nmea0183Parser_General.c +++ b/Src/Nmea0183Parser_General.c @@ -2,13 +2,63 @@ // Created by villuton on 20.03.25. // #include +#include #include "Nmea0183Parser_General.h" #include "Nmea0183Parser_Private.h" +#define Nmea0183ParserEndDataPos(STR,LEN) strnstr((char *) STR, "*", LEN) + +/** + * Calculates the checksum of an NMEA 0183 XOR string of all bytes in the string + * @param str + * @param len + * @return XOR checksum + */ +uint8_t uNmea0183CheckSum(const char *str, size_t len) { + char *end = (char *) (str + len); + + unsigned char result; + result = 0; + + while (str != end) + result ^= *str++; + return result; +} + +/** + * Checking string validity NMEA 0183 + * @param str + * @param len + * @return Checksum comparison result + */ +bool bNmea0183IsValidString(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); + if(Nmea0183ParseCheckSumPosition(&front,&nextDivider,end) > 0){ + uint8_t checksumInString = Nmea0183ParseHexByte(nextDivider); + return checksumCalculated == checksumInString; + } + 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 charsLeft = len - 7; + uint8_t decimalPortion = len - NMEA_HourStrLen+NMEA_MinuteStrLen+NMEA_SecondStrLen+NMEA_UTC_PointStrOffset; if (len > 10 || len < 9) { return false; @@ -18,18 +68,30 @@ bool Nmea0183ParseTime(char *utcString, char const *utcStringEnd, tNmeaTime *tim return false; } - time->hour = Nmea0183ParseShortCharsDecimalNumber(utcString + 0, 2); - time->minute = Nmea0183ParseShortCharsDecimalNumber(utcString + 2, 2); - time->second = Nmea0183ParseShortCharsDecimalNumber(utcString + 4, 2); + 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 + 7, charsLeft); - - charsLeft = 3 - charsLeft; - - while (charsLeft) { + time->millisecond = Nmea0183ParseShortCharsDecimalNumber(utcString + NMEA_DecimalSecondStrOffset, decimalPortion); + while (decimalPortion) { time->millisecond *= 10; - --charsLeft; + --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 diff --git a/Tst/CMakeLists.txt b/Tst/CMakeLists.txt deleted file mode 100644 index 4a7275c..0000000 --- a/Tst/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -cmake_minimum_required(VERSION 3.17) -PROJECT(nmea_parser_test) - -set(CMAKE_CXX_STANDARD 17) - -include(modular.cmake) - -add_executable(test ${SOURCES}) \ No newline at end of file diff --git a/Tst/Src/test.c b/Tst/Src/test.c deleted file mode 100644 index 6f748d4..0000000 --- a/Tst/Src/test.c +++ /dev/null @@ -1,69 +0,0 @@ -// -// Created by xemon on 02.09.22. -// - -#include "printf.h" - -#include "Nmea0183Parser.h" -#include "stdio.h" - - -void testRmc(char *rmcStr, size_t rmcStrLen) { - printf("string %*s\n", (int) rmcStrLen, rmcStr); - if (bNmea0183IsValidString(rmcStr, rmcStrLen)) { - printf("it's valid nmea string\n"); - if (bNmea0183IsRmcString(rmcStr, rmcStrLen)) { - printf("it's rmc string\n"); - tNmeaRmc rmc; - if (bNmea0183ParseRMC(rmcStr + 7, rmcStrLen - 7, &rmc)) { - printf("RMC string parsed OK!\n"); - if (rmc.location.ewIndicator) { - printf("lat %c %f\n", rmc.location.ewIndicator, rmc.location.latitude); - } else { - printf("no lat\n"); - } - if (rmc.location.nsIndicator) { - printf("lon %c %f\n", rmc.location.nsIndicator, rmc.location.longitude); - } else { - printf("no lon\n"); - } - - printf("time %02i:%02i:%02i [%03i]\n", - rmc.time.hour, - rmc.time.minute, - rmc.time.second, - rmc.time.millisecond - ); - - printf("date %i %i 20%02i\n", - rmc.date.day, - rmc.date.month, - rmc.date.year - ); - } else { - printf("Can't parse rmc string!\n"); - } - } else { - printf("it's not rmc string\n"); - } - } else { - printf("it's invalid nmea string\n"); - } - -} - - - - - -int main() { - - char gprmc0[] = "$GPSACP: 115235.000,5244.8321N,04126.7108E,0.6,201.7,3,0.0,0.0,0.0,121022,05,08"; - char gprmc1[] = "$GPRMC,125504.049,A,5542.2389,N,03741.6063,E,0.06,25.82,200906,,,*17"; - printf("\n"); -// testAcp(gprmc0, sizeof(gprmc0) - 1); - - printf("\n"); - testRmc(gprmc1, sizeof(gprmc1) - 1); - return 0; -} \ No newline at end of file diff --git a/Tst/modular.json b/Tst/modular.json deleted file mode 100644 index 236f353..0000000 --- a/Tst/modular.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "dep": [ - { - "type": "local", - "dir": "../" - } - ], - "cmake": { - "inc_dirs": [ - "Inc" - ], - "srcs": [ - "Src/**.c" - ] - } -} \ No newline at end of file