[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];
while (fgets(line, sizeof(line), stdin) != NULL) {
printf("%s", line);
switch (minmea_sentence_id(line)) {
switch (minmea_sentence_id(line, false)) {
case MINMEA_SENTENCE_RMC: {
struct minmea_sentence_rmc frame;
if (minmea_parse_rmc(&frame, line)) {

View File

@ -26,7 +26,7 @@ static int hex2int(char c)
return -1;
}
bool minmea_check(const char *sentence)
bool minmea_check(const char *sentence, bool strict)
{
uint8_t checksum = 0x00;
@ -42,6 +42,7 @@ bool minmea_check(const char *sentence)
while (*sentence && *sentence != '*' && isprint((unsigned char) *sentence))
checksum ^= *sentence++;
// If checksum is present...
if (*sentence == '*') {
// Extract checksum.
sentence++;
@ -56,6 +57,9 @@ bool minmea_check(const char *sentence)
// Check for checksum mismatch.
if (checksum != expected)
return false;
} else if (strict) {
// Discard non-checksummed frames in strict mode.
return false;
}
// 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;
}
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;
char type[6];

View File

@ -141,7 +141,7 @@ struct minmea_sentence_gsv {
/**
* 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.
@ -151,7 +151,7 @@ bool minmea_talker_id(char talker[3], const char *sentence);
/**
* 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:

60
tests.c
View File

@ -16,8 +16,11 @@
#include "minmea.h"
static const char *valid_sequences[] = {
static const char *valid_sequences_nochecksum[] = {
"$GPTXT,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
};
static const char *valid_sequences_checksum[] = {
"$GPTXT,01,01,02,ANTSTATUS=INIT*25",
"$GPRMC,,V,,,,,,,,,,N*53",
"$GPVTG,,,,,,,,,N*30",
@ -55,11 +58,20 @@ static const char *invalid_sequences[] = {
START_TEST(test_minmea_check)
{
for (const char **sequence=valid_sequences; *sequence; sequence++)
ck_assert_msg(minmea_check(*sequence) == true, *sequence);
for (const char **sequence=valid_sequences_nochecksum; *sequence; 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++)
ck_assert_msg(minmea_check(*sequence) == false, *sequence);
for (const char **sequence=valid_sequences_checksum; *sequence; 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
@ -450,7 +462,8 @@ START_TEST(test_minmea_parse_rmc1)
.date = { 13, 9, 98 },
.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(!memcmp(&frame, &expected, sizeof(frame)));
}
@ -467,7 +480,8 @@ START_TEST(test_minmea_parse_rmc2)
.longitude = { -1450736, 100 },
.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(!memcmp(&frame, &expected, sizeof(frame)));
}
@ -490,7 +504,8 @@ START_TEST(test_minmea_parse_gga1)
.height_units = 'M',
.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(!memcmp(&frame, &expected, sizeof(frame)));
}
@ -510,7 +525,8 @@ START_TEST(test_minmea_parse_gst1)
.longitude_error_deviation = { 56, 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(!memcmp(&frame, &expected, sizeof(frame)));
}
@ -528,7 +544,8 @@ START_TEST(test_minmea_parse_gsa1)
.hdop = { 13, 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(!memcmp(&frame, &expected, sizeof(frame)));
}
@ -546,7 +563,8 @@ START_TEST(test_minmea_parse_gll1)
.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(!memcmp(&frame, &expected, sizeof(frame)));
}
@ -564,7 +582,8 @@ START_TEST(test_minmea_parse_gll2)
.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(!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(!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(!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(!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(!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(!memcmp(&frame, &expected, sizeof(frame)));
}
@ -788,7 +812,7 @@ START_TEST(test_minmea_usage1)
};
for (const char **sentence=sentences; *sentence; sentence++) {
switch (minmea_sentence_id(*sentence)) {
switch (minmea_sentence_id(*sentence, false)) {
case MINMEA_SENTENCE_RMC: {
struct minmea_sentence_rmc frame;
ck_assert(minmea_parse_rmc(&frame, *sentence) == true);