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