Init
This commit is contained in:
commit
e35d7b3356
|
|
@ -0,0 +1,63 @@
|
||||||
|
//
|
||||||
|
// Created by xemon on 01.09.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef NMEA_ACP_PARSER_H
|
||||||
|
#define NMEA_ACP_PARSER_H
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "stdbool.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t hour;
|
||||||
|
uint8_t minute;
|
||||||
|
uint8_t second;
|
||||||
|
uint16_t millisecond;
|
||||||
|
} tNmeaTimeAcp;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t day;
|
||||||
|
uint8_t month;
|
||||||
|
uint8_t year;
|
||||||
|
} tNmeaDateAcp;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
double latitude;
|
||||||
|
char nsIndicator;
|
||||||
|
double longitude;
|
||||||
|
double horizontDiluitPrecis;
|
||||||
|
double altitude;
|
||||||
|
char ewIndicator;
|
||||||
|
} tNmeaLocationAcp;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
double declination;
|
||||||
|
double nsat;
|
||||||
|
double mode;
|
||||||
|
} tNmeaMagneticAcp;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char status;
|
||||||
|
|
||||||
|
tNmeaDateAcp date;
|
||||||
|
tNmeaTimeAcp time;
|
||||||
|
tNmeaLocationAcp location;
|
||||||
|
tNmeaMagneticAcp magnetic;
|
||||||
|
|
||||||
|
double knotVelocity;
|
||||||
|
double kmhVelocity;
|
||||||
|
double course;
|
||||||
|
} tNmeaAcp;
|
||||||
|
|
||||||
|
uint32_t iNmeaTimestampFromAcp(tNmeaAcp *env);
|
||||||
|
|
||||||
|
void vNmeaACPSign(char *str, size_t *strLen);
|
||||||
|
|
||||||
|
bool bNmeaACPParse(char *acprmcString, size_t len, tNmeaAcp *result);
|
||||||
|
|
||||||
|
bool bNmeaACPString(char *nmeaString, size_t len, tNmeaAcp *acp);
|
||||||
|
|
||||||
|
bool bNmeaACPIsValidString(char *nmeaString, size_t len);
|
||||||
|
|
||||||
|
#endif //NMEA_0183_PARSER_NMEA_0183_PARSER_H
|
||||||
|
|
@ -0,0 +1,233 @@
|
||||||
|
//
|
||||||
|
// Created by xemon on 01.09.22.
|
||||||
|
//
|
||||||
|
#include "NmeaACPParser.h"
|
||||||
|
#include "AsciiStringAssmeblingUtils.h"
|
||||||
|
#include "AsciiStringParsingUtils.h"
|
||||||
|
#include "time.h"
|
||||||
|
#include <string.h>
|
||||||
|
//#include "printf.h"
|
||||||
|
|
||||||
|
double specifAtCommand;
|
||||||
|
|
||||||
|
//static char *strnstr(const char *haystack, const char *needle, size_t len)
|
||||||
|
//{
|
||||||
|
// int i;
|
||||||
|
// size_t needle_len;
|
||||||
|
//
|
||||||
|
// if (0 == (needle_len = strnlen(needle, len)))
|
||||||
|
// return (char *)haystack;
|
||||||
|
//
|
||||||
|
// for (i=0; i<=(int)(len-needle_len); i++)
|
||||||
|
// {
|
||||||
|
// if ((haystack[0] == needle[0]) &&
|
||||||
|
// (0 == strncmp(haystack, needle, needle_len)))
|
||||||
|
// return (char *)haystack;
|
||||||
|
//
|
||||||
|
// haystack++;
|
||||||
|
// }
|
||||||
|
// return NULL;
|
||||||
|
//}
|
||||||
|
|
||||||
|
#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 NmeaACPParseTime(char *utcString, char const *utcStringEnd, tNmeaTimeAcp *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 NmeaACPParseDate(char *utcString, char const *utcStringEnd, tNmeaDateAcp *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 uNmeaACPChecksum(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 vNmeaACPSign(char *str, size_t *strLen) {
|
||||||
|
uint8_t crc = uNmeaACPChecksum(str, *strLen);
|
||||||
|
vAsciiStringAddChar(str, strLen, '*');
|
||||||
|
vAsciiStringAddByteAsHex(str, strLen, crc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bNmeaACPString(char *nmeaString, size_t len, tNmeaAcp *acp) {
|
||||||
|
if (nmeaString[0] != '$') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t iNmeaTimestampFromAcp(tNmeaAcp *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;
|
||||||
|
time.tm_year = (2000 - 1900) + env->date.year;
|
||||||
|
|
||||||
|
return mktime(&time);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bNmeaACPIsValidString(char *nmeaString, size_t len) {
|
||||||
|
if (specifAtCommand == 1) {
|
||||||
|
char *dataEndPos = strnstr((char *) nmeaString, "*", len);
|
||||||
|
uint8_t checksumCalculated = uNmeaACPChecksum(nmeaString, dataEndPos - nmeaString);
|
||||||
|
++dataEndPos;
|
||||||
|
uint8_t checksumInString = Nmea0183ParseHexByte(dataEndPos);
|
||||||
|
return checksumCalculated == checksumInString;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bNmeaACPParse(char *rmcString, size_t len, tNmeaAcp *result) {
|
||||||
|
|
||||||
|
rmcString = rmcString + 9;
|
||||||
|
len = len - 9;
|
||||||
|
|
||||||
|
char *end = rmcString + len;
|
||||||
|
char *front = rmcString;
|
||||||
|
char *nextDivider = front - 1;
|
||||||
|
|
||||||
|
if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) {
|
||||||
|
if (!NmeaACPParseTime(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);
|
||||||
|
result->location.nsIndicator = front[9];
|
||||||
|
} else {
|
||||||
|
result->location.latitude = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) {
|
||||||
|
result->location.longitude = Nmea0183ParseDouble(front, nextDivider - front);
|
||||||
|
result->location.ewIndicator = front[10];
|
||||||
|
} else {
|
||||||
|
result->location.longitude = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// снижение точности
|
||||||
|
if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) {
|
||||||
|
result->location.horizontDiluitPrecis = Nmea0183ParseDouble(front, nextDivider - front);
|
||||||
|
} else {
|
||||||
|
result->location.horizontDiluitPrecis = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) {
|
||||||
|
result->location.altitude = Nmea0183ParseDouble(front, nextDivider - front);
|
||||||
|
} else {
|
||||||
|
result->location.altitude = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) {
|
||||||
|
result->status = Nmea0183ParseDouble(front, nextDivider - front);
|
||||||
|
if (result->status > 2) {
|
||||||
|
result->status = 'A';
|
||||||
|
} else {
|
||||||
|
result->status = 'V';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result->status = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) {
|
||||||
|
result->course = Nmea0183ParseDouble(front, nextDivider - front);
|
||||||
|
} else {
|
||||||
|
result->course = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) {
|
||||||
|
result->kmhVelocity = Nmea0183ParseDouble(front, nextDivider - front);
|
||||||
|
} else {
|
||||||
|
result->kmhVelocity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) {
|
||||||
|
result->knotVelocity = Nmea0183ParseDouble(front, nextDivider - front);
|
||||||
|
} else {
|
||||||
|
result->knotVelocity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) {
|
||||||
|
if (!NmeaACPParseDate(front, nextDivider, &result->date)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result->date.year = 0;
|
||||||
|
result->date.month = 0;
|
||||||
|
result->date.day = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Nmea0183ParseNextPortion(&front, &nextDivider, end) > 0) {
|
||||||
|
result->magnetic.nsat = *front;
|
||||||
|
} else {
|
||||||
|
result->magnetic.nsat = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"cmake": {
|
||||||
|
"inc_dirs": [
|
||||||
|
"Inc"
|
||||||
|
],
|
||||||
|
"srcs": [
|
||||||
|
"Src/**.c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue