mirror of
https://github.com/adafruit/Adafruit_GPS.git
synced 2026-10-27 06:20:18 +00:00
Merge pull request #167 from ladyada-eagleclaw/fix-checksum-validation
Validate NMEA checksum digits and line ending
This commit is contained in:
2 files changed
+50
-2
No files matched your search
@@ -0,0 +1,38 @@
|
||||
#include <Adafruit_GPS.h>
|
||||
|
||||
Adafruit_GPS GPS;
|
||||
bool testsPassed = false;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
// Wait briefly for the Serial Monitor on native USB boards.
|
||||
while (!Serial && millis() < 5000) {
|
||||
delay(10);
|
||||
}
|
||||
delay(250);
|
||||
Serial.println("Adafruit GPS checksum regression");
|
||||
|
||||
char good[] = "$GPGGA,120009,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*40";
|
||||
if (!GPS.parse(good)) {
|
||||
Serial.println("FAIL: valid checksum was rejected");
|
||||
return;
|
||||
}
|
||||
Serial.println("PASS: valid checksum was accepted");
|
||||
|
||||
char bad[] = "$GPGGA,120009,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*4Z";
|
||||
if (GPS.parse(bad)) {
|
||||
Serial.println("FAIL: invalid checksum character was accepted");
|
||||
return;
|
||||
}
|
||||
Serial.println("PASS: invalid checksum character was rejected");
|
||||
testsPassed = true;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (testsPassed) {
|
||||
Serial.println("PASS: checksum regression");
|
||||
} else {
|
||||
Serial.println("FAIL: checksum regression");
|
||||
}
|
||||
delay(2000);
|
||||
}
|
||||
+12
-2
@@ -21,6 +21,7 @@
|
||||
/**************************************************************************/
|
||||
|
||||
#include <Adafruit_GPS.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@@ -575,8 +576,17 @@ bool Adafruit_GPS::check(char *nmea) {
|
||||
if (*ast != '*')
|
||||
return false; // there is no asterisk
|
||||
else {
|
||||
uint16_t sum = parseHex(*(ast + 1)) * 16; // extract checksum
|
||||
sum += parseHex(*(ast + 2));
|
||||
if (!isxdigit((unsigned char)ast[1]) || !isxdigit((unsigned char)ast[2]))
|
||||
return false; // checksum must contain two hexadecimal digits
|
||||
char *end = ast + 3;
|
||||
if (*end == '\r')
|
||||
end++;
|
||||
if (*end == '\n')
|
||||
end++;
|
||||
if (*end != '\0')
|
||||
return false; // only a line ending may follow the checksum
|
||||
uint16_t sum = parseHex(toupper((unsigned char)ast[1])) * 16;
|
||||
sum += parseHex(toupper((unsigned char)ast[2]));
|
||||
char *p = nmea; // check checksum
|
||||
for (char *p1 = p + 1; p1 < ast; p1++)
|
||||
sum ^= *p1;
|
||||
|
||||
Reference in new issue
Block a user