Merge branch 'master' of https://www.github.com/MalcolmRobb/dump1090 into http_server_wk
This commit is contained in:
commit
f71bc6c130
131
dump1090.c
131
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 <seconds> Show and reset stats every <seconds> seconds\n"
|
||||
"--onlyaddr Show only ICAO addresses (testing purposes)\n"
|
||||
"--metric Use metric units (meters, km/h, ...)\n"
|
||||
"--snip <level> Strip IQ file removing samples < level\n"
|
||||
|
@ -480,6 +481,86 @@ 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 sample blocks processed\n", Modes.stat_blocks_processed);
|
||||
printf("%d sample blocks dropped\n", Modes.stat_blocks_dropped);
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//=========================================================================
|
||||
//
|
||||
|
@ -488,6 +569,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 +584,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 +757,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);
|
||||
|
@ -759,6 +853,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;
|
||||
}
|
||||
|
||||
|
@ -773,7 +868,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);
|
||||
|
@ -785,37 +880,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) {
|
||||
|
|
|
@ -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.
|
||||
|
@ -433,7 +436,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 ();
|
||||
//
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
mode_s.c
18
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) {
|
||||
|
@ -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,10 +2052,12 @@ void 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)) return;
|
||||
if (cprNLFunction(rlat0) != cprNLFunction(rlat1))
|
||||
return (-1);
|
||||
|
||||
// Compute ni and the Longitude Index "m"
|
||||
if (fflag) { // Use odd packet.
|
||||
|
@ -2083,6 +2083,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;
|
||||
}
|
||||
//
|
||||
//=========================================================================
|
||||
|
|
46
net_io.c
46
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);
|
||||
|
@ -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);}
|
||||
|
@ -867,11 +874,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
|
||||
|
|
Loading…
Reference in a new issue