forked from gvanem/Dump1090
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmisc.h
More file actions
721 lines (650 loc) · 32.2 KB
/
Copy pathmisc.h
File metadata and controls
721 lines (650 loc) · 32.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
/**\file misc.h
* \ingroup Misc
*
* Various macros and definitions.
*/
#ifndef _MISC_H
#define _MISC_H
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <winsock2.h>
#include <windows.h>
#include <wchar.h>
#include <rtl-sdr.h>
#include <sdrplay_api.h>
#include "mongoose.h"
#include "cfg_file.h"
#include "csv.h"
/**
* Various helper macros.
*/
#define MODES_NOTUSED(V) ((void)V)
#define IS_SLASH(c) ((c) == '\\' || (c) == '/')
#define TWO_PI (2 * M_PI)
#define DIM(array) (sizeof(array) / sizeof(array[0]))
#define ONE_MEGABYTE (1024*1024)
#define STDIN_FILENO 0
#define FREE(p) (p ? (void) (free((void*)p), p = NULL) : (void)0)
/**
* Network services indices; `global_data::connections [N]`:
*/
#define MODES_NET_SERVICE_RAW_OUT 0
#define MODES_NET_SERVICE_RAW_IN 1
#define MODES_NET_SERVICE_SBS_OUT 2
#define MODES_NET_SERVICE_SBS_IN 3
#define MODES_NET_SERVICE_HTTP 4
#define MODES_NET_SERVICE_RTL_TCP 5
#define MODES_NET_SERVICES_NUM (MODES_NET_SERVICE_RTL_TCP + 1)
#define MODES_NET_SERVICE_FIRST 0
#define MODES_NET_SERVICE_LAST MODES_NET_SERVICE_RTL_TCP
/**
* \def SAFE_COND_SIGNAL(cond, mutex)
* \def SAFE_COND_WAIT(cond, mutex)
*
* Signals are not threadsafe by default.
* Taken from the Osmocom-SDR code and modified to
* use Win-Vista+ functions.
*
* But not used yet.
*/
#define SAFE_COND_SIGNAL(cond, mutex) \
do { \
EnterCriticalSection (mutex); \
WakeConditionVariable (cond); \
LeaveCriticalSection (mutex); \
} while (0)
#define SAFE_COND_WAIT(cond, mutex) \
do { \
EnterCriticalSection (mutex); \
WakeConditionVariable (cond); \
LeaveCriticalSection (mutex); \
} while (0)
/**
* Bits for `Modes.debug`:
*/
#define DEBUG_BADCRC 0x0001
#define DEBUG_GOODCRC 0x0002
#define DEBUG_DEMOD 0x0004
#define DEBUG_DEMODERR 0x0008
#define DEBUG_GENERAL 0x0010
#define DEBUG_GENERAL2 0x0020
#define DEBUG_MONGOOSE 0x0040
#define DEBUG_MONGOOSE2 0x0080
#define DEBUG_NOPREAMBLE 0x0100
#define DEBUG_JS 0x0200
#define DEBUG_NET 0x0400
#define DEBUG_NET2 0x0800
#define DEBUG_ADSB_LOL 0x1000
/**
* \def DEBUG(bit, fmt, ...)
* A more compact tracing macro.
*/
#define DEBUG(bit, fmt, ...) \
do { \
if (Modes.debug & (bit)) \
modeS_flogf (stdout, "%s(%u): " fmt, \
__FILE__, __LINE__, __VA_ARGS__); \
} while (0)
/**
* \def TRACE(fmt, ...)
* As `DEBUG()`, but for the `DEBUG_GENERAL` bit only.
* And with an added new-line for brevity.
*
* Ref. command-line option `--debug g`.
*/
#define TRACE(fmt, ...) DEBUG (DEBUG_GENERAL, fmt ".\n", __VA_ARGS__)
/**
* \def LOG_STDOUT(fmt, ...)
* Print to both `stdout` and optionally to `Modes.log`.
*
* \def LOG_STDERR(fmt, ...)
* Print to both `stderr` and optionally to `Modes.log`.
*
* \def LOG_FILEONLY(fmt, ...)
* Print to `Modes.log` only.
*/
#define LOG_STDOUT(fmt, ...) modeS_flogf (stdout, fmt, __VA_ARGS__)
#define LOG_STDERR(fmt, ...) modeS_flogf (stderr, fmt, __VA_ARGS__)
#define LOG_FILEONLY(fmt, ...) do { \
if (Modes.log) \
modeS_flogf (Modes.log, fmt, __VA_ARGS__); \
} while (0)
typedef struct mg_http_message mg_http_message;
typedef struct mg_connection mg_connection;
typedef struct mg_mgr mg_mgr;
typedef struct mg_addr mg_addr;
typedef struct mg_str mg_str;
typedef struct mg_timer mg_timer;
typedef struct mg_iobuf mg_iobuf;
typedef struct mg_ws_message mg_ws_message;
typedef struct mg_http_serve_opts mg_http_serve_opts;
typedef char mg_file_path [MG_PATH_MAX];
typedef char mg_host_name [200];
typedef char mg_http_uri [256];
/**
* Structure used to describe a network connection,
* client or server.
*/
typedef struct connection {
mg_connection *c; /**< remember which connection this client/server is in */
intptr_t service; /**< this client's service membership */
mg_addr rem; /**< copy of `mg_connection::rem` */
mg_host_name rem_buf; /**< address-string of `mg_connection::rem` */
ULONG id; /**< copy of `mg_connection::id` */
bool keep_alive; /**< client request contains "Connection: keep-alive" */
bool encoding_gzip; /**< gzip compressed client data (not yet) */
struct connection *next; /**< next connection in this list for this service */
} connection;
/**
* A structure defining a passive or active network service.
*/
typedef struct net_service {
mg_connection **c; /**< A pointer to the returned Mongoose connection(s) */
char descr [100]; /**< A textual description of this service */
char protocol [4]; /**< Equals "tcp" unless `is_udp == 1` */
uint16_t port; /**< The port number */
mg_host_name host; /**< The host name/address if `Modes.net_active == true` */
uint16_t num_connections; /**< Number of clients/servers connected to this service */
uint64_t mem_allocated; /**< Number of bytes allocated total for this service */
bool active_send; /**< We are the sending side. Never duplex */
bool is_ip6; /**< The above `host` address is an IPv6 address */
bool is_udp; /**< The above `host` address was prefixed with `udp://` */
char *url; /**< The allocated url for `mg_listen()` or `mg_connect()` */
char *last_err; /**< Last error from a `MG_EV_ERROR` event */
} net_service;
typedef enum metric_unit_t {
MODES_UNIT_FEET = 1,
MODES_UNIT_METERS = 2
} metric_unit_t;
#define UNIT_NAME(unit) (unit == MODES_UNIT_METERS ? "meters" : "feet")
/**
* Spherical position: <br>
* Latitude (North-South) and Longitude (East-West) coordinates. <br>
*
* A position on a Geoid. (ignoring altitude).
*/
typedef struct pos_t {
double lat; /* geodetic latitude */
double lon;
} pos_t;
/**
* A point in Cartesian coordinates.
*/
typedef struct cartesian_t {
double c_x;
double c_y;
double c_z;
} cartesian_t;
/**
* \def SMALL_VAL
* \def BIG_VAL
* \def VALID_POS()
*
* Simple check for a valid geo-position
*/
#define SMALL_VAL 0.0001
#define BIG_VAL 9999999.0
#define VALID_POS(pos) (fabs(pos.lon) >= SMALL_VAL && fabs(pos.lon) < 180.0 && \
fabs(pos.lat) >= SMALL_VAL && fabs(pos.lat) < 90.0)
#define EARTH_RADIUS 6371000.0 /* meters. Assuming a sphere. Approx. 40.000.000 / TWO_PI meters */
#define ASSERT_POS(pos) do { \
assert (pos.lon >= -180 && pos.lon < 180); \
assert (pos.lat >= -90 && pos.lat < 90); \
} while (0)
#define MAX_ME_TYPE 37
#define MAX_ME_SUBTYPE 8
/**
* Statistics on unrecognized ME types and sub-types.
* The sum of a type [0..36] is the sum of the `sub_type[]` array.
*/
typedef struct unrecognized_ME {
uint64_t sub_type [MAX_ME_SUBTYPE]; /**< unrecognized subtypes [0..7] of this type */
} unrecognized_ME;
/**
* Keep all collected statistics in this structure.
*/
typedef struct statistics {
/* Hardware device statistics:
*/
uint64_t valid_preamble;
uint64_t demodulated;
uint64_t good_CRC;
uint64_t bad_CRC;
uint64_t fixed;
uint64_t single_bit_fix;
uint64_t two_bits_fix;
uint64_t out_of_phase;
uint64_t messages_total;
unrecognized_ME unrecognized_ME [MAX_ME_TYPE];
/* Aircraft statistics: \todo Move to 'aircraft_show_stats()'
*/
uint64_t unique_aircrafts;
uint64_t unique_aircrafts_CSV;
uint64_t unique_aircrafts_SQL;
uint64_t unique_helicopters;
/* Network statistics:
*/
uint64_t cli_accepted [MODES_NET_SERVICES_NUM];
uint64_t cli_removed [MODES_NET_SERVICES_NUM];
uint64_t cli_unknown [MODES_NET_SERVICES_NUM];
uint64_t srv_connected [MODES_NET_SERVICES_NUM];
uint64_t srv_removed [MODES_NET_SERVICES_NUM];
uint64_t srv_unknown [MODES_NET_SERVICES_NUM];
uint64_t bytes_sent [MODES_NET_SERVICES_NUM];
uint64_t bytes_recv [MODES_NET_SERVICES_NUM];
uint64_t unique_clients [MODES_NET_SERVICES_NUM];
uint64_t HTTP_get_requests;
uint64_t HTTP_keep_alive_recv;
uint64_t HTTP_keep_alive_sent;
uint64_t HTTP_websockets;
uint64_t HTTP_400_responses;
uint64_t HTTP_404_responses;
uint64_t HTTP_500_responses;
/* Network statistics for receiving RAW and SBS messages:
*/
uint64_t good_SBS;
uint64_t good_raw;
uint64_t unrecognized_SBS;
uint64_t unrecognized_raw;
uint64_t empty_SBS;
uint64_t empty_raw;
} statistics;
/**
* The device configuration for a local RTLSDR device.
* NOT used for a RTL_TCP connection.
*/
typedef struct rtlsdr_conf {
char *name; /**< The manufacturer name of the RTLSDR device to use. As in e.g. `"--device silver"` */
int index; /**< The index of the RTLSDR device to use. As in e.g. `"--device 1"` */
rtlsdr_dev_t *device; /**< The RTLSDR handle from `rtlsdr_open()` */
int ppm_error; /**< Set RTLSDR frequency correction */
int calibrate; /**< Enable calibration for R820T/R828D type devices */
int *gains; /**< Gain table reported from `rtlsdr_get_tuner_gains()` */
int gain_count; /**< Number of gain values in above array */
} rtlsdr_conf;
/**
* The device configuration for a remote RTLSDR device.
*/
typedef struct rtltcp_conf {
void *info; /**< The "RTL0" info message is here if we've got it (\ref RTL_TCP_info) */
int ppm_error; /**< Set RTLSDR frequency correction */
int calibrate; /**< Enable calibration for R820T/R828D type devices */
int *gains; /**< Gain table reported from `rtlsdr_get_tuner_gains()` */
int gain_count; /**< Number of gain values in above array */
} rtltcp_conf;
/**
* The private data for a SDRplay device.
* Ref \file sdrplay.c for this.
*/
struct sdrplay_priv;
/**
* The device configuration for a SDRplay device.
*/
typedef struct sdrplay_conf {
struct sdrplay_priv *priv;
char *name; /**< Name of SDRplay instance to use */
int index; /**< The index of the SDRplay device to use. As in e.g. `"--device sdrplay1"` */
void *device; /**< Device-handle from `sdrplay_init()` */
bool if_mode;
bool over_sample;
bool disable_broadcast_notch;
bool disable_DAB_notch;
int gain_reduction;
int ADSB_mode;
int BW_mode;
int *gains;
int gain_count;
sdrplay_api_Rsp2_AntennaSelectT antenna_port;
sdrplay_api_RspDx_AntennaSelectT DX_antenna_port;
sdrplay_api_TunerSelectT tuner;
sdrplay_api_RspDuoModeT mode;
} sdrplay_conf;
/*
* Forwards:
* Details in "aircraft.h", "airports".h" and "externals/sqlite3.c"
*/
struct aircraft;
struct aircraft_info;
struct airports_priv;
struct sqlite3;
/**
* All program global state is in this structure.
*/
typedef struct global_data {
mg_file_path who_am_I; /**< The full name of this program. */
mg_file_path where_am_I; /**< The directory of this program. */
mg_file_path tmp_dir; /**< The `%TEMP%\\dump1090` directory. (no trailing `\\`). */
mg_file_path cfg_file; /**< The config-file (default: "where_am_I\\dump1090.cfg") */
uintptr_t reader_thread; /**< Device reader thread ID. */
CRITICAL_SECTION data_mutex; /**< Mutex to synchronize buffer access. */
CRITICAL_SECTION print_mutex; /**< Mutex to synchronize printouts. */
uint8_t *data; /**< Raw IQ samples buffer. */
uint32_t data_len; /**< Length of raw IQ buffer. */
uint16_t *magnitude; /**< Magnitude vector. */
uint16_t *magnitude_lut; /**< I/Q -> Magnitude lookup table. */
int fd; /**< File descriptor for `--infile` option. */
volatile bool exit; /**< Exit from the main loop when true. */
volatile bool data_ready; /**< Data ready to be processed. */
uint32_t *ICAO_cache; /**< Recently seen ICAO addresses. */
statistics stat; /**< Decoder, aircraft and network statistics. */
struct aircraft *aircrafts; /**< Linked list of active aircrafts. */
uint64_t last_update_ms; /**< Last screen update in milliseconds. */
uint64_t max_messages; /**< How many messages to process before quitting. */
/** Common stuff for RTLSDR and SDRplay:
*/
char *selected_dev; /**< Name of selected device. */
int dig_agc; /**< Enable digital AGC. */
int bias_tee; /**< Enable bias-T voltage on coax input. */
int gain_auto; /**< Use auto-gain. */
uint32_t band_width; /**< The wanted bandwidth. Default is 0. */
uint16_t gain; /**< The gain setting for the active device (local or remote). Default is MODES_AUTO_GAIN. */
uint32_t freq; /**< The tuned frequency. Default is MODES_DEFAULT_FREQ. */
uint32_t sample_rate; /**< The sample-rate. Default is MODES_DEFAULT_RATE.
* \note This cannot be used yet since the code assumes a
* pulse-width of 0.5 usec based on a fixed rate of 2 MS/s.
*/
rtlsdr_conf rtlsdr; /**< RTLSDR local specific settings. */
rtltcp_conf rtltcp; /**< RTLSDR remote specific settings. */
sdrplay_conf sdrplay; /**< SDRplay specific settings. */
/** Lists of connections for each network service:
*/
connection *connections [MODES_NET_SERVICES_NUM];
mg_connection *sbs_out; /**< SBS output listening connection. */
mg_connection *sbs_in; /**< SBS input active connection. */
mg_connection *raw_out; /**< Raw output active/listening connection. */
mg_connection *raw_in; /**< Raw input listening connection. */
mg_connection *http_out; /**< HTTP listening connection. */
mg_connection *rtl_tcp_in; /**< RTL_TCP active connection. */
mg_mgr mgr; /**< Only one Mongoose connection manager. */
char *dns; /**< Use default Windows DNS server (not 8.8.8.8) */
/** Aircraft history
*/
uint64_t json_interval;
int json_aircraft_history_next;
mg_str json_aircraft_history [120];
/** Configuration
*/
mg_file_path infile; /**< Input IQ samples from file with option `--infile file`. */
mg_file_path logfile; /**< Write debug/info to file with option `--logfile file`. */
FILE *log; /**< Opened it for exclusive write access. */
uint64_t loops; /**< Read input file in a loop. */
uint32_t debug; /**< `DEBUG()` mode bits. */
int raw; /**< Raw output format. */
int net; /**< Enable networking. */
int net_only; /**< Enable just networking. */
int net_active; /**< With `Modes.net`, call `connect()` (not `listen()`). */
int silent; /**< Silent mode for network testing. */
int interactive; /**< Interactive mode */
uint16_t interactive_rows; /**< Interactive mode: max number of rows. */
uint32_t interactive_ttl; /**< Interactive mode: TTL before deletion. */
int win_location; /**< Use 'Windows Location API' to get the 'Modes.home_pos'. */
int only_addr; /**< Print only ICAO addresses. */
int metric; /**< Use metric units. */
bool error_correct_1; /**< Fix 1 bit errors (default: true). */
bool error_correct_2; /**< Fix 2 bit errors (default: false). */
int keep_alive; /**< Send "Connection: keep-alive" if HTTP client sends it. */
mg_file_path web_page; /**< The base-name of the web-page to server for HTTP clients. */
mg_file_path web_root; /**< And it's directory. */
bool web_root_touch; /**< Touch all files in `web_root` first. */
mg_file_path aircraft_db; /**< The `aircraft-database.csv` file. */
char *aircraft_db_url; /**< Value of key `aircrafts-update = url` */
int strip_level; /**< For '--strip X' mode. */
pos_t home_pos; /**< Coordinates of home position. */
cartesian_t home_pos_cart; /**< Coordinates of home position (cartesian). */
bool home_pos_ok; /**< We have a good home position. */
const char *wininet_last_error; /**< Last error from WinInet API. */
char *tests; /**< Perform tests specified by pattern. */
int tui_interface; /**< Selected `--tui` interface. */
bool update; /**< Option `--update' was used to update missing .csv-files */
/** For handling a `Modes.aircraft_db` file:
*/
CSV_context csv_ctx; /**< Structure for the CSV parser. */
struct aircraft_info *aircraft_list_CSV; /**< List of aircrafts sorted on address. From CSV-file only. */
uint32_t aircraft_num_CSV; /**< The length of the list. */
struct sqlite3 *sql_db; /**< For the `aircraft_sql` file. */
/** For handling a airport-data from .CSV files.
*/
mg_file_path airport_db; /**< The `airports-codes.csv` file generated by `tools/gen_airport_codes_csv.py`. */
mg_file_path airport_freq_db; /**< The `airports-frequencies.csv` file. Not used yet. */
mg_file_path airport_cache; /**< The `%%TEMP%%\\dump1090\\airport-api-cache.csv`. */
char *airport_db_url; /**< Value of key `airports-update = url`. Not effective yet. */
struct airports_priv *airports_priv; /**< Private data for `airports.c`. */
} global_data;
extern global_data Modes;
#if defined(USE_READSB_DEMOD)
typedef struct mag_buf {
uint16_t *data; /**< Magnitude data, starting with overlap from the previous block. */
unsigned length; /**< Number of valid samples _after_ overlap. */
unsigned overlap; /**< Number of leading overlap samples at the start of "data". */
/**< also the number of trailing samples that will be preserved for next time. */
uint64_t sampleTimestamp; /**< Clock timestamp of the start of this block, 12MHz clock. */
uint64_t sysTimestamp; /**< Estimated system time at start of block. */
double mean_level; /**< Mean of normalized (0..1) signal level. */
double mean_power; /**< Mean of normalized (0..1) power level. */
unsigned dropped; /**< (approx) number of dropped samples. */
struct mag_buf *next; /**< linked list forward link */
} mag_buf;
void demodulate2400 (struct mag_buf *mag);
#endif
#define MODES_DEFAULT_RATE 2000000
#define MODES_DEFAULT_FREQ 1090000000
#define MODES_ASYNC_BUF_NUMBERS 12
#define MODES_ASYNC_BUF_SIZE (256*1024)
#define MODES_PREAMBLE_US 8 /* microseconds */
#define MODES_LONG_MSG_BITS 112
#define MODES_SHORT_MSG_BITS 56
#define MODES_FULL_LEN (MODES_PREAMBLE_US + MODES_LONG_MSG_BITS)
#define MODES_LONG_MSG_BYTES (MODES_LONG_MSG_BITS / 8)
#define MODES_SHORT_MSG_BYTES (MODES_SHORT_MSG_BITS / 8)
#define MODES_MAX_SBS_SIZE 256
#define MODES_ICAO_CACHE_LEN 1024 /* Power of two required. */
#define MODES_ICAO_CACHE_TTL 60 /* Time to live of cached addresses (sec). */
/**
* When debug is set to DEBUG_NOPREAMBLE, the first sample must be
* at least greater than a given level for us to dump the signal.
*/
#define DEBUG_NOPREAMBLE_LEVEL 25
/**
* Timeout for a screen refresh in interactive mode and
* timeout for removing a stale aircraft.
*/
#define MODES_INTERACTIVE_REFRESH_TIME 250
#define MODES_INTERACTIVE_TTL 60000
/**
* The structure we use to store information about a decoded message.
*/
typedef struct modeS_message {
uint8_t msg [MODES_LONG_MSG_BYTES]; /**< Binary message. */
int msg_bits; /**< Number of bits in message. */
int msg_type; /**< Downlink format #. */
bool CRC_ok; /**< True if CRC was valid. */
uint32_t CRC; /**< Message CRC. */
double sig_level; /**< RSSI, in the range [0..1], as a fraction of full-scale power. */
int error_bit; /**< Bit corrected. -1 if no bit corrected. */
uint8_t AA [3]; /**< ICAO Address bytes 1, 2 and 3 (big-endian). */
bool phase_corrected; /**< True if phase correction was applied. */
/** DF11
*/
int ca; /**< Responder capabilities. */
/** DF 17
*/
int ME_type; /**< Extended squitter message type. */
int ME_subtype; /**< Extended squitter message subtype. */
int heading; /**< Horizontal angle of flight. */
bool heading_is_valid; /**< We got a valid `heading`. */
int aircraft_type; /**< Aircraft identification. "Type A..D". */
int odd_flag; /**< 1 = Odd, 0 = Even CPR message. */
int UTC_flag; /**< UTC synchronized? */
int raw_latitude; /**< Non decoded latitude. */
int raw_longitude; /**< Non decoded longitude. */
char flight [9]; /**< 8 chars flight number. */
int EW_dir; /**< 0 = East, 1 = West. */
int EW_velocity; /**< E/W velocity. */
int NS_dir; /**< 0 = North, 1 = South. */
int NS_velocity; /**< N/S velocity. */
int vert_rate_source; /**< Vertical rate source. */
int vert_rate_sign; /**< Vertical rate sign. */
int vert_rate; /**< Vertical rate. */
int velocity; /**< Computed from EW and NS velocity. */
/** DF4, DF5, DF20, DF21
*/
int flight_status; /**< Flight status for DF4, 5, 20 and 21. */
int DR_status; /**< Request extraction of downlink request. */
int UM_status; /**< Request extraction of downlink request. */
int identity; /**< 13 bits identity (Squawk). */
/** Fields used by multiple message types.
*/
int altitude;
metric_unit_t unit;
} modeS_message;
/*
* Generic table for loading DLLs and functions from them.
*/
struct dyn_struct {
const bool optional;
HINSTANCE mod_handle;
const char *mod_name;
const char *func_name;
void **func_addr;
};
/*
* For `$(OBJ_DIR)/web-page-*.c` files:
*/
typedef struct packed_file {
const unsigned char *data;
size_t size;
time_t mtime;
const char *name;
} packed_file;
/*
* Defined in MSVC's <sal.h>.
*/
#ifndef _Printf_format_string_
#define _Printf_format_string_
#endif
#if defined(__clang__)
#define ATTR_PRINTF(_1, _2) __attribute__((format(printf, _1, _2)))
#else
#define ATTR_PRINTF(_1, _2)
#endif
void modeS_log (const char *buf);
void modeS_logc (char c, void *param);
void modeS_flogf (FILE *f, _Printf_format_string_ const char *fmt, ...) ATTR_PRINTF(2, 3);
void modeS_set_log (void);
void modeS_err_set (bool on);
char *modeS_err_get (void);
char *modeS_SYSTEMTIME_to_str (const SYSTEMTIME *st, bool show_YMD);
char *modeS_FILETIME_to_str (const FILETIME *ft, bool show_YMD);
char *modeS_FILETIME_to_loc_str (const FILETIME *ft, bool show_YMD);
void modeS_signal_handler (int sig);
bool decode_RAW_message (mg_iobuf *msg, int loop_cnt); /* in 'dump1090.c' */
bool decode_SBS_message (mg_iobuf *msg, int loop_cnt); /* in 'dump1090.c' */
uint32_t ato_hertz (const char *Hertz);
bool str_startswith (const char *s1, const char *s2);
bool str_endswith (const char *s1, const char *s2);
char *str_ltrim (char *s);
char *str_rtrim (char *s);
char *str_trim (char *s);
int hex_digit_val (int c);
const char *unescape_hex (const char *value);
char *basename (const char *fname);
char *dirname (const char *fname);
char *slashify (char *fname);
int _gettimeofday (struct timeval *tv, void *timezone);
int get_timespec_UTC (struct timespec *ts);
double get_usec_now (void);
void get_FILETIME_now (FILETIME *ft);
void crtdbug_init (void);
void crtdbug_exit (void);
const char *win_strerror (DWORD err);
const char *get_rtlsdr_error (void);
const char *qword_str (uint64_t val);
const char *dword_str (DWORD val);
void *memdup (const void *from, size_t size);
uint32_t random_range (uint32_t min, uint32_t max);
int32_t random_range2 (int32_t min, int32_t max);
int touch_file (const char *file);
int touch_dir (const char *dir, bool recurse);
FILE *fopen_excl (const char *file, const char *mode);
uint32_t download_to_file (const char *url, const char *file);
char *download_to_buf (const char *url);
int download_status (void);
int load_dynamic_table (struct dyn_struct *tab, int tab_size);
int unload_dynamic_table (struct dyn_struct *tab, int tab_size);
bool test_add (char **pattern, const char *what);
bool test_contains (const char *pattern, const char *what);
void puts_long_line (const char *start, size_t indent);
void show_version_info (bool verbose);
void spherical_to_cartesian (const pos_t *pos, cartesian_t *cart);
bool cartesian_to_spherical (const cartesian_t *cart, pos_t *pos, double heading);
double cartesian_distance (const cartesian_t *a, const cartesian_t *b);
double great_circle_dist (pos_t pos1, pos_t pos2);
double closest_to (double val, double val1, double val2);
void decode_CPR (struct aircraft *a);
const char *mz_version (void); /* in 'externals/zip.c' */
void rx_callback (uint8_t *buf, uint32_t len, void *ctx);
/*
* in 'pconsole.c'. Not used yet.
*/
struct pconsole_t;
bool pconsole_create (struct pconsole_t *pty, const char *cmd_path, const char **cmd_argv);
#if 0
/*
* in 'externals/wcwidth.c'
*/
int wcwidth (wchar_t wc);
int wcswidth (const wchar_t *wcs, size_t n);
#endif
/**
* \def MSEC_TIME()
* Returns a 64-bit tick-time value with 1 millisec granularity.
*/
#if defined(USE_gettimeofday)
static __inline uint64_t MSEC_TIME (void)
{
struct timeval now;
_gettimeofday (&now, NULL);
return (1000 * (uint64_t)now.tv_sec) + (now.tv_usec / 1000);
}
#else
#define MSEC_TIME() GetTickCount64()
#endif
/**
* GNU-like getopt_long() / getopt_long_only() with 4.4BSD optreset extension.
*
* \def no_argument
* The option takes no argument
*
* \def required_argument
* The option must have an argument
*
* \def optional_argument
* The option has an optional argument
*/
#define no_argument 0
#define required_argument 1
#define optional_argument 2
/**
* A typedef for `getopt()` command-line handling.
*/
typedef struct option {
const char *name; /**< name of long option */
/**
* one of `no_argument`, `required_argument` or `optional_argument`:<br>
* whether option takes an argument.
*/
int has_arg;
int *flag; /**< if not NULL, set *flag to val when option found. */
int val; /**< if flag not NULL, value to set \c *flag to; else return value. */
} option;
int getopt_long (int, char * const *, const char *,
const struct option *, int *);
int getopt_long_only (int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx);
int getopt (int nargc, char * const *nargv, const char *options);
extern char *optarg; /**< the argument to an option in `optsstring`. */
extern int optind; /**< the index of the next element to be processed in `argv`. */
extern int opterr; /**< if caller set this to zero, an error-message will never be printed. */
extern int optopt; /**< on errors, an unrecognised option character is stored in `optopt`. */
#endif