Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Karl Lehenbauer 2014-08-16 13:56:56 -05:00
commit f44130ba33
18 changed files with 380 additions and 133 deletions

View File

@ -1 +0,0 @@
dump1090.exe --interactive --net --net-ro-size 500 --net-ro-rate 5

Binary file not shown.

Binary file not shown.

1
anet.c
View File

@ -165,6 +165,7 @@ static int anetTcpGenericConnect(char *err, char *addr, int port, int flags)
if ((s = anetCreateSocket(err,AF_INET)) == ANET_ERR) if ((s = anetCreateSocket(err,AF_INET)) == ANET_ERR)
return ANET_ERR; return ANET_ERR;
memset(&sa,0,sizeof(sa));
sa.sin_family = AF_INET; sa.sin_family = AF_INET;
sa.sin_port = htons((uint16_t)port); sa.sin_port = htons((uint16_t)port);
if (inet_aton(addr, (void*)&sa.sin_addr) == 0) { if (inet_aton(addr, (void*)&sa.sin_addr) == 0) {

Binary file not shown.

View File

@ -1 +0,0 @@
dump1090.exe --interactive --net --net-ro-port 30002 --net-beast --mlat

View File

@ -68,6 +68,7 @@ void modesInitConfig(void) {
// Now initialise things that should not be 0/NULL to their defaults // Now initialise things that should not be 0/NULL to their defaults
Modes.gain = MODES_MAX_GAIN; Modes.gain = MODES_MAX_GAIN;
Modes.freq = MODES_DEFAULT_FREQ; Modes.freq = MODES_DEFAULT_FREQ;
Modes.ppm_error = MODES_DEFAULT_PPM;
Modes.check_crc = 1; Modes.check_crc = 1;
Modes.net_heartbeat_rate = MODES_NET_HEARTBEAT_RATE; Modes.net_heartbeat_rate = MODES_NET_HEARTBEAT_RATE;
Modes.net_output_sbs_port = MODES_NET_OUTPUT_SBS_PORT; Modes.net_output_sbs_port = MODES_NET_OUTPUT_SBS_PORT;
@ -89,6 +90,7 @@ void modesInitConfig(void) {
void modesInit(void) { void modesInit(void) {
int i, q; int i, q;
pthread_mutex_init(&Modes.pDF_mutex,NULL);
pthread_mutex_init(&Modes.data_mutex,NULL); pthread_mutex_init(&Modes.data_mutex,NULL);
pthread_cond_init(&Modes.data_cond,NULL); pthread_cond_init(&Modes.data_cond,NULL);

Binary file not shown.

View File

@ -30,14 +30,14 @@
#ifndef __DUMP1090_H #ifndef __DUMP1090_H
#define __DUMP1090_H #define __DUMP1090_H
// File Version number // File Version number
// ==================== // ====================
// Format is : MajorVer.MinorVer.DayMonth.Year" // Format is : MajorVer.MinorVer.DayMonth.Year"
// MajorVer changes only with significant changes // MajorVer changes only with significant changes
// MinorVer changes when additional features are added, but not for bug fixes (range 00-99) // MinorVer changes when additional features are added, but not for bug fixes (range 00-99)
// DayDate & Year changes for all changes, including for bug fixes. It represent the release date of the update // DayDate & Year changes for all changes, including for bug fixes. It represent the release date of the update
// //
#define MODES_DUMP1090_VERSION "1.08.2705.14" #define MODES_DUMP1090_VERSION "1.09.0608.14"
// ============================= Include files ========================== // ============================= Include files ==========================
@ -67,7 +67,7 @@
// ============================= #defines =============================== // ============================= #defines ===============================
// //
// If you have a valid coaa.h, these values will come from it. If not, // If you have a valid coaa.h, these values will come from it. If not,
// then you can enter your own values in the #else section here // then you can enter your own values in the #else section here
// //
#ifdef USER_LATITUDE #ifdef USER_LATITUDE
@ -76,8 +76,9 @@
#else #else
#define MODES_USER_LATITUDE_DFLT (0.0) #define MODES_USER_LATITUDE_DFLT (0.0)
#define MODES_USER_LONGITUDE_DFLT (0.0) #define MODES_USER_LONGITUDE_DFLT (0.0)
#endif #endif
#define MODES_DEFAULT_PPM 52
#define MODES_DEFAULT_RATE 2000000 #define MODES_DEFAULT_RATE 2000000
#define MODES_DEFAULT_FREQ 1090000000 #define MODES_DEFAULT_FREQ 1090000000
#define MODES_DEFAULT_WIDTH 1000 #define MODES_DEFAULT_WIDTH 1000
@ -115,7 +116,7 @@
#define MODES_LONG_MSG_SIZE (MODES_LONG_MSG_SAMPLES * sizeof(uint16_t)) #define MODES_LONG_MSG_SIZE (MODES_LONG_MSG_SAMPLES * sizeof(uint16_t))
#define MODES_SHORT_MSG_SIZE (MODES_SHORT_MSG_SAMPLES * sizeof(uint16_t)) #define MODES_SHORT_MSG_SIZE (MODES_SHORT_MSG_SAMPLES * sizeof(uint16_t))
#define MODES_RAWOUT_BUF_SIZE (1500) #define MODES_RAWOUT_BUF_SIZE (1500)
#define MODES_RAWOUT_BUF_FLUSH (MODES_RAWOUT_BUF_SIZE - 200) #define MODES_RAWOUT_BUF_FLUSH (MODES_RAWOUT_BUF_SIZE - 200)
#define MODES_RAWOUT_BUF_RATE (1000) // 1000 * 64mS = 1 Min approx #define MODES_RAWOUT_BUF_RATE (1000) // 1000 * 64mS = 1 Min approx
@ -138,12 +139,12 @@
#define MODES_ACFLAGS_AOG (1<<9) // Aircraft is On the Ground #define MODES_ACFLAGS_AOG (1<<9) // Aircraft is On the Ground
#define MODES_ACFLAGS_LLEVEN_VALID (1<<10) // Aircraft Even Lot/Lon is known #define MODES_ACFLAGS_LLEVEN_VALID (1<<10) // Aircraft Even Lot/Lon is known
#define MODES_ACFLAGS_LLODD_VALID (1<<11) // Aircraft Odd Lot/Lon is known #define MODES_ACFLAGS_LLODD_VALID (1<<11) // Aircraft Odd Lot/Lon is known
#define MODES_ACFLAGS_AOG_VALID (1<<12) // MODES_ACFLAGS_AOG is valid #define MODES_ACFLAGS_AOG_VALID (1<<12) // MODES_ACFLAGS_AOG is valid
#define MODES_ACFLAGS_FS_VALID (1<<13) // Aircraft Flight Status is known #define MODES_ACFLAGS_FS_VALID (1<<13) // Aircraft Flight Status is known
#define MODES_ACFLAGS_NSEWSPD_VALID (1<<14) // Aircraft EW and NS Speed is known #define MODES_ACFLAGS_NSEWSPD_VALID (1<<14) // Aircraft EW and NS Speed is known
#define MODES_ACFLAGS_LATLON_REL_OK (1<<15) // Indicates it's OK to do a relative CPR #define MODES_ACFLAGS_LATLON_REL_OK (1<<15) // Indicates it's OK to do a relative CPR
#define MODES_ACFLAGS_LLEITHER_VALID (MODES_ACFLAGS_LLEVEN_VALID | MODES_ACFLAGS_LLODD_VALID) #define MODES_ACFLAGS_LLEITHER_VALID (MODES_ACFLAGS_LLEVEN_VALID | MODES_ACFLAGS_LLODD_VALID)
#define MODES_ACFLAGS_LLBOTH_VALID (MODES_ACFLAGS_LLEVEN_VALID | MODES_ACFLAGS_LLODD_VALID) #define MODES_ACFLAGS_LLBOTH_VALID (MODES_ACFLAGS_LLEVEN_VALID | MODES_ACFLAGS_LLODD_VALID)
#define MODES_ACFLAGS_AOG_GROUND (MODES_ACFLAGS_AOG_VALID | MODES_ACFLAGS_AOG) #define MODES_ACFLAGS_AOG_GROUND (MODES_ACFLAGS_AOG_VALID | MODES_ACFLAGS_AOG)
@ -176,7 +177,7 @@
#define MODES_NET_OUTPUT_FA_TSV_PORT 10001 #define MODES_NET_OUTPUT_FA_TSV_PORT 10001
#define MODES_CLIENT_BUF_SIZE 1024 #define MODES_CLIENT_BUF_SIZE 1024
#define MODES_NET_SNDBUF_SIZE (1024*64) #define MODES_NET_SNDBUF_SIZE (1024*64)
#define MODES_NET_SNDBUF_MAX (7) #define MODES_NET_SNDBUF_MAX (7)
#ifndef HTMLPATH #ifndef HTMLPATH
#define HTMLPATH "./public_html" // default path for gmap.html etc #define HTMLPATH "./public_html" // default path for gmap.html etc
@ -233,6 +234,16 @@ struct aircraft {
struct aircraft *next; // Next aircraft in our linked list struct aircraft *next; // Next aircraft in our linked list
}; };
struct stDF {
struct stDF *pNext; // Pointer to next item in the linked list
struct stDF *pPrev; // Pointer to previous item in the linked list
struct aircraft *pAircraft; // Pointer to the Aircraft structure for this DF
time_t seen; // Dos/UNIX Time at which the this packet was received
uint64_t llTimestamp; // Timestamp at which the this packet was received
uint32_t addr; // Timestamp at which the this packet was received
unsigned char msg[MODES_LONG_MSG_BYTES]; // the binary
} tDF;
// Program global state // Program global state
struct { // Internal state struct { // Internal state
pthread_t reader_thread; pthread_t reader_thread;
@ -243,7 +254,7 @@ struct { // Internal state
struct timeb stSystemTimeRTL[MODES_ASYNC_BUF_NUMBER]; // System time when RTL passed us this block struct timeb stSystemTimeRTL[MODES_ASYNC_BUF_NUMBER]; // System time when RTL passed us this block
int iDataIn; // Fifo input pointer int iDataIn; // Fifo input pointer
int iDataOut; // Fifo output pointer int iDataOut; // Fifo output pointer
int iDataReady; // Fifo content count int iDataReady; // Fifo content count
int iDataLost; // Count of missed buffers int iDataLost; // Count of missed buffers
uint16_t *pFileData; // Raw IQ samples buffer (from a File) uint16_t *pFileData; // Raw IQ samples buffer (from a File)
@ -324,6 +335,12 @@ struct { // Internal state
// Interactive mode // Interactive mode
struct aircraft *aircrafts; struct aircraft *aircrafts;
uint64_t interactive_last_update; // Last screen update in milliseconds uint64_t interactive_last_update; // Last screen update in milliseconds
time_t last_cleanup_time; // Last cleanup time in seconds
// DF List mode
int bEnableDFLogging; // Set to enable DF Logging
pthread_mutex_t pDF_mutex; // Mutex to synchronize pDF access
struct stDF *pDF; // Pointer to DF list
// Statistics // Statistics
unsigned int stat_valid_preamble; unsigned int stat_valid_preamble;
@ -338,7 +355,7 @@ struct { // Internal state
// Histogram of fixed bit errors: index 0 for single bit erros, // Histogram of fixed bit errors: index 0 for single bit erros,
// index 1 for double bit errors etc. // index 1 for double bit errors etc.
unsigned int stat_bit_fix[MODES_MAX_BITERRORS]; unsigned int stat_bit_fix[MODES_MAX_BITERRORS];
unsigned int stat_http_requests; unsigned int stat_http_requests;
unsigned int stat_sbs_connections; unsigned int stat_sbs_connections;
unsigned int stat_fatsv_connections; unsigned int stat_fatsv_connections;
@ -355,7 +372,7 @@ struct { // Internal state
// Histogram of fixed bit errors: index 0 for single bit erros, // Histogram of fixed bit errors: index 0 for single bit erros,
// index 1 for double bit errors etc. // index 1 for double bit errors etc.
unsigned int stat_ph_bit_fix[MODES_MAX_BITERRORS]; unsigned int stat_ph_bit_fix[MODES_MAX_BITERRORS];
unsigned int stat_DF_Len_Corrected; unsigned int stat_DF_Len_Corrected;
unsigned int stat_DF_Type_Corrected; unsigned int stat_DF_Type_Corrected;
unsigned int stat_ModeAC; unsigned int stat_ModeAC;
@ -436,6 +453,8 @@ struct aircraft* interactiveReceiveData(struct modesMessage *mm, struct client *
void interactiveShowData(void); void interactiveShowData(void);
void interactiveRemoveStaleAircrafts(void); void interactiveRemoveStaleAircrafts(void);
int decodeBinMessage (struct client *c, char *p); int decodeBinMessage (struct client *c, char *p);
struct aircraft *interactiveFindAircraft(uint32_t addr);
struct stDF *interactiveFindDF (uint32_t addr);
// //
// Functions exported from net_io.c // Functions exported from net_io.c

View File

@ -13,7 +13,7 @@
## Fill in name of program here. ## Fill in name of program here.
PROG="dump1090" PROG="dump1090"
PROG_PATH="/home/pi/dump1090" PROG_PATH="/home/pi/dump1090"
PROG_ARGS="--quiet --net --net-ro-size 500 --net-ro-rate 5" PROG_ARGS="--quiet --net --net-ro-size 500 --net-ro-rate 5 --net-buffer 5"
PIDFILE="/var/run/dump1090.pid" PIDFILE="/var/run/dump1090.pid"
start() { start() {

View File

@ -42,6 +42,87 @@ static uint64_t mstime(void) {
return mst; return mst;
} }
// //
//=========================================================================
//
// Add a new DF structure to the interactive mode linked list
//
void interactiveCreateDF(struct aircraft *a, struct modesMessage *mm) {
struct stDF *pDF = (struct stDF *) malloc(sizeof(*pDF));
if (pDF) {
// Default everything to zero/NULL
memset(pDF, 0, sizeof(*pDF));
// Now initialise things
pDF->seen = a->seen;
pDF->llTimestamp = mm->timestampMsg;
pDF->addr = mm->addr;
pDF->pAircraft = a;
memcpy(pDF->msg, mm->msg, MODES_LONG_MSG_BYTES);
if (!pthread_mutex_lock(&Modes.pDF_mutex)) {
if ((pDF->pNext = Modes.pDF)) {
Modes.pDF->pPrev = pDF;
}
Modes.pDF = pDF;
pthread_mutex_unlock(&Modes.pDF_mutex);
} else {
free(pDF);
}
}
}
//
// Remove stale DF's from the interactive mode linked list
//
void interactiveRemoveStaleDF(time_t now) {
struct stDF *pDF = NULL;
struct stDF *prev = NULL;
// Only fiddle with the DF list if we gain possession of the mutex
// If we fail to get the mutex we'll get another chance to tidy the
// DF list in a second or so.
if (!pthread_mutex_trylock(&Modes.pDF_mutex)) {
pDF = Modes.pDF;
while(pDF) {
if ((now - pDF->seen) > Modes.interactive_delete_ttl) {
if (Modes.pDF == pDF) {
Modes.pDF = NULL;
} else {
prev->pNext = NULL;
}
// All DF's in the list from here onwards will be time
// expired, so delete them all
while (pDF) {
prev = pDF; pDF = pDF->pNext;
free(prev);
}
} else {
prev = pDF; pDF = pDF->pNext;
}
}
pthread_mutex_unlock (&Modes.pDF_mutex);
}
}
struct stDF *interactiveFindDF(uint32_t addr) {
struct stDF *pDF = NULL;
if (!pthread_mutex_lock(&Modes.pDF_mutex)) {
pDF = Modes.pDF;
while(pDF) {
if (pDF->addr == addr) {
pthread_mutex_unlock (&Modes.pDF_mutex);
return (pDF);
}
pDF = pDF->pNext;
}
pthread_mutex_unlock (&Modes.pDF_mutex);
}
return (NULL);
}
//
//========================= Interactive mode =============================== //========================= Interactive mode ===============================
// //
// Return a new aircraft structure for the interactive mode linked list // Return a new aircraft structure for the interactive mode linked list
@ -70,7 +151,7 @@ struct aircraft *interactiveCreateAircraft(struct modesMessage *mm) {
} else { } else {
mm->altitude = modeC * 100; mm->altitude = modeC * 100;
mm->bFlags |= MODES_ACFLAGS_ALTITUDE_VALID; mm->bFlags |= MODES_ACFLAGS_ALTITUDE_VALID;
} }
} }
return (a); return (a);
} }
@ -113,7 +194,7 @@ struct aircraft *interactiveFindAircraft(uint32_t addr) {
// //
// Note : It's theoretically possible for an aircraft to have the same value for Mode A // Note : It's theoretically possible for an aircraft to have the same value for Mode A
// and Mode C. Therefore we have to check BOTH A AND C for EVERY S. // and Mode C. Therefore we have to check BOTH A AND C for EVERY S.
// //
void interactiveUpdateAircraftModeA(struct aircraft *a) { void interactiveUpdateAircraftModeA(struct aircraft *a) {
struct aircraft *b = Modes.aircrafts; struct aircraft *b = Modes.aircrafts;
@ -127,12 +208,12 @@ void interactiveUpdateAircraftModeA(struct aircraft *a) {
b->modeAcount = a->messages; b->modeAcount = a->messages;
b->modeACflags |= MODEAC_MSG_MODEA_HIT; b->modeACflags |= MODEAC_MSG_MODEA_HIT;
a->modeACflags |= MODEAC_MSG_MODEA_HIT; a->modeACflags |= MODEAC_MSG_MODEA_HIT;
if ( (b->modeAcount > 0) && if ( (b->modeAcount > 0) &&
( (b->modeCcount > 1) ( (b->modeCcount > 1)
|| (a->modeACflags & MODEAC_MSG_MODEA_ONLY)) ) // Allow Mode-A only matches if this Mode-A is invalid Mode-C || (a->modeACflags & MODEAC_MSG_MODEA_ONLY)) ) // Allow Mode-A only matches if this Mode-A is invalid Mode-C
{a->modeACflags |= MODEAC_MSG_MODES_HIT;} // flag this ModeA/C probably belongs to a known Mode S {a->modeACflags |= MODEAC_MSG_MODES_HIT;} // flag this ModeA/C probably belongs to a known Mode S
} }
} }
// If both (a) and (b) have valid altitudes... // If both (a) and (b) have valid altitudes...
if ((a->bFlags & b->bFlags) & MODES_ACFLAGS_ALTITUDE_VALID) { if ((a->bFlags & b->bFlags) & MODES_ACFLAGS_ALTITUDE_VALID) {
@ -143,7 +224,7 @@ void interactiveUpdateAircraftModeA(struct aircraft *a) {
b->modeCcount = a->messages; b->modeCcount = a->messages;
b->modeACflags |= MODEAC_MSG_MODEC_HIT; b->modeACflags |= MODEAC_MSG_MODEC_HIT;
a->modeACflags |= MODEAC_MSG_MODEC_HIT; a->modeACflags |= MODEAC_MSG_MODEC_HIT;
if ( (b->modeAcount > 0) && if ( (b->modeAcount > 0) &&
(b->modeCcount > 1) ) (b->modeCcount > 1) )
{a->modeACflags |= (MODEAC_MSG_MODES_HIT | MODEAC_MSG_MODEC_OLD);} // flag this ModeA/C probably belongs to a known Mode S {a->modeACflags |= (MODEAC_MSG_MODES_HIT | MODEAC_MSG_MODEC_OLD);} // flag this ModeA/C probably belongs to a known Mode S
} }
@ -160,7 +241,7 @@ void interactiveUpdateAircraftModeS() {
while(a) { while(a) {
int flags = a->modeACflags; int flags = a->modeACflags;
if (flags & MODEAC_MSG_FLAG) { // find any fudged ICAO records if (flags & MODEAC_MSG_FLAG) { // find any fudged ICAO records
// clear the current A,C and S hit bits ready for this attempt // clear the current A,C and S hit bits ready for this attempt
a->modeACflags = flags & ~(MODEAC_MSG_MODEA_HIT | MODEAC_MSG_MODEC_HIT | MODEAC_MSG_MODES_HIT); a->modeACflags = flags & ~(MODEAC_MSG_MODEA_HIT | MODEAC_MSG_MODEC_HIT | MODEAC_MSG_MODES_HIT);
@ -179,7 +260,7 @@ struct aircraft *interactiveReceiveData(struct modesMessage *mm, struct client *
struct aircraft *a, *aux; struct aircraft *a, *aux;
// Return if (checking crc) AND (not crcok) AND (not fixed) // Return if (checking crc) AND (not crcok) AND (not fixed)
if (Modes.check_crc && (mm->crcok == 0) && (mm->correctedbits == 0)) if (Modes.check_crc && (mm->crcok == 0) && (mm->correctedbits == 0))
return NULL; return NULL;
// Lookup our aircraft or create a new one // Lookup our aircraft or create a new one
@ -259,7 +340,7 @@ struct aircraft *interactiveReceiveData(struct modesMessage *mm, struct client *
// if the Aircraft has landed or taken off since the last message, clear the even/odd CPR flags // if the Aircraft has landed or taken off since the last message, clear the even/odd CPR flags
if ((mm->bFlags & MODES_ACFLAGS_AOG_VALID) && ((a->bFlags ^ mm->bFlags) & MODES_ACFLAGS_AOG)) { if ((mm->bFlags & MODES_ACFLAGS_AOG_VALID) && ((a->bFlags ^ mm->bFlags) & MODES_ACFLAGS_AOG)) {
a->bFlags &= ~(MODES_ACFLAGS_LLBOTH_VALID | MODES_ACFLAGS_AOG); a->bFlags &= ~(MODES_ACFLAGS_LLBOTH_VALID | MODES_ACFLAGS_AOG);
} }
// If we've got a new cprlat or cprlon // If we've got a new cprlat or cprlon
if (mm->bFlags & MODES_ACFLAGS_LLEITHER_VALID) { if (mm->bFlags & MODES_ACFLAGS_LLEITHER_VALID) {
@ -299,20 +380,25 @@ struct aircraft *interactiveReceiveData(struct modesMessage *mm, struct client *
if (mm->msgtype == 32) { if (mm->msgtype == 32) {
int flags = a->modeACflags; int flags = a->modeACflags;
if ((flags & (MODEAC_MSG_MODEC_HIT | MODEAC_MSG_MODEC_OLD)) == MODEAC_MSG_MODEC_OLD) { if ((flags & (MODEAC_MSG_MODEC_HIT | MODEAC_MSG_MODEC_OLD)) == MODEAC_MSG_MODEC_OLD) {
// //
// This Mode-C doesn't currently hit any known Mode-S, but it used to because MODEAC_MSG_MODEC_OLD is // This Mode-C doesn't currently hit any known Mode-S, but it used to because MODEAC_MSG_MODEC_OLD is
// set So the aircraft it used to match has either changed altitude, or gone out of our receiver range // set So the aircraft it used to match has either changed altitude, or gone out of our receiver range
// //
// We've now received this Mode-A/C again, so it must be a new aircraft. It could be another aircraft // We've now received this Mode-A/C again, so it must be a new aircraft. It could be another aircraft
// at the same Mode-C altitude, or it could be a new airctraft with a new Mods-A squawk. // at the same Mode-C altitude, or it could be a new airctraft with a new Mods-A squawk.
// //
// To avoid masking this aircraft from the interactive display, clear the MODEAC_MSG_MODES_OLD flag // To avoid masking this aircraft from the interactive display, clear the MODEAC_MSG_MODES_OLD flag
// and set messages to 1; // and set messages to 1;
// //
a->modeACflags = flags & ~MODEAC_MSG_MODEC_OLD; a->modeACflags = flags & ~MODEAC_MSG_MODEC_OLD;
a->messages = 1; a->messages = 1;
} }
}
// If we are Logging DF's, and it's not a Mode A/C
if ((Modes.bEnableDFLogging) && (mm->msgtype < 32)) {
interactiveCreateDF(a,mm);
} }
return (a); return (a);
@ -333,10 +419,10 @@ void interactiveShowData(void) {
if ((mstime() - Modes.interactive_last_update) < MODES_INTERACTIVE_REFRESH_TIME) if ((mstime() - Modes.interactive_last_update) < MODES_INTERACTIVE_REFRESH_TIME)
{return;} {return;}
Modes.interactive_last_update = mstime(); Modes.interactive_last_update = mstime();
// Attempt to reconsile any ModeA/C with known Mode-S // Attempt to reconsile any ModeA/C with known Mode-S
// We can't condition on Modes.modeac because ModeA/C could be comming // We can't condition on Modes.modeac because ModeA/C could be comming
// in from a raw input port which we can't turn off. // in from a raw input port which we can't turn off.
interactiveUpdateAircraftModeS(); interactiveUpdateAircraftModeS();
@ -380,7 +466,7 @@ void interactiveShowData(void) {
altitude = (int) (altitude / 3.2828); altitude = (int) (altitude / 3.2828);
speed = (int) (speed * 1.852); speed = (int) (speed * 1.852);
} }
if (a->bFlags & MODES_ACFLAGS_SQUAWK_VALID) { if (a->bFlags & MODES_ACFLAGS_SQUAWK_VALID) {
snprintf(strSquawk,5,"%04x", a->modeA);} snprintf(strSquawk,5,"%04x", a->modeA);}
@ -389,10 +475,10 @@ void interactiveShowData(void) {
if (a->bFlags & MODES_ACFLAGS_HEADING_VALID) { if (a->bFlags & MODES_ACFLAGS_HEADING_VALID) {
snprintf (strTt, 5,"%03d", a->track);} snprintf (strTt, 5,"%03d", a->track);}
if (msgs > 99999) { if (msgs > 99999) {
msgs = 99999;} msgs = 99999;}
if (Modes.interactive_rtl1090) { // RTL1090 display mode if (Modes.interactive_rtl1090) { // RTL1090 display mode
if (a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) { if (a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) {
@ -427,8 +513,8 @@ void interactiveShowData(void) {
} else if (a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) { } else if (a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) {
snprintf(strFl, 6, "%5d", altitude); snprintf(strFl, 6, "%5d", altitude);
} }
printf("%06x %-4s %-4s %-8s %5s %3s %3s %7s %8s %3d %5d %2d\n", printf("%06X %-4s %-4s %-8s %5s %3s %3s %7s %8s %3d %5d %2d\n",
a->addr, strMode, strSquawk, a->flight, strFl, strGs, strTt, a->addr, strMode, strSquawk, a->flight, strFl, strGs, strTt,
strLat, strLon, signalAverage, msgs, (int)(now - a->seen)); strLat, strLon, signalAverage, msgs, (int)(now - a->seen));
} }
@ -449,22 +535,24 @@ void interactiveRemoveStaleAircrafts(void) {
struct aircraft *prev = NULL; struct aircraft *prev = NULL;
time_t now = time(NULL); time_t now = time(NULL);
while(a) { // Only do cleanup once per second
if ((now - a->seen) > Modes.interactive_delete_ttl) { if (Modes.last_cleanup_time != now) {
struct aircraft *next = a->next; Modes.last_cleanup_time = now;
// Remove the element from the linked list, with care
// if we are removing the first element
if (!prev) interactiveRemoveStaleDF(now);
Modes.aircrafts = next;
else
prev->next = next;
free(a); while(a) {
a = next; if ((now - a->seen) > Modes.interactive_delete_ttl) {
} else { // Remove the element from the linked list, with care
prev = a; // if we are removing the first element
a = a->next; if (!prev) {
Modes.aircrafts = a->next; free(a); a = Modes.aircrafts;
} else {
prev->next = a->next; free(a); a = prev->next;
}
} else {
prev = a; a = a->next;
}
} }
} }
} }

132
mode_s.c
View File

@ -907,6 +907,10 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
mm->crcok = ICAOAddressWasRecentlySeen(mm->addr = mm->crc); mm->crcok = ICAOAddressWasRecentlySeen(mm->addr = mm->crc);
} }
// 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;}
// Fields for DF0, DF16 // Fields for DF0, DF16
if (mm->msgtype == 0 || mm->msgtype == 16) { if (mm->msgtype == 0 || mm->msgtype == 16) {
if (msg[0] & 0x04) { // VS Bit if (msg[0] & 0x04) { // VS Bit
@ -982,32 +986,6 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
mm->flight[8] = '\0'; mm->flight[8] = '\0';
} else if (metype >= 5 && metype <= 18) { // Position Message
mm->raw_latitude = ((msg[6] & 3) << 15) | (msg[7] << 7) | (msg[8] >> 1);
mm->raw_longitude = ((msg[8] & 1) << 16) | (msg[9] << 8) | (msg[10]);
mm->bFlags |= (mm->msg[6] & 0x04) ? MODES_ACFLAGS_LLODD_VALID
: MODES_ACFLAGS_LLEVEN_VALID;
if (metype >= 9) { // Airborne
int AC12Field = ((msg[5] << 4) | (msg[6] >> 4)) & 0x0FFF;
mm->bFlags |= MODES_ACFLAGS_AOG_VALID;
if (AC12Field) {// Only attempt to decode if a valid (non zero) altitude is present
mm->bFlags |= MODES_ACFLAGS_ALTITUDE_VALID;
mm->altitude = decodeAC12Field(AC12Field, &mm->unit);
}
} else { // Ground
int movement = ((msg[4] << 4) | (msg[5] >> 4)) & 0x007F;
mm->bFlags |= MODES_ACFLAGS_AOG_VALID | MODES_ACFLAGS_AOG;
if ((movement) && (movement < 125)) {
mm->bFlags |= MODES_ACFLAGS_SPEED_VALID;
mm->velocity = decodeMovementField(movement);
}
if (msg[5] & 0x08) {
mm->bFlags |= MODES_ACFLAGS_HEADING_VALID;
mm->heading = ((((msg[5] << 4) | (msg[6] >> 4)) & 0x007F) * 45) >> 4;
}
}
} else if (metype == 19) { // Airborne Velocity Message } else if (metype == 19) { // Airborne Velocity Message
// Presumably airborne if we get an Airborne Velocity Message // Presumably airborne if we get an Airborne Velocity Message
@ -1076,23 +1054,62 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
mm->heading = ((((msg[5] & 0x03) << 8) | msg[6]) * 45) >> 7; mm->heading = ((((msg[5] & 0x03) << 8) | msg[6]) * 45) >> 7;
} }
} }
} else if (mm->metype == 23) { // Test metype squawk field
if (mm->mesub == 7) { // (see 1090-WP-15-20) } else if (metype >= 5 && metype <= 22) { // Position Message
mm->raw_latitude = ((msg[6] & 3) << 15) | (msg[7] << 7) | (msg[8] >> 1);
mm->raw_longitude = ((msg[8] & 1) << 16) | (msg[9] << 8) | (msg[10]);
mm->bFlags |= (mm->msg[6] & 0x04) ? MODES_ACFLAGS_LLODD_VALID
: MODES_ACFLAGS_LLEVEN_VALID;
if (metype >= 9) { // Airborne
int AC12Field = ((msg[5] << 4) | (msg[6] >> 4)) & 0x0FFF;
mm->bFlags |= MODES_ACFLAGS_AOG_VALID;
if (AC12Field) {// Only attempt to decode if a valid (non zero) altitude is present
mm->bFlags |= MODES_ACFLAGS_ALTITUDE_VALID;
mm->altitude = decodeAC12Field(AC12Field, &mm->unit);
}
} else { // Ground
int movement = ((msg[4] << 4) | (msg[5] >> 4)) & 0x007F;
mm->bFlags |= MODES_ACFLAGS_AOG_VALID | MODES_ACFLAGS_AOG;
if ((movement) && (movement < 125)) {
mm->bFlags |= MODES_ACFLAGS_SPEED_VALID;
mm->velocity = decodeMovementField(movement);
}
if (msg[5] & 0x08) {
mm->bFlags |= MODES_ACFLAGS_HEADING_VALID;
mm->heading = ((((msg[5] << 4) | (msg[6] >> 4)) & 0x007F) * 45) >> 4;
}
}
} else if (metype == 23) { // Test metype squawk field
if (mesub == 7) { // (see 1090-WP-15-20)
int ID13Field = (((msg[5] << 8) | msg[6]) & 0xFFF1)>>3; int ID13Field = (((msg[5] << 8) | msg[6]) & 0xFFF1)>>3;
if (ID13Field) { if (ID13Field) {
mm->bFlags |= MODES_ACFLAGS_SQUAWK_VALID; mm->bFlags |= MODES_ACFLAGS_SQUAWK_VALID;
mm->modeA = decodeID13Field(ID13Field); mm->modeA = decodeID13Field(ID13Field);
} }
} }
} else if (mm->metype == 28) { // Emergency status squawk field
if (mm->mesub == 1) { } else if (metype == 24) { // Reserved for Surface System Status
} else if (metype == 28) { // Extended Squitter Aircraft Status
if (mesub == 1) { // Emergency status squawk field
int ID13Field = (((msg[5] << 8) | msg[6]) & 0x1FFF); int ID13Field = (((msg[5] << 8) | msg[6]) & 0x1FFF);
if (ID13Field) { if (ID13Field) {
mm->bFlags |= MODES_ACFLAGS_SQUAWK_VALID; mm->bFlags |= MODES_ACFLAGS_SQUAWK_VALID;
mm->modeA = decodeID13Field(ID13Field); mm->modeA = decodeID13Field(ID13Field);
} }
} }
}
} else if (metype == 29) { // Aircraft Trajectory Intent
} else if (metype == 30) { // Aircraft Operational Coordination
} else if (metype == 31) { // Aircraft Operational Status
} else { // Other metypes
}
} }
// Fields for DF20, DF21 Comm-B // Fields for DF20, DF21 Comm-B
@ -1268,20 +1285,6 @@ void displayModesMessage(struct modesMessage *mm) {
printf(" Aircraft Type : %c%d\n", ('A' + 4 - mm->metype), mm->mesub); printf(" Aircraft Type : %c%d\n", ('A' + 4 - mm->metype), mm->mesub);
printf(" Identification : %s\n", mm->flight); printf(" Identification : %s\n", mm->flight);
//} else if (mm->metype >= 5 && mm->metype <= 8) { // Surface position
} else if (mm->metype >= 9 && mm->metype <= 18) { // Airborne position Baro
printf(" F flag : %s\n", (mm->msg[6] & 0x04) ? "odd" : "even");
printf(" T flag : %s\n", (mm->msg[6] & 0x08) ? "UTC" : "non-UTC");
printf(" Altitude : %d feet\n", mm->altitude);
if (mm->bFlags & MODES_ACFLAGS_LATLON_VALID) {
printf(" Latitude : %f\n", mm->fLat);
printf(" Longitude: %f\n", mm->fLon);
} else {
printf(" Latitude : %d (not decoded)\n", mm->raw_latitude);
printf(" Longitude: %d (not decoded)\n", mm->raw_longitude);
}
} else if (mm->metype == 19) { // Airborne Velocity } else if (mm->metype == 19) { // Airborne Velocity
if (mm->mesub == 1 || mm->mesub == 2) { if (mm->mesub == 1 || mm->mesub == 2) {
printf(" EW status : %s\n", (mm->bFlags & MODES_ACFLAGS_EWSPEED_VALID) ? "Valid" : "Unavailable"); printf(" EW status : %s\n", (mm->bFlags & MODES_ACFLAGS_EWSPEED_VALID) ? "Valid" : "Unavailable");
@ -1305,7 +1308,17 @@ void displayModesMessage(struct modesMessage *mm) {
printf(" Unrecognized ME subtype: %d subtype: %d\n", mm->metype, mm->mesub); printf(" Unrecognized ME subtype: %d subtype: %d\n", mm->metype, mm->mesub);
} }
//} else if (mm->metype >= 20 && mm->metype <= 22) { // Airborne position GNSS } else if (mm->metype >= 5 && mm->metype <= 22) { // Airborne position Baro
printf(" F flag : %s\n", (mm->msg[6] & 0x04) ? "odd" : "even");
printf(" T flag : %s\n", (mm->msg[6] & 0x08) ? "UTC" : "non-UTC");
printf(" Altitude : %d feet\n", mm->altitude);
if (mm->bFlags & MODES_ACFLAGS_LATLON_VALID) {
printf(" Latitude : %f\n", mm->fLat);
printf(" Longitude: %f\n", mm->fLon);
} else {
printf(" Latitude : %d (not decoded)\n", mm->raw_latitude);
printf(" Longitude: %d (not decoded)\n", mm->raw_longitude);
}
} else if (mm->metype == 28) { // Extended Squitter Aircraft Status } else if (mm->metype == 28) { // Extended Squitter Aircraft Status
if (mm->mesub == 1) { if (mm->mesub == 1) {
@ -1343,20 +1356,6 @@ void displayModesMessage(struct modesMessage *mm) {
printf(" Aircraft Type : %c%d\n", ('A' + 4 - mm->metype), mm->mesub); printf(" Aircraft Type : %c%d\n", ('A' + 4 - mm->metype), mm->mesub);
printf(" Identification : %s\n", mm->flight); printf(" Identification : %s\n", mm->flight);
//} else if (mm->metype >= 5 && mm->metype <= 8) { // Surface position
} else if (mm->metype >= 9 && mm->metype <= 18) { // Airborne position Baro
printf(" F flag : %s\n", (mm->msg[6] & 0x04) ? "odd" : "even");
printf(" T flag : %s\n", (mm->msg[6] & 0x08) ? "UTC" : "non-UTC");
printf(" Altitude : %d feet\n", mm->altitude);
if (mm->bFlags & MODES_ACFLAGS_LATLON_VALID) {
printf(" Latitude : %f\n", mm->fLat);
printf(" Longitude: %f\n", mm->fLon);
} else {
printf(" Latitude : %d (not decoded)\n", mm->raw_latitude);
printf(" Longitude: %d (not decoded)\n", mm->raw_longitude);
}
} else if (mm->metype == 19) { // Airborne Velocity } else if (mm->metype == 19) { // Airborne Velocity
if (mm->mesub == 1 || mm->mesub == 2) { if (mm->mesub == 1 || mm->mesub == 2) {
printf(" EW status : %s\n", (mm->bFlags & MODES_ACFLAGS_EWSPEED_VALID) ? "Valid" : "Unavailable"); printf(" EW status : %s\n", (mm->bFlags & MODES_ACFLAGS_EWSPEED_VALID) ? "Valid" : "Unavailable");
@ -1380,7 +1379,17 @@ void displayModesMessage(struct modesMessage *mm) {
printf(" Unrecognized ME subtype: %d subtype: %d\n", mm->metype, mm->mesub); printf(" Unrecognized ME subtype: %d subtype: %d\n", mm->metype, mm->mesub);
} }
//} else if (mm->metype >= 20 && mm->metype <= 22) { // Airborne position GNSS } else if (mm->metype >= 5 && mm->metype <= 22) { // Ground or Airborne position, Baro or GNSS
printf(" F flag : %s\n", (mm->msg[6] & 0x04) ? "odd" : "even");
printf(" T flag : %s\n", (mm->msg[6] & 0x08) ? "UTC" : "non-UTC");
printf(" Altitude : %d feet\n", mm->altitude);
if (mm->bFlags & MODES_ACFLAGS_LATLON_VALID) {
printf(" Latitude : %f\n", mm->fLat);
printf(" Longitude: %f\n", mm->fLon);
} else {
printf(" Latitude : %d (not decoded)\n", mm->raw_latitude);
printf(" Longitude: %d (not decoded)\n", mm->raw_longitude);
}
} else { } else {
printf(" Unrecognized ME type: %d subtype: %d\n", mm->metype, mm->mesub); printf(" Unrecognized ME type: %d subtype: %d\n", mm->metype, mm->mesub);
@ -2035,7 +2044,6 @@ void decodeCPR(struct aircraft *a, int fflag, int surface) {
surface_rlat = Modes.fUserLat; surface_rlat = Modes.fUserLat;
surface_rlon = Modes.fUserLon; surface_rlon = Modes.fUserLon;
} else { } else {
surface_rlat = Modes.fUserLat;
return; return;
} }
rlat0 += floor(surface_rlat / 90.0) * 90.0; // Move from 1st quadrant to our quadrant rlat0 += floor(surface_rlat / 90.0) * 90.0; // Move from 1st quadrant to our quadrant

View File

@ -374,9 +374,19 @@ void modesSendSBSOutput(struct modesMessage *mm) {
p += sprintf(p, ","); p += sprintf(p, ",");
} }
// Field 13 and 14 are the ground Speed and Heading (if we have them) // Field 13 is the ground Speed (if we have it)
if (mm->bFlags & MODES_ACFLAGS_NSEWSPD_VALID) {p += sprintf(p, ",%d,%d", mm->velocity, mm->heading);} if (mm->bFlags & MODES_ACFLAGS_SPEED_VALID) {
else {p += sprintf(p, ",,");} p += sprintf(p, ",%d", mm->velocity);
} else {
p += sprintf(p, ",");
}
// Field 14 is the ground Heading (if we have it)
if (mm->bFlags & MODES_ACFLAGS_HEADING_VALID) {
p += sprintf(p, ",%d", mm->heading);
} else {
p += sprintf(p, ",");
}
// Fields 15 and 16 are the Lat/Lon (if we have it) // Fields 15 and 16 are the Lat/Lon (if we have it)
if (mm->bFlags & MODES_ACFLAGS_LATLON_VALID) {p += sprintf(p, ",%1.5f,%1.5f", mm->fLat, mm->fLon);} if (mm->bFlags & MODES_ACFLAGS_LATLON_VALID) {p += sprintf(p, ",%1.5f,%1.5f", mm->fLat, mm->fLon);}
@ -462,16 +472,20 @@ int decodeBinMessage(struct client *c, char *p) {
int msgLen = 0; int msgLen = 0;
int j; int j;
char ch; char ch;
char * ptr;
unsigned char msg[MODES_LONG_MSG_BYTES]; unsigned char msg[MODES_LONG_MSG_BYTES];
struct modesMessage mm; struct modesMessage mm;
MODES_NOTUSED(c); MODES_NOTUSED(c);
memset(&mm, 0, sizeof(mm)); memset(&mm, 0, sizeof(mm));
if ((*p == '1') && (Modes.mode_ac)) { // skip ModeA/C unless user enables --modes-ac ch = *p++; /// Get the message type
if (0x1A == ch) {p++;}
if ((ch == '1') && (Modes.mode_ac)) { // skip ModeA/C unless user enables --modes-ac
msgLen = MODEAC_MSG_BYTES; msgLen = MODEAC_MSG_BYTES;
} else if (*p == '2') { } else if (ch == '2') {
msgLen = MODES_SHORT_MSG_BYTES; msgLen = MODES_SHORT_MSG_BYTES;
} else if (*p == '3') { } else if (ch == '3') {
msgLen = MODES_LONG_MSG_BYTES; msgLen = MODES_LONG_MSG_BYTES;
} }
@ -479,8 +493,10 @@ int decodeBinMessage(struct client *c, char *p) {
// Mark messages received over the internet as remote so that we don't try to // Mark messages received over the internet as remote so that we don't try to
// pass them off as being received by this instance when forwarding them // pass them off as being received by this instance when forwarding them
mm.remote = 1; mm.remote = 1;
for (j = 0; j < 7; j++) { // Skip the message type and timestamp
ch = *p++; ptr = (char*) &mm.timestampMsg;
for (j = 0; j < 6; j++) { // Grab the timestamp (big endian format)
ptr[5-j] = ch = *p++;
if (0x1A == ch) {p++;} if (0x1A == ch) {p++;}
} }

View File

@ -51,7 +51,8 @@ void ppup1090InitConfig(void) {
// Now initialise things that should not be 0/NULL to their defaults // Now initialise things that should not be 0/NULL to their defaults
Modes.check_crc = 1; Modes.check_crc = 1;
Modes.quiet = 1; Modes.quiet = 1;
strcpy(ppup1090.net_input_beast_ipaddr,PPUP1090_NET_OUTPUT_IP_ADDRESS); Modes.bEnableDFLogging = 1;
strcpy(ppup1090.net_input_beast_ipaddr,PPUP1090_NET_OUTPUT_IP_ADDRESS);
Modes.net_input_beast_port = MODES_NET_OUTPUT_BEAST_PORT; Modes.net_input_beast_port = MODES_NET_OUTPUT_BEAST_PORT;
Modes.interactive_delete_ttl = MODES_INTERACTIVE_DELETE_TTL; Modes.interactive_delete_ttl = MODES_INTERACTIVE_DELETE_TTL;
Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL; Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL;
@ -71,6 +72,10 @@ void ppup1090Init(void) {
int iErr; int iErr;
pthread_mutex_init(&Modes.pDF_mutex,NULL);
pthread_mutex_init(&Modes.data_mutex,NULL);
pthread_cond_init(&Modes.data_cond,NULL);
// Allocate the various buffers used by Modes // Allocate the various buffers used by Modes
if ( NULL == (Modes.icao_cache = (uint32_t *) malloc(sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2))) if ( NULL == (Modes.icao_cache = (uint32_t *) malloc(sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2)))
{ {
@ -104,6 +109,7 @@ void ppup1090Init(void) {
modesInitErrorInfo(); modesInitErrorInfo();
// Setup the uploader - read the user paramaters from the coaa.h header file // Setup the uploader - read the user paramaters from the coaa.h header file
coaa1090.ppIPAddr = ppup1090.net_pp_ipaddr;
coaa1090.fUserLat = MODES_USER_LATITUDE_DFLT; coaa1090.fUserLat = MODES_USER_LATITUDE_DFLT;
coaa1090.fUserLon = MODES_USER_LONGITUDE_DFLT; coaa1090.fUserLon = MODES_USER_LONGITUDE_DFLT;
strcpy(coaa1090.strAuthCode,STR(USER_AUTHCODE)); strcpy(coaa1090.strAuthCode,STR(USER_AUTHCODE));
@ -126,6 +132,7 @@ void showHelp(void) {
"-----------------------------------------------------------------------------\n" "-----------------------------------------------------------------------------\n"
"--net-bo-ipaddr <IPv4> TCP Beast output listen IPv4 (default: 127.0.0.1)\n" "--net-bo-ipaddr <IPv4> TCP Beast output listen IPv4 (default: 127.0.0.1)\n"
"--net-bo-port <port> TCP Beast output listen port (default: 30005)\n" "--net-bo-port <port> TCP Beast output listen port (default: 30005)\n"
"--net-pp-ipaddr <IPv4> Plane Plotter LAN IPv4 Address (default: 0.0.0.0)\n"
"--quiet Disable output to stdout. Use for daemon applications\n" "--quiet Disable output to stdout. Use for daemon applications\n"
"--help Show this help\n" "--help Show this help\n"
); );
@ -185,6 +192,8 @@ int main(int argc, char **argv) {
Modes.net_input_beast_port = atoi(argv[++j]); Modes.net_input_beast_port = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-bo-ipaddr") && more) { } else if (!strcmp(argv[j],"--net-bo-ipaddr") && more) {
strcpy(ppup1090.net_input_beast_ipaddr, argv[++j]); strcpy(ppup1090.net_input_beast_ipaddr, argv[++j]);
} else if (!strcmp(argv[j],"--net-pp-ipaddr") && more) {
inet_aton(argv[++j], (void *)&ppup1090.net_pp_ipaddr);
} else if (!strcmp(argv[j],"--quiet")) { } else if (!strcmp(argv[j],"--quiet")) {
ppup1090.quiet = 1; ppup1090.quiet = 1;
} else if (!strcmp(argv[j],"--help")) { } else if (!strcmp(argv[j],"--help")) {
@ -199,7 +208,7 @@ int main(int argc, char **argv) {
#ifdef _WIN32 #ifdef _WIN32
// Try to comply with the Copyright license conditions for binary distribution // Try to comply with the Copyright license conditions for binary distribution
if (!Modes.quiet) {showCopyright();} if (!ppup1090.quiet) {showCopyright();}
#endif #endif
// Initialization // Initialization
@ -213,18 +222,18 @@ int main(int argc, char **argv) {
// //
// Setup a service callback client structure for a beast binary input (from dump1090) // Setup a service callback client structure for a beast binary input (from dump1090)
// This is a bit dodgy under Windows. The fd parameter is a handle to the internet // This is a bit dodgy under Windows. The fd parameter is a handle to the internet
// socket on which we are receiving data. Under Linux, these seem to start at 0 and // socket on which we are receiving data. Under Linux, these seem to start at 0 and
// count upwards. However, Windows uses "HANDLES" and these don't nececeriy start at 0. // count upwards. However, Windows uses "HANDLES" and these don't nececeriy start at 0.
// dump1090 limits fd to values less than 1024, and then uses the fd parameter to // dump1090 limits fd to values less than 1024, and then uses the fd parameter to
// index into an array of clients. This is ok-ish if handles are allocated up from 0. // index into an array of clients. This is ok-ish if handles are allocated up from 0.
// However, there is no gaurantee that Windows will behave like this, and if Windows // However, there is no gaurantee that Windows will behave like this, and if Windows
// allocates a handle greater than 1024, then dump1090 won't like it. On my test machine, // allocates a handle greater than 1024, then dump1090 won't like it. On my test machine,
// the first Windows handle is usually in the 0x54 (84 decimal) region. // the first Windows handle is usually in the 0x54 (84 decimal) region.
c = (struct client *) malloc(sizeof(*c)); c = (struct client *) malloc(sizeof(*c));
c->next = NULL; c->next = NULL;
c->buflen = 0; c->buflen = 0;
c->fd = c->fd =
c->service = c->service =
Modes.bis = fd; Modes.bis = fd;
Modes.clients = c; Modes.clients = c;
@ -237,7 +246,7 @@ int main(int argc, char **argv) {
} }
// The user has stopped us, so close any socket we opened // The user has stopped us, so close any socket we opened
if (fd != ANET_ERR) if (fd != ANET_ERR)
{close(fd);} {close(fd);}
closeCOAA (); closeCOAA ();

View File

@ -45,6 +45,9 @@
#include <math.h> #include <math.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/timeb.h> #include <sys/timeb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <signal.h> #include <signal.h>
#include <fcntl.h> #include <fcntl.h>
#include <ctype.h> #include <ctype.h>
@ -69,19 +72,21 @@
// Program global state // Program global state
struct { // Internal state struct { // Internal state
int quiet; int quiet;
// Networking // Networking
char net_input_beast_ipaddr[32]; // IPv4 address or network name of server/RPi uint32_t net_pp_ipaddr; // IPv4 address of PP instance
char net_input_beast_ipaddr[32]; // IPv4 address or network name of server/RPi
} ppup1090; } ppup1090;
// COAA Initialisation structure // COAA Initialisation structure
struct _coaa1090 { struct _coaa1090 {
double fUserLat; uint32_t ppIPAddr;
double fUserLon; double fUserLat;
char strAuthCode[16]; double fUserLon;
char strRegNo[16]; char strAuthCode[16];
char strVersion[16]; char strRegNo[16];
char strVersion[16];
} coaa1090; } coaa1090;
// ======================== function declarations ========================= // ======================== function declarations =========================

85
ppup1090.sh Normal file
View File

@ -0,0 +1,85 @@
#!/bin/bash
### BEGIN INIT INFO
#
# Provides: dump1090
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: dump1090 initscript
#
### END INIT INFO
## Fill in name of program here.
PROG="dump1090"
PROG_PATH="/home/pi/dump1090"
PROG_ARGS="--quiet --net --net-ro-size 500 --net-ro-rate 5 --net-buffer 5"
PIDFILE="/var/run/dump1090.pid"
PROG2="ppup1090"
PROG2_ARGS="--quiet --net-pp-addr 192.168.1.64"
PIDFILE2="/var/run/$PROG2.pid"
DELAY=5
start() {
if [ -e $PIDFILE ]; then
## Program is running, exit with error.
echo "Error! $PROG is currently running!" 1>&2
exit 1
else
## Change from /dev/null to something like /var/log/$PROG if you want to save output.
cd $PROG_PATH
./$PROG $PROG_ARGS 2>&1 >/dev/null &
echo "$PROG started, waiting $DELAY seconds"
touch $PIDFILE
sleep $DELAY
echo "Attempting to start $PROG2.."
./$PROG2 $PROG2_ARGS 2>1 >/dev/null &
echo "$PROG2 started"
touch $PIDFILE2
fi
}
stop() {
if [ -e $PIDFILE ]; then
## Program is running, so stop it
echo "$PROG is running"
killall $PROG2
killall $PROG
rm -f $PIDFILE2
rm -f $PIDFILE
echo "$PROG stopped"
else
## Program is not running, exit with error.
echo "Error! $PROG not started!" 1>&2
exit 1
fi
}
## Check to see if we are running as root first.
## Found at http://www.cyberciti.biz/tips/shell-root-user-check-script.html
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
case "$1" in
start)
start
exit 0
;;
stop)
stop
exit 0
;;
reload|restart|force-reload)
stop
start
exit 0
;;
**)
echo "Usage: $0 {start|stop|reload}" 1>&2
exit 1
;;
esac
#

View File

@ -83,6 +83,21 @@ void view1090InitConfig(void) {
// //
void view1090Init(void) { void view1090Init(void) {
pthread_mutex_init(&Modes.pDF_mutex,NULL);
pthread_mutex_init(&Modes.data_mutex,NULL);
pthread_cond_init(&Modes.data_cond,NULL);
#ifdef _WIN32
if ( (!Modes.wsaData.wVersion)
&& (!Modes.wsaData.wHighVersion) ) {
// Try to start the windows socket support
if (WSAStartup(MAKEWORD(2,1),&Modes.wsaData) != 0)
{
fprintf(stderr, "WSAStartup returned Error\n");
}
}
#endif
// Allocate the various buffers used by Modes // Allocate the various buffers used by Modes
if ( NULL == (Modes.icao_cache = (uint32_t *) malloc(sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2))) if ( NULL == (Modes.icao_cache = (uint32_t *) malloc(sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2)))
{ {
@ -262,6 +277,7 @@ int main(int argc, char **argv) {
#ifdef _WIN32 #ifdef _WIN32
// Try to comply with the Copyright license conditions for binary distribution // Try to comply with the Copyright license conditions for binary distribution
if (!Modes.quiet) {showCopyright();} if (!Modes.quiet) {showCopyright();}
#define MSG_DONTWAIT 0
#endif #endif
#ifndef _WIN32 #ifndef _WIN32