55 {
"Raw TCP output", &
Modes.ros,
Modes.net_output_raw_port},
56 {
"Raw TCP input", &
Modes.ris,
Modes.net_input_raw_port},
57 {
"Beast TCP output", &
Modes.bos,
Modes.net_output_beast_port},
58 {
"Beast TCP input", &
Modes.bis,
Modes.net_input_beast_port},
59 {
"HTTP server", &
Modes.https,
Modes.net_http_port},
60 {
"Basestation TCP output", &
Modes.sbsos,
Modes.net_output_sbs_port}
67 for (j = 0; j < 6; j++) {
70 fprintf(stderr,
"Error opening the listening port %d (%s): %s\n",
71 services[j].port, services[j].descr, strerror(errno));
75 *services[j].socket =
s;
78 signal(SIGPIPE, SIG_IGN);
92 services[0] =
Modes.ros;
93 services[1] =
Modes.ris;
94 services[2] =
Modes.bos;
95 services[3] =
Modes.bis;
96 services[4] =
Modes.https;
97 services[5] =
Modes.sbsos;
99 for (j = 0; j <
sizeof(services)/
sizeof(
int); j++) {
101 if (fd == -1)
continue;
109 c = (
struct client *) malloc(
sizeof(*c));
117 if (services[j] ==
Modes.sbsos)
Modes.stat_sbs_connections++;
118 if (services[j] ==
Modes.ros)
Modes.stat_raw_connections++;
119 if (services[j] ==
Modes.bos)
Modes.stat_beast_connections++;
124 printf(
"Created new client %d\n", fd);
134 if (
Modes.clients[fd]->service ==
Modes.sbsos) {
135 if (
Modes.stat_sbs_connections)
Modes.stat_sbs_connections--;
137 else if (
Modes.clients[fd]->service ==
Modes.ros) {
138 if (
Modes.stat_raw_connections)
Modes.stat_raw_connections--;
140 else if (
Modes.clients[fd]->service ==
Modes.bos) {
141 if (
Modes.stat_beast_connections)
Modes.stat_beast_connections--;
143 free(
Modes.clients[fd]);
147 printf(
"Closing client %d\n", fd);
151 if (
Modes.maxfd == fd) {
169 for (j = 0; j <=
Modes.maxfd; j++) {
170 c =
Modes.clients[j];
171 if (c && c->
service == service) {
172 int nwritten = write(j, msg, len);
173 if (nwritten != len) {
201 for (j = 5; j >= 0; j--) {
202 *p++ = pTimeStamp[j];
207 memcpy(p, mm->
msg, msgLen);
209 Modes.beastOutUsed += (msgLen + 9);
210 if (
Modes.beastOutUsed >=
Modes.net_output_raw_size)
213 Modes.beastOutUsed = 0;
214 Modes.net_output_raw_rate_count = 0;
226 unsigned char * pTimeStamp;
231 for (j = 5; j >= 0; j--) {
232 sprintf(p,
"%02X", pTimeStamp[j]);
235 Modes.rawOutUsed += 12;
239 for (j = 0; j < msgLen; j++) {
240 sprintf(p,
"%02X", mm->
msg[j]);
247 Modes.rawOutUsed += ((msgLen*2) + 3);
248 if (
Modes.rawOutUsed >=
Modes.net_output_raw_size)
251 Modes.rawOutUsed = 0;
252 Modes.net_output_raw_rate_count = 0;
262 char msg[256], *
p = msg;
264 struct timeb epocTime;
280 }
else if (mm->
msgtype == 11) {
296 }
else if (mm->
metype != 19) {
298 }
else if ((mm->
mesub == 1) || (mm->
mesub == 2)) {
305 p += sprintf(p,
"MSG,%d,111,11111,%06X,111111,", msgType, mm->
addr);
309 epocTime =
Modes.stSystemTimeBlk;
311 offset = offset / 12000;
312 epocTime.millitm += offset;
313 if (epocTime.millitm > 999)
314 {epocTime.millitm -= 1000; epocTime.time ++;}
315 stTime = *localtime(&epocTime.time);
316 p += sprintf(p,
"%04d/%02d/%02d,", (stTime.tm_year+1900),(stTime.tm_mon+1), stTime.tm_mday);
317 p += sprintf(p,
"%02d:%02d:%02d.%03d,", stTime.tm_hour, stTime.tm_min, stTime.tm_sec, epocTime.millitm);
319 p += sprintf(p,
",,");
324 stTime = *localtime(&epocTime.time);
325 p += sprintf(p,
"%04d/%02d/%02d,", (stTime.tm_year+1900),(stTime.tm_mon+1), stTime.tm_mday);
326 p += sprintf(p,
"%02d:%02d:%02d.%03d", stTime.tm_hour, stTime.tm_min, stTime.tm_sec, epocTime.millitm);
330 else {p += sprintf(p,
",");}
334 p += sprintf(p,
",0");
336 p += sprintf(p,
",%d", mm->
altitude);
338 p += sprintf(p,
",");
343 else {p += sprintf(p,
",,");}
347 else {p += sprintf(p,
",,");}
351 else {p += sprintf(p,
",");}
355 else {p += sprintf(p,
",");}
359 if ((mm->
fs >= 2) && (mm->
fs <= 4)) {
360 p += sprintf(p,
",-1");
362 p += sprintf(p,
",0");
365 p += sprintf(p,
",");
370 if ((mm->
modeA == 0x7500) || (mm->
modeA == 0x7600) || (mm->
modeA == 0x7700)) {
371 p += sprintf(p,
",-1");
373 p += sprintf(p,
",0");
376 p += sprintf(p,
",");
381 if ((mm->
fs >= 4) && (mm->
fs <= 5)) {
382 p += sprintf(p,
",-1");
384 p += sprintf(p,
",0");
387 p += sprintf(p,
",");
393 p += sprintf(p,
",-1");
395 p += sprintf(p,
",0");
398 p += sprintf(p,
",");
401 p += sprintf(p,
"\r\n");
430 memset(&mm, 0,
sizeof(mm));
432 if ((*p ==
'1') && (
Modes.mode_ac)) {
434 }
else if (*p ==
'2') {
436 }
else if (*p ==
'3') {
446 memcpy(msg, p, msgLen);
466 if (c >=
'0' && c <=
'9')
return c-
'0';
467 else if (c >=
'a' && c <=
'f')
return c-
'a'+10;
485 int l = strlen(hex), j;
489 memset(&mm, 0,
sizeof(mm));
497 while(l && isspace(hex[l-1])) {
498 hex[l-1] =
'\0'; l--;
500 while(isspace(*hex)) {
507 if (hex[l-1] !=
';') {
return (0);}
535 if ( (0 ==
Modes.mode_ac)
539 for (j = 0; j < l; j += 2) {
543 if (high == -1 || low == -1)
return 0;
544 msg[j/2] = (high << 4) | low;
562 time_t now = time(NULL);
565 char *buf = (
char *) malloc(buflen), *
p = buf;
568 l = snprintf(
p,buflen,
"[\n");
588 l = snprintf(
p,buflen,
589 "{\"hex\":\"%06x\", \"squawk\":\"%04x\", \"flight\":\"%s\", \"lat\":%f, "
590 "\"lon\":%f, \"validposition\":%d, \"altitude\":%d, \"vert_rate\":%d,\"track\":%d, \"validtrack\":%d,"
591 "\"speed\":%d, \"messages\":%ld, \"seen\":%d},\n",
592 a->
addr, a->
modeA, a->
flight, a->
lat, a->
lon, position, a->
altitude, a->
vert_rate, a->
track, track,
600 buf = (
char *) realloc(buf,used+buflen);
614 l = snprintf(
p,buflen,
"]\n");
623 #define MODES_CONTENT_TYPE_HTML "text/html;charset=utf-8"
624 #define MODES_CONTENT_TYPE_CSS "text/css;charset=utf-8"
625 #define MODES_CONTENT_TYPE_JSON "application/json;charset=utf-8"
626 #define MODES_CONTENT_TYPE_JS "application/javascript;charset=utf-8"
638 int httpver, keepalive;
645 printf(
"\nHTTP request: %s\n", c->
buf);
648 httpver = (strstr(p,
"HTTP/1.1") != NULL) ? 11 : 10;
651 keepalive = strstr(p,
"Connection: keep-alive") != NULL;
652 }
else if (httpver == 11) {
654 keepalive = strstr(p,
"Connection: close") == NULL;
666 printf(
"\nHTTP keep alive: %d\n", keepalive);
667 printf(
"HTTP requested URL: %s\n\n", url);
670 if (strlen(url) < 2) {
671 snprintf(getFile,
sizeof getFile,
"%s/gmap.html",
HTMLPATH);
673 snprintf(getFile,
sizeof getFile,
"%s/%s",
HTMLPATH, url);
679 if (strstr(url,
"/data.json")) {
686 if (stat(getFile, &sbuf) != -1 && (fd = open(getFile, O_RDONLY)) != -1) {
687 content = (
char *) malloc(sbuf.st_size);
688 if (read(fd, content, sbuf.st_size) == -1) {
689 snprintf(content, sbuf.st_size,
"Error reading from file: %s", strerror(errno));
694 clen = snprintf(buf,
sizeof(buf),
"Error opening HTML file: %s", strerror(errno));
695 content = strdup(buf);
705 ext = strrchr(getFile,
'.');
707 if (strlen(ext) > 0) {
708 if (strstr(ext,
".json")) {
710 }
else if (strstr(ext,
".css")) {
712 }
else if (strstr(ext,
".js")) {
718 hdrlen = snprintf(hdr,
sizeof(hdr),
719 "HTTP/1.1 200 OK\r\n"
720 "Server: Dump1090\r\n"
721 "Content-Type: %s\r\n"
723 "Content-Length: %d\r\n"
724 "Cache-Control: no-cache, must-revalidate\r\n"
725 "Expires: Sat, 26 Jul 1997 05:00:00 GMT\r\n"
728 keepalive ?
"keep-alive" :
"close",
732 printf(
"HTTP Reply header:\n%s", hdr);
736 if (write(c->
fd, hdr, hdrlen) == -1 || write(c->
fd, content, clen) == -1) {
741 Modes.stat_http_requests++;
760 int(*handler)(
struct client *,
char *)) {
783 if ( (nread < 0) && (errno != EAGAIN)) {
802 while (left && ((s = memchr(e, (
char) 0x1a, left)) != NULL)) {
806 }
else if (*s ==
'2') {
808 }
else if (*s ==
'3') {
835 while ((e = strstr(s, sep)) != NULL) {
866 for (j = 0; j <=
Modes.maxfd; j++) {
867 if ((c =
Modes.clients[j]) == NULL)
continue;
#define MODES_CONTENT_TYPE_HTML
int anetTcpServer(char *err, int port, char *bindaddr)
#define MODES_ACFLAGS_NSEWSPD_VALID
void decodeModesMessage(struct modesMessage *mm, unsigned char *msg)
#define MODES_ACFLAGS_ALTITUDE_VALID
void modesQueueOutput(struct modesMessage *mm)
#define MODES_CONTENT_TYPE_JSON
int decodeBinMessage(struct client *c, char *p)
#define MODES_CLIENT_BUF_SIZE
#define MODES_ACFLAGS_FS_VALID
void modesSendBeastOutput(struct modesMessage *mm)
void decodeModeAMessage(struct modesMessage *mm, int ModeA)
void modesReadFromClient(struct client *c, char *sep, int(*handler)(struct client *, char *))
#define MODES_ACFLAGS_AOG
int decodeHexMessage(struct client *c, char *hex)
unsigned char signalLevel
void modesAcceptClients(void)
#define MODES_LONG_MSG_BYTES
void modesReadFromClients(void)
int anetSetSendBuffer(char *err, int fd, int buffsize)
#define MODES_ACFLAGS_SQUAWK_VALID
char * aircraftsToJson(int *len)
#define MODES_ACFLAGS_HEADING_VALID
int anetNonBlock(char *err, int fd)
void modesFreeClient(int fd)
#define MODES_CONTENT_TYPE_CSS
void useModesMessage(struct modesMessage *mm)
#define MODES_ACFLAGS_LATLON_VALID
void modesSendAllClients(int service, void *msg, int len)
void modesSendRawOutput(struct modesMessage *mm)
#define MODES_ACFLAGS_VERTRATE_VALID
#define MODES_NET_SNDBUF_SIZE
#define MODES_ACFLAGS_AOG_VALID
void modesSendSBSOutput(struct modesMessage *mm)
#define MODES_ACFLAGS_CALLSIGN_VALID
int anetTcpAccept(char *err, int s, char *ip, int *port)
#define MODES_SHORT_MSG_BYTES
int handleHTTPRequest(struct client *c, char *p)
#define MODES_ACFLAGS_AOG_GROUND
#define MODES_CONTENT_TYPE_JS