blob: cb5b55c6e9f7993776eb5d27243300918a4cdee2 [file] [log] [blame]
Piotr Krysik35582082015-09-02 21:49:12 +02001#!/usr/bin/env python2
Piotr Krysik6577ec22016-07-15 13:21:09 +02002# -*- coding: utf-8 -*-
Piotr Krysik35582082015-09-02 21:49:12 +02003##################################################
4# GNU Radio Python Flow Graph
Piotr Krysik332e0b52016-02-13 18:37:32 +01005# Title: Gr-gsm Livemon
Piotr Krysik6577ec22016-07-15 13:21:09 +02006# Author: Piotr Krysik
7# Description: Interactive monitor of a single C0 channel with analysis performed by Wireshark (command to run wireshark: sudo wireshark -k -f udp -Y gsmtap -i lo)
8# Generated: Fri Jul 15 13:18:50 2016
Piotr Krysik35582082015-09-02 21:49:12 +02009##################################################
10
11if __name__ == '__main__':
12 import ctypes
13 import sys
14 if sys.platform.startswith('linux'):
15 try:
16 x11 = ctypes.cdll.LoadLibrary('libX11.so')
17 x11.XInitThreads()
18 except:
19 print "Warning: failed to XInitThreads()"
20
21from PyQt4 import Qt
22from gnuradio import blocks
23from gnuradio import eng_notation
24from gnuradio import gr
25from gnuradio import qtgui
26from gnuradio.eng_option import eng_option
27from gnuradio.filter import firdes
28from gnuradio.qtgui import Range, RangeWidget
29from math import pi
30from optparse import OptionParser
31import grgsm
32import osmosdr
33import pmt
34import sip
35import sys
36import time
37
38
Piotr Krysik332e0b52016-02-13 18:37:32 +010039class grgsm_livemon(gr.top_block, Qt.QWidget):
Piotr Krysik35582082015-09-02 21:49:12 +020040
Piotr Krysik6577ec22016-07-15 13:21:09 +020041 def __init__(self, args="", fc=939.4e6, gain=30, ppm=0, samp_rate=2000000.052982, shiftoff=400e3):
Piotr Krysik332e0b52016-02-13 18:37:32 +010042 gr.top_block.__init__(self, "Gr-gsm Livemon")
Piotr Krysik35582082015-09-02 21:49:12 +020043 Qt.QWidget.__init__(self)
Piotr Krysik332e0b52016-02-13 18:37:32 +010044 self.setWindowTitle("Gr-gsm Livemon")
Piotr Krysik35582082015-09-02 21:49:12 +020045 try:
Piotr Krysik6577ec22016-07-15 13:21:09 +020046 self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
Piotr Krysik35582082015-09-02 21:49:12 +020047 except:
Piotr Krysik6577ec22016-07-15 13:21:09 +020048 pass
Piotr Krysik35582082015-09-02 21:49:12 +020049 self.top_scroll_layout = Qt.QVBoxLayout()
50 self.setLayout(self.top_scroll_layout)
51 self.top_scroll = Qt.QScrollArea()
52 self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
53 self.top_scroll_layout.addWidget(self.top_scroll)
54 self.top_scroll.setWidgetResizable(True)
55 self.top_widget = Qt.QWidget()
56 self.top_scroll.setWidget(self.top_widget)
57 self.top_layout = Qt.QVBoxLayout(self.top_widget)
58 self.top_grid_layout = Qt.QGridLayout()
59 self.top_layout.addLayout(self.top_grid_layout)
60
Piotr Krysik332e0b52016-02-13 18:37:32 +010061 self.settings = Qt.QSettings("GNU Radio", "grgsm_livemon")
Piotr Krysik35582082015-09-02 21:49:12 +020062 self.restoreGeometry(self.settings.value("geometry").toByteArray())
63
64 ##################################################
65 # Parameters
66 ##################################################
Piotr Krysik6577ec22016-07-15 13:21:09 +020067 self.args = args
Piotr Krysik35582082015-09-02 21:49:12 +020068 self.fc = fc
69 self.gain = gain
70 self.ppm = ppm
71 self.samp_rate = samp_rate
72 self.shiftoff = shiftoff
73
74 ##################################################
75 # Variables
76 ##################################################
77 self.ppm_slider = ppm_slider = ppm
78 self.g_slider = g_slider = gain
79 self.fc_slider = fc_slider = fc
80
81 ##################################################
82 # Blocks
83 ##################################################
84 self._ppm_slider_range = Range(-150, 150, 1, ppm, 100)
85 self._ppm_slider_win = RangeWidget(self._ppm_slider_range, self.set_ppm_slider, "PPM Offset", "counter", float)
86 self.top_layout.addWidget(self._ppm_slider_win)
87 self._g_slider_range = Range(0, 50, 0.5, gain, 100)
88 self._g_slider_win = RangeWidget(self._g_slider_range, self.set_g_slider, "Gain", "counter", float)
89 self.top_layout.addWidget(self._g_slider_win)
90 self._fc_slider_range = Range(925e6, 1990e6, 2e5, fc, 100)
91 self._fc_slider_win = RangeWidget(self._fc_slider_range, self.set_fc_slider, "Frequency", "counter_slider", float)
92 self.top_layout.addWidget(self._fc_slider_win)
Piotr Krysik7185b662016-02-14 20:24:54 +010093 self.rtlsdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + args )
Piotr Krysik35582082015-09-02 21:49:12 +020094 self.rtlsdr_source_0.set_sample_rate(samp_rate)
95 self.rtlsdr_source_0.set_center_freq(fc_slider-shiftoff, 0)
96 self.rtlsdr_source_0.set_freq_corr(ppm_slider, 0)
97 self.rtlsdr_source_0.set_dc_offset_mode(2, 0)
98 self.rtlsdr_source_0.set_iq_balance_mode(2, 0)
99 self.rtlsdr_source_0.set_gain_mode(False, 0)
100 self.rtlsdr_source_0.set_gain(g_slider, 0)
101 self.rtlsdr_source_0.set_if_gain(20, 0)
102 self.rtlsdr_source_0.set_bb_gain(20, 0)
103 self.rtlsdr_source_0.set_antenna("", 0)
104 self.rtlsdr_source_0.set_bandwidth(250e3+abs(shiftoff), 0)
105
106 self.qtgui_freq_sink_x_0 = qtgui.freq_sink_c(
107 1024, #size
108 firdes.WIN_BLACKMAN_hARRIS, #wintype
109 fc_slider, #fc
110 samp_rate, #bw
111 "", #name
112 1 #number of inputs
113 )
114 self.qtgui_freq_sink_x_0.set_update_time(0.10)
115 self.qtgui_freq_sink_x_0.set_y_axis(-140, 10)
Piotr Krysik6577ec22016-07-15 13:21:09 +0200116 self.qtgui_freq_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "")
117 self.qtgui_freq_sink_x_0.enable_autoscale(False)
118 self.qtgui_freq_sink_x_0.enable_grid(False)
119 self.qtgui_freq_sink_x_0.set_fft_average(1.0)
120 self.qtgui_freq_sink_x_0.enable_control_panel(False)
121
122 if not True:
123 self.qtgui_freq_sink_x_0.disable_legend()
124
125 if "complex" == "float" or "complex" == "msg_float":
126 self.qtgui_freq_sink_x_0.set_plot_pos_half(not True)
127
128 labels = ["", "", "", "", "",
129 "", "", "", "", ""]
130 widths = [1, 1, 1, 1, 1,
131 1, 1, 1, 1, 1]
132 colors = ["blue", "red", "green", "black", "cyan",
133 "magenta", "yellow", "dark red", "dark green", "dark blue"]
134 alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
135 1.0, 1.0, 1.0, 1.0, 1.0]
136 for i in xrange(1):
137 if len(labels[i]) == 0:
138 self.qtgui_freq_sink_x_0.set_line_label(i, "Data {0}".format(i))
139 else:
140 self.qtgui_freq_sink_x_0.set_line_label(i, labels[i])
141 self.qtgui_freq_sink_x_0.set_line_width(i, widths[i])
142 self.qtgui_freq_sink_x_0.set_line_color(i, colors[i])
143 self.qtgui_freq_sink_x_0.set_line_alpha(i, alphas[i])
Piotr Krysik35582082015-09-02 21:49:12 +0200144
145 self._qtgui_freq_sink_x_0_win = sip.wrapinstance(self.qtgui_freq_sink_x_0.pyqwidget(), Qt.QWidget)
146 self.top_layout.addWidget(self._qtgui_freq_sink_x_0_win)
Piotr Krysik6577ec22016-07-15 13:21:09 +0200147 self.gsm_sdcch8_demapper_0 = grgsm.gsm_sdcch8_demapper(
148 timeslot_nr=1,
149 )
150 self.gsm_receiver_0 = grgsm.receiver(4, ([0]), ([]), False)
151 self.gsm_message_printer_1 = grgsm.message_printer(pmt.intern(""), False,
152 False, False)
Piotr Krysik35582082015-09-02 21:49:12 +0200153 self.gsm_input_0 = grgsm.gsm_input(
154 ppm=0,
155 osr=4,
156 fc=fc,
157 samp_rate_in=samp_rate,
158 )
159 self.gsm_decryption_0 = grgsm.decryption(([]), 1)
160 self.gsm_control_channels_decoder_0_0 = grgsm.control_channels_decoder()
161 self.gsm_control_channels_decoder_0 = grgsm.control_channels_decoder()
Piotr Krysik6577ec22016-07-15 13:21:09 +0200162 self.gsm_clock_offset_control_0 = grgsm.clock_offset_control(fc-shiftoff, samp_rate)
163 self.gsm_bcch_ccch_demapper_0 = grgsm.gsm_bcch_ccch_demapper(
164 timeslot_nr=0,
165 )
166 self.blocks_socket_pdu_0_0 = blocks.socket_pdu("UDP_SERVER", "127.0.0.1", "4729", 10000, False)
167 self.blocks_socket_pdu_0 = blocks.socket_pdu("UDP_CLIENT", "127.0.0.1", "4729", 10000, False)
Piotr Krysik35582082015-09-02 21:49:12 +0200168 self.blocks_rotator_cc_0 = blocks.rotator_cc(-2*pi*shiftoff/samp_rate)
169
170 ##################################################
171 # Connections
172 ##################################################
173 self.msg_connect((self.gsm_bcch_ccch_demapper_0, 'bursts'), (self.gsm_control_channels_decoder_0, 'bursts'))
Piotr Krysik6577ec22016-07-15 13:21:09 +0200174 self.msg_connect((self.gsm_clock_offset_control_0, 'ctrl'), (self.gsm_input_0, 'ctrl_in'))
Piotr Krysik35582082015-09-02 21:49:12 +0200175 self.msg_connect((self.gsm_control_channels_decoder_0, 'msgs'), (self.blocks_socket_pdu_0, 'pdus'))
176 self.msg_connect((self.gsm_control_channels_decoder_0, 'msgs'), (self.gsm_message_printer_1, 'msgs'))
177 self.msg_connect((self.gsm_control_channels_decoder_0_0, 'msgs'), (self.blocks_socket_pdu_0, 'pdus'))
178 self.msg_connect((self.gsm_control_channels_decoder_0_0, 'msgs'), (self.gsm_message_printer_1, 'msgs'))
179 self.msg_connect((self.gsm_decryption_0, 'bursts'), (self.gsm_control_channels_decoder_0_0, 'bursts'))
180 self.msg_connect((self.gsm_receiver_0, 'C0'), (self.gsm_bcch_ccch_demapper_0, 'bursts'))
181 self.msg_connect((self.gsm_receiver_0, 'measurements'), (self.gsm_clock_offset_control_0, 'measurements'))
182 self.msg_connect((self.gsm_receiver_0, 'C0'), (self.gsm_sdcch8_demapper_0, 'bursts'))
183 self.msg_connect((self.gsm_sdcch8_demapper_0, 'bursts'), (self.gsm_decryption_0, 'bursts'))
184 self.connect((self.blocks_rotator_cc_0, 0), (self.gsm_input_0, 0))
185 self.connect((self.blocks_rotator_cc_0, 0), (self.qtgui_freq_sink_x_0, 0))
186 self.connect((self.gsm_input_0, 0), (self.gsm_receiver_0, 0))
187 self.connect((self.rtlsdr_source_0, 0), (self.blocks_rotator_cc_0, 0))
188
189 def closeEvent(self, event):
Piotr Krysik332e0b52016-02-13 18:37:32 +0100190 self.settings = Qt.QSettings("GNU Radio", "grgsm_livemon")
Piotr Krysik35582082015-09-02 21:49:12 +0200191 self.settings.setValue("geometry", self.saveGeometry())
192 event.accept()
193
Piotr Krysik6577ec22016-07-15 13:21:09 +0200194
195 def get_args(self):
196 return self.args
197
198 def set_args(self, args):
199 self.args = args
200
Piotr Krysik35582082015-09-02 21:49:12 +0200201 def get_fc(self):
202 return self.fc
203
204 def set_fc(self, fc):
205 self.fc = fc
206 self.set_fc_slider(self.fc)
207 self.gsm_input_0.set_fc(self.fc)
208
209 def get_gain(self):
210 return self.gain
211
212 def set_gain(self, gain):
213 self.gain = gain
214 self.set_g_slider(self.gain)
215
216 def get_ppm(self):
217 return self.ppm
218
219 def set_ppm(self, ppm):
220 self.ppm = ppm
221 self.set_ppm_slider(self.ppm)
222
223 def get_samp_rate(self):
224 return self.samp_rate
225
226 def set_samp_rate(self, samp_rate):
227 self.samp_rate = samp_rate
228 self.blocks_rotator_cc_0.set_phase_inc(-2*pi*self.shiftoff/self.samp_rate)
Piotr Krysik35582082015-09-02 21:49:12 +0200229 self.qtgui_freq_sink_x_0.set_frequency_range(self.fc_slider, self.samp_rate)
230 self.rtlsdr_source_0.set_sample_rate(self.samp_rate)
Piotr Krysik6577ec22016-07-15 13:21:09 +0200231 self.gsm_input_0.set_samp_rate_in(self.samp_rate)
Piotr Krysik35582082015-09-02 21:49:12 +0200232
233 def get_shiftoff(self):
234 return self.shiftoff
235
236 def set_shiftoff(self, shiftoff):
237 self.shiftoff = shiftoff
238 self.blocks_rotator_cc_0.set_phase_inc(-2*pi*self.shiftoff/self.samp_rate)
239 self.rtlsdr_source_0.set_center_freq(self.fc_slider-self.shiftoff, 0)
240 self.rtlsdr_source_0.set_bandwidth(250e3+abs(self.shiftoff), 0)
241
242 def get_ppm_slider(self):
243 return self.ppm_slider
244
245 def set_ppm_slider(self, ppm_slider):
246 self.ppm_slider = ppm_slider
247 self.rtlsdr_source_0.set_freq_corr(self.ppm_slider, 0)
248
249 def get_g_slider(self):
250 return self.g_slider
251
252 def set_g_slider(self, g_slider):
253 self.g_slider = g_slider
254 self.rtlsdr_source_0.set_gain(self.g_slider, 0)
255
256 def get_fc_slider(self):
257 return self.fc_slider
258
259 def set_fc_slider(self, fc_slider):
260 self.fc_slider = fc_slider
261 self.qtgui_freq_sink_x_0.set_frequency_range(self.fc_slider, self.samp_rate)
262 self.rtlsdr_source_0.set_center_freq(self.fc_slider-self.shiftoff, 0)
263
264
Piotr Krysik6577ec22016-07-15 13:21:09 +0200265def argument_parser():
Piotr Krysik35582082015-09-02 21:49:12 +0200266 parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
Piotr Krysik6577ec22016-07-15 13:21:09 +0200267 parser.add_option(
268 "", "--args", dest="args", type="string", default="",
269 help="Set Device Arguments [default=%default]")
270 parser.add_option(
271 "-f", "--fc", dest="fc", type="eng_float", default=eng_notation.num_to_str(939.4e6),
Piotr Krysik35582082015-09-02 21:49:12 +0200272 help="Set fc [default=%default]")
Piotr Krysik6577ec22016-07-15 13:21:09 +0200273 parser.add_option(
274 "-g", "--gain", dest="gain", type="eng_float", default=eng_notation.num_to_str(30),
Piotr Krysik35582082015-09-02 21:49:12 +0200275 help="Set gain [default=%default]")
Piotr Krysik6577ec22016-07-15 13:21:09 +0200276 parser.add_option(
277 "-p", "--ppm", dest="ppm", type="intx", default=0,
Piotr Krysik35582082015-09-02 21:49:12 +0200278 help="Set ppm [default=%default]")
Piotr Krysik6577ec22016-07-15 13:21:09 +0200279 parser.add_option(
280 "-s", "--samp-rate", dest="samp_rate", type="eng_float", default=eng_notation.num_to_str(2000000.052982),
Piotr Krysik35582082015-09-02 21:49:12 +0200281 help="Set samp_rate [default=%default]")
Piotr Krysik6577ec22016-07-15 13:21:09 +0200282 parser.add_option(
283 "-o", "--shiftoff", dest="shiftoff", type="eng_float", default=eng_notation.num_to_str(400e3),
Piotr Krysik35582082015-09-02 21:49:12 +0200284 help="Set shiftoff [default=%default]")
Piotr Krysik6577ec22016-07-15 13:21:09 +0200285 return parser
286
287
288def main(top_block_cls=grgsm_livemon, options=None):
289 if options is None:
290 options, _ = argument_parser().parse_args()
291
292 from distutils.version import StrictVersion
293 if StrictVersion(Qt.qVersion()) >= StrictVersion("4.5.0"):
294 style = gr.prefs().get_string('qtgui', 'style', 'raster')
295 Qt.QApplication.setGraphicsSystem(style)
Piotr Krysik35582082015-09-02 21:49:12 +0200296 qapp = Qt.QApplication(sys.argv)
Piotr Krysik6577ec22016-07-15 13:21:09 +0200297
298 tb = top_block_cls(args=options.args, fc=options.fc, gain=options.gain, ppm=options.ppm, samp_rate=options.samp_rate, shiftoff=options.shiftoff)
Piotr Krysik35582082015-09-02 21:49:12 +0200299 tb.start()
300 tb.show()
301
302 def quitting():
303 tb.stop()
304 tb.wait()
305 qapp.connect(qapp, Qt.SIGNAL("aboutToQuit()"), quitting)
306 qapp.exec_()
Piotr Krysik6577ec22016-07-15 13:21:09 +0200307
308
309if __name__ == '__main__':
310 main()