Merge branch 'upstream'

This commit is contained in:
Oliver Jowett 2016-01-26 11:28:08 +00:00
commit 5de8a7b5f8
8 changed files with 119 additions and 108 deletions

View file

@ -145,13 +145,12 @@ void modesInitConfig(void) {
Modes.ppm_error = MODES_DEFAULT_PPM;
Modes.check_crc = 1;
Modes.net_heartbeat_interval = MODES_NET_HEARTBEAT_INTERVAL;
Modes.net_output_sbs_port = MODES_NET_OUTPUT_SBS_PORT;
Modes.net_output_raw_port = MODES_NET_OUTPUT_RAW_PORT;
Modes.net_input_raw_port = MODES_NET_INPUT_RAW_PORT;
Modes.net_output_beast_port = MODES_NET_OUTPUT_BEAST_PORT;
Modes.net_input_beast_port = MODES_NET_INPUT_BEAST_PORT;
Modes.net_http_port = MODES_NET_HTTP_PORT;
Modes.net_fatsv_port = MODES_NET_OUTPUT_FA_TSV_PORT;
Modes.net_output_raw_ports = strdup("30001");
Modes.net_input_raw_ports = strdup("30002");
Modes.net_output_sbs_ports = strdup("30003");
Modes.net_input_beast_ports = strdup("30004,30104");
Modes.net_output_beast_ports = strdup("30005");
Modes.net_http_ports = strdup("8080");
Modes.interactive_rows = getTermRows();
Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL;
Modes.html_dir = HTMLPATH;
@ -682,13 +681,12 @@ void showHelp(void) {
"--modeac Enable decoding of SSR Modes 3/A & 3/C\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-ri-port <port> TCP raw input listen port (default: 30001)\n"
"--net-ro-port <port> TCP raw output listen port (default: 30002)\n"
"--net-sbs-port <port> TCP BaseStation output listen port (default: 30003)\n"
"--net-bi-port <port> TCP Beast input listen port (default: 30004)\n"
"--net-bo-port <port> TCP Beast output listen port (default: 30005)\n"
"--net-fatsv-port <port> FlightAware TSV output port (default: 10001)\n"
"--net-http-port <ports> HTTP server ports (default: 8080)\n"
"--net-ri-port <ports> TCP raw input listen ports (default: 30001)\n"
"--net-ro-port <ports> TCP raw output listen ports (default: 30002)\n"
"--net-sbs-port <ports> TCP BaseStation output listen ports (default: 30003)\n"
"--net-bi-port <ports> TCP Beast input listen ports (default: 30004,30104)\n"
"--net-bo-port <ports> TCP Beast output listen ports (default: 30005)\n"
"--net-ro-size <size> TCP output minimum size (default: 0)\n"
"--net-ro-interval <rate> TCP output memory flush rate in seconds (default: 0)\n"
"--net-heartbeat <rate> TCP heartbeat rate in seconds (default: 60 sec; 0 to disable)\n"
@ -825,8 +823,8 @@ void backgroundTasks(void) {
next_json = now + Modes.json_interval;
}
if ((Modes.json_dir || Modes.net_http_port) && now >= next_history) {
int rewrite_receiver_json = (Modes.json_aircraft_history[HISTORY_SIZE-1].content == NULL);
if (now >= next_history) {
int rewrite_receiver_json = (Modes.json_dir && Modes.json_aircraft_history[HISTORY_SIZE-1].content == NULL);
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 =
@ -968,7 +966,7 @@ int main(int argc, char **argv) {
} else if (!strcmp(argv[j],"--modeac")) {
Modes.mode_ac = 1;
} else if (!strcmp(argv[j],"--net-beast")) {
Modes.beast = 1;
fprintf(stderr, "--net-beast ignored, use --net-bo-port to control where Beast output is generated\n");
} else if (!strcmp(argv[j],"--net-only")) {
Modes.net = 1;
Modes.net_only = 1;
@ -981,24 +979,26 @@ int main(int argc, char **argv) {
} else if (!strcmp(argv[j],"--net-ro-interval") && more) {
Modes.net_output_flush_interval = (uint64_t)(1000 * atof(argv[++j]));
} else if (!strcmp(argv[j],"--net-ro-port") && more) {
if (Modes.beast) // Required for legacy backward compatibility
{Modes.net_output_beast_port = atoi(argv[++j]);;}
else
{Modes.net_output_raw_port = atoi(argv[++j]);}
free(Modes.net_output_raw_ports);
Modes.net_output_raw_ports = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-ri-port") && more) {
Modes.net_input_raw_port = atoi(argv[++j]);
free(Modes.net_input_raw_ports);
Modes.net_input_raw_ports = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-bo-port") && more) {
Modes.net_output_beast_port = atoi(argv[++j]);
free(Modes.net_output_beast_ports);
Modes.net_output_beast_ports = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-bi-port") && more) {
Modes.net_input_beast_port = atoi(argv[++j]);
free(Modes.net_input_beast_ports);
Modes.net_input_beast_ports = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-bind-address") && more) {
free(Modes.net_bind_address);
Modes.net_bind_address = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-http-port") && more) {
Modes.net_http_port = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-fatsv-port") && more) {
Modes.net_fatsv_port = atoi(argv[++j]);
free(Modes.net_http_ports);
Modes.net_http_ports = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-sbs-port") && more) {
Modes.net_output_sbs_port = atoi(argv[++j]);
free(Modes.net_output_sbs_ports);
Modes.net_output_sbs_ports = strdup(argv[++j]);
} else if (!strcmp(argv[j],"--net-buffer") && more) {
Modes.net_sndbuf_size = atoi(argv[++j]);
} else if (!strcmp(argv[j],"--net-verbatim")) {

View file

@ -191,14 +191,6 @@ typedef struct rtlsdr_dev rtlsdr_dev_t;
#define MODES_NET_HEARTBEAT_INTERVAL 60000 // milliseconds
#define MODES_NET_SERVICES_NUM 7
#define MODES_NET_INPUT_RAW_PORT 30001
#define MODES_NET_OUTPUT_RAW_PORT 30002
#define MODES_NET_OUTPUT_SBS_PORT 30003
#define MODES_NET_INPUT_BEAST_PORT 30004
#define MODES_NET_OUTPUT_BEAST_PORT 30005
#define MODES_NET_HTTP_PORT 8080
#define MODES_NET_OUTPUT_FA_TSV_PORT 10001
#define MODES_CLIENT_BUF_SIZE 1024
#define MODES_NET_SNDBUF_SIZE (1024*64)
#define MODES_NET_SNDBUF_MAX (7)
@ -296,22 +288,20 @@ struct { // Internal state
int nfix_crc; // Number of crc bit error(s) to correct
int check_crc; // Only display messages with good CRC
int raw; // Raw output format
int beast; // Beast binary format output
int mode_ac; // Enable decoding of SSR Modes A & C
int debug; // Debugging mode
int net; // Enable networking
int net_only; // Enable just networking
uint64_t net_heartbeat_interval; // TCP heartbeat interval (milliseconds)
int net_output_sbs_port; // SBS output TCP port
int net_output_flush_size; // Minimum Size of output data
uint64_t net_output_flush_interval; // Maximum interval (in milliseconds) between outputwrites
int net_output_raw_port; // Raw output TCP port
int net_input_raw_port; // Raw input TCP port
int net_output_beast_port; // Beast output 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_fatsv_port; // FlightAware TSV port
char *net_output_raw_ports; // List of raw output TCP ports
char *net_input_raw_ports; // List of raw input TCP ports
char *net_output_sbs_ports; // List of SBS output TCP ports
char *net_input_beast_ports; // List of Beast input TCP ports
char *net_output_beast_ports; // List of Beast output TCP ports
char *net_http_ports; // List of HTTP ports
char *net_bind_address; // Bind address
int net_sndbuf_size; // TCP output buffer size (64Kb * 2^n)
int net_verbatim; // if true, send the original message, not the CRC-corrected one
int forward_mlat; // allow forwarding of mlat messages to output ports

View file

@ -139,7 +139,7 @@ int main(int argc, char **argv) {
int j;
int stdout_option = 0;
char *bo_connect_ipaddr = "127.0.0.1";
int bo_connect_port = MODES_NET_OUTPUT_BEAST_PORT;
int bo_connect_port = 30005;
struct client *c;
struct net_service *beast_input, *fatsv_output;

View file

@ -714,32 +714,36 @@ static void decodeExtendedSquitter(struct modesMessage *mm)
// Check CF on DF18 to work out the format of the ES and whether we need to look for an IMF bit
if (mm->msgtype == 18) {
/* we just globally tag any DF18 as TIS-B,
* which is not strictly true but close enough
*/
mm->bFlags |= MODES_ACFLAGS_FROM_TISB;
switch (mm->cf) {
case 0: // ADS-B ES/NT devices that report the ICAO 24-bit address in the AA field
break;
case 1: // Reserved for ADS-B for ES/NT devices that use other addressing techniques in the AA field
case 5: // TIS-B messages that relay ADS-B Messages using anonymous 24-bit addresses (format not explicitly defined, but it seems to follow DF17)
mm->addr |= MODES_NON_ICAO_ADDRESS;
break;
case 2: // Fine TIS-B message (formats are close enough to DF17 for our purposes)
case 6: // ADS-B rebroadcast using the same type codes and message formats as defined for DF = 17 ADS-B messages
mm->bFlags |= MODES_ACFLAGS_FROM_TISB;
check_imf = 1;
break;
case 3: // Coarse TIS-B airborne position and velocity.
// TODO: decode me.
// For now we only look at the IMF bit.
mm->bFlags |= MODES_ACFLAGS_FROM_TISB;
if (msg[4] & 0x80)
mm->addr |= MODES_NON_ICAO_ADDRESS;
return;
case 5: // TIS-B messages that relay ADS-B Messages using anonymous 24-bit addresses (format not explicitly defined, but it seems to follow DF17)
mm->bFlags |= MODES_ACFLAGS_FROM_TISB;
mm->addr |= MODES_NON_ICAO_ADDRESS;
break;
case 6: // ADS-B rebroadcast using the same type codes and message formats as defined for DF = 17 ADS-B messages
check_imf = 1;
break;
default: // All others, we don't know the format.
mm->addr |= MODES_NON_ICAO_ADDRESS; // assume non-ICAO
return;
@ -1035,9 +1039,9 @@ static void displayExtendedSquitter(struct modesMessage *mm) {
}
if (mm->bFlags & MODES_ACFLAGS_HAE_DELTA_VALID) {
printf(" HAE - Barometric : %d ft\n", mm->hae_delta);
printf(" HAE/Baro offset : %d ft\n", mm->hae_delta);
} else {
printf(" HAE - Barometric : not valid\n");
printf(" HAE/Baro offset : not valid\n");
}
} else if (mm->metype >= 5 && mm->metype <= 22) { // Airborne position Baro
printf(" F flag : %s\n", (mm->msg[6] & 0x04) ? "odd" : "even");
@ -1200,12 +1204,12 @@ void displayModesMessage(struct modesMessage *mm) {
} else if (mm->msgtype == 18) { // DF 18
printf("DF 18: Extended Squitter.\n");
printf(" Control Field : %d (%s)\n", mm->cf, cf_str[mm->cf]);
if ((mm->cf == 0) || (mm->cf == 1) || (mm->cf == 5) || (mm->cf == 6)) {
if (mm->cf == 1 || mm->cf == 5) {
printf(" Other Address : %06x\n", mm->addr);
} else {
printf(" ICAO Address : %06x\n", mm->addr);
}
if (mm->addr & MODES_NON_ICAO_ADDRESS) {
printf(" Other Address : %06x\n", mm->addr);
} else {
printf(" ICAO Address : %06x\n", mm->addr);
}
if ((mm->cf == 0) || (mm->cf == 1) || (mm->cf == 2) || (mm->cf == 5) || (mm->cf == 6)) {
displayExtendedSquitter(mm);
}

102
net_io.c
View file

@ -96,7 +96,7 @@ struct net_service *serviceInit(const char *descr, struct net_writer *writer, he
Modes.services = service;
service->descr = descr;
service->listen_fd = -1;
service->listener_count = 0;
service->connections = 0;
service->writer = writer;
service->read_sep = sep;
@ -163,24 +163,57 @@ struct client *serviceConnect(struct net_service *service, char *addr, int port)
// Set up the given service to listen on an address/port.
// _exits_ on failure!
void serviceListen(struct net_service *service, char *bind_addr, int bind_port)
void serviceListen(struct net_service *service, char *bind_addr, char *bind_ports)
{
int s;
int *fds = NULL;
int n = 0;
char *p, *end;
if (service->listen_fd >= 0) {
if (service->listener_count > 0) {
fprintf(stderr, "Tried to set up the service %s twice!\n", service->descr);
exit(1);
}
s = anetTcpServer(Modes.aneterr, bind_port, bind_addr);
if (s == ANET_ERR) {
fprintf(stderr, "Error opening the listening port %d (%s): %s\n",
bind_port, service->descr, Modes.aneterr);
exit(1);
if (!bind_ports || !strcmp(bind_ports, "") || !strcmp(bind_ports, "0"))
return;
p = bind_ports;
while (*p) {
int s;
unsigned long port = strtoul(p, &end, 10);
if (p == end) {
fprintf(stderr,
"Couldn't parse port list: %s\n"
" %*s^\n",
bind_ports, (int)(p - bind_ports), "");
exit(1);
}
s = anetTcpServer(Modes.aneterr, port, bind_addr);
if (s == ANET_ERR) {
fprintf(stderr, "Error opening the listening port %lu (%s): %s\n",
port, service->descr, Modes.aneterr);
exit(1);
}
anetNonBlock(Modes.aneterr, s);
fds = realloc(fds, (n+1) * sizeof(int));
if (!fds) {
fprintf(stderr, "out of memory\n");
exit(1);
}
fds[n] = s;
++n;
p = end;
if (*p == ',')
++p;
}
anetNonBlock(Modes.aneterr, s);
service->listen_fd = s;
service->listener_count = n;
service->listener_fds = fds;
}
struct net_service *makeBeastInputService(void)
@ -201,41 +234,23 @@ void modesInitNet(void) {
Modes.services = NULL;
// set up listeners
s = serviceInit("Raw TCP output", &Modes.raw_out, send_raw_heartbeat, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_raw_ports);
if (Modes.net_output_raw_port) {
s = serviceInit("Raw TCP output", &Modes.raw_out, send_raw_heartbeat, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_raw_port);
}
s = serviceInit("Beast TCP output", &Modes.beast_out, send_beast_heartbeat, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_beast_ports);
if (Modes.net_output_beast_port) {
s = serviceInit("Beast TCP output", &Modes.beast_out, send_beast_heartbeat, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_beast_port);
}
s = serviceInit("Basestation TCP output", &Modes.sbs_out, send_sbs_heartbeat, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_sbs_ports);
if (Modes.net_output_sbs_port) {
s = serviceInit("Basestation TCP output", &Modes.sbs_out, send_sbs_heartbeat, NULL, NULL);
serviceListen(s, Modes.net_bind_address, Modes.net_output_sbs_port);
}
s = serviceInit("Raw TCP input", NULL, NULL, "\n", decodeHexMessage);
serviceListen(s, Modes.net_bind_address, Modes.net_input_raw_ports);
if (Modes.net_fatsv_port) {
s = makeFatsvOutputService();
serviceListen(s, Modes.net_bind_address, Modes.net_fatsv_port);
}
s = makeBeastInputService();
serviceListen(s, Modes.net_bind_address, Modes.net_input_beast_ports);
if (Modes.net_input_raw_port) {
s = serviceInit("Raw TCP input", NULL, NULL, "\n", decodeHexMessage);
serviceListen(s, Modes.net_bind_address, Modes.net_input_raw_port);
}
if (Modes.net_input_beast_port) {
s = makeBeastInputService();
serviceListen(s, Modes.net_bind_address, Modes.net_input_beast_port);
}
if (Modes.net_http_port) {
s = serviceInit("HTTP server", NULL, NULL, "\r\n\r\n", handleHTTPRequest);
serviceListen(s, Modes.net_bind_address, Modes.net_http_port);
}
s = serviceInit("HTTP server", NULL, NULL, "\r\n\r\n", handleHTTPRequest);
serviceListen(s, Modes.net_bind_address, Modes.net_http_ports);
}
//
//=========================================================================
@ -248,8 +263,9 @@ static struct client * modesAcceptClients(void) {
struct net_service *s;
for (s = Modes.services; s; s = s->next) {
if (s->listen_fd >= 0) {
while ((fd = anetTcpAccept(Modes.aneterr, s->listen_fd, NULL, &port)) >= 0) {
int i;
for (i = 0; i < s->listener_count; ++i) {
while ((fd = anetTcpAccept(Modes.aneterr, s->listener_fds[i], NULL, &port)) >= 0) {
createSocketClient(s, fd);
}
}

View file

@ -33,7 +33,8 @@ typedef void (*heartbeat_fn)(struct net_service *);
struct net_service {
struct net_service* next;
const char *descr;
int listen_fd;
int listener_count; // number of listeners
int *listener_fds; // listening FDs
int connections; // number of active clients
@ -63,7 +64,7 @@ struct net_writer {
struct net_service *serviceInit(const char *descr, struct net_writer *writer, heartbeat_fn hb_handler, const char *sep, read_fn read_handler);
struct client *serviceConnect(struct net_service *service, char *addr, int port);
void serviceListen(struct net_service *service, char *bind_addr, int bind_port);
void serviceListen(struct net_service *service, char *bind_addr, char *bind_ports);
struct client *createSocketClient(struct net_service *service, int fd);
struct client *createGenericClient(struct net_service *service, int fd);

View file

@ -155,7 +155,7 @@ void display_stats(struct stats *st) {
printf("%u unique aircraft tracks\n", st->unique_aircraft);
printf("%u aircraft tracks where only one message was seen\n", st->single_message_aircraft);
if (Modes.net && Modes.net_http_port)
if (Modes.net)
printf("%d HTTP requests\n", st->http_requests);
{

View file

@ -149,7 +149,7 @@ int main(int argc, char **argv) {
struct client *c;
struct net_service *s;
char *bo_connect_ipaddr = "127.0.0.1";
int bo_connect_port = MODES_NET_OUTPUT_BEAST_PORT;
int bo_connect_port = 30005;
// Set sane defaults