Merge remote-tracking branch 'upstream/master' into net-cleanups
This commit is contained in:
commit
29d1e53f9f
BIN
coaa1090.obj
BIN
coaa1090.obj
Binary file not shown.
Binary file not shown.
|
@ -406,6 +406,7 @@ void showHelp(void) {
|
||||||
"--net Enable networking\n"
|
"--net Enable networking\n"
|
||||||
"--modeac Enable decoding of SSR Modes 3/A & 3/C\n"
|
"--modeac Enable decoding of SSR Modes 3/A & 3/C\n"
|
||||||
"--net-only Enable just networking, no RTL device or file used\n"
|
"--net-only Enable just networking, no RTL device or file used\n"
|
||||||
|
"--net-bind-address <ip> IP address to bind to (default: Any; Use 127.0.0.1 for private)\n"
|
||||||
"--net-http-port <port> HTTP server port (default: 8080)\n"
|
"--net-http-port <port> HTTP server port (default: 8080)\n"
|
||||||
"--net-ri-port <port> TCP raw input listen port (default: 30001)\n"
|
"--net-ri-port <port> TCP raw input listen port (default: 30001)\n"
|
||||||
"--net-ro-port <port> TCP raw output listen port (default: 30002)\n"
|
"--net-ro-port <port> TCP raw output listen port (default: 30002)\n"
|
||||||
|
@ -715,6 +716,8 @@ int main(int argc, char **argv) {
|
||||||
Modes.net_output_beast_port = atoi(argv[++j]);
|
Modes.net_output_beast_port = atoi(argv[++j]);
|
||||||
} else if (!strcmp(argv[j],"--net-bi-port") && more) {
|
} else if (!strcmp(argv[j],"--net-bi-port") && more) {
|
||||||
Modes.net_input_beast_port = atoi(argv[++j]);
|
Modes.net_input_beast_port = atoi(argv[++j]);
|
||||||
|
} else if (!strcmp(argv[j],"--net-bind-address") && more) {
|
||||||
|
Modes.net_bind_address = strdup(argv[++j]);
|
||||||
} else if (!strcmp(argv[j],"--net-http-port") && more) {
|
} else if (!strcmp(argv[j],"--net-http-port") && more) {
|
||||||
Modes.net_http_port = atoi(argv[++j]);
|
Modes.net_http_port = atoi(argv[++j]);
|
||||||
} else if (!strcmp(argv[j],"--net-sbs-port") && more) {
|
} else if (!strcmp(argv[j],"--net-sbs-port") && more) {
|
||||||
|
|
|
@ -131,6 +131,10 @@ SOURCE=.\winstubs.h
|
||||||
# Begin Group "Resource Files"
|
# Begin Group "Resource Files"
|
||||||
|
|
||||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\Dump1090.rc
|
||||||
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "Library Files"
|
# Begin Group "Library Files"
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
// 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.09.0608.14"
|
#define MODES_DUMP1090_VERSION "1.10.3010.14"
|
||||||
|
|
||||||
// ============================= Include files ==========================
|
// ============================= Include files ==========================
|
||||||
|
|
||||||
|
@ -310,6 +310,7 @@ struct { // Internal state
|
||||||
int net_input_raw_port; // Raw input TCP port
|
int net_input_raw_port; // Raw input TCP port
|
||||||
int net_output_beast_port; // Beast output TCP port
|
int net_output_beast_port; // Beast output TCP port
|
||||||
int net_input_beast_port; // Beast input TCP port
|
int net_input_beast_port; // Beast input TCP port
|
||||||
|
char *net_bind_address; // Bind address
|
||||||
int net_http_port; // HTTP port
|
int net_http_port; // HTTP port
|
||||||
int net_sndbuf_size; // TCP output buffer size (64Kb * 2^n)
|
int net_sndbuf_size; // TCP output buffer size (64Kb * 2^n)
|
||||||
int quiet; // Suppress stdout
|
int quiet; // Suppress stdout
|
||||||
|
|
115
dump1090.rc
Normal file
115
dump1090.rc
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
//Microsoft Developer Studio generated resource script.
|
||||||
|
//
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
|
#define APSTUDIO_READONLY_SYMBOLS
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Generated from the TEXTINCLUDE 2 resource.
|
||||||
|
//
|
||||||
|
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||||
|
#include "windows.h"
|
||||||
|
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||||
|
#include "ntverp.h"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// English (U.S.) resources
|
||||||
|
|
||||||
|
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||||
|
#ifdef _WIN32
|
||||||
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
|
#pragma code_page(1252)
|
||||||
|
#endif //_WIN32
|
||||||
|
|
||||||
|
#ifndef _MAC
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Version
|
||||||
|
//
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION 1,10,2910,14
|
||||||
|
PRODUCTVERSION 1,10,2910,14
|
||||||
|
FILEFLAGSMASK 0x3fL
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS 0x1L
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0x0L
|
||||||
|
#endif
|
||||||
|
FILEOS 0x40004L
|
||||||
|
FILETYPE 0x3L
|
||||||
|
FILESUBTYPE 0x7L
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904b0"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Comments", "Dump1090 for Win32 \0"
|
||||||
|
VALUE "CompanyName", "\0"
|
||||||
|
VALUE "FileDescription", "Mode A/C/S decoder for RTL Dongles\0"
|
||||||
|
VALUE "FileVersion", "1, 10, 2910, 14\0"
|
||||||
|
VALUE "InternalName", "DUMP1090.EXE\0"
|
||||||
|
VALUE "LegalCopyright", "Copyright © 2012 by Salvatore Sanfilippo <antirez@gmail.com>\r\nCopyright © 2014 by Malcolm Robb <support@attavionics.com>\0"
|
||||||
|
VALUE "LegalTrademarks", "\0"
|
||||||
|
VALUE "OriginalFilename", "DUMP1090.EXE\0"
|
||||||
|
VALUE "PrivateBuild", "\0"
|
||||||
|
VALUE "ProductName", "DUMP1090\0"
|
||||||
|
VALUE "ProductVersion", "1, 10, 2910, 14\0"
|
||||||
|
VALUE "SpecialBuild", "\0"
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x409, 1200
|
||||||
|
END
|
||||||
|
END
|
||||||
|
|
||||||
|
#endif // !_MAC
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// TEXTINCLUDE
|
||||||
|
//
|
||||||
|
|
||||||
|
1 TEXTINCLUDE DISCARDABLE
|
||||||
|
BEGIN
|
||||||
|
"resource.h\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
2 TEXTINCLUDE DISCARDABLE
|
||||||
|
BEGIN
|
||||||
|
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||||
|
"#include ""windows.h""\r\n"
|
||||||
|
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||||
|
"#include ""ntverp.h""\r\n"
|
||||||
|
"\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
3 TEXTINCLUDE DISCARDABLE
|
||||||
|
BEGIN
|
||||||
|
"\r\n"
|
||||||
|
"\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
#endif // APSTUDIO_INVOKED
|
||||||
|
|
||||||
|
#endif // English (U.S.) resources
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef APSTUDIO_INVOKED
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Generated from the TEXTINCLUDE 3 resource.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // not APSTUDIO_INVOKED
|
||||||
|
|
107
mode_s.c
107
mode_s.c
|
@ -1456,46 +1456,75 @@ int detectOutOfPhase(uint16_t *pPreamble) {
|
||||||
if (pPreamble[-1] > pPreamble[1]/3) return -1;
|
if (pPreamble[-1] > pPreamble[1]/3) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t clamped_scale(uint16_t v, uint16_t scale) {
|
||||||
|
uint32_t scaled = (uint32_t)v * scale / 16384;
|
||||||
|
if (scaled > 65535) return 65535;
|
||||||
|
return (uint16_t) scaled;
|
||||||
|
}
|
||||||
|
// This function decides whether we are sampling early or late,
|
||||||
|
// and by approximately how much, by looking at the energy in
|
||||||
|
// preamble bits before and after the expected pulse locations.
|
||||||
//
|
//
|
||||||
//=========================================================================
|
// It then deals with one sample pair at a time, comparing samples
|
||||||
//
|
// to make a decision about the bit value. Based on this decision it
|
||||||
// This function does not really correct the phase of the message, it just
|
// modifies the sample value of the *adjacent* sample which will
|
||||||
// applies a transformation to the first sample representing a given bit:
|
// contain some of the energy from the bit we just inspected.
|
||||||
//
|
|
||||||
// If the previous bit was one, we amplify it a bit.
|
|
||||||
// If the previous bit was zero, we decrease it a bit.
|
|
||||||
//
|
|
||||||
// This simple transformation makes the message a bit more likely to be
|
|
||||||
// correctly decoded for out of phase messages:
|
|
||||||
//
|
|
||||||
// When messages are out of phase there is more uncertainty in
|
|
||||||
// sequences of the same bit multiple times, since 11111 will be
|
|
||||||
// transmitted as continuously altering magnitude (high, low, high, low...)
|
|
||||||
//
|
|
||||||
// However because the message is out of phase some part of the high
|
|
||||||
// is mixed in the low part, so that it is hard to distinguish if it is
|
|
||||||
// a zero or a one.
|
|
||||||
//
|
|
||||||
// However when the message is out of phase passing from 0 to 1 or from
|
|
||||||
// 1 to 0 happens in a very recognizable way, for instance in the 0 -> 1
|
|
||||||
// transition, magnitude goes low, high, high, low, and one of of the
|
|
||||||
// two middle samples the high will be *very* high as part of the previous
|
|
||||||
// or next high signal will be mixed there.
|
|
||||||
//
|
|
||||||
// Applying our simple transformation we make more likely if the current
|
|
||||||
// bit is a zero, to detect another zero. Symmetrically if it is a one
|
|
||||||
// it will be more likely to detect a one because of the transformation.
|
|
||||||
// In this way similar levels will be interpreted more likely in the
|
|
||||||
// correct way.
|
|
||||||
//
|
//
|
||||||
|
// pPayload[0] should be the start of the preamble,
|
||||||
|
// pPayload[-1 .. MODES_PREAMBLE_SAMPLES + MODES_LONG_MSG_SAMPLES - 1] should be accessible.
|
||||||
|
// pPayload[MODES_PREAMBLE_SAMPLES .. MODES_PREAMBLE_SAMPLES + MODES_LONG_MSG_SAMPLES - 1] will be updated.
|
||||||
void applyPhaseCorrection(uint16_t *pPayload) {
|
void applyPhaseCorrection(uint16_t *pPayload) {
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (j = 0; j < MODES_LONG_MSG_SAMPLES; j += 2, pPayload += 2) {
|
// we expect 1 bits at 0, 2, 7, 9
|
||||||
if (pPayload[0] > pPayload[1]) { // One
|
// and 0 bits at -1, 1, 3, 4, 5, 6, 8, 10, 11, 12, 13, 14
|
||||||
pPayload[2] = (pPayload[2] * 5) / 4;
|
// use bits -1,6 for early detection (bit 0/7 arrived a little early, our sample period starts after the bit phase so we include some of the next bit)
|
||||||
} else { // Zero
|
// use bits 3,10 for late detection (bit 2/9 arrived a little late, our sample period starts before the bit phase so we include some of the last bit)
|
||||||
pPayload[2] = (pPayload[2] * 4) / 5;
|
|
||||||
|
uint32_t onTime = (pPayload[0] + pPayload[2] + pPayload[7] + pPayload[9]);
|
||||||
|
uint32_t early = (pPayload[-1] + pPayload[6]) << 1;
|
||||||
|
uint32_t late = (pPayload[3] + pPayload[10]) << 1;
|
||||||
|
|
||||||
|
if (early > late) {
|
||||||
|
// Our sample period starts late and so includes some of the next bit.
|
||||||
|
|
||||||
|
uint16_t scaleUp = 16384 + 16384 * early / (early + onTime); // 1 + early / (early+onTime)
|
||||||
|
uint16_t scaleDown = 16384 - 16384 * early / (early + onTime); // 1 - early / (early+onTime)
|
||||||
|
|
||||||
|
// trailing bits are 0; final data sample will be a bit low.
|
||||||
|
pPayload[MODES_PREAMBLE_SAMPLES + MODES_LONG_MSG_SAMPLES - 1] =
|
||||||
|
clamped_scale(pPayload[MODES_PREAMBLE_SAMPLES + MODES_LONG_MSG_SAMPLES - 1], scaleUp);
|
||||||
|
for (j = MODES_PREAMBLE_SAMPLES + MODES_LONG_MSG_SAMPLES - 2; j > MODES_PREAMBLE_SAMPLES; j -= 2) {
|
||||||
|
if (pPayload[j] > pPayload[j+1]) {
|
||||||
|
// x [1 0] y
|
||||||
|
// x overlapped with the "1" bit and is slightly high
|
||||||
|
pPayload[j-1] = clamped_scale(pPayload[j-1], scaleDown);
|
||||||
|
} else {
|
||||||
|
// x [0 1] y
|
||||||
|
// x overlapped with the "0" bit and is slightly low
|
||||||
|
pPayload[j-1] = clamped_scale(pPayload[j-1], scaleUp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Our sample period starts early and so includes some of the previous bit.
|
||||||
|
|
||||||
|
uint16_t scaleUp = 16384 + 16384 * late / (late + onTime); // 1 + late / (late+onTime)
|
||||||
|
uint16_t scaleDown = 16384 - 16384 * late / (late + onTime); // 1 - late / (late+onTime)
|
||||||
|
|
||||||
|
// leading bits are 0; first data sample will be a bit low.
|
||||||
|
pPayload[MODES_PREAMBLE_SAMPLES] = clamped_scale(pPayload[MODES_PREAMBLE_SAMPLES], scaleUp);
|
||||||
|
for (j = MODES_PREAMBLE_SAMPLES; j < MODES_PREAMBLE_SAMPLES + MODES_LONG_MSG_SAMPLES - 2; j += 2) {
|
||||||
|
if (pPayload[j] > pPayload[j+1]) {
|
||||||
|
// x [1 0] y
|
||||||
|
// y overlapped with the "0" bit and is slightly low
|
||||||
|
pPayload[j+2] = clamped_scale(pPayload[j+2], scaleUp);
|
||||||
|
} else {
|
||||||
|
// x [0 1] y
|
||||||
|
// y overlapped with the "1" bit and is slightly high
|
||||||
|
pPayload[j+2] = clamped_scale(pPayload[j+2], scaleDown);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1509,7 +1538,7 @@ void applyPhaseCorrection(uint16_t *pPayload) {
|
||||||
void detectModeS(uint16_t *m, uint32_t mlen) {
|
void detectModeS(uint16_t *m, uint32_t mlen) {
|
||||||
struct modesMessage mm;
|
struct modesMessage mm;
|
||||||
unsigned char msg[MODES_LONG_MSG_BYTES], *pMsg;
|
unsigned char msg[MODES_LONG_MSG_BYTES], *pMsg;
|
||||||
uint16_t aux[MODES_LONG_MSG_SAMPLES];
|
uint16_t aux[MODES_PREAMBLE_SAMPLES+MODES_LONG_MSG_SAMPLES+1];
|
||||||
uint32_t j;
|
uint32_t j;
|
||||||
int use_correction = 0;
|
int use_correction = 0;
|
||||||
|
|
||||||
|
@ -1631,10 +1660,10 @@ void detectModeS(uint16_t *m, uint32_t mlen) {
|
||||||
// If the previous attempt with this message failed, retry using
|
// If the previous attempt with this message failed, retry using
|
||||||
// magnitude correction
|
// magnitude correction
|
||||||
// Make a copy of the Payload, and phase correct the copy
|
// Make a copy of the Payload, and phase correct the copy
|
||||||
memcpy(aux, pPayload, sizeof(aux));
|
memcpy(aux, &pPreamble[-1], sizeof(aux));
|
||||||
applyPhaseCorrection(aux);
|
applyPhaseCorrection(&aux[1]);
|
||||||
Modes.stat_out_of_phase++;
|
Modes.stat_out_of_phase++;
|
||||||
pPayload = aux;
|
pPayload = &aux[1 + MODES_PREAMBLE_SAMPLES];
|
||||||
// TODO ... apply other kind of corrections
|
// TODO ... apply other kind of corrections
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
72
net_io.c
72
net_io.c
|
@ -86,7 +86,7 @@ void modesInitNet(void) {
|
||||||
for (j = 0; j < MODES_NET_SERVICES_NUM; j++) {
|
for (j = 0; j < MODES_NET_SERVICES_NUM; j++) {
|
||||||
services[j].enabled = (services[j].port != 0);
|
services[j].enabled = (services[j].port != 0);
|
||||||
if (services[j].enabled) {
|
if (services[j].enabled) {
|
||||||
int s = anetTcpServer(Modes.aneterr, services[j].port, NULL);
|
int s = anetTcpServer(Modes.aneterr, services[j].port, Modes.net_bind_address);
|
||||||
if (s == -1) {
|
if (s == -1) {
|
||||||
fprintf(stderr, "Error opening the listening port %d (%s): %s\n",
|
fprintf(stderr, "Error opening the listening port %d (%s): %s\n",
|
||||||
services[j].port, services[j].descr, Modes.aneterr);
|
services[j].port, services[j].descr, Modes.aneterr);
|
||||||
|
@ -159,7 +159,7 @@ struct client * modesAcceptClients(void) {
|
||||||
//
|
//
|
||||||
// On error free the client, collect the structure, adjust maxfd if needed.
|
// On error free the client, collect the structure, adjust maxfd if needed.
|
||||||
//
|
//
|
||||||
void modesFreeClient(struct client *c) {
|
void modesCloseClient(struct client *c) {
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
// Clean up, but defer removing from the list until modesNetCleanup().
|
// Clean up, but defer removing from the list until modesNetCleanup().
|
||||||
|
@ -200,7 +200,7 @@ static void flushWrites(struct net_writer *writer) {
|
||||||
int nwritten = send(c->fd, writer->data, writer->dataUsed, 0 );
|
int nwritten = send(c->fd, writer->data, writer->dataUsed, 0 );
|
||||||
#endif
|
#endif
|
||||||
if (nwritten != writer->dataUsed) {
|
if (nwritten != writer->dataUsed) {
|
||||||
modesFreeClient(c);
|
modesCloseClient(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -744,6 +744,7 @@ int handleHTTPRequest(struct client *c, char *p) {
|
||||||
char hdr[512];
|
char hdr[512];
|
||||||
int clen, hdrlen;
|
int clen, hdrlen;
|
||||||
int httpver, keepalive;
|
int httpver, keepalive;
|
||||||
|
int statuscode = 500;
|
||||||
char *url, *content;
|
char *url, *content;
|
||||||
char ctype[48];
|
char ctype[48];
|
||||||
char getFile[1024];
|
char getFile[1024];
|
||||||
|
@ -756,11 +757,12 @@ int handleHTTPRequest(struct client *c, char *p) {
|
||||||
httpver = (strstr(p, "HTTP/1.1") != NULL) ? 11 : 10;
|
httpver = (strstr(p, "HTTP/1.1") != NULL) ? 11 : 10;
|
||||||
if (httpver == 10) {
|
if (httpver == 10) {
|
||||||
// HTTP 1.0 defaults to close, unless otherwise specified.
|
// HTTP 1.0 defaults to close, unless otherwise specified.
|
||||||
keepalive = strstr(p, "Connection: keep-alive") != NULL;
|
//keepalive = strstr(p, "Connection: keep-alive") != NULL;
|
||||||
} else if (httpver == 11) {
|
} else if (httpver == 11) {
|
||||||
// HTTP 1.1 defaults to keep-alive, unless close is specified.
|
// HTTP 1.1 defaults to keep-alive, unless close is specified.
|
||||||
keepalive = strstr(p, "Connection: close") == NULL;
|
//keepalive = strstr(p, "Connection: close") == NULL;
|
||||||
}
|
}
|
||||||
|
keepalive = 0;
|
||||||
|
|
||||||
// Identify he URL.
|
// Identify he URL.
|
||||||
p = strchr(p,' ');
|
p = strchr(p,' ');
|
||||||
|
@ -785,22 +787,35 @@ int handleHTTPRequest(struct client *c, char *p) {
|
||||||
// "/" -> Our google map application.
|
// "/" -> Our google map application.
|
||||||
// "/data.json" -> Our ajax request to update planes.
|
// "/data.json" -> Our ajax request to update planes.
|
||||||
if (strstr(url, "/data.json")) {
|
if (strstr(url, "/data.json")) {
|
||||||
|
statuscode = 200;
|
||||||
content = aircraftsToJson(&clen);
|
content = aircraftsToJson(&clen);
|
||||||
//snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_JSON);
|
//snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_JSON);
|
||||||
} else {
|
} else {
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
char *rp, *hrp;
|
||||||
|
|
||||||
|
rp = realpath(getFile, NULL);
|
||||||
|
hrp = realpath(HTMLPATH, NULL);
|
||||||
|
hrp = (hrp ? hrp : HTMLPATH);
|
||||||
|
clen = -1;
|
||||||
|
content = strdup("Server error occured");
|
||||||
|
if (rp && (!strncmp(hrp, rp, strlen(hrp)))) {
|
||||||
if (stat(getFile, &sbuf) != -1 && (fd = open(getFile, O_RDONLY)) != -1) {
|
if (stat(getFile, &sbuf) != -1 && (fd = open(getFile, O_RDONLY)) != -1) {
|
||||||
content = (char *) malloc(sbuf.st_size);
|
content = (char *) realloc(content, sbuf.st_size);
|
||||||
if (read(fd, content, sbuf.st_size) == -1) {
|
if (read(fd, content, sbuf.st_size) != -1) {
|
||||||
snprintf(content, sbuf.st_size, "Error reading from file: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
clen = sbuf.st_size;
|
clen = sbuf.st_size;
|
||||||
|
statuscode = 200;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
char buf[128];
|
errno = ENOENT;
|
||||||
clen = snprintf(buf,sizeof(buf),"Error opening HTML file: %s", strerror(errno));
|
}
|
||||||
content = strdup(buf);
|
|
||||||
|
if (clen < 0) {
|
||||||
|
content = realloc(content, 128);
|
||||||
|
clen = snprintf(content, 128,"Error opening HTML file: %s", strerror(errno));
|
||||||
|
statuscode = 404;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd != -1) {
|
if (fd != -1) {
|
||||||
|
@ -824,7 +839,7 @@ int handleHTTPRequest(struct client *c, char *p) {
|
||||||
|
|
||||||
// Create the header and send the reply
|
// Create the header and send the reply
|
||||||
hdrlen = snprintf(hdr, sizeof(hdr),
|
hdrlen = snprintf(hdr, sizeof(hdr),
|
||||||
"HTTP/1.1 200 OK\r\n"
|
"HTTP/1.1 %d \r\n"
|
||||||
"Server: Dump1090\r\n"
|
"Server: Dump1090\r\n"
|
||||||
"Content-Type: %s\r\n"
|
"Content-Type: %s\r\n"
|
||||||
"Connection: %s\r\n"
|
"Connection: %s\r\n"
|
||||||
|
@ -832,6 +847,7 @@ int handleHTTPRequest(struct client *c, char *p) {
|
||||||
"Cache-Control: no-cache, must-revalidate\r\n"
|
"Cache-Control: no-cache, must-revalidate\r\n"
|
||||||
"Expires: Sat, 26 Jul 1997 05:00:00 GMT\r\n"
|
"Expires: Sat, 26 Jul 1997 05:00:00 GMT\r\n"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
|
statuscode,
|
||||||
ctype,
|
ctype,
|
||||||
keepalive ? "keep-alive" : "close",
|
keepalive ? "keep-alive" : "close",
|
||||||
clen);
|
clen);
|
||||||
|
@ -899,17 +915,25 @@ void modesReadFromClient(struct client *c, char *sep,
|
||||||
if (nread != left) {
|
if (nread != left) {
|
||||||
bContinue = 0;
|
bContinue = 0;
|
||||||
}
|
}
|
||||||
#ifndef _WIN32
|
|
||||||
if ( (nread < 0 && errno != EAGAIN && errno != EWOULDBLOCK) || nread == 0 ) { // Error, or end of file
|
if (nread == 0) { // End of file
|
||||||
#else
|
modesCloseClient(c);
|
||||||
if ( (nread < 0) && (errno != EWOULDBLOCK)) { // Error, or end of file
|
|
||||||
#endif
|
|
||||||
modesFreeClient(c);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nread <= 0) {
|
|
||||||
break; // Serve next client
|
#ifndef _WIN32
|
||||||
|
if (nread < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) { // No data available (not really an error)
|
||||||
|
#else
|
||||||
|
if (nread < 0 && errno == EWOULDBLOCK) { // No data available (not really an error)
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nread < 0) { // Other errors
|
||||||
|
modesCloseClient(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
c->buflen += nread;
|
c->buflen += nread;
|
||||||
|
|
||||||
// Always null-term so we are free to use strstr() (it won't affect binary case)
|
// Always null-term so we are free to use strstr() (it won't affect binary case)
|
||||||
|
@ -952,7 +976,7 @@ void modesReadFromClient(struct client *c, char *sep,
|
||||||
}
|
}
|
||||||
// Have a 0x1a followed by 1, 2 or 3 - pass message less 0x1a to handler.
|
// Have a 0x1a followed by 1, 2 or 3 - pass message less 0x1a to handler.
|
||||||
if (handler(c, s)) {
|
if (handler(c, s)) {
|
||||||
modesFreeClient(c);
|
modesCloseClient(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fullmsg = 1;
|
fullmsg = 1;
|
||||||
|
@ -968,7 +992,7 @@ void modesReadFromClient(struct client *c, char *sep,
|
||||||
while ((e = strstr(s, sep)) != NULL) { // end of first message if found
|
while ((e = strstr(s, sep)) != NULL) { // end of first message if found
|
||||||
*e = '\0'; // The handler expects null terminated strings
|
*e = '\0'; // The handler expects null terminated strings
|
||||||
if (handler(c, s)) { // Pass message to handler.
|
if (handler(c, s)) { // Pass message to handler.
|
||||||
modesFreeClient(c); // Handler returns 1 on error to signal we .
|
modesCloseClient(c); // Handler returns 1 on error to signal we .
|
||||||
return; // should close the client connection
|
return; // should close the client connection
|
||||||
}
|
}
|
||||||
s = e + strlen(sep); // Move to start of next message
|
s = e + strlen(sep); // Move to start of next message
|
||||||
|
@ -980,7 +1004,7 @@ void modesReadFromClient(struct client *c, char *sep,
|
||||||
c->buflen = &(c->buf[c->buflen]) - s; // Update the unprocessed buffer length
|
c->buflen = &(c->buf[c->buflen]) - s; // Update the unprocessed buffer length
|
||||||
memmove(c->buf, s, c->buflen); // Move what's remaining to the start of the buffer
|
memmove(c->buf, s, c->buflen); // Move what's remaining to the start of the buffer
|
||||||
} else { // If no message was decoded process the next client
|
} else { // If no message was decoded process the next client
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ CONST_ZOOMLVL = 5;
|
||||||
// The default marker color
|
// The default marker color
|
||||||
MarkerColor = "rgb(127, 127, 127)";
|
MarkerColor = "rgb(127, 127, 127)";
|
||||||
SelectedColor = "rgb(225, 225, 225)";
|
SelectedColor = "rgb(225, 225, 225)";
|
||||||
|
StaleColor = "rgb(190, 190, 190)";
|
||||||
|
|
||||||
// -- Site Settings ---------------------------------------
|
// -- Site Settings ---------------------------------------
|
||||||
SiteShow = false; // true or false
|
SiteShow = false; // true or false
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||||
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
|
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
|
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
|
||||||
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry"></script>
|
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry"></script>
|
||||||
<script type="text/javascript" src="config.js"></script>
|
<script type="text/javascript" src="config.js"></script>
|
||||||
<script type="text/javascript" src="planeObject.js"></script>
|
<script type="text/javascript" src="planeObject.js"></script>
|
||||||
<script type="text/javascript" src="options.js"></script>
|
<script type="text/javascript" src="options.js"></script>
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
<script type="text/javascript" src="coolclock/excanvas.js"></script>
|
<script type="text/javascript" src="coolclock/excanvas.js"></script>
|
||||||
<script type="text/javascript" src="coolclock/coolclock.js"></script>
|
<script type="text/javascript" src="coolclock/coolclock.js"></script>
|
||||||
<script type="text/javascript" src="coolclock/moreskins.js"></script>
|
<script type="text/javascript" src="coolclock/moreskins.js"></script>
|
||||||
|
<title>DUMP1090</title>
|
||||||
</head>
|
</head>
|
||||||
<body onload="initialize()">
|
<body onload="initialize()">
|
||||||
<div id="dialog-modal" title="Basic modal dialog" style="display:none;">
|
<div id="dialog-modal" title="Basic modal dialog" style="display:none;">
|
||||||
|
|
|
@ -53,11 +53,17 @@ var planeObject = {
|
||||||
|
|
||||||
// Should create an icon for us to use on the map...
|
// Should create an icon for us to use on the map...
|
||||||
funcGetIcon : function() {
|
funcGetIcon : function() {
|
||||||
|
this.markerColor = MarkerColor;
|
||||||
// If this marker is selected we should make it lighter than the rest.
|
// If this marker is selected we should make it lighter than the rest.
|
||||||
if (this.is_selected == true) {
|
if (this.is_selected == true) {
|
||||||
this.markerColor = SelectedColor;
|
this.markerColor = SelectedColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have not seen a recent update, change color
|
||||||
|
if (this.seen > 15) {
|
||||||
|
this.markerColor = StaleColor;
|
||||||
|
}
|
||||||
|
|
||||||
// Plane marker
|
// Plane marker
|
||||||
var baseSvg = {
|
var baseSvg = {
|
||||||
planeData : "M 1.9565564,41.694305 C 1.7174505,40.497708 1.6419973,38.448747 " +
|
planeData : "M 1.9565564,41.694305 C 1.7174505,40.497708 1.6419973,38.448747 " +
|
||||||
|
|
|
@ -267,8 +267,10 @@ function refreshSelected() {
|
||||||
} else if (selected && selected.squawk == 7700) { // General Emergency
|
} else if (selected && selected.squawk == 7700) { // General Emergency
|
||||||
html += ' <span class="squawk7700"> Squawking: General Emergency </span>';
|
html += ' <span class="squawk7700"> Squawking: General Emergency </span>';
|
||||||
} else if (selected && selected.flight != '') {
|
} else if (selected && selected.flight != '') {
|
||||||
|
html += ' <a href="http://fr24.com/'+selected.flight+'" target="_blank">[FR24]</a>';
|
||||||
html += ' <a href="http://www.flightstats.com/go/FlightStatus/flightStatusByFlight.do?';
|
html += ' <a href="http://www.flightstats.com/go/FlightStatus/flightStatusByFlight.do?';
|
||||||
html += 'flightNumber='+selected.flight+'" target="_blank">[FlightStats]</a>';
|
html += 'flightNumber='+selected.flight+'" target="_blank">[FlightStats]</a>';
|
||||||
|
html += ' <a href="http://flightaware.com/live/flight/'+selected.flight+'" target="_blank">[FlightAware]</a>';
|
||||||
}
|
}
|
||||||
html += '<td></tr>';
|
html += '<td></tr>';
|
||||||
|
|
||||||
|
@ -330,12 +332,12 @@ function refreshSelected() {
|
||||||
dist /= 1852;
|
dist /= 1852;
|
||||||
}
|
}
|
||||||
dist = (Math.round((dist)*10)/10).toFixed(1);
|
dist = (Math.round((dist)*10)/10).toFixed(1);
|
||||||
html += '<tr><td colspan="' + columns + '">Distance from Site: ' + dist +
|
html += '<tr><td colspan="' + columns + '" align="center">Distance from Site: ' + dist +
|
||||||
(Metric ? ' km' : ' NM') + '</td></tr>';
|
(Metric ? ' km' : ' NM') + '</td></tr>';
|
||||||
} // End of SiteShow
|
} // End of SiteShow
|
||||||
} else {
|
} else {
|
||||||
if (SiteShow) {
|
if (SiteShow) {
|
||||||
html += '<tr><td colspan="' + columns + '">Distance from Site: n/a ' +
|
html += '<tr><td colspan="' + columns + '" align="center">Distance from Site: n/a ' +
|
||||||
(Metric ? ' km' : ' NM') + '</td></tr>';
|
(Metric ? ' km' : ' NM') + '</td></tr>';
|
||||||
} else {
|
} else {
|
||||||
html += 'n/a</td></tr>';
|
html += 'n/a</td></tr>';
|
||||||
|
@ -403,11 +405,16 @@ function refreshTableInfo() {
|
||||||
'align="right">Altitude</td>';
|
'align="right">Altitude</td>';
|
||||||
html += '<td onclick="setASC_DESC(\'4\');sortTable(\'tableinfo\',\'4\');" ' +
|
html += '<td onclick="setASC_DESC(\'4\');sortTable(\'tableinfo\',\'4\');" ' +
|
||||||
'align="right">Speed</td>';
|
'align="right">Speed</td>';
|
||||||
|
// Add distance column header to table if site coordinates are provided
|
||||||
|
if (SiteShow && (typeof SiteLat !== 'undefined' || typeof SiteLon !== 'undefined')) {
|
||||||
html += '<td onclick="setASC_DESC(\'5\');sortTable(\'tableinfo\',\'5\');" ' +
|
html += '<td onclick="setASC_DESC(\'5\');sortTable(\'tableinfo\',\'5\');" ' +
|
||||||
|
'align="right">Distance</td>';
|
||||||
|
}
|
||||||
|
html += '<td onclick="setASC_DESC(\'5\');sortTable(\'tableinfo\',\'6\');" ' +
|
||||||
'align="right">Track</td>';
|
'align="right">Track</td>';
|
||||||
html += '<td onclick="setASC_DESC(\'6\');sortTable(\'tableinfo\',\'6\');" ' +
|
html += '<td onclick="setASC_DESC(\'6\');sortTable(\'tableinfo\',\'7\');" ' +
|
||||||
'align="right">Msgs</td>';
|
'align="right">Msgs</td>';
|
||||||
html += '<td onclick="setASC_DESC(\'7\');sortTable(\'tableinfo\',\'7\');" ' +
|
html += '<td onclick="setASC_DESC(\'7\');sortTable(\'tableinfo\',\'8\');" ' +
|
||||||
'align="right">Seen</td></thead><tbody>';
|
'align="right">Seen</td></thead><tbody>';
|
||||||
for (var tablep in Planes) {
|
for (var tablep in Planes) {
|
||||||
var tableplane = Planes[tablep]
|
var tableplane = Planes[tablep]
|
||||||
|
@ -451,6 +458,25 @@ function refreshTableInfo() {
|
||||||
html += '<td align="right">' + tableplane.altitude + '</td>';
|
html += '<td align="right">' + tableplane.altitude + '</td>';
|
||||||
html += '<td align="right">' + tableplane.speed + '</td>';
|
html += '<td align="right">' + tableplane.speed + '</td>';
|
||||||
}
|
}
|
||||||
|
// Add distance column to table if site coordinates are provided
|
||||||
|
if (SiteShow && (typeof SiteLat !== 'undefined' || typeof SiteLon !== 'undefined')) {
|
||||||
|
html += '<td align="right">';
|
||||||
|
if (tableplane.vPosition) {
|
||||||
|
var siteLatLon = new google.maps.LatLng(SiteLat, SiteLon);
|
||||||
|
var planeLatLon = new google.maps.LatLng(tableplane.latitude, tableplane.longitude);
|
||||||
|
var dist = google.maps.geometry.spherical.computeDistanceBetween (siteLatLon, planeLatLon);
|
||||||
|
if (Metric) {
|
||||||
|
dist /= 1000;
|
||||||
|
} else {
|
||||||
|
dist /= 1852;
|
||||||
|
}
|
||||||
|
dist = (Math.round((dist)*10)/10).toFixed(1);
|
||||||
|
html += dist;
|
||||||
|
} else {
|
||||||
|
html += '0';
|
||||||
|
}
|
||||||
|
html += '</td>';
|
||||||
|
}
|
||||||
|
|
||||||
html += '<td align="right">';
|
html += '<td align="right">';
|
||||||
if (tableplane.vTrack) {
|
if (tableplane.vTrack) {
|
||||||
|
@ -503,6 +529,8 @@ function sortTable(szTableID,iCol) {
|
||||||
if (typeof iCol==='undefined'){
|
if (typeof iCol==='undefined'){
|
||||||
if(iSortCol!=-1){
|
if(iSortCol!=-1){
|
||||||
var iCol=iSortCol;
|
var iCol=iSortCol;
|
||||||
|
} else if (SiteShow && (typeof SiteLat !== 'undefined' || typeof SiteLon !== 'undefined')) {
|
||||||
|
var iCol=5;
|
||||||
} else {
|
} else {
|
||||||
var iCol=iDefaultSortCol;
|
var iCol=iDefaultSortCol;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
html, body {
|
html, body {
|
||||||
margin: 0; padding: 0; background-color: #ffffff; font-family: Tahoma, Sans-Serif;
|
margin: 0; padding: 0; background-color: #ffffff; font-family: Tahoma, Sans-Serif;
|
||||||
font-size: 10pt; overflow: auto;
|
font-size: 10pt; overflow: auto; height: 100%;
|
||||||
}
|
}
|
||||||
div#map_container { float: left; width: 100%; height: 100%; }
|
div#map_container { float: left; width: 100%; height: 100%; }
|
||||||
div#map_canvas { height: 100%; margin-right: 420px; }
|
div#map_canvas { height: 100%; margin-right: 420px; }
|
||||||
|
|
|
@ -72,9 +72,10 @@ _inline double trunc(double d) {return (d>0) ? floor(d):ceil(d) ;}
|
||||||
//usleep works in microseconds, and isn't supported in Windows. This will do for our use.
|
//usleep works in microseconds, and isn't supported in Windows. This will do for our use.
|
||||||
_inline void usleep(UINT32 ulSleep) {Sleep(ulSleep/1000);}
|
_inline void usleep(UINT32 ulSleep) {Sleep(ulSleep/1000);}
|
||||||
_inline uint64_t strtoll(const char *p, void *e, UINT32 base) {return _atoi64(p);}
|
_inline uint64_t strtoll(const char *p, void *e, UINT32 base) {return _atoi64(p);}
|
||||||
_inline int inet_aton(const char * cp, DWORD * ulAddr) { *ulAddr = inet_addr(cp); return 0;}
|
_inline int inet_aton(const char * cp, DWORD * ulAddr) { *ulAddr = inet_addr(cp); return (INADDR_NONE != *ulAddr);}
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#define vsnprintf _vsnprintf
|
#define vsnprintf _vsnprintf
|
||||||
|
#define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
|
||||||
|
|
||||||
_inline void cls() {
|
_inline void cls() {
|
||||||
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
Loading…
Reference in a new issue