97 lines
2.9 KiB
C
97 lines
2.9 KiB
C
//
|
|
// Created by villuton on 20.03.25.
|
|
//
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#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 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;
|
|
} |