-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmode_s.py
165 lines (143 loc) · 4.3 KB
/
mode_s.py
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
from ctypes import *
from rtlsdr import *
from time import gmtime
from libmodes import *
from pprint import pprint
import sys
#from bitstring import *
#except ImportError: from .libmodes import libModeS, modesMessage
class ModeSDetectorMessage():
"""
Class member variables
"""
msg = None
msgpos = None
msgbits = None
msgtype = None
crcok = None
crc = None
correctedbits = None
corrected = None
addr = None
phase_corrected = None
timestampMsg = None
remote = None
signalLevel = None
capability = None
iid = None
metype = None
mesub = None
heading = None
raw_latitude = None
raw_longitude = None
fLat = None
fLon = None
flight = None
ew_velocity = None
ns_velocity = None
vert_rate = None
velocity = None
fs = None
modeA = None
altitude = None
unit = None
bFlags = None
"""
Initializes the object with a mode_s message struct
TODO: support for bflags
"""
def __init__(self, modesMessage):
if sys.version_info[0] >= 3:
self.msg = "".join("{:02x}".format(c) for c in modesMessage.msg)
else:
self.msg = "".join("{:02x}".format(ord(c)) for c in modesMessage.msg)
# this msg needs to be sanitized...
if modesMessage.msgbits == 56:
self.msg = self.msg[:14]
self.msgpos = modesMessage.msgpos
self.msgbits = modesMessage.msgbits
self.msgtype = modesMessage.msgtype
self.crcok = False if modesMessage == 0 else True
self.crc = "{:06x}".format(modesMessage.crc)
self.correctedbits = modesMessage.correctedbits
self.corrected = modesMessage.corrected
self.addr = "{:06x}".format(modesMessage.addr)
self.phase_corrected = False if modesMessage.phase_corrected == 0 else True
# note: this timestamp is left out at the moment
self.timestampMsg = gmtime()
self.remote = modesMessage.remote
self.signalLevel = ord(modesMessage.signalLevel)
self.capability = modesMessage.ca
self.iid = modesMessage.iid
self.metype = modesMessage.metype
self.mesub = modesMessage.mesub
self.heading = modesMessage.heading
self.raw_latitude = modesMessage.raw_latitude
self.raw_longitude = modesMessage.raw_longitude
self.fLat = modesMessage.fLat
self.fLon = modesMessage.fLon
self.flight = modesMessage.flight
self.ew_velocity = modesMessage.ew_velocity
self.ns_velocity = modesMessage.ns_velocity
self.vert_rate = modesMessage.vert_rate
self.velocity = modesMessage.velocity
self.fs = modesMessage.fs
self.modeA = modesMessage.modeA
self.altitude = modesMessage.altitude
self.unit = 'feet' if modesMessage.unit == 0 else 'meter'
self.bFlags = modesMessage.bFlags
class ModeSDetector(object):
ADSB_FREQ = 1090000000
ADSB_RATE = 2000000
ADSB_BUF_SIZE = 4*16*16384 # 1MB
messages = []
def __init__(self, device_index=0):
self.device_index = device_index
libModeS.modesInit()
libModeS.setPhaseEnhance()
libModeS.setAggressiveFixCRC()
def readFromFile(self, filename):
with open(filename,'rb') as f:
while True:
data = f.read(self.ADSB_BUF_SIZE)
if not data:
break
else:
buff = create_string_buffer(data)
mm = libModeS.processData(buff)
self.readDataToBuffer(mm)
def initRTLSDR(self):
self.rtlsdr = RtlSdr(device_index=self.device_index)
self.rtlsdr.set_center_freq(self.ADSB_FREQ)
self.rtlsdr.set_sample_rate(self.ADSB_RATE)
self.rtlsdr.set_gain(100)
self.rtlsdr.init = True
def readFromRTLSDR(self,times):
if not self.rtlsdr.init:
self.initRTLSDR()
if sys.version_info[0] >= 3:
for i in range(0,times):
data = self.rtlsdr.read_bytes(self.ADSB_BUF_SIZE)
self.processFromRTLSDR(data)
else:
for i in xrange(0,times):
data = self.rtlsdr.read_bytes(self.ADSB_BUF_SIZE)
self.processFromRTLSDR(data)
def processFromRTLSDR(self,data,rtlsdr=None):
mm = libModeS.processData(cast(data,c_char_p))
self.readDataToBuffer(mm)
def readFromRTLSDRAsync(self):
self.rtlsdr.read_bytes_async(self.processFromRTLSDR,num_bytes=self.ADSB_BUF_SIZE)
def stopReadFromRTLSDRAsync(self):
self.rtlsdr.cancel_read_async()
def readDataToBuffer(self,mm):
while mm:
message = ModeSDetectorMessage(mm.contents)
self.messages.append(message)
mm = mm.contents.next
def printMessages(self):
for message in self.messages:
pprint(vars(message))
modes = ModeSDetector()
modes.readFromFile("output.bin")
modes.printMessages()