fix
This commit is contained in:
parent
63e2f271b5
commit
1065b3f790
|
|
@ -7,17 +7,10 @@
|
|||
|
||||
#include <stdint-gcc.h>
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,323 +7,3 @@
|
|||
#include "time.h"
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue