forked from mutability/dump1090
-
Notifications
You must be signed in to change notification settings - Fork 239
/
mode_s.h
151 lines (122 loc) · 5.87 KB
/
mode_s.h
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
// Part of dump1090, a Mode S message decoder for RTLSDR devices.
//
// mode_s.h: Mode S message decoding (prototypes)
//
// Copyright (c) 2017-2021 FlightAware, LLC
// Copyright (c) 2017 Oliver Jowett <[email protected]>
//
// This file is free software: you may copy, redistribute and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 2 of the License, or (at your
// option) any later version.
//
// This file is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef MODE_S_H
#define MODE_S_H
#include <assert.h>
//
// Functions exported from mode_s.c
//
// Possible return values of scoreModesMessage,
// ordered from worst to best
typedef enum {
SR_NOT_SET = 0, // message has not been scored yet
SR_ALL_ZEROS, // a message that's all zeros
SR_UNKNOWN_DF, // message with unrecognized DF
SR_UNCORRECTABLE, // message with uncorrectable errors
SR_UNKNOWN_THRESHOLD, // cutoff for message that might be valid, but don't match an existing aircraft
SR_UNRELIABLE_UNKNOWN, // Address/Parity, unknown aircraft
SR_DF11_IID_1ERROR_UNKNOWN, // DF11, non-zero IID, 1 error, unknown aircraft
SR_DF11_ACQ_1ERROR_UNKNOWN, // DF11, zero IID, 1 error, unknown aircraft
SR_DF11_IID_UNKNOWN, // DF11, non-zero IID, no errors, unknown aircraft
SR_DF18_2ERROR_UNKNOWN, // DF17, 2 errors, unknown aircraft
SR_DF17_2ERROR_UNKNOWN, // DF17, 2 errors, unknown aircraft
SR_ACCEPT_THRESHOLD, // cutoff for accepting messages
// Address/Parity is unreliable, prefer anything else but this
SR_UNRELIABLE_KNOWN, // Address/Parity, known aircraft
// 2-bit error correction is quite unreliable, put it low down the ranking even for known aircraft
SR_DF18_2ERROR_KNOWN, // DF18, 2 errors, known aircraft
SR_DF17_2ERROR_KNOWN, // DF17, 2 errors, known aircraft
// 1-bit error when we haven't previously seen anything from this address, low priority
SR_DF18_1ERROR_UNKNOWN, // DF18, 1 error, unknown aircraft
SR_DF17_1ERROR_UNKNOWN, // DF17, 1 error, unknown aircraft
// We need to accept at least one non-ES message type from unknown aircraft
// or else we'd never accept message from Mode-S only aircraft
SR_DF11_ACQ_UNKNOWN, // DF11, zero IID, no errors, unknown aircraft
SR_DF11_IID_1ERROR_KNOWN, // DF11, non-zero IID, 1 error, known aircraft
SR_DF11_ACQ_1ERROR_KNOWN, // DF11, zero IID, 1 error, known aircraft
SR_DF11_IID_KNOWN, // DF11, non-zero IID, no errors, known aircraft
SR_DF18_1ERROR_KNOWN, // DF18, 1 error, known aircraft
SR_DF17_1ERROR_KNOWN, // DF17, 1 error, known aircraft
SR_DF11_ACQ_KNOWN, // DF11, zero IID, no errors, known aircraft
SR_DF18_UNKNOWN, // DF18, no errors, unknown aircraft
SR_DF17_UNKNOWN, // DF17, no errors, unknown aircraft
SR_DF18_KNOWN, // DF18, no errors, known aircraft
SR_DF17_KNOWN, // DF17, no errors, known aircraft
} score_rank;
int modesMessageLenByType(int type);
score_rank scoreModesMessage(const unsigned char *msg);
int decodeModesMessage (struct modesMessage *mm, const unsigned char *msg);
void displayModesMessage(struct modesMessage *mm);
void useModesMessage (struct modesMessage *mm);
// datafield extraction helpers
// The first bit (MSB of the first byte) is numbered 1, for consistency
// with how the specs number them.
// Extract one bit from a message.
static inline __attribute__((always_inline)) unsigned getbit(const unsigned char *data, unsigned bitnum)
{
unsigned bi = bitnum - 1;
unsigned by = bi >> 3;
unsigned mask = 1 << (7 - (bi & 7));
return (data[by] & mask) != 0;
}
// Extract some bits (firstbit .. lastbit inclusive) from a message.
static inline __attribute__((always_inline)) unsigned getbits(const unsigned char *data, unsigned firstbit, unsigned lastbit)
{
unsigned fbi = firstbit - 1;
unsigned lbi = lastbit - 1;
unsigned nbi = (lastbit - firstbit + 1);
unsigned fby = fbi >> 3;
unsigned lby = lbi >> 3;
unsigned nby = (lby - fby) + 1;
unsigned shift = 7 - (lbi & 7);
unsigned topmask = 0xFF >> (fbi & 7);
assert (fbi <= lbi);
assert (nbi <= 32);
assert (nby <= 5);
if (nby == 5) {
return
((data[fby] & topmask) << (32 - shift)) |
(data[fby + 1] << (24 - shift)) |
(data[fby + 2] << (16 - shift)) |
(data[fby + 3] << (8 - shift)) |
(data[fby + 4] >> shift);
} else if (nby == 4) {
return
((data[fby] & topmask) << (24 - shift)) |
(data[fby + 1] << (16 - shift)) |
(data[fby + 2] << (8 - shift)) |
(data[fby + 3] >> shift);
} else if (nby == 3) {
return
((data[fby] & topmask) << (16 - shift)) |
(data[fby + 1] << (8 - shift)) |
(data[fby + 2] >> shift);
} else if (nby == 2) {
return
((data[fby] & topmask) << (8 - shift)) |
(data[fby + 1] >> shift);
} else if (nby == 1) {
return
(data[fby] & topmask) >> shift;
} else {
return 0;
}
}
#endif