diff --git a/dump1090.h b/dump1090.h index d2c602a..21ea3bf 100644 --- a/dump1090.h +++ b/dump1090.h @@ -256,6 +256,9 @@ typedef enum { #define MAX_AMPLITUDE 65535.0 #define MAX_POWER (MAX_AMPLITUDE * MAX_AMPLITUDE) +#define FAUP_DEFAULT_RATE_MULTIPLIER 1.0 // FA Upload rate multiplier + + // Include subheaders after all the #defines are in place #include "util.h" @@ -357,6 +360,7 @@ struct _Modes { // Internal state uint64_t json_interval; // Interval between rewriting the json aircraft file, in milliseconds; also the advertised map refresh interval uint64_t json_stats_interval; // Interval between rewriting the json stats file, in milliseconds int json_location_accuracy; // Accuracy of location metadata: 0=none, 1=approx, 2=exact + double faup_rate_multiplier; // Multiplier to adjust rate of faup1090 messages emitted int json_aircraft_history_next; struct { diff --git a/faup1090.c b/faup1090.c index cf83db9..a13c677 100644 --- a/faup1090.c +++ b/faup1090.c @@ -77,6 +77,7 @@ static void faupInitConfig(void) { Modes.quiet = 1; Modes.net_output_flush_size = MODES_OUT_FLUSH_SIZE; Modes.net_output_flush_interval = 200; // milliseconds + Modes.faup_rate_multiplier = FAUP_DEFAULT_RATE_MULTIPLIER; } // @@ -149,7 +150,7 @@ int main(int argc, char **argv) { char *bo_connect_ipaddr = "127.0.0.1"; int bo_connect_port = 30005; struct client *c; - struct net_service *beast_input, *fatsv_output; + struct net_service *beast_input, *fatsv_output, *fa_cmd_input; // Set sane defaults faupInitConfig(); @@ -207,6 +208,9 @@ int main(int argc, char **argv) { fatsv_output = makeFatsvOutputService(); createGenericClient(fatsv_output, STDOUT_FILENO); + fa_cmd_input = makeFaCmdInputService(); + createGenericClient(fa_cmd_input, STDIN_FILENO); + // Run it until we've lost either connection while (!Modes.exit && beast_input->connections && fatsv_output->connections) { struct timespec r = { 0, 100 * 1000 * 1000}; diff --git a/net_io.c b/net_io.c index 8cb1e28..dfeecad 100644 --- a/net_io.c +++ b/net_io.c @@ -71,6 +71,7 @@ static int handleBeastCommand(struct client *c, char *p); static int decodeBinMessage(struct client *c, char *p); static int decodeHexMessage(struct client *c, char *hex); +static int handleFaupCommand(struct client *c, char *hex); static void moveNetClient(struct client *c, struct net_service *new_service); @@ -250,6 +251,11 @@ struct net_service *makeFatsvOutputService(void) return serviceInit("FATSV TCP output", &Modes.fatsv_out, NULL, READ_MODE_IGNORE, NULL, NULL); } +struct net_service *makeFaCmdInputService(void) +{ + return serviceInit("faup Command input", NULL, NULL, READ_MODE_ASCII, "\n", handleFaupCommand); +} + void modesInitNet(void) { struct net_service *s; @@ -1109,6 +1115,37 @@ static void moveNetClient(struct client *c, struct net_service *new_service) c->service = new_service; } +static int handleFaupCommand(struct client *c, char *p) { + if (p == NULL) + return 0; + + MODES_NOTUSED(c); + char* msg_field; + double multiplier; + msg_field = strtok (p, "\t"); + + // Traverse through message for commands + while (msg_field != NULL) { + if (strcmp(msg_field, "upload_rate_multiplier") == 0) { + msg_field = strtok (NULL, "\t"); + multiplier = atof(msg_field); + + // Sanity check on multiplier value + if (!(multiplier > 0 && multiplier <= 100)) { + fprintf(stderr, "handleFaupCommand(): upload_rate_multiplier (%0.2f) out of range\n", multiplier); + return 0; + } + + fprintf(stderr, "handleFaupCommand(): Adjusting message rate to FlightAware by %0.2fx\n", multiplier); + Modes.faup_rate_multiplier = multiplier; + break; + } + msg_field = strtok (NULL, "\t"); + } + + return 0; +} + // // Handle a Beast command message. // Currently, we just look for the Mode A/C command message @@ -2466,6 +2503,7 @@ static void writeFATSV() (trackDataValid(&a->emergency_valid) && a->emergency != a->fatsv_emitted_emergency); uint64_t minAge; + double adjustedMinAge; if (immediate) { // a change we want to emit right away minAge = 0; @@ -2485,8 +2523,12 @@ static void writeFATSV() minAge = (changed ? 10000 : 30000); } - if ((now - a->fatsv_last_emitted) < minAge) + // Adjust rate for multiplier + adjustedMinAge = minAge / Modes.faup_rate_multiplier; + + if ((now - a->fatsv_last_emitted) < adjustedMinAge) { continue; + } char *p = prepareWrite(&Modes.fatsv_out, TSV_MAX_PACKET_SIZE); if (!p) diff --git a/net_io.h b/net_io.h index 2c39f6f..661cdb4 100644 --- a/net_io.h +++ b/net_io.h @@ -80,6 +80,7 @@ struct client *createGenericClient(struct net_service *service, int fd); // view1090 / faup1090 want to create these themselves: struct net_service *makeBeastInputService(void); struct net_service *makeFatsvOutputService(void); +struct net_service *makeFaCmdInputService(void); void sendBeastSettings(struct client *c, const char *settings);