1019
This commit is contained in:
parent
f2cec055b8
commit
f3ff85be3d
|
|
@ -7,6 +7,12 @@
|
||||||
|
|
||||||
#include "AsciiStringParsingUtils.h"
|
#include "AsciiStringParsingUtils.h"
|
||||||
|
|
||||||
|
#define Nmea0183StartEncapsulateSentenceDelimiter '!'
|
||||||
|
#define Nmea0183StartDelimiter '$'
|
||||||
|
#define Nmea0183CheckSumDelimiter '*'
|
||||||
|
#define Nmea0183FieldDelimiter ','
|
||||||
|
|
||||||
|
|
||||||
#define Nmea0183ParseShortCharsDecimalNumber(STR, LEN) (uint16_t) iAsciiStringParseUnsignedLongDecimalNumber(STR,((STR)+(LEN)))
|
#define Nmea0183ParseShortCharsDecimalNumber(STR, LEN) (uint16_t) iAsciiStringParseUnsignedLongDecimalNumber(STR,((STR)+(LEN)))
|
||||||
|
|
||||||
#define Nmea0183ParseDouble(STR, LEN) dAsciiStringParseDouble(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 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)
|
#define Nmea0183ParseHexByte(STR) iAsciiStringParseHexByte(STR)
|
||||||
|
|
||||||
#endif //NMEA0183PARSER_PRIVATE_H
|
#endif //NMEA0183PARSER_PRIVATE_H
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,63 @@
|
||||||
// Created by villuton on 20.03.25.
|
// Created by villuton on 20.03.25.
|
||||||
//
|
//
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
#include "Nmea0183Parser_General.h"
|
#include "Nmea0183Parser_General.h"
|
||||||
#include "Nmea0183Parser_Private.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) {
|
bool Nmea0183ParseTime(char *utcString, char const *utcStringEnd, tNmeaTime *time) {
|
||||||
|
|
||||||
uint32_t len = utcStringEnd - utcString;
|
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) {
|
if (len > 10 || len < 9) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -18,18 +68,30 @@ bool Nmea0183ParseTime(char *utcString, char const *utcStringEnd, tNmeaTime *tim
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
time->hour = Nmea0183ParseShortCharsDecimalNumber(utcString + 0, 2);
|
time->hour = Nmea0183ParseShortCharsDecimalNumber(utcString + NMEA_HourStrOffset, NMEA_HourStrLen);
|
||||||
time->minute = Nmea0183ParseShortCharsDecimalNumber(utcString + 2, 2);
|
time->minute = Nmea0183ParseShortCharsDecimalNumber(utcString + NMEA_MinuteStrOffset, NMEA_MinuteStrLen);
|
||||||
time->second = Nmea0183ParseShortCharsDecimalNumber(utcString + 4, 2);
|
time->second = Nmea0183ParseShortCharsDecimalNumber(utcString + NMEA_SecondStrOffset, NMEA_SecondStrLen);
|
||||||
|
|
||||||
time->millisecond = Nmea0183ParseShortCharsDecimalNumber(utcString + 7, charsLeft);
|
time->millisecond = Nmea0183ParseShortCharsDecimalNumber(utcString + NMEA_DecimalSecondStrOffset, decimalPortion);
|
||||||
|
while (decimalPortion) {
|
||||||
charsLeft = 3 - charsLeft;
|
|
||||||
|
|
||||||
while (charsLeft) {
|
|
||||||
time->millisecond *= 10;
|
time->millisecond *= 10;
|
||||||
--charsLeft;
|
--decimalPortion;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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;
|
||||||
|
}
|
||||||
|
|
@ -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})
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"dep": [
|
|
||||||
{
|
|
||||||
"type": "local",
|
|
||||||
"dir": "../"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cmake": {
|
|
||||||
"inc_dirs": [
|
|
||||||
"Inc"
|
|
||||||
],
|
|
||||||
"srcs": [
|
|
||||||
"Src/**.c"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue