Add support for $GPGSA sequences.
This commit is contained in:
parent
b341777f60
commit
e2838ed642
61
minmea.c
61
minmea.c
@ -271,6 +271,8 @@ enum minmea_type minmea_type(const char *sentence)
|
|||||||
return MINMEA_GPRMC;
|
return MINMEA_GPRMC;
|
||||||
if (!strcmp(type, "GPGGA"))
|
if (!strcmp(type, "GPGGA"))
|
||||||
return MINMEA_GPGGA;
|
return MINMEA_GPGGA;
|
||||||
|
if (!strcmp(type, "GPGSA"))
|
||||||
|
return MINMEA_GPGSA;
|
||||||
|
|
||||||
return MINMEA_UNKNOWN;
|
return MINMEA_UNKNOWN;
|
||||||
}
|
}
|
||||||
@ -333,6 +335,65 @@ bool minmea_parse_gpgga(struct minmea_gpgga *frame, const char *sentence)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool minmea_parse_gpgsa(struct minmea_gpgsa *frame, const char *sentence){
|
||||||
|
// $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39
|
||||||
|
char type[6];
|
||||||
|
|
||||||
|
if (!minmea_scan(sentence, "tciiiiiiiiiiiiifff",
|
||||||
|
type,
|
||||||
|
&frame->mode,
|
||||||
|
&frame->fix_type,
|
||||||
|
&frame->sat1,
|
||||||
|
&frame->sat2,
|
||||||
|
&frame->sat3,
|
||||||
|
&frame->sat4,
|
||||||
|
&frame->sat5,
|
||||||
|
&frame->sat6,
|
||||||
|
&frame->sat7,
|
||||||
|
&frame->sat8,
|
||||||
|
&frame->sat9,
|
||||||
|
&frame->sat10,
|
||||||
|
&frame->sat11,
|
||||||
|
&frame->sat12,
|
||||||
|
&frame->pdop,
|
||||||
|
&frame->pdop_scale,
|
||||||
|
&frame->hdop,
|
||||||
|
&frame->hdop_scale,
|
||||||
|
&frame->vdop,
|
||||||
|
&frame->vdop_scale
|
||||||
|
)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (strcmp(type, "GPGSA")){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(frame->mode == 'A'){
|
||||||
|
frame->mode = GPGSA_MODE_AUTO;
|
||||||
|
}
|
||||||
|
else if(frame->mode == 'M'){
|
||||||
|
frame->mode = GPGSA_MODE_FORCED;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(frame->fix_type == 1){
|
||||||
|
frame->fix_type = GPGSA_FIX_NONE;
|
||||||
|
}
|
||||||
|
else if(frame->fix_type == 2){
|
||||||
|
frame->fix_type = GPGSA_FIX_2D;
|
||||||
|
}
|
||||||
|
else if(frame->fix_type == 3){
|
||||||
|
frame->fix_type = GPGSA_FIX_3D;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int minmea_gettimeofday(struct timeval *tv, const struct minmea_date *date, const struct minmea_time *time)
|
int minmea_gettimeofday(struct timeval *tv, const struct minmea_date *date, const struct minmea_time *time)
|
||||||
{
|
{
|
||||||
if (date->year == -1 || time->hours == -1)
|
if (date->year == -1 || time->hours == -1)
|
||||||
|
33
minmea.h
33
minmea.h
@ -27,6 +27,7 @@ enum minmea_type {
|
|||||||
MINMEA_UNKNOWN = 0,
|
MINMEA_UNKNOWN = 0,
|
||||||
MINMEA_GPRMC,
|
MINMEA_GPRMC,
|
||||||
MINMEA_GPGGA,
|
MINMEA_GPGGA,
|
||||||
|
MINMEA_GPGSA,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct minmea_date {
|
struct minmea_date {
|
||||||
@ -65,6 +66,37 @@ struct minmea_gpgga {
|
|||||||
int dgps_age;
|
int dgps_age;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum minmea_gpgsa_mode {
|
||||||
|
GPGSA_MODE_AUTO,
|
||||||
|
GPGSA_MODE_FORCED
|
||||||
|
};
|
||||||
|
|
||||||
|
enum minmea_gpgsa_fix_type {
|
||||||
|
GPGSA_FIX_NONE,
|
||||||
|
GPGSA_FIX_2D,
|
||||||
|
GPGSA_FIX_3D
|
||||||
|
};
|
||||||
|
|
||||||
|
struct minmea_gpgsa {
|
||||||
|
int mode;
|
||||||
|
int fix_type;
|
||||||
|
int sat1;
|
||||||
|
int sat2;
|
||||||
|
int sat3;
|
||||||
|
int sat4;
|
||||||
|
int sat5;
|
||||||
|
int sat6;
|
||||||
|
int sat7;
|
||||||
|
int sat8;
|
||||||
|
int sat9;
|
||||||
|
int sat10;
|
||||||
|
int sat11;
|
||||||
|
int sat12;
|
||||||
|
int pdop, pdop_scale;
|
||||||
|
int hdop, hdop_scale;
|
||||||
|
int vdop, vdop_scale;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check sequence validity and checksum. Returns true for valid sequences.
|
* Check sequence validity and checksum. Returns true for valid sequences.
|
||||||
*/
|
*/
|
||||||
@ -93,6 +125,7 @@ bool minmea_scan(const char *sentence, const char *format, ...);
|
|||||||
*/
|
*/
|
||||||
bool minmea_parse_gprmc(struct minmea_gprmc *frame, const char *sentence);
|
bool minmea_parse_gprmc(struct minmea_gprmc *frame, const char *sentence);
|
||||||
bool minmea_parse_gpgga(struct minmea_gpgga *frame, const char *sentence);
|
bool minmea_parse_gpgga(struct minmea_gpgga *frame, const char *sentence);
|
||||||
|
bool minmea_parse_gpgsa(struct minmea_gpgsa *frame, const char *sentence);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert GPS UTC date/time representation to a UNIX timestamp.
|
* Convert GPS UTC date/time representation to a UNIX timestamp.
|
||||||
|
40
tests.c
40
tests.c
@ -328,11 +328,44 @@ START_TEST(test_minmea_parse_gpgga1)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_minmea_parse_gpgsa1)
|
||||||
|
{
|
||||||
|
const char *sentence = "$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39";
|
||||||
|
struct minmea_gpgsa frame = {};
|
||||||
|
struct minmea_gpgsa expected = {
|
||||||
|
.mode = GPGSA_MODE_AUTO,
|
||||||
|
.fix_type = GPGSA_FIX_3D,
|
||||||
|
.sat1 = 4,
|
||||||
|
.sat2 = 5,
|
||||||
|
.sat3 = 0,
|
||||||
|
.sat4 = 9,
|
||||||
|
.sat5 = 12,
|
||||||
|
.sat6 = 0,
|
||||||
|
.sat7 = 0,
|
||||||
|
.sat8 = 24,
|
||||||
|
.sat9 = 0,
|
||||||
|
.sat10 = 0,
|
||||||
|
.sat11 = 0,
|
||||||
|
.sat12 = 0,
|
||||||
|
.pdop = 25,
|
||||||
|
.pdop_scale = 10,
|
||||||
|
.hdop = 13,
|
||||||
|
.hdop_scale = 10,
|
||||||
|
.vdop = 21,
|
||||||
|
.vdop_scale = 10
|
||||||
|
};
|
||||||
|
ck_assert(minmea_check(sentence) == true);
|
||||||
|
ck_assert(minmea_parse_gpgsa(&frame, sentence) == true);
|
||||||
|
ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
START_TEST(test_minmea_usage1)
|
START_TEST(test_minmea_usage1)
|
||||||
{
|
{
|
||||||
const char *sentences[] = {
|
const char *sentences[] = {
|
||||||
"$GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62",
|
"$GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62",
|
||||||
"$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47",
|
"$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47",
|
||||||
|
"$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -348,6 +381,12 @@ START_TEST(test_minmea_usage1)
|
|||||||
ck_assert(minmea_parse_gpgga(&frame, *sentence) == true);
|
ck_assert(minmea_parse_gpgga(&frame, *sentence) == true);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case MINMEA_GPGSA: {
|
||||||
|
struct minmea_gpgsa frame;
|
||||||
|
ck_assert(minmea_parse_gpgsa(&frame, *sentence) == true);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@ -424,6 +463,7 @@ Suite *minmea_suite(void)
|
|||||||
tcase_add_test(tc_parse, test_minmea_parse_gprmc1);
|
tcase_add_test(tc_parse, test_minmea_parse_gprmc1);
|
||||||
tcase_add_test(tc_parse, test_minmea_parse_gprmc2);
|
tcase_add_test(tc_parse, test_minmea_parse_gprmc2);
|
||||||
tcase_add_test(tc_parse, test_minmea_parse_gpgga1);
|
tcase_add_test(tc_parse, test_minmea_parse_gpgga1);
|
||||||
|
tcase_add_test(tc_parse, test_minmea_parse_gpgsa1);
|
||||||
suite_add_tcase(s, tc_parse);
|
suite_add_tcase(s, tc_parse);
|
||||||
|
|
||||||
TCase *tc_usage = tcase_create("minmea_usage");
|
TCase *tc_usage = tcase_create("minmea_usage");
|
||||||
|
Loading…
Reference in New Issue
Block a user