Add support for $GPGSA sequences.

This commit is contained in:
Denys Kuzmenko 2014-02-25 17:32:56 +01:00
parent b341777f60
commit e2838ed642
3 changed files with 134 additions and 0 deletions

View File

@ -271,6 +271,8 @@ enum minmea_type minmea_type(const char *sentence)
return MINMEA_GPRMC;
if (!strcmp(type, "GPGGA"))
return MINMEA_GPGGA;
if (!strcmp(type, "GPGSA"))
return MINMEA_GPGSA;
return MINMEA_UNKNOWN;
}
@ -333,6 +335,65 @@ bool minmea_parse_gpgga(struct minmea_gpgga *frame, const char *sentence)
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)
{
if (date->year == -1 || time->hours == -1)

View File

@ -27,6 +27,7 @@ enum minmea_type {
MINMEA_UNKNOWN = 0,
MINMEA_GPRMC,
MINMEA_GPGGA,
MINMEA_GPGSA,
};
struct minmea_date {
@ -65,6 +66,37 @@ struct minmea_gpgga {
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.
*/
@ -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_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.

40
tests.c
View File

@ -328,11 +328,44 @@ START_TEST(test_minmea_parse_gpgga1)
}
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)
{
const char *sentences[] = {
"$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",
"$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39",
NULL,
};
@ -348,6 +381,12 @@ START_TEST(test_minmea_usage1)
ck_assert(minmea_parse_gpgga(&frame, *sentence) == true);
} break;
case MINMEA_GPGSA: {
struct minmea_gpgsa frame;
ck_assert(minmea_parse_gpgsa(&frame, *sentence) == true);
} break;
default: {
} 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_gprmc2);
tcase_add_test(tc_parse, test_minmea_parse_gpgga1);
tcase_add_test(tc_parse, test_minmea_parse_gpgsa1);
suite_add_tcase(s, tc_parse);
TCase *tc_usage = tcase_create("minmea_usage");