1 /* Mode1090, a Mode S messages decoder for RTLSDR devices.
2  *
3  * Copyright (C) 2012 by Salvatore Sanfilippo <antirez@gmail.com>
4  *
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are
9  * met:
10  *
11  *  *  Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer.
13  *
14  *  *  Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <pthread.h>
35 #include <stdint.h>
36 #include <errno.h>
37 #include <unistd.h>
38 #include <math.h>
39 #include <sys/time.h>
40 #include <signal.h>
41 #include <fcntl.h>
42 #include <ctype.h>
43 #include <sys/stat.h>
44 #include <sys/ioctl.h>
45 #include <sys/select.h>
46 #include "rtl-sdr.h"
47 #include "anet.h"
48 
49 #define MODES_DEFAULT_RATE         2000000
50 #define MODES_DEFAULT_FREQ         1090000000
51 #define MODES_DEFAULT_WIDTH        1000
52 #define MODES_DEFAULT_HEIGHT       700
53 #define MODES_ASYNC_BUF_NUMBER     12
54 #define MODES_DATA_LEN             (16*16384)   /* 256k */
55 #define MODES_AUTO_GAIN            -100         /* Use automatic gain. */
56 #define MODES_MAX_GAIN             999999       /* Use max available gain. */
57 
58 #define MODES_PREAMBLE_US 8       /* microseconds */
59 #define MODES_LONG_MSG_BITS 112
60 #define MODES_SHORT_MSG_BITS 56
61 #define MODES_FULL_LEN (MODES_PREAMBLE_US+MODES_LONG_MSG_BITS)
62 #define MODES_LONG_MSG_BYTES (112/8)
63 #define MODES_SHORT_MSG_BYTES (56/8)
64 
65 #define MODES_ICAO_CACHE_LEN 1024 /* Power of two required. */
66 #define MODES_ICAO_CACHE_TTL 60   /* Time to live of cached addresses. */
67 #define MODES_UNIT_FEET 0
68 #define MODES_UNIT_METERS 1
69 
70 #define MODES_DEBUG_DEMOD (1<<0)
71 #define MODES_DEBUG_DEMODERR (1<<1)
72 #define MODES_DEBUG_BADCRC (1<<2)
73 #define MODES_DEBUG_GOODCRC (1<<3)
74 #define MODES_DEBUG_NOPREAMBLE (1<<4)
75 #define MODES_DEBUG_NET (1<<5)
76 #define MODES_DEBUG_JS (1<<6)
77 
78 /* When debug is set to MODES_DEBUG_NOPREAMBLE, the first sample must be
79  * at least greater than a given level for us to dump the signal. */
80 #define MODES_DEBUG_NOPREAMBLE_LEVEL 25
81 
82 #define MODES_INTERACTIVE_REFRESH_TIME 250      /* Milliseconds */
83 #define MODES_INTERACTIVE_ROWS 15               /* Rows on screen */
84 #define MODES_INTERACTIVE_TTL 60                /* TTL before being removed */
85 
86 #define MODES_NET_MAX_FD 1024
87 #define MODES_NET_OUTPUT_SBS_PORT 30003
88 #define MODES_NET_OUTPUT_RAW_PORT 30002
89 #define MODES_NET_INPUT_RAW_PORT 30001
90 #define MODES_NET_HTTP_PORT 8080
91 #define MODES_CLIENT_BUF_SIZE 1024
92 #define MODES_NET_SNDBUF_SIZE (1024*64)
93 
94 #define MODES_NOTUSED(V) ((void) V)
95 
96 /* Structure used to describe a networking client. */
97 struct client {
98     int fd;         /* File descriptor. */
99     int service;    /* TCP port the client is connected to. */
100     char buf[MODES_CLIENT_BUF_SIZE+1];    /* Read buffer. */
101     int buflen;                         /* Amount of data on buffer. */
102 };
103 
104 /* Structure used to describe an aircraft in iteractive mode. */
105 struct aircraft {
106     uint32_t addr;      /* ICAO address */
107     char hexaddr[7];    /* Printable ICAO address */
108     char flight[9];     /* Flight number */
109     int altitude;       /* Altitude */
110     int speed;          /* Velocity computed from EW and NS components. */
111     int track;          /* Angle of flight. */
112     time_t seen;        /* Time at which the last packet was received. */
113     long messages;      /* Number of Mode S messages received. */
114     /* Encoded latitude and longitude as extracted by odd and even
115      * CPR encoded messages. */
116     int odd_cprlat;
117     int odd_cprlon;
118     int even_cprlat;
119     int even_cprlon;
120     double lat, lon;    /* Coordinated obtained from CPR encoded data. */
121     long long odd_cprtime, even_cprtime;
122     struct aircraft *next; /* Next aircraft in our linked list. */
123 };
124 
125 /* Program global state. */
126 struct {
127     /* Internal state */
128     pthread_t reader_thread;
129     pthread_mutex_t data_mutex;     /* Mutex to synchronize buffer access. */
130     pthread_cond_t data_cond;       /* Conditional variable associated. */
131     unsigned char *data;            /* Raw IQ samples buffer */
132     uint16_t *magnitude;            /* Magnitude vector */
133     uint32_t data_len;              /* Buffer length. */
134     int fd;                         /* --ifile option file descriptor. */
135     int data_ready;                 /* Data ready to be processed. */
136     uint32_t *icao_cache;           /* Recently seen ICAO addresses cache. */
137     uint16_t *maglut;               /* I/Q -> Magnitude lookup table. */
138     int exit;                       /* Exit from the main loop when true. */
139 
140     /* RTLSDR */
141     int dev_index;
142     int gain;
143     int enable_agc;
144     rtlsdr_dev_t *dev;
145     int freq;
146 
147     /* Networking */
148     char aneterr[ANET_ERR_LEN];
149     struct client *clients[MODES_NET_MAX_FD]; /* Our clients. */
150     int maxfd;                      /* Greatest fd currently active. */
151     int sbsos;                      /* SBS output listening socket. */
152     int ros;                        /* Raw output listening socket. */
153     int ris;                        /* Raw input listening socket. */
154     int https;                      /* HTTP listening socket. */
155 
156     /* Configuration */
157     char *filename;                 /* Input form file, --ifile option. */
158     int loop;                       /* Read input file again and again. */
159     int fix_errors;                 /* Single bit error correction if true. */
160     int check_crc;                  /* Only display messages with good CRC. */
161     int raw;                        /* Raw output format. */
162     int debug;                      /* Debugging mode. */
163     int net;                        /* Enable networking. */
164     int net_only;                   /* Enable just networking. */
165     int interactive;                /* Interactive mode */
166     int interactive_rows;           /* Interactive mode: max number of rows. */
167     int interactive_ttl;            /* Interactive mode: TTL before deletion. */
168     int stats;                      /* Print stats at exit in --ifile mode. */
169     int onlyaddr;                   /* Print only ICAO addresses. */
170     int metric;                     /* Use metric units. */
171     int aggressive;                 /* Aggressive detection algorithm. */
172 
173     /* Interactive mode */
174     struct aircraft *aircrafts;
175     long long interactive_last_update;  /* Last screen update in milliseconds */
176 
177     /* Statistics */
178     long long stat_valid_preamble;
179     long long stat_demodulated;
180     long long stat_goodcrc;
181     long long stat_badcrc;
182     long long stat_fixed;
183     long long stat_single_bit_fix;
184     long long stat_two_bits_fix;
185     long long stat_http_requests;
186     long long stat_sbs_connections;
187     long long stat_out_of_phase;
188 } Modes;
189 
190 /* The struct we use to store information about a decoded message. */
191 struct modesMessage {
192     /* Generic fields */
193     unsigned char msg[MODES_LONG_MSG_BYTES]; /* Binary message. */
194     int msgbits;                /* Number of bits in message */
195     int msgtype;                /* Downlink format # */
196     int crcok;                  /* True if CRC was valid */
197     uint32_t crc;               /* Message CRC */
198     int errorbit;               /* Bit corrected. -1 if no bit corrected. */
199     int aa1, aa2, aa3;          /* ICAO Address bytes 1 2 and 3 */
200     int phase_corrected;        /* True if phase correction was applied. */
201 
202     /* DF 11 */
203     int ca;                     /* Responder capabilities. */
204 
205     /* DF 17 */
206     int metype;                 /* Extended squitter message type. */
207     int mesub;                  /* Extended squitter message subtype. */
208     int heading_is_valid;
209     int heading;
210     int aircraft_type;
211     int fflag;                  /* 1 = Odd, 0 = Even CPR message. */
212     int tflag;                  /* UTC synchronized? */
213     int raw_latitude;           /* Non decoded latitude */
214     int raw_longitude;          /* Non decoded longitude */
215     char flight[9];             /* 8 chars flight number. */
216     int ew_dir;                 /* 0 = East, 1 = West. */
217     int ew_velocity;            /* E/W velocity. */
218     int ns_dir;                 /* 0 = North, 1 = South. */
219     int ns_velocity;            /* N/S velocity. */
220     int vert_rate_source;       /* Vertical rate source. */
221     int vert_rate_sign;         /* Vertical rate sign. */
222     int vert_rate;              /* Vertical rate. */
223     int velocity;               /* Computed from EW and NS velocity. */
224 
225     /* DF4, DF5, DF20, DF21 */
226     int fs;                     /* Flight status for DF4,5,20,21 */
227     int dr;                     /* Request extraction of downlink request. */
228     int um;                     /* Request extraction of downlink request. */
229     int identity;               /* 13 bits identity (Squawk). */
230 
231     /* Fields used by multiple message types. */
232     int altitude, unit;
233 };
234 
235 void interactiveShowData(void);
236 struct aircraft* interactiveReceiveData(struct modesMessage *mm);
237 void modesSendRawOutput(struct modesMessage *mm);
238 void modesSendSBSOutput(struct modesMessage *mm, struct aircraft *a);
239 void useModesMessage(struct modesMessage *mm);
240 int fixSingleBitErrors(unsigned char *msg, int bits);
241 int fixTwoBitsErrors(unsigned char *msg, int bits);
242 int modesMessageLenByType(int type);
243 void sigWinchCallback();
244 int getTermRows();
245 
246 /* ============================= Utility functions ========================== */
247 
mstime(void)248 static long long mstime(void) {
249     struct timeval tv;
250     long long mst;
251 
252     gettimeofday(&tv, NULL);
253     mst = ((long long)tv.tv_sec)*1000;
254     mst += tv.tv_usec/1000;
255     return mst;
256 }
257 
258 /* =============================== Initialization =========================== */
259 
modesInitConfig(void)260 void modesInitConfig(void) {
261     Modes.gain = MODES_MAX_GAIN;
262     Modes.dev_index = 0;
263     Modes.enable_agc = 0;
264     Modes.freq = MODES_DEFAULT_FREQ;
265     Modes.filename = NULL;
266     Modes.fix_errors = 1;
267     Modes.check_crc = 1;
268     Modes.raw = 0;
269     Modes.net = 0;
270     Modes.net_only = 0;
271     Modes.onlyaddr = 0;
272     Modes.debug = 0;
273     Modes.interactive = 0;
274     Modes.interactive_rows = MODES_INTERACTIVE_ROWS;
275     Modes.interactive_ttl = MODES_INTERACTIVE_TTL;
276     Modes.aggressive = 0;
277     Modes.interactive_rows = getTermRows();
278     Modes.loop = 0;
279 }
280 
modesInit(void)281 void modesInit(void) {
282     int i, q;
283 
284     pthread_mutex_init(&Modes.data_mutex,NULL);
285     pthread_cond_init(&Modes.data_cond,NULL);
286     /* We add a full message minus a final bit to the length, so that we
287      * can carry the remaining part of the buffer that we can't process
288      * in the message detection loop, back at the start of the next data
289      * to process. This way we are able to also detect messages crossing
290      * two reads. */
291     Modes.data_len = MODES_DATA_LEN + (MODES_FULL_LEN-1)*4;
292     Modes.data_ready = 0;
293     /* Allocate the ICAO address cache. We use two uint32_t for every
294      * entry because it's a addr / timestamp pair for every entry. */
295     Modes.icao_cache = malloc(sizeof(uint32_t)*MODES_ICAO_CACHE_LEN*2);
296     memset(Modes.icao_cache,0,sizeof(uint32_t)*MODES_ICAO_CACHE_LEN*2);
297     Modes.aircrafts = NULL;
298     Modes.interactive_last_update = 0;
299     if ((Modes.data = malloc(Modes.data_len)) == NULL ||
300         (Modes.magnitude = malloc(Modes.data_len*2)) == NULL) {
301         fprintf(stderr, "Out of memory allocating data buffer.\n");
302         exit(1);
303     }
304     memset(Modes.data,127,Modes.data_len);
305 
306     /* Populate the I/Q -> Magnitude lookup table. It is used because
307      * sqrt or round may be expensive and may vary a lot depending on
308      * the libc used.
309      *
310      * We scale to 0-255 range multiplying by 1.4 in order to ensure that
311      * every different I/Q pair will result in a different magnitude value,
312      * not losing any resolution. */
313     Modes.maglut = malloc(129*129*2);
314     for (i = 0; i <= 128; i++) {
315         for (q = 0; q <= 128; q++) {
316             Modes.maglut[i*129+q] = round(sqrt(i*i+q*q)*360);
317         }
318     }
319 
320     /* Statistics */
321     Modes.stat_valid_preamble = 0;
322     Modes.stat_demodulated = 0;
323     Modes.stat_goodcrc = 0;
324     Modes.stat_badcrc = 0;
325     Modes.stat_fixed = 0;
326     Modes.stat_single_bit_fix = 0;
327     Modes.stat_two_bits_fix = 0;
328     Modes.stat_http_requests = 0;
329     Modes.stat_sbs_connections = 0;
330     Modes.stat_out_of_phase = 0;
331     Modes.exit = 0;
332 }
333 
334 /* =============================== RTLSDR handling ========================== */
335 
modesInitRTLSDR(void)336 void modesInitRTLSDR(void) {
337     int j;
338     int device_count;
339     int ppm_error = 0;
340     char vendor[256], product[256], serial[256];
341 
342     device_count = rtlsdr_get_device_count();
343     if (!device_count) {
344         fprintf(stderr, "No supported RTLSDR devices found.\n");
345         exit(1);
346     }
347 
348     fprintf(stderr, "Found %d device(s):\n", device_count);
349     for (j = 0; j < device_count; j++) {
350         rtlsdr_get_device_usb_strings(j, vendor, product, serial);
351         fprintf(stderr, "%d: %s, %s, SN: %s %s\n", j, vendor, product, serial,
352             (j == Modes.dev_index) ? "(currently selected)" : "");
353     }
354 
355     if (rtlsdr_open(&Modes.dev, Modes.dev_index) < 0) {
356         fprintf(stderr, "Error opening the RTLSDR device: %s\n",
357             strerror(errno));
358         exit(1);
359     }
360 
361     /* Set gain, frequency, sample rate, and reset the device. */
362     rtlsdr_set_tuner_gain_mode(Modes.dev,
363         (Modes.gain == MODES_AUTO_GAIN) ? 0 : 1);
364     if (Modes.gain != MODES_AUTO_GAIN) {
365         if (Modes.gain == MODES_MAX_GAIN) {
366             /* Find the maximum gain available. */
367             int numgains;
368             int gains[100];
369 
370             numgains = rtlsdr_get_tuner_gains(Modes.dev, gains);
371             Modes.gain = gains[numgains-1];
372             fprintf(stderr, "Max available gain is: %.2f\n", Modes.gain/10.0);
373         }
374         rtlsdr_set_tuner_gain(Modes.dev, Modes.gain);
375         fprintf(stderr, "Setting gain to: %.2f\n", Modes.gain/10.0);
376     } else {
377         fprintf(stderr, "Using automatic gain control.\n");
378     }
379     rtlsdr_set_freq_correction(Modes.dev, ppm_error);
380     if (Modes.enable_agc) rtlsdr_set_agc_mode(Modes.dev, 1);
381     rtlsdr_set_center_freq(Modes.dev, Modes.freq);
382     rtlsdr_set_sample_rate(Modes.dev, MODES_DEFAULT_RATE);
383     rtlsdr_reset_buffer(Modes.dev);
384     fprintf(stderr, "Gain reported by device: %.2f\n",
385         rtlsdr_get_tuner_gain(Modes.dev)/10.0);
386 }
387 
388 /* We use a thread reading data in background, while the main thread
389  * handles decoding and visualization of data to the user.
390  *
391  * The reading thread calls the RTLSDR API to read data asynchronously, and
392  * uses a callback to populate the data buffer.
393  * A Mutex is used to avoid races with the decoding thread. */
rtlsdrCallback(unsigned char * buf,uint32_t len,void * ctx)394 void rtlsdrCallback(unsigned char *buf, uint32_t len, void *ctx) {
395     MODES_NOTUSED(ctx);
396 
397     pthread_mutex_lock(&Modes.data_mutex);
398     if (len > MODES_DATA_LEN) len = MODES_DATA_LEN;
399     /* Move the last part of the previous buffer, that was not processed,
400      * on the start of the new buffer. */
401     memcpy(Modes.data, Modes.data+MODES_DATA_LEN, (MODES_FULL_LEN-1)*4);
402     /* Read the new data. */
403     memcpy(Modes.data+(MODES_FULL_LEN-1)*4, buf, len);
404     Modes.data_ready = 1;
405     /* Signal to the other thread that new data is ready */
406     pthread_cond_signal(&Modes.data_cond);
407     pthread_mutex_unlock(&Modes.data_mutex);
408 }
409 
410 /* This is used when --ifile is specified in order to read data from file
411  * instead of using an RTLSDR device. */
readDataFromFile(void)412 void readDataFromFile(void) {
413     pthread_mutex_lock(&Modes.data_mutex);
414     while(1) {
415         ssize_t nread, toread;
416         unsigned char *p;
417 
418         if (Modes.data_ready) {
419             pthread_cond_wait(&Modes.data_cond,&Modes.data_mutex);
420             continue;
421         }
422 
423         if (Modes.interactive) {
424             /* When --ifile and --interactive are used together, slow down
425              * playing at the natural rate of the RTLSDR received. */
426             pthread_mutex_unlock(&Modes.data_mutex);
427             usleep(5000);
428             pthread_mutex_lock(&Modes.data_mutex);
429         }
430 
431         /* Move the last part of the previous buffer, that was not processed,
432          * on the start of the new buffer. */
433         memcpy(Modes.data, Modes.data+MODES_DATA_LEN, (MODES_FULL_LEN-1)*4);
434         toread = MODES_DATA_LEN;
435         p = Modes.data+(MODES_FULL_LEN-1)*4;
436         while(toread) {
437             nread = read(Modes.fd, p, toread);
438             /* In --file mode, seek the file again from the start
439              * and re-play it if --loop was given. */
440             if (nread == 0 &&
441                 Modes.filename != NULL &&
442                 Modes.fd != STDIN_FILENO &&
443                 Modes.loop)
444             {
445                 if (lseek(Modes.fd,0,SEEK_SET) != -1) continue;
446             }
447 
448             if (nread <= 0) {
449                 Modes.exit = 1; /* Signal the other thread to exit. */
450                 break;
451             }
452             p += nread;
453             toread -= nread;
454         }
455         if (toread) {
456             /* Not enough data on file to fill the buffer? Pad with
457              * no signal. */
458             memset(p,127,toread);
459         }
460         Modes.data_ready = 1;
461         /* Signal to the other thread that new data is ready */
462         pthread_cond_signal(&Modes.data_cond);
463     }
464 }
465 
466 /* We read data using a thread, so the main thread only handles decoding
467  * without caring about data acquisition. */
readerThreadEntryPoint(void * arg)468 void *readerThreadEntryPoint(void *arg) {
469     MODES_NOTUSED(arg);
470 
471     if (Modes.filename == NULL) {
472         rtlsdr_read_async(Modes.dev, rtlsdrCallback, NULL,
473                               MODES_ASYNC_BUF_NUMBER,
474                               MODES_DATA_LEN);
475     } else {
476         readDataFromFile();
477     }
478     return NULL;
479 }
480 
481 /* ============================== Debugging ================================= */
482 
483 /* Helper function for dumpMagnitudeVector().
484  * It prints a single bar used to display raw signals.
485  *
486  * Since every magnitude sample is between 0-255, the function uses
487  * up to 63 characters for every bar. Every character represents
488  * a length of 4, 3, 2, 1, specifically:
489  *
490  * "O" is 4
491  * "o" is 3
492  * "-" is 2
493  * "." is 1
494  */
dumpMagnitudeBar(int index,int magnitude)495 void dumpMagnitudeBar(int index, int magnitude) {
496     char *set = " .-o";
497     char buf[256];
498     int div = magnitude / 256 / 4;
499     int rem = magnitude / 256 % 4;
500 
501     memset(buf,'O',div);
502     buf[div] = set[rem];
503     buf[div+1] = '\0';
504 
505     if (index >= 0) {
506         int markchar = ']';
507 
508         /* preamble peaks are marked with ">" */
509         if (index == 0 || index == 2 || index == 7 || index == 9)
510             markchar = '>';
511         /* Data peaks are marked to distinguish pairs of bits. */
512         if (index >= 16) markchar = ((index-16)/2 & 1) ? '|' : ')';
513         printf("[%.3d%c |%-66s %d\n", index, markchar, buf, magnitude);
514     } else {
515         printf("[%.2d] |%-66s %d\n", index, buf, magnitude);
516     }
517 }
518 
519 /* Display an ASCII-art alike graphical representation of the undecoded
520  * message as a magnitude signal.
521  *
522  * The message starts at the specified offset in the "m" buffer.
523  * The function will display enough data to cover a short 56 bit message.
524  *
525  * If possible a few samples before the start of the messsage are included
526  * for context. */
527 
dumpMagnitudeVector(uint16_t * m,uint32_t offset)528 void dumpMagnitudeVector(uint16_t *m, uint32_t offset) {
529     uint32_t padding = 5; /* Show a few samples before the actual start. */
530     uint32_t start = (offset < padding) ? 0 : offset-padding;
531     uint32_t end = offset + (MODES_PREAMBLE_US*2)+(MODES_SHORT_MSG_BITS*2) - 1;
532     uint32_t j;
533 
534     for (j = start; j <= end; j++) {
535         dumpMagnitudeBar(j-offset, m[j]);
536     }
537 }
538 
539 /* Produce a raw representation of the message as a Javascript file
540  * loadable by debug.html. */
dumpRawMessageJS(char * descr,unsigned char * msg,uint16_t * m,uint32_t offset,int fixable)541 void dumpRawMessageJS(char *descr, unsigned char *msg,
542                       uint16_t *m, uint32_t offset, int fixable)
543 {
544     int padding = 5; /* Show a few samples before the actual start. */
545     int start = offset - padding;
546     int end = offset + (MODES_PREAMBLE_US*2)+(MODES_LONG_MSG_BITS*2) - 1;
547     FILE *fp;
548     int j, fix1 = -1, fix2 = -1;
549 
550     if (fixable != -1) {
551         fix1 = fixable & 0xff;
552         if (fixable > 255) fix2 = fixable >> 8;
553     }
554 
555     if ((fp = fopen("frames.js","a")) == NULL) {
556         fprintf(stderr, "Error opening frames.js: %s\n", strerror(errno));
557         exit(1);
558     }
559 
560     fprintf(fp,"frames.push({\"descr\": \"%s\", \"mag\": [", descr);
561     for (j = start; j <= end; j++) {
562         fprintf(fp,"%d", j < 0 ? 0 : m[j]);
563         if (j != end) fprintf(fp,",");
564     }
565     fprintf(fp,"], \"fix1\": %d, \"fix2\": %d, \"bits\": %d, \"hex\": \"",
566         fix1, fix2, modesMessageLenByType(msg[0]>>3));
567     for (j = 0; j < MODES_LONG_MSG_BYTES; j++)
568         fprintf(fp,"\\x%02x",msg[j]);
569     fprintf(fp,"\"});\n");
570     fclose(fp);
571 }
572 
573 /* This is a wrapper for dumpMagnitudeVector() that also show the message
574  * in hex format with an additional description.
575  *
576  * descr  is the additional message to show to describe the dump.
577  * msg    points to the decoded message
578  * m      is the original magnitude vector
579  * offset is the offset where the message starts
580  *
581  * The function also produces the Javascript file used by debug.html to
582  * display packets in a graphical format if the Javascript output was
583  * enabled.
584  */
dumpRawMessage(char * descr,unsigned char * msg,uint16_t * m,uint32_t offset)585 void dumpRawMessage(char *descr, unsigned char *msg,
586                     uint16_t *m, uint32_t offset)
587 {
588     int j;
589     int msgtype = msg[0]>>3;
590     int fixable = -1;
591 
592     if (msgtype == 11 || msgtype == 17) {
593         int msgbits = (msgtype == 11) ? MODES_SHORT_MSG_BITS :
594                                         MODES_LONG_MSG_BITS;
595         fixable = fixSingleBitErrors(msg,msgbits);
596         if (fixable == -1)
597             fixable = fixTwoBitsErrors(msg,msgbits);
598     }
599 
600     if (Modes.debug & MODES_DEBUG_JS) {
601         dumpRawMessageJS(descr, msg, m, offset, fixable);
602         return;
603     }
604 
605     printf("\n--- %s\n    ", descr);
606     for (j = 0; j < MODES_LONG_MSG_BYTES; j++) {
607         printf("%02x",msg[j]);
608         if (j == MODES_SHORT_MSG_BYTES-1) printf(" ... ");
609     }
610     printf(" (DF %d, Fixable: %d)\n", msgtype, fixable);
611     dumpMagnitudeVector(m,offset);
612     printf("---\n\n");
613 }
614 
615 /* ===================== Mode S detection and decoding  ===================== */
616 
617 /* Parity table for MODE S Messages.
618  * The table contains 112 elements, every element corresponds to a bit set
619  * in the message, starting from the first bit of actual data after the
620  * preamble.
621  *
622  * For messages of 112 bit, the whole table is used.
623  * For messages of 56 bits only the last 56 elements are used.
624  *
625  * The algorithm is as simple as xoring all the elements in this table
626  * for which the corresponding bit on the message is set to 1.
627  *
628  * The latest 24 elements in this table are set to 0 as the checksum at the
629  * end of the message should not affect the computation.
630  *
631  * Note: this function can be used with DF11 and DF17, other modes have
632  * the CRC xored with the sender address as they are reply to interrogations,
633  * but a casual listener can't split the address from the checksum.
634  */
635 uint32_t modes_checksum_table[112] = {
636 0x3935ea, 0x1c9af5, 0xf1b77e, 0x78dbbf, 0xc397db, 0x9e31e9, 0xb0e2f0, 0x587178,
637 0x2c38bc, 0x161c5e, 0x0b0e2f, 0xfa7d13, 0x82c48d, 0xbe9842, 0x5f4c21, 0xd05c14,
638 0x682e0a, 0x341705, 0xe5f186, 0x72f8c3, 0xc68665, 0x9cb936, 0x4e5c9b, 0xd8d449,
639 0x939020, 0x49c810, 0x24e408, 0x127204, 0x093902, 0x049c81, 0xfdb444, 0x7eda22,
640 0x3f6d11, 0xe04c8c, 0x702646, 0x381323, 0xe3f395, 0x8e03ce, 0x4701e7, 0xdc7af7,
641 0x91c77f, 0xb719bb, 0xa476d9, 0xadc168, 0x56e0b4, 0x2b705a, 0x15b82d, 0xf52612,
642 0x7a9309, 0xc2b380, 0x6159c0, 0x30ace0, 0x185670, 0x0c2b38, 0x06159c, 0x030ace,
643 0x018567, 0xff38b7, 0x80665f, 0xbfc92b, 0xa01e91, 0xaff54c, 0x57faa6, 0x2bfd53,
644 0xea04ad, 0x8af852, 0x457c29, 0xdd4410, 0x6ea208, 0x375104, 0x1ba882, 0x0dd441,
645 0xf91024, 0x7c8812, 0x3e4409, 0xe0d800, 0x706c00, 0x383600, 0x1c1b00, 0x0e0d80,
646 0x0706c0, 0x038360, 0x01c1b0, 0x00e0d8, 0x00706c, 0x003836, 0x001c1b, 0xfff409,
647 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
648 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
649 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000
650 };
651 
modesChecksum(unsigned char * msg,int bits)652 uint32_t modesChecksum(unsigned char *msg, int bits) {
653     uint32_t crc = 0;
654     int offset = (bits == 112) ? 0 : (112-56);
655     int j;
656 
657     for(j = 0; j < bits; j++) {
658         int byte = j/8;
659         int bit = j%8;
660         int bitmask = 1 << (7-bit);
661 
662         /* If bit is set, xor with corresponding table entry. */
663         if (msg[byte] & bitmask)
664             crc ^= modes_checksum_table[j+offset];
665     }
666     return crc; /* 24 bit checksum. */
667 }
668 
669 /* Given the Downlink Format (DF) of the message, return the message length
670  * in bits. */
modesMessageLenByType(int type)671 int modesMessageLenByType(int type) {
672     if (type == 16 || type == 17 ||
673         type == 19 || type == 20 ||
674         type == 21)
675         return MODES_LONG_MSG_BITS;
676     else
677         return MODES_SHORT_MSG_BITS;
678 }
679 
680 /* Try to fix single bit errors using the checksum. On success modifies
681  * the original buffer with the fixed version, and returns the position
682  * of the error bit. Otherwise if fixing failed -1 is returned. */
fixSingleBitErrors(unsigned char * msg,int bits)683 int fixSingleBitErrors(unsigned char *msg, int bits) {
684     int j;
685     unsigned char aux[MODES_LONG_MSG_BITS/8];
686 
687     for (j = 0; j < bits; j++) {
688         int byte = j/8;
689         int bitmask = 1 << (7-(j%8));
690         uint32_t crc1, crc2;
691 
692         memcpy(aux,msg,bits/8);
693         aux[byte] ^= bitmask; /* Flip j-th bit. */
694 
695         crc1 = ((uint32_t)aux[(bits/8)-3] << 16) |
696                ((uint32_t)aux[(bits/8)-2] << 8) |
697                 (uint32_t)aux[(bits/8)-1];
698         crc2 = modesChecksum(aux,bits);
699 
700         if (crc1 == crc2) {
701             /* The error is fixed. Overwrite the original buffer with
702              * the corrected sequence, and returns the error bit
703              * position. */
704             memcpy(msg,aux,bits/8);
705             return j;
706         }
707     }
708     return -1;
709 }
710 
711 /* Similar to fixSingleBitErrors() but try every possible two bit combination.
712  * This is very slow and should be tried only against DF17 messages that
713  * don't pass the checksum, and only in Aggressive Mode. */
fixTwoBitsErrors(unsigned char * msg,int bits)714 int fixTwoBitsErrors(unsigned char *msg, int bits) {
715     int j, i;
716     unsigned char aux[MODES_LONG_MSG_BITS/8];
717 
718     for (j = 0; j < bits; j++) {
719         int byte1 = j/8;
720         int bitmask1 = 1 << (7-(j%8));
721 
722         /* Don't check the same pairs multiple times, so i starts from j+1 */
723         for (i = j+1; i < bits; i++) {
724             int byte2 = i/8;
725             int bitmask2 = 1 << (7-(i%8));
726             uint32_t crc1, crc2;
727 
728             memcpy(aux,msg,bits/8);
729 
730             aux[byte1] ^= bitmask1; /* Flip j-th bit. */
731             aux[byte2] ^= bitmask2; /* Flip i-th bit. */
732 
733             crc1 = ((uint32_t)aux[(bits/8)-3] << 16) |
734                    ((uint32_t)aux[(bits/8)-2] << 8) |
735                     (uint32_t)aux[(bits/8)-1];
736             crc2 = modesChecksum(aux,bits);
737 
738             if (crc1 == crc2) {
739                 /* The error is fixed. Overwrite the original buffer with
740                  * the corrected sequence, and returns the error bit
741                  * position. */
742                 memcpy(msg,aux,bits/8);
743                 /* We return the two bits as a 16 bit integer by shifting
744                  * 'i' on the left. This is possible since 'i' will always
745                  * be non-zero because i starts from j+1. */
746                 return j | (i<<8);
747             }
748         }
749     }
750     return -1;
751 }
752 
753 /* Hash the ICAO address to index our cache of MODES_ICAO_CACHE_LEN
754  * elements, that is assumed to be a power of two. */
ICAOCacheHashAddress(uint32_t a)755 uint32_t ICAOCacheHashAddress(uint32_t a) {
756     /* The following three rounds wil make sure that every bit affects
757      * every output bit with ~ 50% of probability. */
758     a = ((a >> 16) ^ a) * 0x45d9f3b;
759     a = ((a >> 16) ^ a) * 0x45d9f3b;
760     a = ((a >> 16) ^ a);
761     return a & (MODES_ICAO_CACHE_LEN-1);
762 }
763 
764 /* Add the specified entry to the cache of recently seen ICAO addresses.
765  * Note that we also add a timestamp so that we can make sure that the
766  * entry is only valid for MODES_ICAO_CACHE_TTL seconds. */
addRecentlySeenICAOAddr(uint32_t addr)767 void addRecentlySeenICAOAddr(uint32_t addr) {
768     uint32_t h = ICAOCacheHashAddress(addr);
769     Modes.icao_cache[h*2] = addr;
770     Modes.icao_cache[h*2+1] = (uint32_t) time(NULL);
771 }
772 
773 /* Returns 1 if the specified ICAO address was seen in a DF format with
774  * proper checksum (not xored with address) no more than * MODES_ICAO_CACHE_TTL
775  * seconds ago. Otherwise returns 0. */
ICAOAddressWasRecentlySeen(uint32_t addr)776 int ICAOAddressWasRecentlySeen(uint32_t addr) {
777     uint32_t h = ICAOCacheHashAddress(addr);
778     uint32_t a = Modes.icao_cache[h*2];
779     uint32_t t = Modes.icao_cache[h*2+1];
780 
781     return a && a == addr && time(NULL)-t <= MODES_ICAO_CACHE_TTL;
782 }
783 
784 /* If the message type has the checksum xored with the ICAO address, try to
785  * brute force it using a list of recently seen ICAO addresses.
786  *
787  * Do this in a brute-force fashion by xoring the predicted CRC with
788  * the address XOR checksum field in the message. This will recover the
789  * address: if we found it in our cache, we can assume the message is ok.
790  *
791  * This function expects mm->msgtype and mm->msgbits to be correctly
792  * populated by the caller.
793  *
794  * On success the correct ICAO address is stored in the modesMessage
795  * structure in the aa3, aa2, and aa1 fiedls.
796  *
797  * If the function successfully recovers a message with a correct checksum
798  * it returns 1. Otherwise 0 is returned. */
bruteForceAP(unsigned char * msg,struct modesMessage * mm)799 int bruteForceAP(unsigned char *msg, struct modesMessage *mm) {
800     unsigned char aux[MODES_LONG_MSG_BYTES];
801     int msgtype = mm->msgtype;
802     int msgbits = mm->msgbits;
803 
804     if (msgtype == 0 ||         /* Short air surveillance */
805         msgtype == 4 ||         /* Surveillance, altitude reply */
806         msgtype == 5 ||         /* Surveillance, identity reply */
807         msgtype == 16 ||        /* Long Air-Air survillance */
808         msgtype == 20 ||        /* Comm-A, altitude request */
809         msgtype == 21 ||        /* Comm-A, identity request */
810         msgtype == 24)          /* Comm-C ELM */
811     {
812         uint32_t addr;
813         uint32_t crc;
814         int lastbyte = (msgbits/8)-1;
815 
816         /* Work on a copy. */
817         memcpy(aux,msg,msgbits/8);
818 
819         /* Compute the CRC of the message and XOR it with the AP field
820          * so that we recover the address, because:
821          *
822          * (ADDR xor CRC) xor CRC = ADDR. */
823         crc = modesChecksum(aux,msgbits);
824         aux[lastbyte] ^= crc & 0xff;
825         aux[lastbyte-1] ^= (crc >> 8) & 0xff;
826         aux[lastbyte-2] ^= (crc >> 16) & 0xff;
827 
828         /* If the obtained address exists in our cache we consider
829          * the message valid. */
830         addr = aux[lastbyte] | (aux[lastbyte-1] << 8) | (aux[lastbyte-2] << 16);
831         if (ICAOAddressWasRecentlySeen(addr)) {
832             mm->aa1 = aux[lastbyte-2];
833             mm->aa2 = aux[lastbyte-1];
834             mm->aa3 = aux[lastbyte];
835             return 1;
836         }
837     }
838     return 0;
839 }
840 
841 /* Decode the 13 bit AC altitude field (in DF 20 and others).
842  * Returns the altitude, and set 'unit' to either MODES_UNIT_METERS
843  * or MDOES_UNIT_FEETS. */
decodeAC13Field(unsigned char * msg,int * unit)844 int decodeAC13Field(unsigned char *msg, int *unit) {
845     int m_bit = msg[3] & (1<<6);
846     int q_bit = msg[3] & (1<<4);
847 
848     if (!m_bit) {
849         *unit = MODES_UNIT_FEET;
850         if (q_bit) {
851             /* N is the 11 bit integer resulting from the removal of bit
852              * Q and M */
853             int n = ((msg[2]&31)<<6) |
854                     ((msg[3]&0x80)>>2) |
855                     ((msg[3]&0x20)>>1) |
856                      (msg[3]&15);
857             /* The final altitude is due to the resulting number multiplied
858              * by 25, minus 1000. */
859             return n*25-1000;
860         } else {
861             /* TODO: Implement altitude where Q=0 and M=0 */
862         }
863     } else {
864         *unit = MODES_UNIT_METERS;
865         /* TODO: Implement altitude when meter unit is selected. */
866     }
867     return 0;
868 }
869 
870 /* Decode the 12 bit AC altitude field (in DF 17 and others).
871  * Returns the altitude or 0 if it can't be decoded. */
decodeAC12Field(unsigned char * msg,int * unit)872 int decodeAC12Field(unsigned char *msg, int *unit) {
873     int q_bit = msg[5] & 1;
874 
875     if (q_bit) {
876         /* N is the 11 bit integer resulting from the removal of bit
877          * Q */
878         *unit = MODES_UNIT_FEET;
879         int n = ((msg[5]>>1)<<4) | ((msg[6]&0xF0) >> 4);
880         /* The final altitude is due to the resulting number multiplied
881          * by 25, minus 1000. */
882         return n*25-1000;
883     } else {
884         return 0;
885     }
886 }
887 
888 /* Capability table. */
889 char *ca_str[8] = {
890     /* 0 */ "Level 1 (Survillance Only)",
891     /* 1 */ "Level 2 (DF0,4,5,11)",
892     /* 2 */ "Level 3 (DF0,4,5,11,20,21)",
893     /* 3 */ "Level 4 (DF0,4,5,11,20,21,24)",
894     /* 4 */ "Level 2+3+4 (DF0,4,5,11,20,21,24,code7 - is on ground)",
895     /* 5 */ "Level 2+3+4 (DF0,4,5,11,20,21,24,code7 - is on airborne)",
896     /* 6 */ "Level 2+3+4 (DF0,4,5,11,20,21,24,code7)",
897     /* 7 */ "Level 7 ???"
898 };
899 
900 /* Flight status table. */
901 char *fs_str[8] = {
902     /* 0 */ "Normal, Airborne",
903     /* 1 */ "Normal, On the ground",
904     /* 2 */ "ALERT,  Airborne",
905     /* 3 */ "ALERT,  On the ground",
906     /* 4 */ "ALERT & Special Position Identification. Airborne or Ground",
907     /* 5 */ "Special Position Identification. Airborne or Ground",
908     /* 6 */ "Value 6 is not assigned",
909     /* 7 */ "Value 7 is not assigned"
910 };
911 
912 /* ME message type to description table. */
913 char *me_str[] = {
914 };
915 
getMEDescription(int metype,int mesub)916 char *getMEDescription(int metype, int mesub) {
917     char *mename = "Unknown";
918 
919     if (metype >= 1 && metype <= 4)
920         mename = "Aircraft Identification and Category";
921     else if (metype >= 5 && metype <= 8)
922         mename = "Surface Position";
923     else if (metype >= 9 && metype <= 18)
924         mename = "Airborne Position (Baro Altitude)";
925     else if (metype == 19 && mesub >=1 && mesub <= 4)
926         mename = "Airborne Velocity";
927     else if (metype >= 20 && metype <= 22)
928         mename = "Airborne Position (GNSS Height)";
929     else if (metype == 23 && mesub == 0)
930         mename = "Test Message";
931     else if (metype == 24 && mesub == 1)
932         mename = "Surface System Status";
933     else if (metype == 28 && mesub == 1)
934         mename = "Extended Squitter Aircraft Status (Emergency)";
935     else if (metype == 28 && mesub == 2)
936         mename = "Extended Squitter Aircraft Status (1090ES TCAS RA)";
937     else if (metype == 29 && (mesub == 0 || mesub == 1))
938         mename = "Target State and Status Message";
939     else if (metype == 31 && (mesub == 0 || mesub == 1))
940         mename = "Aircraft Operational Status Message";
941     return mename;
942 }
943 
944 /* Decode a raw Mode S message demodulated as a stream of bytes by
945  * detectModeS(), and split it into fields populating a modesMessage
946  * structure. */
decodeModesMessage(struct modesMessage * mm,unsigned char * msg)947 void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
948     uint32_t crc2;   /* Computed CRC, used to verify the message CRC. */
949     char *ais_charset = "?ABCDEFGHIJKLMNOPQRSTUVWXYZ????? ???????????????0123456789??????";
950 
951     /* Work on our local copy */
952     memcpy(mm->msg,msg,MODES_LONG_MSG_BYTES);
953     msg = mm->msg;
954 
955     /* Get the message type ASAP as other operations depend on this */
956     mm->msgtype = msg[0]>>3;    /* Downlink Format */
957     mm->msgbits = modesMessageLenByType(mm->msgtype);
958 
959     /* CRC is always the last three bytes. */
960     mm->crc = ((uint32_t)msg[(mm->msgbits/8)-3] << 16) |
961               ((uint32_t)msg[(mm->msgbits/8)-2] << 8) |
962                (uint32_t)msg[(mm->msgbits/8)-1];
963     crc2 = modesChecksum(msg,mm->msgbits);
964 
965     /* Check CRC and fix single bit errors using the CRC when
966      * possible (DF 11 and 17). */
967     mm->errorbit = -1;  /* No error */
968     mm->crcok = (mm->crc == crc2);
969 
970     if (!mm->crcok && Modes.fix_errors &&
971         (mm->msgtype == 11 || mm->msgtype == 17))
972     {
973         if ((mm->errorbit = fixSingleBitErrors(msg,mm->msgbits)) != -1) {
974             mm->crc = modesChecksum(msg,mm->msgbits);
975             mm->crcok = 1;
976         } else if (Modes.aggressive && mm->msgtype == 17 &&
977                    (mm->errorbit = fixTwoBitsErrors(msg,mm->msgbits)) != -1)
978         {
979             mm->crc = modesChecksum(msg,mm->msgbits);
980             mm->crcok = 1;
981         }
982     }
983 
984     /* Note that most of the other computation happens *after* we fix
985      * the single bit errors, otherwise we would need to recompute the
986      * fields again. */
987     mm->ca = msg[0] & 7;        /* Responder capabilities. */
988 
989     /* ICAO address */
990     mm->aa1 = msg[1];
991     mm->aa2 = msg[2];
992     mm->aa3 = msg[3];
993 
994     /* DF 17 type (assuming this is a DF17, otherwise not used) */
995     mm->metype = msg[4] >> 3;   /* Extended squitter message type. */
996     mm->mesub = msg[4] & 7;     /* Extended squitter message subtype. */
997 
998     /* Fields for DF4,5,20,21 */
999     mm->fs = msg[0] & 7;        /* Flight status for DF4,5,20,21 */
1000     mm->dr = msg[1] >> 3 & 31;  /* Request extraction of downlink request. */
1001     mm->um = ((msg[1] & 7)<<3)| /* Request extraction of downlink request. */
1002               msg[2]>>5;
1003 
1004     /* In the squawk (identity) field bits are interleaved like that
1005      * (message bit 20 to bit 32):
1006      *
1007      * C1-A1-C2-A2-C4-A4-ZERO-B1-D1-B2-D2-B4-D4
1008      *
1009      * So every group of three bits A, B, C, D represent an integer
1010      * from 0 to 7.
1011      *
1012      * The actual meaning is just 4 octal numbers, but we convert it
1013      * into a base ten number tha happens to represent the four
1014      * octal numbers.
1015      *
1016      * For more info: http://en.wikipedia.org/wiki/Gillham_code */
1017     {
1018         int a,b,c,d;
1019 
1020         a = ((msg[3] & 0x80) >> 5) |
1021             ((msg[2] & 0x02) >> 0) |
1022             ((msg[2] & 0x08) >> 3);
1023         b = ((msg[3] & 0x02) << 1) |
1024             ((msg[3] & 0x08) >> 2) |
1025             ((msg[3] & 0x20) >> 5);
1026         c = ((msg[2] & 0x01) << 2) |
1027             ((msg[2] & 0x04) >> 1) |
1028             ((msg[2] & 0x10) >> 4);
1029         d = ((msg[3] & 0x01) << 2) |
1030             ((msg[3] & 0x04) >> 1) |
1031             ((msg[3] & 0x10) >> 4);
1032         mm->identity = a*1000 + b*100 + c*10 + d;
1033     }
1034 
1035     /* DF 11 & 17: try to populate our ICAO addresses whitelist.
1036      * DFs with an AP field (xored addr and crc), try to decode it. */
1037     if (mm->msgtype != 11 && mm->msgtype != 17) {
1038         /* Check if we can check the checksum for the Downlink Formats where
1039          * the checksum is xored with the aircraft ICAO address. We try to
1040          * brute force it using a list of recently seen aircraft addresses. */
1041         if (bruteForceAP(msg,mm)) {
1042             /* We recovered the message, mark the checksum as valid. */
1043             mm->crcok = 1;
1044         } else {
1045             mm->crcok = 0;
1046         }
1047     } else {
1048         /* If this is DF 11 or DF 17 and the checksum was ok,
1049          * we can add this address to the list of recently seen
1050          * addresses. */
1051         if (mm->crcok && mm->errorbit == -1) {
1052             uint32_t addr = (mm->aa1 << 16) | (mm->aa2 << 8) | mm->aa3;
1053             addRecentlySeenICAOAddr(addr);
1054         }
1055     }
1056 
1057     /* Decode 13 bit altitude for DF0, DF4, DF16, DF20 */
1058     if (mm->msgtype == 0 || mm->msgtype == 4 ||
1059         mm->msgtype == 16 || mm->msgtype == 20) {
1060         mm->altitude = decodeAC13Field(msg, &mm->unit);
1061     }
1062 
1063     /* Decode extended squitter specific stuff. */
1064     if (mm->msgtype == 17) {
1065         /* Decode the extended squitter message. */
1066 
1067         if (mm->metype >= 1 && mm->metype <= 4) {
1068             /* Aircraft Identification and Category */
1069             mm->aircraft_type = mm->metype-1;
1070             mm->flight[0] = ais_charset[msg[5]>>2];
1071             mm->flight[1] = ais_charset[((msg[5]&3)<<4)|(msg[6]>>4)];
1072             mm->flight[2] = ais_charset[((msg[6]&15)<<2)|(msg[7]>>6)];
1073             mm->flight[3] = ais_charset[msg[7]&63];
1074             mm->flight[4] = ais_charset[msg[8]>>2];
1075             mm->flight[5] = ais_charset[((msg[8]&3)<<4)|(msg[9]>>4)];
1076             mm->flight[6] = ais_charset[((msg[9]&15)<<2)|(msg[10]>>6)];
1077             mm->flight[7] = ais_charset[msg[10]&63];
1078             mm->flight[8] = '\0';
1079         } else if (mm->metype >= 9 && mm->metype <= 18) {
1080             /* Airborne position Message */
1081             mm->fflag = msg[6] & (1<<2);
1082             mm->tflag = msg[6] & (1<<3);
1083             mm->altitude = decodeAC12Field(msg,&mm->unit);
1084             mm->raw_latitude = ((msg[6] & 3) << 15) |
1085                                 (msg[7] << 7) |
1086                                 (msg[8] >> 1);
1087             mm->raw_longitude = ((msg[8]&1) << 16) |
1088                                  (msg[9] << 8) |
1089                                  msg[10];
1090         } else if (mm->metype == 19 && mm->mesub >= 1 && mm->mesub <= 4) {
1091             /* Airborne Velocity Message */
1092             if (mm->mesub == 1 || mm->mesub == 2) {
1093                 mm->ew_dir = (msg[5]&4) >> 2;
1094                 mm->ew_velocity = ((msg[5]&3) << 8) | msg[6];
1095                 mm->ns_dir = (msg[7]&0x80) >> 7;
1096                 mm->ns_velocity = ((msg[7]&0x7f) << 3) | ((msg[8]&0xe0) >> 5);
1097                 mm->vert_rate_source = (msg[8]&0x10) >> 4;
1098                 mm->vert_rate_sign = (msg[8]&0x8) >> 3;
1099                 mm->vert_rate = ((msg[8]&7) << 6) | ((msg[9]&0xfc) >> 2);
1100                 /* Compute velocity and angle from the two speed
1101                  * components. */
1102                 mm->velocity = sqrt(mm->ns_velocity*mm->ns_velocity+
1103                                     mm->ew_velocity*mm->ew_velocity);
1104                 if (mm->velocity) {
1105                     int ewv = mm->ew_velocity;
1106                     int nsv = mm->ns_velocity;
1107                     double heading;
1108 
1109                     if (mm->ew_dir) ewv *= -1;
1110                     if (mm->ns_dir) nsv *= -1;
1111                     heading = atan2(ewv,nsv);
1112 
1113                     /* Convert to degrees. */
1114                     mm->heading = heading * 360 / (M_PI*2);
1115                     /* We don't want negative values but a 0-360 scale. */
1116                     if (mm->heading < 0) mm->heading += 360;
1117                 } else {
1118                     mm->heading = 0;
1119                 }
1120             } else if (mm->mesub == 3 || mm->mesub == 4) {
1121                 mm->heading_is_valid = msg[5] & (1<<2);
1122                 mm->heading = (360.0/128) * (((msg[5] & 3) << 5) |
1123                                               (msg[6] >> 3));
1124             }
1125         }
1126     }
1127     mm->phase_corrected = 0; /* Set to 1 by the caller if needed. */
1128 }
1129 
1130 /* This function gets a decoded Mode S Message and prints it on the screen
1131  * in a human readable format. */
displayModesMessage(struct modesMessage * mm)1132 void displayModesMessage(struct modesMessage *mm) {
1133     int j;
1134 
1135     /* Handle only addresses mode first. */
1136     if (Modes.onlyaddr) {
1137         printf("%02x%02x%02x\n", mm->aa1, mm->aa2, mm->aa3);
1138         return;
1139     }
1140 
1141     /* Show the raw message. */
1142     printf("*");
1143     for (j = 0; j < mm->msgbits/8; j++) printf("%02x", mm->msg[j]);
1144     printf(";\n");
1145 
1146     if (Modes.raw) {
1147         fflush(stdout); /* Provide data to the reader ASAP. */
1148         return; /* Enough for --raw mode */
1149     }
1150 
1151     printf("CRC: %06x (%s)\n", (int)mm->crc, mm->crcok ? "ok" : "wrong");
1152     if (mm->errorbit != -1)
1153         printf("Single bit error fixed, bit %d\n", mm->errorbit);
1154 
1155     if (mm->msgtype == 0) {
1156         /* DF 0 */
1157         printf("DF 0: Short Air-Air Surveillance.\n");
1158         printf("  Altitude       : %d %s\n", mm->altitude,
1159             (mm->unit == MODES_UNIT_METERS) ? "meters" : "feet");
1160         printf("  ICAO Address   : %02x%02x%02x\n", mm->aa1, mm->aa2, mm->aa3);
1161     } else if (mm->msgtype == 4 || mm->msgtype == 20) {
1162         printf("DF %d: %s, Altitude Reply.\n", mm->msgtype,
1163             (mm->msgtype == 4) ? "Surveillance" : "Comm-B");
1164         printf("  Flight Status  : %s\n", fs_str[mm->fs]);
1165         printf("  DR             : %d\n", mm->dr);
1166         printf("  UM             : %d\n", mm->um);
1167         printf("  Altitude       : %d %s\n", mm->altitude,
1168             (mm->unit == MODES_UNIT_METERS) ? "meters" : "feet");
1169         printf("  ICAO Address   : %02x%02x%02x\n", mm->aa1, mm->aa2, mm->aa3);
1170 
1171         if (mm->msgtype == 20) {
1172             /* TODO: 56 bits DF20 MB additional field. */
1173         }
1174     } else if (mm->msgtype == 5 || mm->msgtype == 21) {
1175         printf("DF %d: %s, Identity Reply.\n", mm->msgtype,
1176             (mm->msgtype == 5) ? "Surveillance" : "Comm-B");
1177         printf("  Flight Status  : %s\n", fs_str[mm->fs]);
1178         printf("  DR             : %d\n", mm->dr);
1179         printf("  UM             : %d\n", mm->um);
1180         printf("  Squawk         : %d\n", mm->identity);
1181         printf("  ICAO Address   : %02x%02x%02x\n", mm->aa1, mm->aa2, mm->aa3);
1182 
1183         if (mm->msgtype == 21) {
1184             /* TODO: 56 bits DF21 MB additional field. */
1185         }
1186     } else if (mm->msgtype == 11) {
1187         /* DF 11 */
1188         printf("DF 11: All Call Reply.\n");
1189         printf("  Capability  : %s\n", ca_str[mm->ca]);
1190         printf("  ICAO Address: %02x%02x%02x\n", mm->aa1, mm->aa2, mm->aa3);
1191     } else if (mm->msgtype == 17) {
1192         /* DF 17 */
1193         printf("DF 17: ADS-B message.\n");
1194         printf("  Capability     : %d (%s)\n", mm->ca, ca_str[mm->ca]);
1195         printf("  ICAO Address   : %02x%02x%02x\n", mm->aa1, mm->aa2, mm->aa3);
1196         printf("  Extended Squitter  Type: %d\n", mm->metype);
1197         printf("  Extended Squitter  Sub : %d\n", mm->mesub);
1198         printf("  Extended Squitter  Name: %s\n",
1199             getMEDescription(mm->metype,mm->mesub));
1200 
1201         /* Decode the extended squitter message. */
1202         if (mm->metype >= 1 && mm->metype <= 4) {
1203             /* Aircraft identification. */
1204             char *ac_type_str[4] = {
1205                 "Aircraft Type D",
1206                 "Aircraft Type C",
1207                 "Aircraft Type B",
1208                 "Aircraft Type A"
1209             };
1210 
1211             printf("    Aircraft Type  : %s\n", ac_type_str[mm->aircraft_type]);
1212             printf("    Identification : %s\n", mm->flight);
1213         } else if (mm->metype >= 9 && mm->metype <= 18) {
1214             printf("    F flag   : %s\n", mm->fflag ? "odd" : "even");
1215             printf("    T flag   : %s\n", mm->tflag ? "UTC" : "non-UTC");
1216             printf("    Altitude : %d feet\n", mm->altitude);
1217             printf("    Latitude : %d (not decoded)\n", mm->raw_latitude);
1218             printf("    Longitude: %d (not decoded)\n", mm->raw_longitude);
1219         } else if (mm->metype == 19 && mm->mesub >= 1 && mm->mesub <= 4) {
1220             if (mm->mesub == 1 || mm->mesub == 2) {
1221                 /* Velocity */
1222                 printf("    EW direction      : %d\n", mm->ew_dir);
1223                 printf("    EW velocity       : %d\n", mm->ew_velocity);
1224                 printf("    NS direction      : %d\n", mm->ns_dir);
1225                 printf("    NS velocity       : %d\n", mm->ns_velocity);
1226                 printf("    Vertical rate src : %d\n", mm->vert_rate_source);
1227                 printf("    Vertical rate sign: %d\n", mm->vert_rate_sign);
1228                 printf("    Vertical rate     : %d\n", mm->vert_rate);
1229             } else if (mm->mesub == 3 || mm->mesub == 4) {
1230                 printf("    Heading status: %d", mm->heading_is_valid);
1231                 printf("    Heading: %d", mm->heading);
1232             }
1233         } else {
1234             printf("    Unrecognized ME type: %d subtype: %d\n",
1235                 mm->metype, mm->mesub);
1236         }
1237     } else {
1238         if (Modes.check_crc)
1239             printf("DF %d with good CRC received "
1240                    "(decoding still not implemented).\n",
1241                 mm->msgtype);
1242     }
1243 }
1244 
1245 /* Turn I/Q samples pointed by Modes.data into the magnitude vector
1246  * pointed by Modes.magnitude. */
computeMagnitudeVector(void)1247 void computeMagnitudeVector(void) {
1248     uint16_t *m = Modes.magnitude;
1249     unsigned char *p = Modes.data;
1250     uint32_t j;
1251 
1252     /* Compute the magnitudo vector. It's just SQRT(I^2 + Q^2), but
1253      * we rescale to the 0-255 range to exploit the full resolution. */
1254     for (j = 0; j < Modes.data_len; j += 2) {
1255         int i = p[j]-127;
1256         int q = p[j+1]-127;
1257 
1258         if (i < 0) i = -i;
1259         if (q < 0) q = -q;
1260         m[j/2] = Modes.maglut[i*129+q];
1261     }
1262 }
1263 
1264 /* Return -1 if the message is out of fase left-side
1265  * Return  1 if the message is out of fase right-size
1266  * Return  0 if the message is not particularly out of phase.
1267  *
1268  * Note: this function will access m[-1], so the caller should make sure to
1269  * call it only if we are not at the start of the current buffer. */
detectOutOfPhase(uint16_t * m)1270 int detectOutOfPhase(uint16_t *m) {
1271     if (m[3] > m[2]/3) return 1;
1272     if (m[10] > m[9]/3) return 1;
1273     if (m[6] > m[7]/3) return -1;
1274     if (m[-1] > m[1]/3) return -1;
1275     return 0;
1276 }
1277 
1278 /* This function does not really correct the phase of the message, it just
1279  * applies a transformation to the first sample representing a given bit:
1280  *
1281  * If the previous bit was one, we amplify it a bit.
1282  * If the previous bit was zero, we decrease it a bit.
1283  *
1284  * This simple transformation makes the message a bit more likely to be
1285  * correctly decoded for out of phase messages:
1286  *
1287  * When messages are out of phase there is more uncertainty in
1288  * sequences of the same bit multiple times, since 11111 will be
1289  * transmitted as continuously altering magnitude (high, low, high, low...)
1290  *
1291  * However because the message is out of phase some part of the high
1292  * is mixed in the low part, so that it is hard to distinguish if it is
1293  * a zero or a one.
1294  *
1295  * However when the message is out of phase passing from 0 to 1 or from
1296  * 1 to 0 happens in a very recognizable way, for instance in the 0 -> 1
1297  * transition, magnitude goes low, high, high, low, and one of of the
1298  * two middle samples the high will be *very* high as part of the previous
1299  * or next high signal will be mixed there.
1300  *
1301  * Applying our simple transformation we make more likely if the current
1302  * bit is a zero, to detect another zero. Symmetrically if it is a one
1303  * it will be more likely to detect a one because of the transformation.
1304  * In this way similar levels will be interpreted more likely in the
1305  * correct way. */
applyPhaseCorrection(uint16_t * m)1306 void applyPhaseCorrection(uint16_t *m) {
1307     int j;
1308 
1309     m += 16; /* Skip preamble. */
1310     for (j = 0; j < (MODES_LONG_MSG_BITS-1)*2; j += 2) {
1311         if (m[j] > m[j+1]) {
1312             /* One */
1313             m[j+2] = (m[j+2] * 5) / 4;
1314         } else {
1315             /* Zero */
1316             m[j+2] = (m[j+2] * 4) / 5;
1317         }
1318     }
1319 }
1320 
1321 /* Detect a Mode S messages inside the magnitude buffer pointed by 'm' and of
1322  * size 'mlen' bytes. Every detected Mode S message is convert it into a
1323  * stream of bits and passed to the function to display it. */
detectModeS(uint16_t * m,uint32_t mlen)1324 void detectModeS(uint16_t *m, uint32_t mlen) {
1325     unsigned char bits[MODES_LONG_MSG_BITS];
1326     unsigned char msg[MODES_LONG_MSG_BITS/2];
1327     uint16_t aux[MODES_LONG_MSG_BITS*2];
1328     uint32_t j;
1329     int use_correction = 0;
1330 
1331     /* The Mode S preamble is made of impulses of 0.5 microseconds at
1332      * the following time offsets:
1333      *
1334      * 0   - 0.5 usec: first impulse.
1335      * 1.0 - 1.5 usec: second impulse.
1336      * 3.5 - 4   usec: third impulse.
1337      * 4.5 - 5   usec: last impulse.
1338      *
1339      * Since we are sampling at 2 Mhz every sample in our magnitude vector
1340      * is 0.5 usec, so the preamble will look like this, assuming there is
1341      * an impulse at offset 0 in the array:
1342      *
1343      * 0   -----------------
1344      * 1   -
1345      * 2   ------------------
1346      * 3   --
1347      * 4   -
1348      * 5   --
1349      * 6   -
1350      * 7   ------------------
1351      * 8   --
1352      * 9   -------------------
1353      */
1354     for (j = 0; j < mlen - MODES_FULL_LEN*2; j++) {
1355         int low, high, delta, i, errors;
1356         int good_message = 0;
1357 
1358         if (use_correction) goto good_preamble; /* We already checked it. */
1359 
1360         /* First check of relations between the first 10 samples
1361          * representing a valid preamble. We don't even investigate further
1362          * if this simple test is not passed. */
1363         if (!(m[j] > m[j+1] &&
1364             m[j+1] < m[j+2] &&
1365             m[j+2] > m[j+3] &&
1366             m[j+3] < m[j] &&
1367             m[j+4] < m[j] &&
1368             m[j+5] < m[j] &&
1369             m[j+6] < m[j] &&
1370             m[j+7] > m[j+8] &&
1371             m[j+8] < m[j+9] &&
1372             m[j+9] > m[j+6]))
1373         {
1374             if (Modes.debug & MODES_DEBUG_NOPREAMBLE &&
1375                 m[j] > MODES_DEBUG_NOPREAMBLE_LEVEL)
1376                 dumpRawMessage("Unexpected ratio among first 10 samples",
1377                     msg, m, j);
1378             continue;
1379         }
1380 
1381         /* The samples between the two spikes must be < than the average
1382          * of the high spikes level. We don't test bits too near to
1383          * the high levels as signals can be out of phase so part of the
1384          * energy can be in the near samples. */
1385         high = (m[j]+m[j+2]+m[j+7]+m[j+9])/6;
1386         if (m[j+4] >= high ||
1387             m[j+5] >= high)
1388         {
1389             if (Modes.debug & MODES_DEBUG_NOPREAMBLE &&
1390                 m[j] > MODES_DEBUG_NOPREAMBLE_LEVEL)
1391                 dumpRawMessage(
1392                     "Too high level in samples between 3 and 6",
1393                     msg, m, j);
1394             continue;
1395         }
1396 
1397         /* Similarly samples in the range 11-14 must be low, as it is the
1398          * space between the preamble and real data. Again we don't test
1399          * bits too near to high levels, see above. */
1400         if (m[j+11] >= high ||
1401             m[j+12] >= high ||
1402             m[j+13] >= high ||
1403             m[j+14] >= high)
1404         {
1405             if (Modes.debug & MODES_DEBUG_NOPREAMBLE &&
1406                 m[j] > MODES_DEBUG_NOPREAMBLE_LEVEL)
1407                 dumpRawMessage(
1408                     "Too high level in samples between 10 and 15",
1409                     msg, m, j);
1410             continue;
1411         }
1412         Modes.stat_valid_preamble++;
1413 
1414 good_preamble:
1415         /* If the previous attempt with this message failed, retry using
1416          * magnitude correction. */
1417         if (use_correction) {
1418             memcpy(aux,m+j+MODES_PREAMBLE_US*2,sizeof(aux));
1419             if (j && detectOutOfPhase(m+j)) {
1420                 applyPhaseCorrection(m+j);
1421                 Modes.stat_out_of_phase++;
1422             }
1423             /* TODO ... apply other kind of corrections. */
1424         }
1425 
1426         /* Decode all the next 112 bits, regardless of the actual message
1427          * size. We'll check the actual message type later. */
1428         errors = 0;
1429         for (i = 0; i < MODES_LONG_MSG_BITS*2; i += 2) {
1430             low = m[j+i+MODES_PREAMBLE_US*2];
1431             high = m[j+i+MODES_PREAMBLE_US*2+1];
1432             delta = low-high;
1433             if (delta < 0) delta = -delta;
1434 
1435             if (i > 0 && delta < 256) {
1436                 bits[i/2] = bits[i/2-1];
1437             } else if (low == high) {
1438                 /* Checking if two adiacent samples have the same magnitude
1439                  * is an effective way to detect if it's just random noise
1440                  * that was detected as a valid preamble. */
1441                 bits[i/2] = 2; /* error */
1442                 if (i < MODES_SHORT_MSG_BITS*2) errors++;
1443             } else if (low > high) {
1444                 bits[i/2] = 1;
1445             } else {
1446                 /* (low < high) for exclusion  */
1447                 bits[i/2] = 0;
1448             }
1449         }
1450 
1451         /* Restore the original message if we used magnitude correction. */
1452         if (use_correction)
1453             memcpy(m+j+MODES_PREAMBLE_US*2,aux,sizeof(aux));
1454 
1455         /* Pack bits into bytes */
1456         for (i = 0; i < MODES_LONG_MSG_BITS; i += 8) {
1457             msg[i/8] =
1458                 bits[i]<<7 |
1459                 bits[i+1]<<6 |
1460                 bits[i+2]<<5 |
1461                 bits[i+3]<<4 |
1462                 bits[i+4]<<3 |
1463                 bits[i+5]<<2 |
1464                 bits[i+6]<<1 |
1465                 bits[i+7];
1466         }
1467 
1468         int msgtype = msg[0]>>3;
1469         int msglen = modesMessageLenByType(msgtype)/8;
1470 
1471         /* Last check, high and low bits are different enough in magnitude
1472          * to mark this as real message and not just noise? */
1473         delta = 0;
1474         for (i = 0; i < msglen*8*2; i += 2) {
1475             delta += abs(m[j+i+MODES_PREAMBLE_US*2]-
1476                          m[j+i+MODES_PREAMBLE_US*2+1]);
1477         }
1478         delta /= msglen*4;
1479 
1480         /* Filter for an average delta of three is small enough to let almost
1481          * every kind of message to pass, but high enough to filter some
1482          * random noise. */
1483         if (delta < 10*255) {
1484             use_correction = 0;
1485             continue;
1486         }
1487 
1488         /* If we reached this point, and error is zero, we are very likely
1489          * with a Mode S message in our hands, but it may still be broken
1490          * and CRC may not be correct. This is handled by the next layer. */
1491         if (errors == 0 || (Modes.aggressive && errors < 3)) {
1492             struct modesMessage mm;
1493 
1494             /* Decode the received message and update statistics */
1495             decodeModesMessage(&mm,msg);
1496 
1497             /* Update statistics. */
1498             if (mm.crcok || use_correction) {
1499                 if (errors == 0) Modes.stat_demodulated++;
1500                 if (mm.errorbit == -1) {
1501                     if (mm.crcok)
1502                         Modes.stat_goodcrc++;
1503                     else
1504                         Modes.stat_badcrc++;
1505                 } else {
1506                     Modes.stat_badcrc++;
1507                     Modes.stat_fixed++;
1508                     if (mm.errorbit < MODES_LONG_MSG_BITS)
1509                         Modes.stat_single_bit_fix++;
1510                     else
1511                         Modes.stat_two_bits_fix++;
1512                 }
1513             }
1514 
1515             /* Output debug mode info if needed. */
1516             if (use_correction == 0) {
1517                 if (Modes.debug & MODES_DEBUG_DEMOD)
1518                     dumpRawMessage("Demodulated with 0 errors", msg, m, j);
1519                 else if (Modes.debug & MODES_DEBUG_BADCRC &&
1520                          mm.msgtype == 17 &&
1521                          (!mm.crcok || mm.errorbit != -1))
1522                     dumpRawMessage("Decoded with bad CRC", msg, m, j);
1523                 else if (Modes.debug & MODES_DEBUG_GOODCRC && mm.crcok &&
1524                          mm.errorbit == -1)
1525                     dumpRawMessage("Decoded with good CRC", msg, m, j);
1526             }
1527 
1528             /* Skip this message if we are sure it's fine. */
1529             if (mm.crcok) {
1530                 j += (MODES_PREAMBLE_US+(msglen*8))*2;
1531                 good_message = 1;
1532                 if (use_correction)
1533                     mm.phase_corrected = 1;
1534             }
1535 
1536             /* Pass data to the next layer */
1537             useModesMessage(&mm);
1538         } else {
1539             if (Modes.debug & MODES_DEBUG_DEMODERR && use_correction) {
1540                 printf("The following message has %d demod errors\n", errors);
1541                 dumpRawMessage("Demodulated with errors", msg, m, j);
1542             }
1543         }
1544 
1545         /* Retry with phase correction if possible. */
1546         if (!good_message && !use_correction) {
1547             j--;
1548             use_correction = 1;
1549         } else {
1550             use_correction = 0;
1551         }
1552     }
1553 }
1554 
1555 /* When a new message is available, because it was decoded from the
1556  * RTL device, file, or received in the TCP input port, or any other
1557  * way we can receive a decoded message, we call this function in order
1558  * to use the message.
1559  *
1560  * Basically this function passes a raw message to the upper layers for
1561  * further processing and visualization. */
useModesMessage(struct modesMessage * mm)1562 void useModesMessage(struct modesMessage *mm) {
1563     if (!Modes.stats && (Modes.check_crc == 0 || mm->crcok)) {
1564         /* Track aircrafts in interactive mode or if the HTTP
1565          * interface is enabled. */
1566         if (Modes.interactive || Modes.stat_http_requests > 0 || Modes.stat_sbs_connections > 0) {
1567             struct aircraft *a = interactiveReceiveData(mm);
1568             if (a && Modes.stat_sbs_connections > 0) modesSendSBSOutput(mm, a);  /* Feed SBS output clients. */
1569         }
1570         /* In non-interactive way, display messages on standard output. */
1571         if (!Modes.interactive) {
1572             displayModesMessage(mm);
1573             if (!Modes.raw && !Modes.onlyaddr) printf("\n");
1574         }
1575         /* Send data to connected clients. */
1576         if (Modes.net) {
1577             modesSendRawOutput(mm);  /* Feed raw output clients. */
1578         }
1579     }
1580 }
1581 
1582 /* ========================= Interactive mode =============================== */
1583 
1584 /* Return a new aircraft structure for the interactive mode linked list
1585  * of aircrafts. */
interactiveCreateAircraft(uint32_t addr)1586 struct aircraft *interactiveCreateAircraft(uint32_t addr) {
1587     struct aircraft *a = malloc(sizeof(*a));
1588 
1589     a->addr = addr;
1590     snprintf(a->hexaddr,sizeof(a->hexaddr),"%06x",(int)addr);
1591     a->flight[0] = '\0';
1592     a->altitude = 0;
1593     a->speed = 0;
1594     a->track = 0;
1595     a->odd_cprlat = 0;
1596     a->odd_cprlon = 0;
1597     a->odd_cprtime = 0;
1598     a->even_cprlat = 0;
1599     a->even_cprlon = 0;
1600     a->even_cprtime = 0;
1601     a->lat = 0;
1602     a->lon = 0;
1603     a->seen = time(NULL);
1604     a->messages = 0;
1605     a->next = NULL;
1606     return a;
1607 }
1608 
1609 /* Return the aircraft with the specified address, or NULL if no aircraft
1610  * exists with this address. */
interactiveFindAircraft(uint32_t addr)1611 struct aircraft *interactiveFindAircraft(uint32_t addr) {
1612     struct aircraft *a = Modes.aircrafts;
1613 
1614     while(a) {
1615         if (a->addr == addr) return a;
1616         a = a->next;
1617     }
1618     return NULL;
1619 }
1620 
1621 /* Always positive MOD operation, used for CPR decoding. */
cprModFunction(int a,int b)1622 int cprModFunction(int a, int b) {
1623     int res = a % b;
1624     if (res < 0) res += b;
1625     return res;
1626 }
1627 
1628 /* The NL function uses the precomputed table from 1090-WP-9-14 */
cprNLFunction(double lat)1629 int cprNLFunction(double lat) {
1630     if (lat < 0) lat = -lat; /* Table is simmetric about the equator. */
1631     if (lat < 10.47047130) return 59;
1632     if (lat < 14.82817437) return 58;
1633     if (lat < 18.18626357) return 57;
1634     if (lat < 21.02939493) return 56;
1635     if (lat < 23.54504487) return 55;
1636     if (lat < 25.82924707) return 54;
1637     if (lat < 27.93898710) return 53;
1638     if (lat < 29.91135686) return 52;
1639     if (lat < 31.77209708) return 51;
1640     if (lat < 33.53993436) return 50;
1641     if (lat < 35.22899598) return 49;
1642     if (lat < 36.85025108) return 48;
1643     if (lat < 38.41241892) return 47;
1644     if (lat < 39.92256684) return 46;
1645     if (lat < 41.38651832) return 45;
1646     if (lat < 42.80914012) return 44;
1647     if (lat < 44.19454951) return 43;
1648     if (lat < 45.54626723) return 42;
1649     if (lat < 46.86733252) return 41;
1650     if (lat < 48.16039128) return 40;
1651     if (lat < 49.42776439) return 39;
1652     if (lat < 50.67150166) return 38;
1653     if (lat < 51.89342469) return 37;
1654     if (lat < 53.09516153) return 36;
1655     if (lat < 54.27817472) return 35;
1656     if (lat < 55.44378444) return 34;
1657     if (lat < 56.59318756) return 33;
1658     if (lat < 57.72747354) return 32;
1659     if (lat < 58.84763776) return 31;
1660     if (lat < 59.95459277) return 30;
1661     if (lat < 61.04917774) return 29;
1662     if (lat < 62.13216659) return 28;
1663     if (lat < 63.20427479) return 27;
1664     if (lat < 64.26616523) return 26;
1665     if (lat < 65.31845310) return 25;
1666     if (lat < 66.36171008) return 24;
1667     if (lat < 67.39646774) return 23;
1668     if (lat < 68.42322022) return 22;
1669     if (lat < 69.44242631) return 21;
1670     if (lat < 70.45451075) return 20;
1671     if (lat < 71.45986473) return 19;
1672     if (lat < 72.45884545) return 18;
1673     if (lat < 73.45177442) return 17;
1674     if (lat < 74.43893416) return 16;
1675     if (lat < 75.42056257) return 15;
1676     if (lat < 76.39684391) return 14;
1677     if (lat < 77.36789461) return 13;
1678     if (lat < 78.33374083) return 12;
1679     if (lat < 79.29428225) return 11;
1680     if (lat < 80.24923213) return 10;
1681     if (lat < 81.19801349) return 9;
1682     if (lat < 82.13956981) return 8;
1683     if (lat < 83.07199445) return 7;
1684     if (lat < 83.99173563) return 6;
1685     if (lat < 84.89166191) return 5;
1686     if (lat < 85.75541621) return 4;
1687     if (lat < 86.53536998) return 3;
1688     if (lat < 87.00000000) return 2;
1689     else return 1;
1690 }
1691 
cprNFunction(double lat,int isodd)1692 int cprNFunction(double lat, int isodd) {
1693     int nl = cprNLFunction(lat) - isodd;
1694     if (nl < 1) nl = 1;
1695     return nl;
1696 }
1697 
cprDlonFunction(double lat,int isodd)1698 double cprDlonFunction(double lat, int isodd) {
1699     return 360.0 / cprNFunction(lat, isodd);
1700 }
1701 
1702 /* This algorithm comes from:
1703  * http://www.lll.lu/~edward/edward/adsb/DecodingADSBposition.html.
1704  *
1705  *
1706  * A few remarks:
1707  * 1) 131072 is 2^17 since CPR latitude and longitude are encoded in 17 bits.
1708  * 2) We assume that we always received the odd packet as last packet for
1709  *    simplicity. This may provide a position that is less fresh of a few
1710  *    seconds.
1711  */
decodeCPR(struct aircraft * a)1712 void decodeCPR(struct aircraft *a) {
1713     const double AirDlat0 = 360.0 / 60;
1714     const double AirDlat1 = 360.0 / 59;
1715     double lat0 = a->even_cprlat;
1716     double lat1 = a->odd_cprlat;
1717     double lon0 = a->even_cprlon;
1718     double lon1 = a->odd_cprlon;
1719 
1720     /* Compute the Latitude Index "j" */
1721     int j = floor(((59*lat0 - 60*lat1) / 131072) + 0.5);
1722     double rlat0 = AirDlat0 * (cprModFunction(j,60) + lat0 / 131072);
1723     double rlat1 = AirDlat1 * (cprModFunction(j,59) + lat1 / 131072);
1724 
1725     if (rlat0 >= 270) rlat0 -= 360;
1726     if (rlat1 >= 270) rlat1 -= 360;
1727 
1728     /* Check that both are in the same latitude zone, or abort. */
1729     if (cprNLFunction(rlat0) != cprNLFunction(rlat1)) return;
1730 
1731     /* Compute ni and the longitude index m */
1732     if (a->even_cprtime > a->odd_cprtime) {
1733         /* Use even packet. */
1734         int ni = cprNFunction(rlat0,0);
1735         int m = floor((((lon0 * (cprNLFunction(rlat0)-1)) -
1736                         (lon1 * cprNLFunction(rlat0))) / 131072) + 0.5);
1737         a->lon = cprDlonFunction(rlat0,0) * (cprModFunction(m,ni)+lon0/131072);
1738         a->lat = rlat0;
1739     } else {
1740         /* Use odd packet. */
1741         int ni = cprNFunction(rlat1,1);
1742         int m = floor((((lon0 * (cprNLFunction(rlat1)-1)) -
1743                         (lon1 * cprNLFunction(rlat1))) / 131072.0) + 0.5);
1744         a->lon = cprDlonFunction(rlat1,1) * (cprModFunction(m,ni)+lon1/131072);
1745         a->lat = rlat1;
1746     }
1747     if (a->lon > 180) a->lon -= 360;
1748 }
1749 
1750 /* Receive new messages and populate the interactive mode with more info. */
interactiveReceiveData(struct modesMessage * mm)1751 struct aircraft *interactiveReceiveData(struct modesMessage *mm) {
1752     uint32_t addr;
1753     struct aircraft *a, *aux;
1754 
1755     if (Modes.check_crc && mm->crcok == 0) return NULL;
1756     addr = (mm->aa1 << 16) | (mm->aa2 << 8) | mm->aa3;
1757 
1758     /* Loookup our aircraft or create a new one. */
1759     a = interactiveFindAircraft(addr);
1760     if (!a) {
1761         a = interactiveCreateAircraft(addr);
1762         a->next = Modes.aircrafts;
1763         Modes.aircrafts = a;
1764     } else {
1765         /* If it is an already known aircraft, move it on head
1766          * so we keep aircrafts ordered by received message time.
1767          *
1768          * However move it on head only if at least one second elapsed
1769          * since the aircraft that is currently on head sent a message,
1770          * othewise with multiple aircrafts at the same time we have an
1771          * useless shuffle of positions on the screen. */
1772         if (0 && Modes.aircrafts != a && (time(NULL) - a->seen) >= 1) {
1773             aux = Modes.aircrafts;
1774             while(aux->next != a) aux = aux->next;
1775             /* Now we are a node before the aircraft to remove. */
1776             aux->next = aux->next->next; /* removed. */
1777             /* Add on head */
1778             a->next = Modes.aircrafts;
1779             Modes.aircrafts = a;
1780         }
1781     }
1782 
1783     a->seen = time(NULL);
1784     a->messages++;
1785 
1786     if (mm->msgtype == 0 || mm->msgtype == 4 || mm->msgtype == 20) {
1787         a->altitude = mm->altitude;
1788     } else if (mm->msgtype == 17) {
1789         if (mm->metype >= 1 && mm->metype <= 4) {
1790             memcpy(a->flight, mm->flight, sizeof(a->flight));
1791         } else if (mm->metype >= 9 && mm->metype <= 18) {
1792             a->altitude = mm->altitude;
1793             if (mm->fflag) {
1794                 a->odd_cprlat = mm->raw_latitude;
1795                 a->odd_cprlon = mm->raw_longitude;
1796                 a->odd_cprtime = mstime();
1797             } else {
1798                 a->even_cprlat = mm->raw_latitude;
1799                 a->even_cprlon = mm->raw_longitude;
1800                 a->even_cprtime = mstime();
1801             }
1802             /* If the two data is less than 10 seconds apart, compute
1803              * the position. */
1804             if (abs(a->even_cprtime - a->odd_cprtime) <= 10000) {
1805                 decodeCPR(a);
1806             }
1807         } else if (mm->metype == 19) {
1808             if (mm->mesub == 1 || mm->mesub == 2) {
1809                 a->speed = mm->velocity;
1810                 a->track = mm->heading;
1811             }
1812         }
1813     }
1814     return a;
1815 }
1816 
1817 /* Show the currently captured interactive data on screen. */
interactiveShowData(void)1818 void interactiveShowData(void) {
1819     struct aircraft *a = Modes.aircrafts;
1820     time_t now = time(NULL);
1821     char progress[4];
1822     int count = 0;
1823 
1824     memset(progress,' ',3);
1825     progress[time(NULL)%3] = '.';
1826     progress[3] = '\0';
1827 
1828     printf("\x1b[H\x1b[2J");    /* Clear the screen */
1829     printf(
1830 "Hex    Flight   Altitude  Speed   Lat       Lon       Track  Messages Seen %s\n"
1831 "--------------------------------------------------------------------------------\n",
1832         progress);
1833 
1834     while(a && count < Modes.interactive_rows) {
1835         int altitude = a->altitude, speed = a->speed;
1836 
1837         /* Convert units to metric if --metric was specified. */
1838         if (Modes.metric) {
1839             altitude /= 3.2828;
1840             speed *= 1.852;
1841         }
1842 
1843         printf("%-6s %-8s %-9d %-7d %-7.03f   %-7.03f   %-3d   %-9ld %d sec\n",
1844             a->hexaddr, a->flight, altitude, speed,
1845             a->lat, a->lon, a->track, a->messages,
1846             (int)(now - a->seen));
1847         a = a->next;
1848         count++;
1849     }
1850 }
1851 
1852 /* When in interactive mode If we don't receive new nessages within
1853  * MODES_INTERACTIVE_TTL seconds we remove the aircraft from the list. */
interactiveRemoveStaleAircrafts(void)1854 void interactiveRemoveStaleAircrafts(void) {
1855     struct aircraft *a = Modes.aircrafts;
1856     struct aircraft *prev = NULL;
1857     time_t now = time(NULL);
1858 
1859     while(a) {
1860         if ((now - a->seen) > Modes.interactive_ttl) {
1861             struct aircraft *next = a->next;
1862             /* Remove the element from the linked list, with care
1863              * if we are removing the first element. */
1864             free(a);
1865             if (!prev)
1866                 Modes.aircrafts = next;
1867             else
1868                 prev->next = next;
1869             a = next;
1870         } else {
1871             prev = a;
1872             a = a->next;
1873         }
1874     }
1875 }
1876 
1877 /* ============================== Snip mode ================================= */
1878 
1879 /* Get raw IQ samples and filter everything is < than the specified level
1880  * for more than 256 samples in order to reduce example file size. */
snipMode(int level)1881 void snipMode(int level) {
1882     int i, q;
1883     long long c = 0;
1884 
1885     while ((i = getchar()) != EOF && (q = getchar()) != EOF) {
1886         if (abs(i-127) < level && abs(q-127) < level) {
1887             c++;
1888             if (c > MODES_PREAMBLE_US*4) continue;
1889         } else {
1890             c = 0;
1891         }
1892         putchar(i);
1893         putchar(q);
1894     }
1895 }
1896 
1897 /* ============================= Networking =================================
1898  * Note: here we risregard any kind of good coding practice in favor of
1899  * extreme simplicity, that is:
1900  *
1901  * 1) We only rely on the kernel buffers for our I/O without any kind of
1902  *    user space buffering.
1903  * 2) We don't register any kind of event handler, from time to time a
1904  *    function gets called and we accept new connections. All the rest is
1905  *    handled via non-blocking I/O and manually pulling clients to see if
1906  *    they have something new to share with us when reading is needed.
1907  */
1908 
1909 #define MODES_NET_SERVICE_RAWO 0
1910 #define MODES_NET_SERVICE_RAWI 1
1911 #define MODES_NET_SERVICE_HTTP 2
1912 #define MODES_NET_SERVICE_SBS 3
1913 #define MODES_NET_SERVICES_NUM 4
1914 struct {
1915     char *descr;
1916     int *socket;
1917     int port;
1918 } modesNetServices[MODES_NET_SERVICES_NUM] = {
1919     {"Raw TCP output", &Modes.ros, MODES_NET_OUTPUT_RAW_PORT},
1920     {"Raw TCP input", &Modes.ris, MODES_NET_INPUT_RAW_PORT},
1921     {"HTTP server", &Modes.https, MODES_NET_HTTP_PORT},
1922     {"Basestation TCP output", &Modes.sbsos, MODES_NET_OUTPUT_SBS_PORT}
1923 };
1924 
1925 /* Networking "stack" initialization. */
modesInitNet(void)1926 void modesInitNet(void) {
1927     int j;
1928 
1929     memset(Modes.clients,0,sizeof(Modes.clients));
1930     Modes.maxfd = -1;
1931 
1932     for (j = 0; j < MODES_NET_SERVICES_NUM; j++) {
1933         int s = anetTcpServer(Modes.aneterr, modesNetServices[j].port, NULL);
1934         if (s == -1) {
1935             fprintf(stderr, "Error opening the listening port %d (%s): %s\n",
1936                 modesNetServices[j].port,
1937                 modesNetServices[j].descr,
1938                 strerror(errno));
1939             exit(1);
1940         }
1941         anetNonBlock(Modes.aneterr, s);
1942         *modesNetServices[j].socket = s;
1943     }
1944 
1945     signal(SIGPIPE, SIG_IGN);
1946 }
1947 
1948 /* This function gets called from time to time when the decoding thread is
1949  * awakened by new data arriving. This usually happens a few times every
1950  * second. */
modesAcceptClients(void)1951 void modesAcceptClients(void) {
1952     int fd, port;
1953     unsigned int j;
1954     struct client *c;
1955 
1956     for (j = 0; j < MODES_NET_SERVICES_NUM; j++) {
1957         fd = anetTcpAccept(Modes.aneterr, *modesNetServices[j].socket,
1958                            NULL, &port);
1959         if (fd == -1) {
1960             if (Modes.debug & MODES_DEBUG_NET && errno != EAGAIN)
1961                 printf("Accept %d: %s\n", *modesNetServices[j].socket,
1962                        strerror(errno));
1963             continue;
1964         }
1965 
1966         if (fd >= MODES_NET_MAX_FD) {
1967             close(fd);
1968             return; /* Max number of clients reached. */
1969         }
1970 
1971         anetNonBlock(Modes.aneterr, fd);
1972         c = malloc(sizeof(*c));
1973         c->service = *modesNetServices[j].socket;
1974         c->fd = fd;
1975         c->buflen = 0;
1976         Modes.clients[fd] = c;
1977         anetSetSendBuffer(Modes.aneterr,fd,MODES_NET_SNDBUF_SIZE);
1978 
1979         if (Modes.maxfd < fd) Modes.maxfd = fd;
1980         if (*modesNetServices[j].socket == Modes.sbsos)
1981             Modes.stat_sbs_connections++;
1982 
1983         j--; /* Try again with the same listening port. */
1984 
1985         if (Modes.debug & MODES_DEBUG_NET)
1986             printf("Created new client %d\n", fd);
1987     }
1988 }
1989 
1990 /* On error free the client, collect the structure, adjust maxfd if needed. */
modesFreeClient(int fd)1991 void modesFreeClient(int fd) {
1992     close(fd);
1993     free(Modes.clients[fd]);
1994     Modes.clients[fd] = NULL;
1995 
1996     if (Modes.debug & MODES_DEBUG_NET)
1997         printf("Closing client %d\n", fd);
1998 
1999     /* If this was our maxfd, scan the clients array to find the new max.
2000      * Note that we are sure there is no active fd greater than the closed
2001      * fd, so we scan from fd-1 to 0. */
2002     if (Modes.maxfd == fd) {
2003         int j;
2004 
2005         Modes.maxfd = -1;
2006         for (j = fd-1; j >= 0; j--) {
2007             if (Modes.clients[j]) {
2008                 Modes.maxfd = j;
2009                 break;
2010             }
2011         }
2012     }
2013 }
2014 
2015 /* Send the specified message to all clients listening for a given service. */
modesSendAllClients(int service,void * msg,int len)2016 void modesSendAllClients(int service, void *msg, int len) {
2017     int j;
2018     struct client *c;
2019 
2020     for (j = 0; j <= Modes.maxfd; j++) {
2021         c = Modes.clients[j];
2022         if (c && c->service == service) {
2023             int nwritten = write(j, msg, len);
2024             if (nwritten != len) {
2025                 modesFreeClient(j);
2026             }
2027         }
2028     }
2029 }
2030 
2031 /* Write raw output to TCP clients. */
modesSendRawOutput(struct modesMessage * mm)2032 void modesSendRawOutput(struct modesMessage *mm) {
2033     char msg[128], *p = msg;
2034     int j;
2035 
2036     *p++ = '*';
2037     for (j = 0; j < mm->msgbits/8; j++) {
2038         sprintf(p, "%02X", mm->msg[j]);
2039         p += 2;
2040     }
2041     *p++ = ';';
2042     *p++ = '\n';
2043     modesSendAllClients(Modes.ros, msg, p-msg);
2044 }
2045 
2046 
2047 /* Write SBS output to TCP clients. */
modesSendSBSOutput(struct modesMessage * mm,struct aircraft * a)2048 void modesSendSBSOutput(struct modesMessage *mm, struct aircraft *a) {
2049     char msg[256], *p = msg;
2050     int emergency = 0, ground = 0, alert = 0, spi = 0;
2051 
2052     if (mm->msgtype == 4 || mm->msgtype == 5 || mm->msgtype == 21) {
2053         /* Node: identity is calculated/kept in base10 but is actually
2054          * octal (07500 is represented as 7500) */
2055         if (mm->identity == 7500 || mm->identity == 7600 ||
2056             mm->identity == 7700) emergency = -1;
2057         if (mm->fs == 1 || mm->fs == 3) ground = -1;
2058         if (mm->fs == 2 || mm->fs == 3 || mm->fs == 4) alert = -1;
2059         if (mm->fs == 4 || mm->fs == 5) spi = -1;
2060     }
2061 
2062     if (mm->msgtype == 0) {
2063         p += sprintf(p, "MSG,5,,,%02X%02X%02X,,,,,,,%d,,,,,,,,,,",
2064         mm->aa1, mm->aa2, mm->aa3, mm->altitude);
2065     } else if (mm->msgtype == 4) {
2066         p += sprintf(p, "MSG,5,,,%02X%02X%02X,,,,,,,%d,,,,,,,%d,%d,%d,%d",
2067         mm->aa1, mm->aa2, mm->aa3, mm->altitude, alert, emergency, spi, ground);
2068     } else if (mm->msgtype == 5) {
2069         p += sprintf(p, "MSG,6,,,%02X%02X%02X,,,,,,,,,,,,,%d,%d,%d,%d,%d",
2070         mm->aa1, mm->aa2, mm->aa3, mm->identity, alert, emergency, spi, ground);
2071     } else if (mm->msgtype == 11) {
2072         p += sprintf(p, "MSG,8,,,%02X%02X%02X,,,,,,,,,,,,,,,,,",
2073         mm->aa1, mm->aa2, mm->aa3);
2074     } else if (mm->msgtype == 17 && mm->metype == 4) {
2075         p += sprintf(p, "MSG,1,,,%02X%02X%02X,,,,,,%s,,,,,,,,0,0,0,0",
2076         mm->aa1, mm->aa2, mm->aa3, mm->flight);
2077     } else if (mm->msgtype == 17 && mm->metype >= 9 && mm->metype <= 18) {
2078         if (a->lat == 0 && a->lon == 0)
2079             p += sprintf(p, "MSG,3,,,%02X%02X%02X,,,,,,,%d,,,,,,,0,0,0,0",
2080             mm->aa1, mm->aa2, mm->aa3, mm->altitude);
2081         else
2082             p += sprintf(p, "MSG,3,,,%02X%02X%02X,,,,,,,%d,,,%1.5f,%1.5f,,,"
2083                             "0,0,0,0",
2084             mm->aa1, mm->aa2, mm->aa3, mm->altitude, a->lat, a->lon);
2085     } else if (mm->msgtype == 17 && mm->metype == 19 && mm->mesub == 1) {
2086         int vr = (mm->vert_rate_sign==0?1:-1) * (mm->vert_rate-1) * 64;
2087 
2088         p += sprintf(p, "MSG,4,,,%02X%02X%02X,,,,,,,,%d,%d,,,%i,,0,0,0,0",
2089         mm->aa1, mm->aa2, mm->aa3, a->speed, a->track, vr);
2090     } else if (mm->msgtype == 21) {
2091         p += sprintf(p, "MSG,6,,,%02X%02X%02X,,,,,,,,,,,,,%d,%d,%d,%d,%d",
2092         mm->aa1, mm->aa2, mm->aa3, mm->identity, alert, emergency, spi, ground);
2093     } else {
2094         return;
2095     }
2096 
2097     *p++ = '\n';
2098     modesSendAllClients(Modes.sbsos, msg, p-msg);
2099 }
2100 
2101 /* Turn an hex digit into its 4 bit decimal value.
2102  * Returns -1 if the digit is not in the 0-F range. */
hexDigitVal(int c)2103 int hexDigitVal(int c) {
2104     c = tolower(c);
2105     if (c >= '0' && c <= '9') return c-'0';
2106     else if (c >= 'a' && c <= 'f') return c-'a'+10;
2107     else return -1;
2108 }
2109 
2110 /* This function decodes a string representing a Mode S message in
2111  * raw hex format like: *8D4B969699155600E87406F5B69F;
2112  * The string is supposed to be at the start of the client buffer
2113  * and null-terminated.
2114  *
2115  * The message is passed to the higher level layers, so it feeds
2116  * the selected screen output, the network output and so forth.
2117  *
2118  * If the message looks invalid is silently discarded.
2119  *
2120  * The function always returns 0 (success) to the caller as there is
2121  * no case where we want broken messages here to close the client
2122  * connection. */
decodeHexMessage(struct client * c)2123 int decodeHexMessage(struct client *c) {
2124     char *hex = c->buf;
2125     int l = strlen(hex), j;
2126     unsigned char msg[MODES_LONG_MSG_BYTES];
2127     struct modesMessage mm;
2128 
2129     /* Remove spaces on the left and on the right. */
2130     while(l && isspace(hex[l-1])) {
2131         hex[l-1] = '\0';
2132         l--;
2133     }
2134     while(isspace(*hex)) {
2135         hex++;
2136         l--;
2137     }
2138 
2139     /* Turn the message into binary. */
2140     if (l < 2 || hex[0] != '*' || hex[l-1] != ';') return 0;
2141     hex++; l-=2; /* Skip * and ; */
2142     if (l > MODES_LONG_MSG_BYTES*2) return 0; /* Too long message... broken. */
2143     for (j = 0; j < l; j += 2) {
2144         int high = hexDigitVal(hex[j]);
2145         int low = hexDigitVal(hex[j+1]);
2146 
2147         if (high == -1 || low == -1) return 0;
2148         msg[j/2] = (high<<4) | low;
2149     }
2150     decodeModesMessage(&mm,msg);
2151     useModesMessage(&mm);
2152     return 0;
2153 }
2154 
2155 /* Return a description of planes in json. */
aircraftsToJson(int * len)2156 char *aircraftsToJson(int *len) {
2157     struct aircraft *a = Modes.aircrafts;
2158     int buflen = 1024; /* The initial buffer is incremented as needed. */
2159     char *buf = malloc(buflen), *p = buf;
2160     int l;
2161 
2162     l = snprintf(p,buflen,"[\n");
2163     p += l; buflen -= l;
2164     while(a) {
2165         int altitude = a->altitude, speed = a->speed;
2166 
2167         /* Convert units to metric if --metric was specified. */
2168         if (Modes.metric) {
2169             altitude /= 3.2828;
2170             speed *= 1.852;
2171         }
2172 
2173         if (a->lat != 0 && a->lon != 0) {
2174             l = snprintf(p,buflen,
2175                 "{\"hex\":\"%s\", \"flight\":\"%s\", \"lat\":%f, "
2176                 "\"lon\":%f, \"altitude\":%d, \"track\":%d, "
2177                 "\"speed\":%d},\n",
2178                 a->hexaddr, a->flight, a->lat, a->lon, a->altitude, a->track,
2179                 a->speed);
2180             p += l; buflen -= l;
2181             /* Resize if needed. */
2182             if (buflen < 256) {
2183                 int used = p-buf;
2184                 buflen += 1024; /* Our increment. */
2185                 buf = realloc(buf,used+buflen);
2186                 p = buf+used;
2187             }
2188         }
2189         a = a->next;
2190     }
2191     /* Remove the final comma if any, and closes the json array. */
2192     if (*(p-2) == ',') {
2193         *(p-2) = '\n';
2194         p--;
2195         buflen++;
2196     }
2197     l = snprintf(p,buflen,"]\n");
2198     p += l; buflen -= l;
2199 
2200     *len = p-buf;
2201     return buf;
2202 }
2203 
2204 #define MODES_CONTENT_TYPE_HTML "text/html;charset=utf-8"
2205 #define MODES_CONTENT_TYPE_JSON "application/json;charset=utf-8"
2206 
2207 /* Get an HTTP request header and write the response to the client.
2208  * Again here we assume that the socket buffer is enough without doing
2209  * any kind of userspace buffering.
2210  *
2211  * Returns 1 on error to signal the caller the client connection should
2212  * be closed. */
handleHTTPRequest(struct client * c)2213 int handleHTTPRequest(struct client *c) {
2214     char hdr[512];
2215     int clen, hdrlen;
2216     int httpver, keepalive;
2217     char *p, *url, *content;
2218     char *ctype;
2219 
2220     if (Modes.debug & MODES_DEBUG_NET)
2221         printf("\nHTTP request: %s\n", c->buf);
2222 
2223     /* Minimally parse the request. */
2224     httpver = (strstr(c->buf, "HTTP/1.1") != NULL) ? 11 : 10;
2225     if (httpver == 10) {
2226         /* HTTP 1.0 defaults to close, unless otherwise specified. */
2227         keepalive = strstr(c->buf, "Connection: keep-alive") != NULL;
2228     } else if (httpver == 11) {
2229         /* HTTP 1.1 defaults to keep-alive, unless close is specified. */
2230         keepalive = strstr(c->buf, "Connection: close") == NULL;
2231     }
2232 
2233     /* Identify he URL. */
2234     p = strchr(c->buf,' ');
2235     if (!p) return 1; /* There should be the method and a space... */
2236     url = ++p; /* Now this should point to the requested URL. */
2237     p = strchr(p, ' ');
2238     if (!p) return 1; /* There should be a space before HTTP/... */
2239     *p = '\0';
2240 
2241     if (Modes.debug & MODES_DEBUG_NET) {
2242         printf("\nHTTP keep alive: %d\n", keepalive);
2243         printf("HTTP requested URL: %s\n\n", url);
2244     }
2245 
2246     /* Select the content to send, we have just two so far:
2247      * "/" -> Our google map application.
2248      * "/data.json" -> Our ajax request to update planes. */
2249     if (strstr(url, "/data.json")) {
2250         content = aircraftsToJson(&clen);
2251         ctype = MODES_CONTENT_TYPE_JSON;
2252     } else {
2253         struct stat sbuf;
2254         int fd = -1;
2255 
2256         if (stat("/usr/local/share/dump1090/gmap.html",&sbuf) != -1 &&
2257             (fd = open("/usr/local/share/dump1090/gmap.html",O_RDONLY)) != -1)
2258         {
2259             content = malloc(sbuf.st_size);
2260             if (read(fd,content,sbuf.st_size) == -1) {
2261                 snprintf(content,sbuf.st_size,"Error reading from file: %s",
2262                     strerror(errno));
2263             }
2264             clen = sbuf.st_size;
2265         } else {
2266             char buf[128];
2267 
2268             clen = snprintf(buf,sizeof(buf),"Error opening HTML file: %s",
2269                 strerror(errno));
2270             content = strdup(buf);
2271         }
2272         if (fd != -1) close(fd);
2273         ctype = MODES_CONTENT_TYPE_HTML;
2274     }
2275 
2276     /* Create the header and send the reply. */
2277     hdrlen = snprintf(hdr, sizeof(hdr),
2278         "HTTP/1.1 200 OK\r\n"
2279         "Server: Dump1090\r\n"
2280         "Content-Type: %s\r\n"
2281         "Connection: %s\r\n"
2282         "Content-Length: %d\r\n"
2283         "Access-Control-Allow-Origin: *\r\n"
2284         "\r\n",
2285         ctype,
2286         keepalive ? "keep-alive" : "close",
2287         clen);
2288 
2289     if (Modes.debug & MODES_DEBUG_NET)
2290         printf("HTTP Reply header:\n%s", hdr);
2291 
2292     /* Send header and content. */
2293     if (write(c->fd, hdr, hdrlen) != hdrlen ||
2294         write(c->fd, content, clen) != clen)
2295     {
2296         free(content);
2297         return 1;
2298     }
2299     free(content);
2300     Modes.stat_http_requests++;
2301     return !keepalive;
2302 }
2303 
2304 /* This function polls the clients using read() in order to receive new
2305  * messages from the net.
2306  *
2307  * The message is supposed to be separated by the next message by the
2308  * separator 'sep', that is a null-terminated C string.
2309  *
2310  * Every full message received is decoded and passed to the higher layers
2311  * calling the function 'handler'.
2312  *
2313  * The handelr returns 0 on success, or 1 to signal this function we
2314  * should close the connection with the client in case of non-recoverable
2315  * errors. */
modesReadFromClient(struct client * c,char * sep,int (* handler)(struct client *))2316 void modesReadFromClient(struct client *c, char *sep,
2317                          int(*handler)(struct client *))
2318 {
2319     while(1) {
2320         int left = MODES_CLIENT_BUF_SIZE - c->buflen;
2321         int nread = read(c->fd, c->buf+c->buflen, left);
2322         int fullmsg = 0;
2323         int i;
2324         char *p;
2325 
2326         if (nread <= 0) {
2327             if (nread == 0 || errno != EAGAIN) {
2328                 /* Error, or end of file. */
2329                 modesFreeClient(c->fd);
2330             }
2331             break; /* Serve next client. */
2332         }
2333         c->buflen += nread;
2334 
2335         /* Always null-term so we are free to use strstr() */
2336         c->buf[c->buflen] = '\0';
2337 
2338         /* If there is a complete message there must be the separator 'sep'
2339          * in the buffer, note that we full-scan the buffer at every read
2340          * for simplicity. */
2341         while ((p = strstr(c->buf, sep)) != NULL) {
2342             i = p - c->buf; /* Turn it as an index inside the buffer. */
2343             c->buf[i] = '\0'; /* Te handler expects null terminated strings. */
2344             /* Call the function to process the message. It returns 1
2345              * on error to signal we should close the client connection. */
2346             if (handler(c)) {
2347                 modesFreeClient(c->fd);
2348                 return;
2349             }
2350             /* Move what's left at the start of the buffer. */
2351             i += strlen(sep); /* The separator is part of the previous msg. */
2352             memmove(c->buf,c->buf+i,c->buflen-i);
2353             c->buflen -= i;
2354             c->buf[c->buflen] = '\0';
2355             /* Maybe there are more messages inside the buffer.
2356              * Start looping from the start again. */
2357             fullmsg = 1;
2358         }
2359         /* If our buffer is full discard it, this is some badly
2360          * formatted shit. */
2361         if (c->buflen == MODES_CLIENT_BUF_SIZE) {
2362             c->buflen = 0;
2363             /* If there is garbage, read more to discard it ASAP. */
2364             continue;
2365         }
2366         /* If no message was decoded process the next client, otherwise
2367          * read more data from the same client. */
2368         if (!fullmsg) break;
2369     }
2370 }
2371 
2372 /* Read data from clients. This function actually delegates a lower-level
2373  * function that depends on the kind of service (raw, http, ...). */
modesReadFromClients(void)2374 void modesReadFromClients(void) {
2375     int j;
2376     struct client *c;
2377 
2378     for (j = 0; j <= Modes.maxfd; j++) {
2379         if ((c = Modes.clients[j]) == NULL) continue;
2380         if (c->service == Modes.ris)
2381             modesReadFromClient(c,"\n",decodeHexMessage);
2382         else if (c->service == Modes.https)
2383             modesReadFromClient(c,"\r\n\r\n",handleHTTPRequest);
2384     }
2385 }
2386 
2387 /* This function is used when "net only" mode is enabled to know when there
2388  * is at least a new client to serve. Note that the dump1090 networking model
2389  * is extremely trivial and a function takes care of handling all the clients
2390  * that have something to serve, without a proper event library, so the
2391  * function here returns as long as there is a single client ready, or
2392  * when the specified timeout in milliesconds elapsed, without specifying to
2393  * the caller what client requires to be served. */
modesWaitReadableClients(int timeout_ms)2394 void modesWaitReadableClients(int timeout_ms) {
2395     struct timeval tv;
2396     fd_set fds;
2397     int j, maxfd = Modes.maxfd;
2398 
2399     FD_ZERO(&fds);
2400 
2401     /* Set client FDs */
2402     for (j = 0; j <= Modes.maxfd; j++) {
2403         if (Modes.clients[j]) FD_SET(j,&fds);
2404     }
2405 
2406     /* Set listening sockets to accept new clients ASAP. */
2407     for (j = 0; j < MODES_NET_SERVICES_NUM; j++) {
2408         int s = *modesNetServices[j].socket;
2409         FD_SET(s,&fds);
2410         if (s > maxfd) maxfd = s;
2411     }
2412 
2413     tv.tv_sec = timeout_ms/1000;
2414     tv.tv_usec = (timeout_ms%1000)*1000;
2415     /* We don't care why select returned here, timeout, error, or
2416      * FDs ready are all conditions for which we just return. */
2417     select(maxfd+1,&fds,NULL,NULL,&tv);
2418 }
2419 
2420 /* ============================ Terminal handling  ========================== */
2421 
2422 /* Handle resizing terminal. */
sigWinchCallback()2423 void sigWinchCallback() {
2424     signal(SIGWINCH, SIG_IGN);
2425     Modes.interactive_rows = getTermRows();
2426     interactiveShowData();
2427     signal(SIGWINCH, sigWinchCallback);
2428 }
2429 
2430 /* Get the number of rows after the terminal changes size. */
getTermRows()2431 int getTermRows() {
2432     struct winsize w;
2433     ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
2434     return w.ws_row;
2435 }
2436 
2437 /* ================================ Main ==================================== */
2438 
showHelp(void)2439 void showHelp(void) {
2440     printf(
2441 "--device-index <index>   Select RTL device (default: 0).\n"
2442 "--gain <db>              Set gain (default: max gain. Use -100 for auto-gain).\n"
2443 "--enable-agc             Enable the Automatic Gain Control (default: off).\n"
2444 "--freq <hz>              Set frequency (default: 1090 Mhz).\n"
2445 "--ifile <filename>       Read data from file (use '-' for stdin).\n"
2446 "--loop                   With --ifile, read the same file in a loop.\n"
2447 "--interactive            Interactive mode refreshing data on screen.\n"
2448 "--interactive-rows <num> Max number of rows in interactive mode (default: 15).\n"
2449 "--interactive-ttl <sec>  Remove from list if idle for <sec> (default: 60).\n"
2450 "--raw                    Show only messages hex values.\n"
2451 "--net                    Enable networking.\n"
2452 "--net-only               Enable just networking, no RTL device or file used.\n"
2453 "--net-ro-port <port>     TCP listening port for raw output (default: 30002).\n"
2454 "--net-ri-port <port>     TCP listening port for raw input (default: 30001).\n"
2455 "--net-http-port <port>   HTTP server port (default: 8080).\n"
2456 "--net-sbs-port <port>    TCP listening port for BaseStation format output (default: 30003).\n"
2457 "--no-fix                 Disable single-bits error correction using CRC.\n"
2458 "--no-crc-check           Disable messages with broken CRC (discouraged).\n"
2459 "--aggressive             More CPU for more messages (two bits fixes, ...).\n"
2460 "--stats                  With --ifile print stats at exit. No other output.\n"
2461 "--onlyaddr               Show only ICAO addresses (testing purposes).\n"
2462 "--metric                 Use metric units (meters, km/h, ...).\n"
2463 "--snip <level>           Strip IQ file removing samples < level.\n"
2464 "--debug <flags>          Debug mode (verbose), see README for details.\n"
2465 "--help                   Show this help.\n"
2466 "\n"
2467 "Debug mode flags: d = Log frames decoded with errors\n"
2468 "                  D = Log frames decoded with zero errors\n"
2469 "                  c = Log frames with bad CRC\n"
2470 "                  C = Log frames with good CRC\n"
2471 "                  p = Log frames with bad preamble\n"
2472 "                  n = Log network debugging info\n"
2473 "                  j = Log frames to frames.js, loadable by debug.html.\n"
2474     );
2475 }
2476 
2477 /* This function is called a few times every second by main in order to
2478  * perform tasks we need to do continuously, like accepting new clients
2479  * from the net, refreshing the screen in interactive mode, and so forth. */
backgroundTasks(void)2480 void backgroundTasks(void) {
2481     if (Modes.net) {
2482         modesAcceptClients();
2483         modesReadFromClients();
2484         interactiveRemoveStaleAircrafts();
2485     }
2486 
2487     /* Refresh screen when in interactive mode. */
2488     if (Modes.interactive &&
2489         (mstime() - Modes.interactive_last_update) >
2490         MODES_INTERACTIVE_REFRESH_TIME)
2491     {
2492         interactiveRemoveStaleAircrafts();
2493         interactiveShowData();
2494         Modes.interactive_last_update = mstime();
2495     }
2496 }
2497 
main(int argc,char ** argv)2498 int main(int argc, char **argv) {
2499     int j;
2500 
2501     /* Set sane defaults. */
2502     modesInitConfig();
2503 
2504     /* Parse the command line options */
2505     for (j = 1; j < argc; j++) {
2506         int more = j+1 < argc; /* There are more arguments. */
2507 
2508         if (!strcmp(argv[j],"--device-index") && more) {
2509             Modes.dev_index = atoi(argv[++j]);
2510         } else if (!strcmp(argv[j],"--gain") && more) {
2511             Modes.gain = atof(argv[++j])*10; /* Gain is in tens of DBs */
2512         } else if (!strcmp(argv[j],"--enable-agc")) {
2513             Modes.enable_agc++;
2514         } else if (!strcmp(argv[j],"--freq") && more) {
2515             Modes.freq = strtoll(argv[++j],NULL,10);
2516         } else if (!strcmp(argv[j],"--ifile") && more) {
2517             Modes.filename = strdup(argv[++j]);
2518         } else if (!strcmp(argv[j],"--loop")) {
2519             Modes.loop = 1;
2520         } else if (!strcmp(argv[j],"--no-fix")) {
2521             Modes.fix_errors = 0;
2522         } else if (!strcmp(argv[j],"--no-crc-check")) {
2523             Modes.check_crc = 0;
2524         } else if (!strcmp(argv[j],"--raw")) {
2525             Modes.raw = 1;
2526         } else if (!strcmp(argv[j],"--net")) {
2527             Modes.net = 1;
2528         } else if (!strcmp(argv[j],"--net-only")) {
2529             Modes.net = 1;
2530             Modes.net_only = 1;
2531         } else if (!strcmp(argv[j],"--net-ro-port") && more) {
2532             modesNetServices[MODES_NET_SERVICE_RAWO].port = atoi(argv[++j]);
2533         } else if (!strcmp(argv[j],"--net-ri-port") && more) {
2534             modesNetServices[MODES_NET_SERVICE_RAWI].port = atoi(argv[++j]);
2535         } else if (!strcmp(argv[j],"--net-http-port") && more) {
2536             modesNetServices[MODES_NET_SERVICE_HTTP].port = atoi(argv[++j]);
2537         } else if (!strcmp(argv[j],"--net-sbs-port") && more) {
2538             modesNetServices[MODES_NET_SERVICE_SBS].port = atoi(argv[++j]);
2539         } else if (!strcmp(argv[j],"--onlyaddr")) {
2540             Modes.onlyaddr = 1;
2541         } else if (!strcmp(argv[j],"--metric")) {
2542             Modes.metric = 1;
2543         } else if (!strcmp(argv[j],"--aggressive")) {
2544             Modes.aggressive++;
2545         } else if (!strcmp(argv[j],"--interactive")) {
2546             Modes.interactive = 1;
2547         } else if (!strcmp(argv[j],"--interactive-rows")) {
2548             Modes.interactive_rows = atoi(argv[++j]);
2549         } else if (!strcmp(argv[j],"--interactive-ttl")) {
2550             Modes.interactive_ttl = atoi(argv[++j]);
2551         } else if (!strcmp(argv[j],"--debug") && more) {
2552             char *f = argv[++j];
2553             while(*f) {
2554                 switch(*f) {
2555                 case 'D': Modes.debug |= MODES_DEBUG_DEMOD; break;
2556                 case 'd': Modes.debug |= MODES_DEBUG_DEMODERR; break;
2557                 case 'C': Modes.debug |= MODES_DEBUG_GOODCRC; break;
2558                 case 'c': Modes.debug |= MODES_DEBUG_BADCRC; break;
2559                 case 'p': Modes.debug |= MODES_DEBUG_NOPREAMBLE; break;
2560                 case 'n': Modes.debug |= MODES_DEBUG_NET; break;
2561                 case 'j': Modes.debug |= MODES_DEBUG_JS; break;
2562                 default:
2563                     fprintf(stderr, "Unknown debugging flag: %c\n", *f);
2564                     exit(1);
2565                     break;
2566                 }
2567                 f++;
2568             }
2569         } else if (!strcmp(argv[j],"--stats")) {
2570             Modes.stats = 1;
2571         } else if (!strcmp(argv[j],"--snip") && more) {
2572             snipMode(atoi(argv[++j]));
2573             exit(0);
2574         } else if (!strcmp(argv[j],"--help")) {
2575             showHelp();
2576             exit(0);
2577         } else {
2578             fprintf(stderr,
2579                 "Unknown or not enough arguments for option '%s'.\n\n",
2580                 argv[j]);
2581             showHelp();
2582             exit(1);
2583         }
2584     }
2585 
2586     /* Setup for SIGWINCH for handling lines */
2587     if (Modes.interactive == 1) signal(SIGWINCH, sigWinchCallback);
2588 
2589     /* Initialization */
2590     modesInit();
2591     if (Modes.net_only) {
2592         fprintf(stderr,"Net-only mode, no RTL device or file open.\n");
2593     } else if (Modes.filename == NULL) {
2594         modesInitRTLSDR();
2595     } else {
2596         if (Modes.filename[0] == '-' && Modes.filename[1] == '\0') {
2597             Modes.fd = STDIN_FILENO;
2598         } else if ((Modes.fd = open(Modes.filename,O_RDONLY)) == -1) {
2599             perror("Opening data file");
2600             exit(1);
2601         }
2602     }
2603     if (Modes.net) modesInitNet();
2604 
2605     /* If the user specifies --net-only, just run in order to serve network
2606      * clients without reading data from the RTL device. */
2607     while (Modes.net_only) {
2608         backgroundTasks();
2609         modesWaitReadableClients(100);
2610     }
2611 
2612     /* Create the thread that will read the data from the device. */
2613     pthread_create(&Modes.reader_thread, NULL, readerThreadEntryPoint, NULL);
2614 
2615     pthread_mutex_lock(&Modes.data_mutex);
2616     while(1) {
2617         if (!Modes.data_ready) {
2618             pthread_cond_wait(&Modes.data_cond,&Modes.data_mutex);
2619             continue;
2620         }
2621         computeMagnitudeVector();
2622 
2623         /* Signal to the other thread that we processed the available data
2624          * and we want more (useful for --ifile). */
2625         Modes.data_ready = 0;
2626         pthread_cond_signal(&Modes.data_cond);
2627 
2628         /* Process data after releasing the lock, so that the capturing
2629          * thread can read data while we perform computationally expensive
2630          * stuff * at the same time. (This should only be useful with very
2631          * slow processors). */
2632         pthread_mutex_unlock(&Modes.data_mutex);
2633         detectModeS(Modes.magnitude, Modes.data_len/2);
2634         backgroundTasks();
2635         pthread_mutex_lock(&Modes.data_mutex);
2636         if (Modes.exit) break;
2637     }
2638 
2639     /* If --ifile and --stats were given, print statistics. */
2640     if (Modes.stats && Modes.filename) {
2641         printf("%lld valid preambles\n", Modes.stat_valid_preamble);
2642         printf("%lld demodulated again after phase correction\n",
2643             Modes.stat_out_of_phase);
2644         printf("%lld demodulated with zero errors\n",
2645             Modes.stat_demodulated);
2646         printf("%lld with good crc\n", Modes.stat_goodcrc);
2647         printf("%lld with bad crc\n", Modes.stat_badcrc);
2648         printf("%lld errors corrected\n", Modes.stat_fixed);
2649         printf("%lld single bit errors\n", Modes.stat_single_bit_fix);
2650         printf("%lld two bits errors\n", Modes.stat_two_bits_fix);
2651         printf("%lld total usable messages\n",
2652             Modes.stat_goodcrc + Modes.stat_fixed);
2653     }
2654 
2655     rtlsdr_close(Modes.dev);
2656     return 0;
2657 }
2658 
2659 
2660