diff --git a/dump1090.c b/dump1090.c index f584553..0039085 100644 --- a/dump1090.c +++ b/dump1090.c @@ -680,7 +680,8 @@ static void display_stats(void) { // void backgroundTasks(void) { static time_t next_stats; - static time_t next_json; + static time_t next_json, next_history; + time_t now = time(NULL); if (Modes.net) { @@ -709,6 +710,20 @@ void backgroundTasks(void) { writeJsonToFile("aircraft.json", generateAircraftJson); next_json = now + Modes.json_interval; } + + if ((Modes.json_dir || Modes.net_http_port) && now >= next_history) { + char filebuf[PATH_MAX]; + + free(Modes.json_aircraft_history[Modes.json_aircraft_history_next].content); // might be NULL, that's OK. + Modes.json_aircraft_history[Modes.json_aircraft_history_next].content = + generateAircraftJson("/data/aircraft.json", &Modes.json_aircraft_history[Modes.json_aircraft_history_next].clen); + + snprintf(filebuf, PATH_MAX, "history_%d.json", Modes.json_aircraft_history_next); + writeJsonToFile(filebuf, generateHistoryJson); + + Modes.json_aircraft_history_next = (Modes.json_aircraft_history_next+1) % HISTORY_SIZE; + next_history = now + HISTORY_INTERVAL; + } } // diff --git a/dump1090.h b/dump1090.h index 236cdda..5e1a4aa 100644 --- a/dump1090.h +++ b/dump1090.h @@ -214,6 +214,9 @@ struct client { char buf[MODES_CLIENT_BUF_SIZE+1]; // Read buffer }; +#define HISTORY_SIZE 240 +#define HISTORY_INTERVAL 15 + // Structure used to describe an aircraft in iteractive mode struct aircraft { uint32_t addr; // ICAO address @@ -362,6 +365,12 @@ struct { // Internal state int json_interval; // Interval between rewriting the json aircraft file int json_location_accuracy; // Accuracy of location metadata: 0=none, 1=approx, 2=exact + int json_aircraft_history_next; + struct { + char *content; + int clen; + } json_aircraft_history[HISTORY_SIZE]; + // User details double fUserLat; // Users receiver/antenna lat/lon needed for initial surface location double fUserLon; // Users receiver/antenna lat/lon needed for initial surface location @@ -487,6 +496,7 @@ void modesNetPeriodicWork (void); void writeJsonToFile(const char *file, char * (*generator) (const char*,int*)); char *generateAircraftJson(const char *url_path, int *len); char *generateReceiverJson(const char *url_path, int *len); +char *generateHistoryJson(const char *url_path, int *len); #ifdef __cplusplus } diff --git a/net_io.c b/net_io.c index 46af05d..e5a7859 100644 --- a/net_io.c +++ b/net_io.c @@ -742,8 +742,9 @@ char *generateReceiverJson(const char *url_path, int *len) p += sprintf(p, "{ " \ "\"version\" : \"%s\", " - "\"refresh\" : %d", - MODES_DUMP1090_VERSION, Modes.json_interval * 1000); + "\"refresh\" : %d, " + "\"history\" : %d", + MODES_DUMP1090_VERSION, Modes.json_interval * 1000, HISTORY_SIZE); if (Modes.json_location_accuracy && (Modes.fUserLat != 0.0 || Modes.fUserLon != 0.0)) { if (Modes.json_location_accuracy == 1) { @@ -765,6 +766,23 @@ char *generateReceiverJson(const char *url_path, int *len) return buf; } +char *generateHistoryJson(const char *url_path, int *len) +{ + int history_index = -1; + + if (sscanf(url_path, "/data/history_%d.json", &history_index) != 1) + return NULL; + + if (history_index < 0 || history_index >= HISTORY_SIZE) + return NULL; + + if (!Modes.json_aircraft_history[history_index].content) + return NULL; + + *len = Modes.json_aircraft_history[history_index].clen; + return strdup(Modes.json_aircraft_history[history_index].content); +} + // Write JSON to file void writeJsonToFile(const char *file, char * (*generator) (const char *,int*)) { @@ -828,10 +846,12 @@ static struct { char *path; char * (*handler)(const char*,int*); char *content_type; + int prefix; } url_handlers[] = { - { "/data/aircraft.json", generateAircraftJson, MODES_CONTENT_TYPE_JSON }, - { "/data/receiver.json", generateReceiverJson, MODES_CONTENT_TYPE_JSON }, - { NULL, NULL, NULL } + { "/data/aircraft.json", generateAircraftJson, MODES_CONTENT_TYPE_JSON, 0 }, + { "/data/receiver.json", generateReceiverJson, MODES_CONTENT_TYPE_JSON, 0 }, + { "/data/history_", generateHistoryJson, MODES_CONTENT_TYPE_JSON, 1 }, + { NULL, NULL, NULL, 0 } }; // @@ -887,7 +907,8 @@ int handleHTTPRequest(struct client *c, char *p) { statuscode = 404; statusmsg = "Not Found"; for (i = 0; url_handlers[i].path; ++i) { - if (!strcmp(url, url_handlers[i].path)) { + if ((url_handlers[i].prefix && !strncmp(url, url_handlers[i].path, strlen(url_handlers[i].path))) || + (!url_handlers[i].prefix && !strcmp(url, url_handlers[i].path))) { content_type = url_handlers[i].content_type; content = url_handlers[i].handler(url, &clen); if (!content)