[API CHANGE] minmea_check: add "strict" argument

In strict mode, non-checksummed frames are discarded.
This commit is contained in:
Kosma Moczek 2014-09-11 15:19:11 +02:00
parent a6b4f4367d
commit bf0f7d30f9
4 changed files with 52 additions and 24 deletions

View File

@ -19,7 +19,7 @@ int main(void)
char line[MINMEA_MAX_LENGTH]; char line[MINMEA_MAX_LENGTH];
while (fgets(line, sizeof(line), stdin) != NULL) { while (fgets(line, sizeof(line), stdin) != NULL) {
printf("%s", line); printf("%s", line);
switch (minmea_sentence_id(line)) { switch (minmea_sentence_id(line, false)) {
case MINMEA_SENTENCE_RMC: { case MINMEA_SENTENCE_RMC: {
struct minmea_sentence_rmc frame; struct minmea_sentence_rmc frame;
if (minmea_parse_rmc(&frame, line)) { if (minmea_parse_rmc(&frame, line)) {

View File

@ -26,7 +26,7 @@ static int hex2int(char c)
return -1; return -1;
} }
bool minmea_check(const char *sentence) bool minmea_check(const char *sentence, bool strict)
{ {
uint8_t checksum = 0x00; uint8_t checksum = 0x00;
@ -42,6 +42,7 @@ bool minmea_check(const char *sentence)
while (*sentence && *sentence != '*' && isprint((unsigned char) *sentence)) while (*sentence && *sentence != '*' && isprint((unsigned char) *sentence))
checksum ^= *sentence++; checksum ^= *sentence++;
// If checksum is present...
if (*sentence == '*') { if (*sentence == '*') {
// Extract checksum. // Extract checksum.
sentence++; sentence++;
@ -56,6 +57,9 @@ bool minmea_check(const char *sentence)
// Check for checksum mismatch. // Check for checksum mismatch.
if (checksum != expected) if (checksum != expected)
return false; return false;
} else if (strict) {
// Discard non-checksummed frames in strict mode.
return false;
} }
// The only stuff allowed at this point is a newline. // The only stuff allowed at this point is a newline.
@ -323,9 +327,9 @@ bool minmea_talker_id(char talker[3], const char *sentence)
return true; return true;
} }
enum minmea_sentence_id minmea_sentence_id(const char *sentence) enum minmea_sentence_id minmea_sentence_id(const char *sentence, bool strict)
{ {
if (!minmea_check(sentence)) if (!minmea_check(sentence, strict))
return MINMEA_INVALID; return MINMEA_INVALID;
char type[6]; char type[6];

View File

@ -141,7 +141,7 @@ struct minmea_sentence_gsv {
/** /**
* Check sentence validity and checksum. Returns true for valid sentences. * Check sentence validity and checksum. Returns true for valid sentences.
*/ */
bool minmea_check(const char *sentence); bool minmea_check(const char *sentence, bool strict);
/** /**
* Determine talker identifier. * Determine talker identifier.
@ -151,7 +151,7 @@ bool minmea_talker_id(char talker[3], const char *sentence);
/** /**
* Determine sentence identifier. * Determine sentence identifier.
*/ */
enum minmea_sentence_id minmea_sentence_id(const char *sentence); enum minmea_sentence_id minmea_sentence_id(const char *sentence, bool strict);
/** /**
* Scanf-like processor for NMEA sentences. Supports the following formats: * Scanf-like processor for NMEA sentences. Supports the following formats:

60
tests.c
View File

@ -16,8 +16,11 @@
#include "minmea.h" #include "minmea.h"
static const char *valid_sequences[] = { static const char *valid_sequences_nochecksum[] = {
"$GPTXT,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "$GPTXT,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
};
static const char *valid_sequences_checksum[] = {
"$GPTXT,01,01,02,ANTSTATUS=INIT*25", "$GPTXT,01,01,02,ANTSTATUS=INIT*25",
"$GPRMC,,V,,,,,,,,,,N*53", "$GPRMC,,V,,,,,,,,,,N*53",
"$GPVTG,,,,,,,,,N*30", "$GPVTG,,,,,,,,,N*30",
@ -55,11 +58,20 @@ static const char *invalid_sequences[] = {
START_TEST(test_minmea_check) START_TEST(test_minmea_check)
{ {
for (const char **sequence=valid_sequences; *sequence; sequence++) for (const char **sequence=valid_sequences_nochecksum; *sequence; sequence++) {
ck_assert_msg(minmea_check(*sequence) == true, *sequence); ck_assert_msg(minmea_check(*sequence, false) == true, *sequence);
ck_assert_msg(minmea_check(*sequence, true) == false, *sequence);
}
for (const char **sequence=invalid_sequences; *sequence; sequence++) for (const char **sequence=valid_sequences_checksum; *sequence; sequence++) {
ck_assert_msg(minmea_check(*sequence) == false, *sequence); ck_assert_msg(minmea_check(*sequence, false) == true, *sequence);
ck_assert_msg(minmea_check(*sequence, true) == true, *sequence);
}
for (const char **sequence=invalid_sequences; *sequence; sequence++) {
ck_assert_msg(minmea_check(*sequence, false) == false, *sequence);
ck_assert_msg(minmea_check(*sequence, true) == false, *sequence);
}
} }
END_TEST END_TEST
@ -450,7 +462,8 @@ START_TEST(test_minmea_parse_rmc1)
.date = { 13, 9, 98 }, .date = { 13, 9, 98 },
.variation = { 113, 10 }, .variation = { 113, 10 },
}; };
ck_assert(minmea_check(sentence) == true); ck_assert(minmea_check(sentence, false) == true);
ck_assert(minmea_check(sentence, true) == false);
ck_assert(minmea_parse_rmc(&frame, sentence) == true); ck_assert(minmea_parse_rmc(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame))); ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
} }
@ -467,7 +480,8 @@ START_TEST(test_minmea_parse_rmc2)
.longitude = { -1450736, 100 }, .longitude = { -1450736, 100 },
.date = { -1, -1, -1 }, .date = { -1, -1, -1 },
}; };
ck_assert(minmea_check(sentence) == true); ck_assert(minmea_check(sentence, false) == true);
ck_assert(minmea_check(sentence, true) == false);
ck_assert(minmea_parse_rmc(&frame, sentence) == true); ck_assert(minmea_parse_rmc(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame))); ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
} }
@ -490,7 +504,8 @@ START_TEST(test_minmea_parse_gga1)
.height_units = 'M', .height_units = 'M',
.dgps_age = 0, .dgps_age = 0,
}; };
ck_assert(minmea_check(sentence) == true); ck_assert(minmea_check(sentence, false) == true);
ck_assert(minmea_check(sentence, true) == true);
ck_assert(minmea_parse_gga(&frame, sentence) == true); ck_assert(minmea_parse_gga(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame))); ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
} }
@ -510,7 +525,8 @@ START_TEST(test_minmea_parse_gst1)
.longitude_error_deviation = { 56, 10 }, .longitude_error_deviation = { 56, 10 },
.altitude_error_deviation = { 220, 10 }, .altitude_error_deviation = { 220, 10 },
}; };
ck_assert(minmea_check(sentence) == true); ck_assert(minmea_check(sentence, false) == true);
ck_assert(minmea_check(sentence, true) == true);
ck_assert(minmea_parse_gst(&frame, sentence) == true); ck_assert(minmea_parse_gst(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame))); ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
} }
@ -528,7 +544,8 @@ START_TEST(test_minmea_parse_gsa1)
.hdop = { 13, 10 }, .hdop = { 13, 10 },
.vdop = { 21, 10 }, .vdop = { 21, 10 },
}; };
ck_assert(minmea_check(sentence) == true); ck_assert(minmea_check(sentence, false) == true);
ck_assert(minmea_check(sentence, true) == true);
ck_assert(minmea_parse_gsa(&frame, sentence) == true); ck_assert(minmea_parse_gsa(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame))); ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
} }
@ -546,7 +563,8 @@ START_TEST(test_minmea_parse_gll1)
.mode = MINMEA_GLL_MODE_AUTONOMOUS, .mode = MINMEA_GLL_MODE_AUTONOMOUS,
}; };
ck_assert(minmea_check(sentence) == true); ck_assert(minmea_check(sentence, false) == true);
ck_assert(minmea_check(sentence, true) == true);
ck_assert(minmea_parse_gll(&frame, sentence) == true); ck_assert(minmea_parse_gll(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame))); ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
} }
@ -564,7 +582,8 @@ START_TEST(test_minmea_parse_gll2)
.mode = 0, .mode = 0,
}; };
ck_assert(minmea_check(sentence) == true); ck_assert(minmea_check(sentence, false) == true);
ck_assert(minmea_check(sentence, true) == false);
ck_assert(minmea_parse_gll(&frame, sentence) == true); ck_assert(minmea_parse_gll(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame))); ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
} }
@ -605,7 +624,8 @@ START_TEST(test_minmea_parse_gsv1)
} }
} }
}; };
ck_assert(minmea_check(sentence) == true); ck_assert(minmea_check(sentence, false) == true);
ck_assert(minmea_check(sentence, true) == true);
ck_assert(minmea_parse_gsv(&frame, sentence) == true); ck_assert(minmea_parse_gsv(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame))); ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
} }
@ -646,7 +666,8 @@ START_TEST(test_minmea_parse_gsv2)
} }
} }
}; };
ck_assert(minmea_check(sentence) == true); ck_assert(minmea_check(sentence, false) == true);
ck_assert(minmea_check(sentence, true) == true);
ck_assert(minmea_parse_gsv(&frame, sentence) == true); ck_assert(minmea_parse_gsv(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame))); ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
} }
@ -687,7 +708,8 @@ START_TEST(test_minmea_parse_gsv3)
} }
} }
}; };
ck_assert(minmea_check(sentence) == true); ck_assert(minmea_check(sentence, false) == true);
ck_assert(minmea_check(sentence, true) == true);
ck_assert(minmea_parse_gsv(&frame, sentence) == true); ck_assert(minmea_parse_gsv(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame))); ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
} }
@ -728,7 +750,8 @@ START_TEST(test_minmea_parse_gsv4)
} }
} }
}; };
ck_assert(minmea_check(sentence) == true); ck_assert(minmea_check(sentence, false) == true);
ck_assert(minmea_check(sentence, true) == true);
ck_assert(minmea_parse_gsv(&frame, sentence) == true); ck_assert(minmea_parse_gsv(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame))); ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
} }
@ -769,7 +792,8 @@ START_TEST(test_minmea_parse_gsv5)
} }
} }
}; };
ck_assert(minmea_check(sentence) == true); ck_assert(minmea_check(sentence, false) == true);
ck_assert(minmea_check(sentence, true) == true);
ck_assert(minmea_parse_gsv(&frame, sentence) == true); ck_assert(minmea_parse_gsv(&frame, sentence) == true);
ck_assert(!memcmp(&frame, &expected, sizeof(frame))); ck_assert(!memcmp(&frame, &expected, sizeof(frame)));
} }
@ -788,7 +812,7 @@ START_TEST(test_minmea_usage1)
}; };
for (const char **sentence=sentences; *sentence; sentence++) { for (const char **sentence=sentences; *sentence; sentence++) {
switch (minmea_sentence_id(*sentence)) { switch (minmea_sentence_id(*sentence, false)) {
case MINMEA_SENTENCE_RMC: { case MINMEA_SENTENCE_RMC: {
struct minmea_sentence_rmc frame; struct minmea_sentence_rmc frame;
ck_assert(minmea_parse_rmc(&frame, *sentence) == true); ck_assert(minmea_parse_rmc(&frame, *sentence) == true);