|
|
@@ -73,6 +73,9 @@ static struct {
|
|
|
unsigned char gga_ok : 1;
|
|
|
unsigned char gsa_ok : 1;
|
|
|
unsigned char logged : 1;
|
|
|
+ unsigned char quality_rejected : 1; /* REJECT_REASON_QUALITY already
|
|
|
+ counted this epoch - RMC status=V and GGA quality=0 both fire on the
|
|
|
+ same no-fix epoch, and would otherwise double-count one rejection */
|
|
|
} epoch;
|
|
|
|
|
|
#define FIELD_BUF_LEN 32
|
|
|
@@ -168,6 +171,7 @@ static time_t gp_rmc_parse(const char *str) {
|
|
|
epoch.gga_ok = 0;
|
|
|
epoch.gsa_ok = 0;
|
|
|
epoch.logged = 0;
|
|
|
+ epoch.quality_rejected = 0;
|
|
|
|
|
|
p = gp_col(str, 1); /* Get h:m:s */
|
|
|
if (!p)
|
|
|
@@ -191,6 +195,10 @@ static time_t gp_rmc_parse(const char *str) {
|
|
|
if (!p || *p != 'A') {
|
|
|
System.location_valid = LOC_INVALID;
|
|
|
FLAGS &= ~F_GPSOK;
|
|
|
+ if (!epoch.quality_rejected) {
|
|
|
+ epoch.quality_rejected = 1;
|
|
|
+ log_reject(REJECT_REASON_QUALITY);
|
|
|
+ }
|
|
|
return 0; /* Return 0 even is time is valid (comes from module's internal RTC) */
|
|
|
}
|
|
|
|
|
|
@@ -250,6 +258,10 @@ static void gp_gga_parse(const char *str) {
|
|
|
return;
|
|
|
if (*p == '0') {
|
|
|
System.location_valid = LOC_INVALID;
|
|
|
+ if (!epoch.quality_rejected) {
|
|
|
+ epoch.quality_rejected = 1;
|
|
|
+ log_reject(REJECT_REASON_QUALITY);
|
|
|
+ }
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
@@ -265,12 +277,21 @@ static void gp_gga_parse(const char *str) {
|
|
|
* System.fix_type is set by GSA, parsed after GGA within the epoch, so
|
|
|
* it's last epoch's value here - same staleness as HDOP above, but a
|
|
|
* bad 2D fix reliably spans several consecutive epochs, so a one-epoch
|
|
|
- * lag isn't a practical gap here (unlike a true point fix). */
|
|
|
+ * lag isn't a practical gap here (unlike a true point fix).
|
|
|
+ * log_reject() logs System.hdop_x100 (GSA's, same one-epoch-stale value
|
|
|
+ * checked above), not this epoch's GGA hdop_x100 just computed here -
|
|
|
+ * close enough for the coalesced diagnostic line, and keeps every
|
|
|
+ * REJECT_REASON logging the same field, sourced the same way. */
|
|
|
if (!System.sat_count_low && hdop_x100 <= FIX_QUALITY_HDOP_MAX_X100
|
|
|
- && System.fix_type == FIX_TYPE_3D)
|
|
|
+ && System.fix_type == FIX_TYPE_3D) {
|
|
|
System.location_valid = LOC_VALID_NEW;
|
|
|
- else
|
|
|
+ } else {
|
|
|
System.location_valid = LOC_INVALID;
|
|
|
+ if (!epoch.quality_rejected) {
|
|
|
+ epoch.quality_rejected = 1;
|
|
|
+ log_reject(REJECT_REASON_QUALITY);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
/* parse location */
|
|
|
p = gp_col(str, 2); /* latitude */
|