From 7fab5b0cb55276760f9ac73a2281ad30fa5b5f38 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Sat, 13 Sep 2014 12:11:19 +0100 Subject: [PATCH 1/9] Check if bit correction happened before bailing out due to a bad CRC. --- mode_s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mode_s.c b/mode_s.c index 34ddec1..2a746d0 100644 --- a/mode_s.c +++ b/mode_s.c @@ -909,7 +909,7 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) { // If we're checking CRC and the CRC is invalid, then we can't trust any // of the data contents, so save time and give up now. - if ((Modes.check_crc) && (!mm->crcok)) { return;} + if ((Modes.check_crc) && (!mm->crcok) && (!mm->correctedbits)) { return;} // Fields for DF0, DF16 if (mm->msgtype == 0 || mm->msgtype == 16) { From 661246d347d272bca543ded4a4d910aa74dacd56 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Thu, 25 Sep 2014 17:10:55 +0100 Subject: [PATCH 2/9] Prefer to use global CPR decoding where possible. There is a danger in always using relative decoding where possible. If there is an undetected error in the first pair of messages received, then global CPR decoding will give a bad position, and subsequent relative decoding will just walk around near that bad position even though many error-free pairs of odd/even messages may have been received. The first pair of position messages also tends to be the most error-prone, as they are usually received at the extreme edge of receiver range. (I see this happen at least once a day in practice) So, instead, prefer to use global decoding when we have sufficiently recent data. With recent data this should always be as good as relative decoding, and it avoids getting stuck with bad data for long periods of time. If we don't have enough recent data for a global solution, fall back to relative decoding. --- dump1090.h | 2 +- interactive.c | 31 ++++++++++++++++--------------- mode_s.c | 13 +++++++------ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/dump1090.h b/dump1090.h index 77584bb..acfc675 100644 --- a/dump1090.h +++ b/dump1090.h @@ -433,7 +433,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 6d08fc8..4f7e029 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 34ddec1..cccf89b 100644 --- a/mode_s.c +++ b/mode_s.c @@ -2014,11 +2014,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; @@ -2044,7 +2041,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; @@ -2054,7 +2052,8 @@ void decodeCPR(struct aircraft *a, int fflag, int surface) { } // 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. @@ -2080,6 +2079,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; } // //========================================================================= From 10061675dede41ab05f92eed0d60dee1db991c27 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Thu, 25 Sep 2014 20:33:50 +0100 Subject: [PATCH 3/9] Add --stats-every option. Periodically displays and resets stats. Useful for unattended operation. --- dump1090.c | 119 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 87 insertions(+), 32 deletions(-) diff --git a/dump1090.c b/dump1090.c index b3bef28..c129fd4 100644 --- a/dump1090.c +++ b/dump1090.c @@ -428,6 +428,7 @@ void showHelp(void) { "--aggressive More CPU for more messages (two bits fixes, ...)\n" "--mlat display raw messages in Beast ascii mode\n" "--stats With --ifile print stats at exit. No other output\n" +"--stats-every Show and reset stats every seconds\n" "--onlyaddr Show only ICAO addresses (testing purposes)\n" "--metric Use metric units (meters, km/h, ...)\n" "--snip Strip IQ file removing samples < level\n" @@ -480,6 +481,77 @@ void showCopyright(void) { while (llTime >= time(NULL)) {} } #endif + + +static void display_stats(void) { + int j; + time_t now = time(NULL); + + printf("\n\n"); + if (Modes.interactive) + interactiveShowData(); + + printf("Statistics as at %s", ctime(&now)); + + printf("%d ModeA/C detected\n", Modes.stat_ModeAC); + printf("%d valid Mode-S preambles\n", Modes.stat_valid_preamble); + printf("%d DF-?? fields corrected for length\n", Modes.stat_DF_Len_Corrected); + printf("%d DF-?? fields corrected for type\n", Modes.stat_DF_Type_Corrected); + printf("%d demodulated with 0 errors\n", Modes.stat_demodulated0); + printf("%d demodulated with 1 error\n", Modes.stat_demodulated1); + printf("%d demodulated with 2 errors\n", Modes.stat_demodulated2); + printf("%d demodulated with > 2 errors\n", Modes.stat_demodulated3); + printf("%d with good crc\n", Modes.stat_goodcrc); + printf("%d with bad crc\n", Modes.stat_badcrc); + printf("%d errors corrected\n", Modes.stat_fixed); + + Modes.stat_ModeAC = + Modes.stat_valid_preamble = + Modes.stat_DF_Len_Corrected = + Modes.stat_DF_Type_Corrected = + Modes.stat_demodulated0 = + Modes.stat_demodulated1 = + Modes.stat_demodulated2 = + Modes.stat_demodulated3 = + Modes.stat_goodcrc = + Modes.stat_badcrc = + Modes.stat_fixed = 0; + + for (j = 0; j < MODES_MAX_BITERRORS; j++) { + printf(" %d with %d bit %s\n", Modes.stat_bit_fix[j], j+1, (j==0)?"error":"errors"); + Modes.stat_bit_fix[j] = 0; + } + + if (Modes.phase_enhance) { + printf("%d phase enhancement attempts\n", Modes.stat_out_of_phase); + printf("%d phase enhanced demodulated with 0 errors\n", Modes.stat_ph_demodulated0); + printf("%d phase enhanced demodulated with 1 error\n", Modes.stat_ph_demodulated1); + printf("%d phase enhanced demodulated with 2 errors\n", Modes.stat_ph_demodulated2); + printf("%d phase enhanced demodulated with > 2 errors\n", Modes.stat_ph_demodulated3); + printf("%d phase enhanced with good crc\n", Modes.stat_ph_goodcrc); + printf("%d phase enhanced with bad crc\n", Modes.stat_ph_badcrc); + printf("%d phase enhanced errors corrected\n", Modes.stat_ph_fixed); + + Modes.stat_out_of_phase = + Modes.stat_ph_demodulated0 = + Modes.stat_ph_demodulated1 = + Modes.stat_ph_demodulated2 = + Modes.stat_ph_demodulated3 = + Modes.stat_ph_goodcrc = + Modes.stat_ph_badcrc = + Modes.stat_ph_fixed = 0; + + for (j = 0; j < MODES_MAX_BITERRORS; j++) { + printf(" %d with %d bit %s\n", Modes.stat_ph_bit_fix[j], j+1, (j==0)?"error":"errors"); + Modes.stat_ph_bit_fix[j] = 0; + } + } + + printf("%d total usable messages\n", Modes.stat_goodcrc + Modes.stat_ph_goodcrc + Modes.stat_fixed + Modes.stat_ph_fixed); + fflush(stdout); +} + + // //========================================================================= // @@ -488,6 +560,8 @@ void showCopyright(void) { // from the net, refreshing the screen in interactive mode, and so forth // void backgroundTasks(void) { + static time_t next_stats; + if (Modes.net) { modesReadFromClients(); } @@ -501,6 +575,15 @@ void backgroundTasks(void) { if (Modes.interactive) { interactiveShowData(); } + + if (Modes.stats > 0) { + time_t now = time(NULL); + if (now > next_stats) { + if (next_stats != 0) + display_stats(); + next_stats = now + Modes.stats; + } + } } // //========================================================================= @@ -665,7 +748,9 @@ int main(int argc, char **argv) { f++; } } else if (!strcmp(argv[j],"--stats")) { - Modes.stats = 1; + Modes.stats = -1; + } else if (!strcmp(argv[j],"--stats-every") && more) { + Modes.stats = atoi(argv[++j]); } else if (!strcmp(argv[j],"--snip") && more) { snipMode(atoi(argv[++j])); exit(0); @@ -779,37 +864,7 @@ int main(int argc, char **argv) { // If --stats were given, print statistics if (Modes.stats) { - printf("\n\n"); - if (Modes.interactive) - interactiveShowData(); - printf("%d ModeA/C detected\n", Modes.stat_ModeAC); - printf("%d valid Mode-S preambles\n", Modes.stat_valid_preamble); - printf("%d DF-?? fields corrected for length\n", Modes.stat_DF_Len_Corrected); - printf("%d DF-?? fields corrected for type\n", Modes.stat_DF_Type_Corrected); - printf("%d demodulated with 0 errors\n", Modes.stat_demodulated0); - printf("%d demodulated with 1 error\n", Modes.stat_demodulated1); - printf("%d demodulated with 2 errors\n", Modes.stat_demodulated2); - printf("%d demodulated with > 2 errors\n", Modes.stat_demodulated3); - printf("%d with good crc\n", Modes.stat_goodcrc); - printf("%d with bad crc\n", Modes.stat_badcrc); - printf("%d errors corrected\n", Modes.stat_fixed); - for (j = 0; j < MODES_MAX_BITERRORS; j++) { - printf(" %d with %d bit %s\n", Modes.stat_bit_fix[j], j+1, (j==0)?"error":"errors"); - } - if (Modes.phase_enhance) { - printf("%d phase enhancement attempts\n", Modes.stat_out_of_phase); - printf("%d phase enhanced demodulated with 0 errors\n", Modes.stat_ph_demodulated0); - printf("%d phase enhanced demodulated with 1 error\n", Modes.stat_ph_demodulated1); - printf("%d phase enhanced demodulated with 2 errors\n", Modes.stat_ph_demodulated2); - printf("%d phase enhanced demodulated with > 2 errors\n", Modes.stat_ph_demodulated3); - printf("%d phase enhanced with good crc\n", Modes.stat_ph_goodcrc); - printf("%d phase enhanced with bad crc\n", Modes.stat_ph_badcrc); - printf("%d phase enhanced errors corrected\n", Modes.stat_ph_fixed); - for (j = 0; j < MODES_MAX_BITERRORS; j++) { - printf(" %d with %d bit %s\n", Modes.stat_ph_bit_fix[j], j+1, (j==0)?"error":"errors"); - } - } - printf("%d total usable messages\n", Modes.stat_goodcrc + Modes.stat_ph_goodcrc + Modes.stat_fixed + Modes.stat_ph_fixed); + display_stats(); } if (Modes.filename == NULL) { From 4fc26975556b771d36abf5667751a9ba56e5a092 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Thu, 25 Sep 2014 20:35:54 +0100 Subject: [PATCH 4/9] Add stats for number of sample blocks processed and dropped. --- dump1090.c | 7 ++++++- dump1090.h | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/dump1090.c b/dump1090.c index c129fd4..00f21d8 100644 --- a/dump1090.c +++ b/dump1090.c @@ -492,6 +492,10 @@ static void display_stats(void) { interactiveShowData(); printf("Statistics as at %s", ctime(&now)); + printf("%d sample blocks processed\n", Modes.stat_blocks_processed); + printf("%d sample blocks dropped\n", Modes.stat_blocks_dropped); + Modes.stat_blocks_processed = + Modes.stat_blocks_dropped = 0; printf("%d ModeA/C detected\n", Modes.stat_ModeAC); printf("%d valid Mode-S preambles\n", Modes.stat_valid_preamble); @@ -838,6 +842,7 @@ int main(int argc, char **argv) { // If we lost some blocks, correct the timestamp if (Modes.iDataLost) { Modes.timestampBlk += (MODES_ASYNC_BUF_SAMPLES * 6 * Modes.iDataLost); + Modes.stat_blocks_dropped += Modes.iDataLost; Modes.iDataLost = 0; } @@ -852,7 +857,7 @@ int main(int argc, char **argv) { // Update the timestamp ready for the next block Modes.timestampBlk += (MODES_ASYNC_BUF_SAMPLES*6); - + Modes.stat_blocks_processed++; } else { pthread_cond_signal (&Modes.data_cond); pthread_mutex_unlock(&Modes.data_mutex); diff --git a/dump1090.h b/dump1090.h index 77584bb..1339382 100644 --- a/dump1090.h +++ b/dump1090.h @@ -366,6 +366,9 @@ struct { // Internal state unsigned int stat_DF_Len_Corrected; unsigned int stat_DF_Type_Corrected; unsigned int stat_ModeAC; + + unsigned int stat_blocks_processed; + unsigned int stat_blocks_dropped; } Modes; // The struct we use to store information about a decoded message. From b98c6856b3e5baad98ad82fc7f776226e3a0989f Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Thu, 25 Sep 2014 22:02:52 +0100 Subject: [PATCH 5/9] Move the stats reset strictly after stats display, so the total message count is shown correctly. --- dump1090.c | 55 +++++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/dump1090.c b/dump1090.c index 00f21d8..ee4ff40 100644 --- a/dump1090.c +++ b/dump1090.c @@ -492,10 +492,9 @@ static void display_stats(void) { interactiveShowData(); printf("Statistics as at %s", ctime(&now)); + printf("%d sample blocks processed\n", Modes.stat_blocks_processed); printf("%d sample blocks dropped\n", Modes.stat_blocks_dropped); - Modes.stat_blocks_processed = - Modes.stat_blocks_dropped = 0; printf("%d ModeA/C detected\n", Modes.stat_ModeAC); printf("%d valid Mode-S preambles\n", Modes.stat_valid_preamble); @@ -509,21 +508,8 @@ static void display_stats(void) { printf("%d with bad crc\n", Modes.stat_badcrc); printf("%d errors corrected\n", Modes.stat_fixed); - Modes.stat_ModeAC = - Modes.stat_valid_preamble = - Modes.stat_DF_Len_Corrected = - Modes.stat_DF_Type_Corrected = - Modes.stat_demodulated0 = - Modes.stat_demodulated1 = - Modes.stat_demodulated2 = - Modes.stat_demodulated3 = - Modes.stat_goodcrc = - Modes.stat_badcrc = - Modes.stat_fixed = 0; - for (j = 0; j < MODES_MAX_BITERRORS; j++) { printf(" %d with %d bit %s\n", Modes.stat_bit_fix[j], j+1, (j==0)?"error":"errors"); - Modes.stat_bit_fix[j] = 0; } if (Modes.phase_enhance) { @@ -536,23 +522,42 @@ static void display_stats(void) { printf("%d phase enhanced with bad crc\n", Modes.stat_ph_badcrc); printf("%d phase enhanced errors corrected\n", Modes.stat_ph_fixed); - Modes.stat_out_of_phase = - Modes.stat_ph_demodulated0 = - Modes.stat_ph_demodulated1 = - Modes.stat_ph_demodulated2 = - Modes.stat_ph_demodulated3 = - Modes.stat_ph_goodcrc = - Modes.stat_ph_badcrc = - Modes.stat_ph_fixed = 0; - for (j = 0; j < MODES_MAX_BITERRORS; j++) { printf(" %d with %d bit %s\n", Modes.stat_ph_bit_fix[j], j+1, (j==0)?"error":"errors"); - Modes.stat_ph_bit_fix[j] = 0; } } printf("%d total usable messages\n", Modes.stat_goodcrc + Modes.stat_ph_goodcrc + Modes.stat_fixed + Modes.stat_ph_fixed); fflush(stdout); + + Modes.stat_blocks_processed = + Modes.stat_blocks_dropped = 0; + + Modes.stat_ModeAC = + Modes.stat_valid_preamble = + Modes.stat_DF_Len_Corrected = + Modes.stat_DF_Type_Corrected = + Modes.stat_demodulated0 = + Modes.stat_demodulated1 = + Modes.stat_demodulated2 = + Modes.stat_demodulated3 = + Modes.stat_goodcrc = + Modes.stat_badcrc = + Modes.stat_fixed = 0; + + Modes.stat_out_of_phase = + Modes.stat_ph_demodulated0 = + Modes.stat_ph_demodulated1 = + Modes.stat_ph_demodulated2 = + Modes.stat_ph_demodulated3 = + Modes.stat_ph_goodcrc = + Modes.stat_ph_badcrc = + Modes.stat_ph_fixed = 0; + + for (j = 0; j < MODES_MAX_BITERRORS; j++) { + Modes.stat_ph_bit_fix[j] = 0; + Modes.stat_bit_fix[j] = 0; + } } From a513c3677ba72faff5bf32afb56b1f879678fc2f Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Wed, 1 Oct 2014 12:29:16 +0100 Subject: [PATCH 6/9] Detect client EOF properly. Handle EWOULDBLOCK. Client disconnection appears as a read of 0 bytes. Without a test for this, dump1090 continues to poll that client forever. Also, read() may return EWOULDBLOCK as well as EAGAIN for "no data right now", so handle that. I don't know if there is an equivalent Win32 bug here as the Win32 interfaces seem subtly different to vanilla POSIX. The following test/break can probably be removed if Win32 needs the same fix. --- net_io.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net_io.c b/net_io.c index 2b0ed9a..0283394 100644 --- a/net_io.c +++ b/net_io.c @@ -851,11 +851,12 @@ void modesReadFromClient(struct client *c, char *sep, bContinue = 0; } #ifndef _WIN32 - if ( (nread < 0) && (errno != EAGAIN)) { // Error, or end of file + if ( (nread < 0 && errno != EAGAIN && errno != EWOULDBLOCK) || nread == 0 ) { // Error, or end of file #else if ( (nread < 0) && (errno != EWOULDBLOCK)) { // Error, or end of file #endif modesFreeClient(c); + return; } if (nread <= 0) { break; // Serve next client From 186cac5c25075381f7c4f1793983f09131406909 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Wed, 1 Oct 2014 12:37:29 +0100 Subject: [PATCH 7/9] Use the anet-reported error string when reporting bind errors. errno may have been modified by the time you see it. --- net_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net_io.c b/net_io.c index 2b0ed9a..4aa2a54 100644 --- a/net_io.c +++ b/net_io.c @@ -88,7 +88,7 @@ void modesInitNet(void) { int s = anetTcpServer(Modes.aneterr, services[j].port, NULL); if (s == -1) { fprintf(stderr, "Error opening the listening port %d (%s): %s\n", - services[j].port, services[j].descr, strerror(errno)); + services[j].port, services[j].descr, Modes.aneterr); exit(1); } anetNonBlock(Modes.aneterr, s); From 15f3408d8e52cfa82165212b849d996624ba556f Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Thu, 2 Oct 2014 12:20:37 +0100 Subject: [PATCH 8/9] Always emit a message reception time, as otherwise the FR24 uploader is unhappy. When we don't have a time available (e.g. remote message) use the system time. --- net_io.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/net_io.c b/net_io.c index 2b0ed9a..cc0b1a9 100644 --- a/net_io.c +++ b/net_io.c @@ -293,8 +293,8 @@ void modesSendRawOutput(struct modesMessage *mm) { void modesSendSBSOutput(struct modesMessage *mm) { char msg[256], *p = msg; uint32_t offset; - struct timeb epocTime; - struct tm stTime; + struct timeb epocTime_receive, epocTime_now; + struct tm stTime_receive, stTime_now; int msgType; // @@ -336,26 +336,33 @@ void modesSendSBSOutput(struct modesMessage *mm) { // Fields 1 to 6 : SBS message type and ICAO address of the aircraft and some other stuff p += sprintf(p, "MSG,%d,111,11111,%06X,111111,", msgType, mm->addr); - // Fields 7 & 8 are the message reception time and date - if (mm->timestampMsg && !mm->remote) { // Make sure the records' timestamp is valid before outputing it - epocTime = Modes.stSystemTimeBlk; // This is the time of the start of the Block we're processing + // Find current system time + ftime(&epocTime_now); // get the current system time & date + stTime_now = *localtime(&epocTime_now.time); + + // Find message reception time + if (mm->timestampMsg && !mm->remote) { // Make sure the records' timestamp is valid before using it + epocTime_receive = Modes.stSystemTimeBlk; // This is the time of the start of the Block we're processing offset = (int) (mm->timestampMsg - Modes.timestampBlk); // This is the time (in 12Mhz ticks) into the Block offset = offset / 12000; // convert to milliseconds - epocTime.millitm += offset; // add on the offset time to the Block start time - if (epocTime.millitm > 999) // if we've caused an overflow into the next second... - {epocTime.millitm -= 1000; epocTime.time ++;} // ..correct the overflow - stTime = *localtime(&epocTime.time); // convert the time to year, month day, hours, min, sec - p += sprintf(p, "%04d/%02d/%02d,", (stTime.tm_year+1900),(stTime.tm_mon+1), stTime.tm_mday); - p += sprintf(p, "%02d:%02d:%02d.%03d,", stTime.tm_hour, stTime.tm_min, stTime.tm_sec, epocTime.millitm); + epocTime_receive.millitm += offset; // add on the offset time to the Block start time + if (epocTime_receive.millitm > 999) { // if we've caused an overflow into the next second... + epocTime_receive.millitm -= 1000; + epocTime_receive.time ++; // ..correct the overflow + } + stTime_receive = *localtime(&epocTime_receive.time); } else { - p += sprintf(p, ",,"); - } + epocTime_receive = epocTime_now; // We don't have a usable reception time; use the current system time + stTime_receive = stTime_now; + } + + // Fields 7 & 8 are the message reception time and date + p += sprintf(p, "%04d/%02d/%02d,", (stTime_receive.tm_year+1900),(stTime_receive.tm_mon+1), stTime_receive.tm_mday); + p += sprintf(p, "%02d:%02d:%02d.%03d,", stTime_receive.tm_hour, stTime_receive.tm_min, stTime_receive.tm_sec, epocTime_receive.millitm); // Fields 9 & 10 are the current time and date - ftime(&epocTime); // get the current system time & date - stTime = *localtime(&epocTime.time); // convert the time to year, month day, hours, min, sec - p += sprintf(p, "%04d/%02d/%02d,", (stTime.tm_year+1900),(stTime.tm_mon+1), stTime.tm_mday); - p += sprintf(p, "%02d:%02d:%02d.%03d", stTime.tm_hour, stTime.tm_min, stTime.tm_sec, epocTime.millitm); + p += sprintf(p, "%04d/%02d/%02d,", (stTime_now.tm_year+1900),(stTime_now.tm_mon+1), stTime_now.tm_mday); + p += sprintf(p, "%02d:%02d:%02d.%03d", stTime_now.tm_hour, stTime_now.tm_min, stTime_now.tm_sec, epocTime_now.millitm); // Field 11 is the callsign (if we have it) if (mm->bFlags & MODES_ACFLAGS_CALLSIGN_VALID) {p += sprintf(p, ",%s", mm->flight);} From 4f449a8d44b41823a463550db90d10e897ce3257 Mon Sep 17 00:00:00 2001 From: Malcolm Robb Date: Thu, 2 Oct 2014 21:08:57 +0100 Subject: [PATCH 9/9] Make Pull # compatible with Pull #42 --- mode_s.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mode_s.c b/mode_s.c index 4d470bd..03aa58f 100644 --- a/mode_s.c +++ b/mode_s.c @@ -2052,7 +2052,8 @@ int decodeCPR(struct aircraft *a, int fflag, int surface) { } // Check to see that the latitude is in range: -90 .. +90 - if (rlat0 < -90 || rlat0 > 90 || rlat1 < -90 || rlat1 > 90) return; + if (rlat0 < -90 || rlat0 > 90 || rlat1 < -90 || rlat1 > 90) + return (-1); // Check that both are in the same latitude zone, or abort. if (cprNLFunction(rlat0) != cprNLFunction(rlat1))