Skip to content
This repository was archived by the owner on Jan 28, 2021. It is now read-only.

Commit 4cc1afa

Browse files
committed
Better packet validity checking
1 parent 48105d3 commit 4cc1afa

File tree

2 files changed

+78
-52
lines changed

2 files changed

+78
-52
lines changed

src/SparkFun_Ublox_Arduino_Library.cpp

Lines changed: 67 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -467,13 +467,13 @@ void SFE_UBLOX_GPS::process(uint8_t incoming)
467467
if (incoming == UBX_CLASS_ACK)
468468
{
469469
packetAck.counter = 0;
470-
packetAck.valid = false;
470+
packetAck.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED;
471471
ubxFrameClass = CLASS_ACK;
472472
}
473473
else
474474
{
475475
packetCfg.counter = 0;
476-
packetCfg.valid = false;
476+
packetCfg.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED;
477477
ubxFrameClass = CLASS_NOT_AN_ACK;
478478
}
479479
}
@@ -568,7 +568,7 @@ void SFE_UBLOX_GPS::processRTCM(uint8_t incoming)
568568
}
569569

570570
//Given a character, file it away into the uxb packet structure
571-
//Set valid = true once sentence is completely received and passes CRC
571+
//Set valid to VALID or NOT_VALID once sentence is completely received and passes or fails CRC
572572
//The payload portion of the packet can be 100s of bytes but the max array
573573
//size is roughly 64 bytes. startingSpot can be set so we only record
574574
//a subset of bytes within a larger packet.
@@ -608,7 +608,7 @@ void SFE_UBLOX_GPS::processUBX(uint8_t incoming, ubxPacket *incomingUBX)
608608
//Validate this sentence
609609
if (incomingUBX->checksumA == rollingChecksumA && incomingUBX->checksumB == rollingChecksumB)
610610
{
611-
incomingUBX->valid = true;
611+
incomingUBX->valid = SFE_UBLOX_PACKET_VALIDITY_VALID;
612612

613613
if (_printDebug == true)
614614
{
@@ -617,14 +617,14 @@ void SFE_UBLOX_GPS::processUBX(uint8_t incoming, ubxPacket *incomingUBX)
617617
_debugSerial->print(F(" Received: "));
618618
printPacket(incomingUBX);
619619

620-
if (packetCfg.valid == true)
620+
if (packetCfg.valid == SFE_UBLOX_PACKET_VALIDITY_VALID)
621621
{
622622
if (_printDebug == true)
623623
{
624624
_debugSerial->println(F("packetCfg now valid"));
625625
}
626626
}
627-
if (packetAck.valid == true)
627+
if (packetAck.valid == SFE_UBLOX_PACKET_VALIDITY_VALID)
628628
{
629629
if (_printDebug == true)
630630
{
@@ -635,8 +635,10 @@ void SFE_UBLOX_GPS::processUBX(uint8_t incoming, ubxPacket *incomingUBX)
635635

636636
processUBXpacket(incomingUBX); //We've got a valid packet, now do something with it
637637
}
638-
else
638+
else // Checksum failure
639639
{
640+
incomingUBX->valid = SFE_UBLOX_PACKET_VALIDITY_NOT_VALID;
641+
640642
if (_printDebug == true)
641643
{
642644
//Drive an external pin to allow for easier logic analyzation
@@ -1062,18 +1064,30 @@ void SFE_UBLOX_GPS::printPacket(ubxPacket *packet)
10621064
//"not acknowledge"(UBX-ACK-NAK) message back to the sender, depending on whether or not the message was processed correctly.
10631065
//Some messages from other classes also use the same acknowledgement mechanism.
10641066

1065-
//If the packetCfg len is 1, then we are querying the device for data
1066-
//If the packetCfg len is >1, then we are sending a new setting
1067+
//When we poll or get a setting, we will receive _both_ a config packet and an ACK
1068+
//If the poll or get request is not valid, we will receive _only_ a NACK
1069+
1070+
//If we are trying to get or poll a setting, then packetCfg.len will be 0 or 1 when the packetCfg is _sent_.
1071+
//If we poll the setting for a particular port using UBX-CFG-PRT then .len will be 1 initially
1072+
//For all other gets or polls, .len will be 0 initially
1073+
//(It would be possible for .len to be 2 _if_ we were using UBX-CFG-MSG to poll the settings for a particular message - but we don't use that (currently))
1074+
1075+
//If the get or poll _fails_, i.e. is NACK'd, then packetCfg.len could still be 0 or 1 after the NACK is received
1076+
//But if the get or poll is ACK'd, then packetCfg.len will have been updated by the incoming data and will always be at least 2
1077+
1078+
//If we are going to set the value for a setting, then packetCfg.len will be at least 3 when the packetCfg is _sent_.
1079+
//(UBX-CFG-MSG appears to have the shortest set length of 3 bytes)
10671080

1068-
//Returns true if we got the following:
1069-
//* If packetCfg len is 1 and we got and ACK and a valid packetCfg (module is responding with register content)
1070-
//* If packetCfg len is >1 and we got an ACK (no valid packetCfg needed, module absorbs new register data)
1071-
//Returns false if we timed out, got a NACK (command unknown), or had a CLS/ID mismatch
1081+
//Returns SFE_UBLOX_STATUS_DATA_RECEIVED if we got an ACK and a valid packetCfg (module is responding with register content)
1082+
//Returns SFE_UBLOX_STATUS_DATA_SENT if we got an ACK and no packetCfg (no valid packetCfg needed, module absorbs new register data)
1083+
//Returns SFE_UBLOX_STATUS_FAIL if we got an invalid packetCfg (checksum failure)
1084+
//Returns SFE_UBLOX_STATUS_COMMAND_UNKNOWN if we got a NACK (command unknown)
1085+
//Returns SFE_UBLOX_STATUS_TIMEOUT if we timed out
10721086
sfe_ublox_status_e SFE_UBLOX_GPS::waitForACKResponse(uint8_t requestedClass, uint8_t requestedID, uint16_t maxTime)
10731087
{
10741088
commandAck = UBX_ACK_NONE; //Reset flag
1075-
packetCfg.valid = false; //This will go true when we receive a response to the packet we sent
1076-
packetAck.valid = false;
1089+
packetCfg.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; //This will go VALID (or NOT_VALID) when we receive a response to the packet we sent
1090+
packetAck.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED;
10771091

10781092
unsigned long startTime = millis();
10791093
while (millis() - startTime < maxTime)
@@ -1090,42 +1104,43 @@ sfe_ublox_status_e SFE_UBLOX_GPS::waitForACKResponse(uint8_t requestedClass, uin
10901104
_debugSerial->println(F(" msec"));
10911105
}
10921106

1093-
//Are we expecting data back or just an ACK?
1094-
if (packetCfg.len == 1)
1107+
//We've got the a valid ACK for this CLS/ID, so is packetCfg valid?
1108+
if (packetCfg.valid == SFE_UBLOX_PACKET_VALIDITY_VALID)
10951109
{
1096-
//We are expecting a data response so now we verify the response packet was valid
1097-
if (packetCfg.valid == true)
1110+
//We've got a valid packetCfg, so does it match the requested Class and ID?
1111+
if (packetCfg.cls == requestedClass && packetCfg.id == requestedID)
10981112
{
1099-
if (packetCfg.cls == requestedClass && packetCfg.id == requestedID)
1100-
{
1101-
if (_printDebug == true)
1102-
{
1103-
_debugSerial->print(F("waitForACKResponse: CLS/ID match after "));
1104-
_debugSerial->print(millis() - startTime);
1105-
_debugSerial->println(F(" msec"));
1106-
}
1107-
return (SFE_UBLOX_STATUS_DATA_RECEIVED); //Received a data and a correct ACK!
1108-
}
1109-
else
1113+
if (_printDebug == true)
11101114
{
1111-
//Reset packet and continue checking incoming data for matching cls/id
1112-
if (_printDebug == true)
1113-
{
1114-
_debugSerial->println(F("waitForACKResponse: CLS/ID mismatch, continue to wait..."));
1115-
}
1116-
packetCfg.valid = false; //This will go true when we receive a response to the packet we sent
1115+
_debugSerial->print(F("waitForACKResponse: CLS/ID match after "));
1116+
_debugSerial->print(millis() - startTime);
1117+
_debugSerial->println(F(" msec"));
11171118
}
1119+
return (SFE_UBLOX_STATUS_DATA_RECEIVED); //Received a data and a correct ACK!
11181120
}
11191121
else
1122+
// The Class and/or ID don't match the requested ones, so keep trying...
11201123
{
1121-
//We were expecting data but didn't get a valid config packet
1124+
//Reset packet and continue checking incoming data for matching cls/id
11221125
if (_printDebug == true)
11231126
{
1124-
_debugSerial->println(F("waitForACKResponse: Invalid config packet"));
1127+
_debugSerial->println(F("waitForACKResponse: CLS/ID mismatch, continue to wait..."));
11251128
}
1126-
return (SFE_UBLOX_STATUS_FAIL); //We got an ACK, we're never going to get valid config data
1129+
packetCfg.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; //This will go VALID (or NOT_VALID) when we receive a response to the packet we sent
1130+
}
1131+
}
1132+
//If we received an invalid packetCfg (checksum failure) then we can't trust it, including its Class and ID
1133+
else if (packetCfg.valid == SFE_UBLOX_PACKET_VALIDITY_NOT_VALID)
1134+
{
1135+
//We were expecting data but didn't get a valid config packet
1136+
if (_printDebug == true)
1137+
{
1138+
_debugSerial->println(F("waitForACKResponse: Invalid config packet"));
11271139
}
1140+
return (SFE_UBLOX_STATUS_FAIL); //We got a checksum failure, we're never going to get valid config data
11281141
}
1142+
//We didn't receive a valid or invalid packetCfg, so we must have only received the ACK
1143+
//Let's hope this was a set?
11291144
else
11301145
{
11311146
//We have sent new data. We expect an ACK but no return config packet.
@@ -1136,6 +1151,7 @@ sfe_ublox_status_e SFE_UBLOX_GPS::waitForACKResponse(uint8_t requestedClass, uin
11361151
return (SFE_UBLOX_STATUS_DATA_SENT); //New data successfully sent
11371152
}
11381153
}
1154+
//Did we receive a NACK?
11391155
else if (commandAck == UBX_ACK_NACK)
11401156
{
11411157
if (_printDebug == true)
@@ -1153,7 +1169,7 @@ sfe_ublox_status_e SFE_UBLOX_GPS::waitForACKResponse(uint8_t requestedClass, uin
11531169

11541170
//TODO add check here if config went valid but we never got the following ack
11551171
//Through debug warning, This command might not get an ACK
1156-
if (packetCfg.valid == true)
1172+
if (packetCfg.valid == SFE_UBLOX_PACKET_VALIDITY_VALID)
11571173
{
11581174
if (_printDebug == true)
11591175
{
@@ -1172,12 +1188,13 @@ sfe_ublox_status_e SFE_UBLOX_GPS::waitForACKResponse(uint8_t requestedClass, uin
11721188
}
11731189

11741190
//For non-CFG queries no ACK is sent so we use this function
1175-
//Returns true if we got a config packet full of response data that has CLS/ID match to our query packet
1176-
//Returns false if we timed out
1191+
//Returns SFE_UBLOX_STATUS_DATA_RECEIVED if we got a config packet full of response data that has CLS/ID match to our query packet
1192+
//Returns SFE_UBLOX_STATUS_CRC_FAIL if we got a corrupt config packet that has CLS/ID match to our query packet
1193+
//Returns SFE_UBLOX_STATUS_TIMEOUT if we timed out
11771194
sfe_ublox_status_e SFE_UBLOX_GPS::waitForNoACKResponse(uint8_t requestedClass, uint8_t requestedID, uint16_t maxTime)
11781195
{
1179-
packetCfg.valid = false; //This will go true when we receive a response to the packet we sent
1180-
packetAck.valid = false;
1196+
packetCfg.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; //This will go VALID (or NOT_VALID) when we receive a response to the packet we sent
1197+
packetAck.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED;
11811198
packetCfg.cls = 255;
11821199
packetCfg.id = 255;
11831200

@@ -1187,10 +1204,10 @@ sfe_ublox_status_e SFE_UBLOX_GPS::waitForNoACKResponse(uint8_t requestedClass, u
11871204
if (checkUblox() == true) //See if new data is available. Process bytes as they come in.
11881205
{
11891206
//Did we receive a config packet that matches the cls/id we requested?
1190-
if (packetCfg.cls == requestedClass && packetCfg.id == requestedID)
1207+
if ((packetCfg.cls == requestedClass) && (packetCfg.id == requestedID) && (packetCfg.valid != SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED))
11911208
{
11921209
//This packet might be good or it might be CRC corrupt
1193-
if (packetCfg.valid == true)
1210+
if (packetCfg.valid == SFE_UBLOX_PACKET_VALIDITY_VALID)
11941211
{
11951212
if (_printDebug == true)
11961213
{
@@ -1200,7 +1217,7 @@ sfe_ublox_status_e SFE_UBLOX_GPS::waitForNoACKResponse(uint8_t requestedClass, u
12001217
}
12011218
return (SFE_UBLOX_STATUS_DATA_RECEIVED); //We have new data to act upon
12021219
}
1203-
else
1220+
else // if (packetCfg.valid == SFE_UBLOX_PACKET_VALIDITY_NOT_VALID)
12041221
{
12051222
if (_printDebug == true)
12061223
{
@@ -1209,8 +1226,9 @@ sfe_ublox_status_e SFE_UBLOX_GPS::waitForNoACKResponse(uint8_t requestedClass, u
12091226
return (SFE_UBLOX_STATUS_CRC_FAIL); //We got the right packet but it was corrupt
12101227
}
12111228
}
1212-
else if (packetCfg.cls < 255 && packetCfg.id < 255)
1229+
else if ((packetCfg.cls < 255) && (packetCfg.id < 255) && (packetCfg.valid != SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED))
12131230
{
1231+
//We got a valid or invalid packet but it was not the droid we were looking for
12141232
//Reset packet and continue checking incoming data for matching cls/id
12151233
if (_printDebug == true)
12161234
{
@@ -1222,7 +1240,7 @@ sfe_ublox_status_e SFE_UBLOX_GPS::waitForNoACKResponse(uint8_t requestedClass, u
12221240
_debugSerial->println();
12231241
}
12241242

1225-
packetCfg.valid = false; //This will go true when we receive a response to the packet we sent
1243+
packetCfg.valid = SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED; //This will go VALID (or NOT_VALID) when we receive a response to the packet we sent
12261244
packetCfg.cls = 255;
12271245
packetCfg.id = 255;
12281246
}

src/SparkFun_Ublox_Arduino_Library.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,14 @@ typedef enum
104104
SFE_UBLOX_STATUS_I2C_COMM_FAILURE,
105105
} sfe_ublox_status_e;
106106

107+
// ubxPacket validity
108+
typedef enum
109+
{
110+
SFE_UBLOX_PACKET_VALIDITY_NOT_VALID,
111+
SFE_UBLOX_PACKET_VALIDITY_VALID,
112+
SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED
113+
} sfe_ublox_packet_validity_e;
114+
107115
//Registers
108116
const uint8_t UBX_SYNCH_1 = 0xB5;
109117
const uint8_t UBX_SYNCH_2 = 0x62;
@@ -400,7 +408,7 @@ typedef struct
400408
uint8_t *payload;
401409
uint8_t checksumA; //Given to us from module. Checked against the rolling calculated A/B checksums.
402410
uint8_t checksumB;
403-
boolean valid; //Goes true when both checksums pass
411+
sfe_ublox_packet_validity_e valid; //Goes from NOT_DEFINED to VALID or NOT_VALID when checksum is checked
404412
} ubxPacket;
405413

406414
// Struct to hold the results returned by getGeofenceState (returned by UBX-NAV-GEOFENCE)
@@ -702,8 +710,8 @@ class SFE_UBLOX_GPS
702710
uint8_t payloadCfg[MAX_PAYLOAD_SIZE];
703711

704712
//Init the packet structures and init them with pointers to the payloadAck and payloadCfg arrays
705-
ubxPacket packetAck = {0, 0, 0, 0, 0, payloadAck, 0, 0, false};
706-
ubxPacket packetCfg = {0, 0, 0, 0, 0, payloadCfg, 0, 0, false};
713+
ubxPacket packetAck = {0, 0, 0, 0, 0, payloadAck, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};
714+
ubxPacket packetCfg = {0, 0, 0, 0, 0, payloadCfg, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};
707715

708716
//Limit checking of new data to every X ms
709717
//If we are expecting an update every X Hz then we should check every half that amount of time

0 commit comments

Comments
 (0)