diff --git a/README.md b/README.md index 8d788b0..bce0c0c 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ systems. * ``RMC`` (Recommended Minimum: position, velocity, time) * ``GGA`` (Fix Data) * ``GSA`` (DOP and active satellites) +* ``GLL`` (Geographic Position -- Latitude/Longitude) Adding support for more sentences is trivial; see ``minmea.c`` source. diff --git a/example.c b/example.c old mode 100644 new mode 100755 index e973814..ca9e933 Binary files a/example.c and b/example.c differ diff --git a/minmea.c b/minmea.c index 8bbbc59..a6d676d 100644 --- a/minmea.c +++ b/minmea.c @@ -287,6 +287,8 @@ enum minmea_sentence_id minmea_sentence_id(const char *sentence) return MINMEA_SENTENCE_GGA; if (!strcmp(type+2, "GSA")) return MINMEA_SENTENCE_GSA; + if (!strcmp(type+2, "GLL")) + return MINMEA_SENTENCE_GLL; return MINMEA_UNKNOWN; } @@ -385,6 +387,30 @@ bool minmea_parse_gsa(struct minmea_sentence_gsa *frame, const char *sentence) return true; } +bool minmea_parse_gll(struct minmea_sentence_gll *frame, const char *sentence) +{ + // $GPGLL,3723.2475,N,12158.3416,W,161229.487,A,A*41$; + char type[6]; + int latitude_direction; + int longitude_direction; + + if (!minmea_scan(sentence, "tfdfdTcc", + type, + &frame->latitude, &frame->latitude_scale, &latitude_direction, + &frame->longitude, &frame->longitude_scale, &longitude_direction, + &frame->time, + &frame->status, + &frame->mode)) + return false; + if (strcmp(type+2, "GLL")) + return false; + + frame->latitude *= latitude_direction; + frame->longitude *= longitude_direction; + + 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) diff --git a/minmea.h b/minmea.h index 1caa0b3..173bf7e 100644 --- a/minmea.h +++ b/minmea.h @@ -29,6 +29,7 @@ enum minmea_sentence_id { MINMEA_SENTENCE_RMC, MINMEA_SENTENCE_GGA, MINMEA_SENTENCE_GSA, + MINMEA_SENTENCE_GLL }; struct minmea_date { @@ -67,6 +68,24 @@ struct minmea_sentence_gga { int dgps_age; }; +enum minmea_gll_status { + MINMEA_GLL_STATUS_DATA_VALID = 'A', + MINMEA_GLL_STATUS_DATA_NOT_VALID = 'V' +}; + +enum minmea_gll_mode { + MINMEA_GLL_MODE_AUTONOMOUS = 'A', + MINMEA_GLL_MODE_DPGS = 'D', + MINMEA_GLL_MODE_DR = 'E' +}; + +struct minmea_sentence_gll { + int latitude, latitude_scale; + int longitude, longitude_scale; + struct minmea_time time; + char status; + char mode; +}; enum minmea_gsa_mode { MINMEA_GPGSA_MODE_AUTO = 'A', MINMEA_GPGSA_MODE_FORCED = 'M', @@ -121,6 +140,7 @@ bool minmea_scan(const char *sentence, const char *format, ...); bool minmea_parse_rmc(struct minmea_sentence_rmc *frame, const char *sentence); bool minmea_parse_gga(struct minmea_sentence_gga *frame, const char *sentence); bool minmea_parse_gsa(struct minmea_sentence_gsa *frame, const char *sentence); +bool minmea_parse_gll(struct minmea_sentence_gll *frame, const char *sentence); /** * Convert GPS UTC date/time representation to a UNIX timestamp. diff --git a/tests.c b/tests.c index c45bde3..605cad9 100644 --- a/tests.c +++ b/tests.c @@ -377,12 +377,36 @@ START_TEST(test_minmea_parse_gsa1) } END_TEST +START_TEST(test_minmea_parse_gpgll) +{ + const char *sentence = "$GPGLL,3723.2475,N,12158.3416,W,161229.487,A,A*41"; + struct minmea_sentence_gll frame = {}; + struct minmea_sentence_gll expected = {}; + + expected.latitude = 37232475; + expected.latitude_scale = 10000; + expected.longitude = -121583416; + expected.longitude_scale = 10000; + expected.time.hours = 16; + expected.time.minutes = 12; + expected.time.seconds = 29; + expected.time.microseconds = 487000; + expected.status = MINMEA_GLL_STATUS_DATA_VALID; + expected.mode = MINMEA_GLL_MODE_AUTONOMOUS; + + ck_assert(minmea_check(sentence) == true); + ck_assert(minmea_parse_gll(&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", "$GNGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1", + "$GPGLL,3723.2475,N,12158.3416,W,161229.487,A,A*41", NULL, }; @@ -403,6 +427,11 @@ START_TEST(test_minmea_usage1) ck_assert(minmea_parse_gsa(&frame, *sentence) == true); } break; + case MINMEA_SENTENCE_GLL: { + struct minmea_sentence_gll frame; + ck_assert(minmea_parse_gll(&frame, *sentence) == true); + } break; + default: { } break; @@ -495,6 +524,7 @@ Suite *minmea_suite(void) tcase_add_test(tc_parse, test_minmea_parse_rmc2); tcase_add_test(tc_parse, test_minmea_parse_gga1); tcase_add_test(tc_parse, test_minmea_parse_gsa1); + tcase_add_test(tc_parse, test_minmea_parse_gpgll); suite_add_tcase(s, tc_parse); TCase *tc_usage = tcase_create("minmea_usage");