Add generation of history JSON.

Add support for URL handlers that match a path prefix.

(cherry picked from commit 38faa510cb881cbf9d2a0a85bbde61130b5259e7)
This commit is contained in:
Oliver Jowett 2015-01-15 20:55:55 +00:00
parent b1bfb4d520
commit 1db63ebc65
3 changed files with 53 additions and 7 deletions

View file

@ -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;
}
}
//

View file

@ -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
}

View file

@ -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)