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:
parent
b1bfb4d520
commit
1db63ebc65
17
dump1090.c
17
dump1090.c
|
@ -680,7 +680,8 @@ static void display_stats(void) {
|
||||||
//
|
//
|
||||||
void backgroundTasks(void) {
|
void backgroundTasks(void) {
|
||||||
static time_t next_stats;
|
static time_t next_stats;
|
||||||
static time_t next_json;
|
static time_t next_json, next_history;
|
||||||
|
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
|
||||||
if (Modes.net) {
|
if (Modes.net) {
|
||||||
|
@ -709,6 +710,20 @@ void backgroundTasks(void) {
|
||||||
writeJsonToFile("aircraft.json", generateAircraftJson);
|
writeJsonToFile("aircraft.json", generateAircraftJson);
|
||||||
next_json = now + Modes.json_interval;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
10
dump1090.h
10
dump1090.h
|
@ -214,6 +214,9 @@ struct client {
|
||||||
char buf[MODES_CLIENT_BUF_SIZE+1]; // Read buffer
|
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
|
// Structure used to describe an aircraft in iteractive mode
|
||||||
struct aircraft {
|
struct aircraft {
|
||||||
uint32_t addr; // ICAO address
|
uint32_t addr; // ICAO address
|
||||||
|
@ -362,6 +365,12 @@ struct { // Internal state
|
||||||
int json_interval; // Interval between rewriting the json aircraft file
|
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_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
|
// User details
|
||||||
double fUserLat; // Users receiver/antenna lat/lon needed for initial surface location
|
double fUserLat; // Users receiver/antenna lat/lon needed for initial surface location
|
||||||
double fUserLon; // 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*));
|
void writeJsonToFile(const char *file, char * (*generator) (const char*,int*));
|
||||||
char *generateAircraftJson(const char *url_path, int *len);
|
char *generateAircraftJson(const char *url_path, int *len);
|
||||||
char *generateReceiverJson(const char *url_path, int *len);
|
char *generateReceiverJson(const char *url_path, int *len);
|
||||||
|
char *generateHistoryJson(const char *url_path, int *len);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
33
net_io.c
33
net_io.c
|
@ -742,8 +742,9 @@ char *generateReceiverJson(const char *url_path, int *len)
|
||||||
|
|
||||||
p += sprintf(p, "{ " \
|
p += sprintf(p, "{ " \
|
||||||
"\"version\" : \"%s\", "
|
"\"version\" : \"%s\", "
|
||||||
"\"refresh\" : %d",
|
"\"refresh\" : %d, "
|
||||||
MODES_DUMP1090_VERSION, Modes.json_interval * 1000);
|
"\"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 && (Modes.fUserLat != 0.0 || Modes.fUserLon != 0.0)) {
|
||||||
if (Modes.json_location_accuracy == 1) {
|
if (Modes.json_location_accuracy == 1) {
|
||||||
|
@ -765,6 +766,23 @@ char *generateReceiverJson(const char *url_path, int *len)
|
||||||
return buf;
|
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
|
// Write JSON to file
|
||||||
void writeJsonToFile(const char *file, char * (*generator) (const char *,int*))
|
void writeJsonToFile(const char *file, char * (*generator) (const char *,int*))
|
||||||
{
|
{
|
||||||
|
@ -828,10 +846,12 @@ static struct {
|
||||||
char *path;
|
char *path;
|
||||||
char * (*handler)(const char*,int*);
|
char * (*handler)(const char*,int*);
|
||||||
char *content_type;
|
char *content_type;
|
||||||
|
int prefix;
|
||||||
} url_handlers[] = {
|
} url_handlers[] = {
|
||||||
{ "/data/aircraft.json", generateAircraftJson, MODES_CONTENT_TYPE_JSON },
|
{ "/data/aircraft.json", generateAircraftJson, MODES_CONTENT_TYPE_JSON, 0 },
|
||||||
{ "/data/receiver.json", generateReceiverJson, MODES_CONTENT_TYPE_JSON },
|
{ "/data/receiver.json", generateReceiverJson, MODES_CONTENT_TYPE_JSON, 0 },
|
||||||
{ NULL, NULL, NULL }
|
{ "/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;
|
statuscode = 404;
|
||||||
statusmsg = "Not Found";
|
statusmsg = "Not Found";
|
||||||
for (i = 0; url_handlers[i].path; ++i) {
|
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_type = url_handlers[i].content_type;
|
||||||
content = url_handlers[i].handler(url, &clen);
|
content = url_handlers[i].handler(url, &clen);
|
||||||
if (!content)
|
if (!content)
|
||||||
|
|
Loading…
Reference in a new issue