diff --git a/dump1090.h b/dump1090.h index dbc3383..fb36a9c 100644 --- a/dump1090.h +++ b/dump1090.h @@ -435,7 +435,7 @@ void decodeModesMessage (struct modesMessage *mm, unsigned char *msg); void displayModesMessage(struct modesMessage *mm); void useModesMessage (struct modesMessage *mm); void computeMagnitudeVector(uint16_t *pData); -void decodeCPR (struct aircraft *a, int fflag, int surface); +int decodeCPR (struct aircraft *a, int fflag, int surface); int decodeCPRrelative (struct aircraft *a, int fflag, int surface); void modesInitErrorInfo (); // diff --git a/interactive.c b/interactive.c index 579144c..95af551 100644 --- a/interactive.c +++ b/interactive.c @@ -343,6 +343,7 @@ struct aircraft *interactiveReceiveData(struct modesMessage *mm) { // If we've got a new cprlat or cprlon if (mm->bFlags & MODES_ACFLAGS_LLEITHER_VALID) { + int location_ok = 0; if (mm->bFlags & MODES_ACFLAGS_LLODD_VALID) { a->odd_cprlat = mm->raw_latitude; @@ -354,23 +355,23 @@ struct aircraft *interactiveReceiveData(struct modesMessage *mm) { a->even_cprtime = mstime(); } - if (((mm->bFlags | a->bFlags) & MODES_ACFLAGS_LLEITHER_VALID) == MODES_ACFLAGS_LLBOTH_VALID) { - // If we now have both even and odd, decode the CPR - - // Try relative CPR first - if (decodeCPRrelative(a, (mm->bFlags & MODES_ACFLAGS_LLODD_VALID), (mm->bFlags & MODES_ACFLAGS_AOG))) { - // If relative CPR fails then try global if the two data are less than 10 seconds apart - if (abs((int)(a->even_cprtime - a->odd_cprtime)) <= 10000) { - decodeCPR(a, (mm->bFlags & MODES_ACFLAGS_LLODD_VALID), (mm->bFlags & MODES_ACFLAGS_AOG)); - } + // If we have enough recent data, try global CPR + if (((mm->bFlags | a->bFlags) & MODES_ACFLAGS_LLEITHER_VALID) == MODES_ACFLAGS_LLBOTH_VALID && abs((int)(a->even_cprtime - a->odd_cprtime)) <= 10000) { + if (decodeCPR(a, (mm->bFlags & MODES_ACFLAGS_LLODD_VALID), (mm->bFlags & MODES_ACFLAGS_AOG)) == 0) { + location_ok = 1; } + } - //If we sucessfully decoded, back copy the results to mm so that we can print them in list output - if (a->bFlags & MODES_ACFLAGS_LATLON_VALID) { - mm->bFlags |= MODES_ACFLAGS_LATLON_VALID; - mm->fLat = a->lat; - mm->fLon = a->lon; - } + // Otherwise try relative CPR. + if (!location_ok && decodeCPRrelative(a, (mm->bFlags & MODES_ACFLAGS_LLODD_VALID), (mm->bFlags & MODES_ACFLAGS_AOG)) == 0) { + location_ok = 1; + } + + //If we sucessfully decoded, back copy the results to mm so that we can print them in list output + if (location_ok) { + mm->bFlags |= MODES_ACFLAGS_LATLON_VALID; + mm->fLat = a->lat; + mm->fLon = a->lon; } } diff --git a/mode_s.c b/mode_s.c index 5c4b26e..25943a5 100644 --- a/mode_s.c +++ b/mode_s.c @@ -2062,11 +2062,8 @@ double cprDlonFunction(double lat, int fflag, int surface) { // // A few remarks: // 1) 131072 is 2^17 since CPR latitude and longitude are encoded in 17 bits. -// 2) We assume that we always received the odd packet as last packet for -// simplicity. This may provide a position that is less fresh of a few -// seconds. // -void decodeCPR(struct aircraft *a, int fflag, int surface) { +int decodeCPR(struct aircraft *a, int fflag, int surface) { double AirDlat0 = (surface ? 90.0 : 360.0) / 60.0; double AirDlat1 = (surface ? 90.0 : 360.0) / 59.0; double lat0 = a->even_cprlat; @@ -2092,7 +2089,8 @@ void decodeCPR(struct aircraft *a, int fflag, int surface) { surface_rlat = Modes.fUserLat; surface_rlon = Modes.fUserLon; } else { - return; + // No local reference, give up + return (-1); } rlat0 += floor(surface_rlat / 90.0) * 90.0; // Move from 1st quadrant to our quadrant rlat1 += floor(surface_rlat / 90.0) * 90.0; @@ -2105,7 +2103,8 @@ void decodeCPR(struct aircraft *a, int fflag, int surface) { if (rlat0 < -90 || rlat0 > 90 || rlat1 < -90 || rlat1 > 90) return; // Check that both are in the same latitude zone, or abort. - if (cprNLFunction(rlat0) != cprNLFunction(rlat1)) return; + if (cprNLFunction(rlat0) != cprNLFunction(rlat1)) + return (-1); // Compute ni and the Longitude Index "m" if (fflag) { // Use odd packet. @@ -2131,6 +2130,8 @@ void decodeCPR(struct aircraft *a, int fflag, int surface) { a->seenLatLon = a->seen; a->timestampLatLon = a->timestamp; a->bFlags |= (MODES_ACFLAGS_LATLON_VALID | MODES_ACFLAGS_LATLON_REL_OK); + + return 0; } // //=========================================================================