blob: dc36fca7a5556fda8b1fa5d49f54df3ba8f65971 [file] [log] [blame]
Petter Reinholdtsen0af55122017-08-28 22:19:11 +02001#!/usr/bin/env python2
2# -*- coding: utf-8 -*-
3##################################################
4# GNU Radio Python Flow Graph
5# Title: Gr-gsm Livemon
6# 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: Mon Aug 28 10:09:07 2017
9##################################################
10
11from gnuradio import blocks
12from gnuradio import eng_notation
13from gnuradio import gr
14from gnuradio.eng_option import eng_option
15from gnuradio.filter import firdes
16from math import pi
17from optparse import OptionParser
18import grgsm
19import osmosdr
20import pmt
21import time
22
23
24class grgsm_livemon_headless(gr.top_block):
25
26 def __init__(self, args="", collector='localhost', collectorport='4729', fc=941.8e6, gain=30, osr=4, ppm=0, samp_rate=2000000.052982, serverport='4729', shiftoff=400e3):
27 gr.top_block.__init__(self, "Gr-gsm Livemon")
28
29 ##################################################
30 # Parameters
31 ##################################################
32 self.args = args
33 self.collector = collector
34 self.collectorport = collectorport
35 self.fc = fc
36 self.gain = gain
37 self.osr = osr
38 self.ppm = ppm
39 self.samp_rate = samp_rate
40 self.serverport = serverport
41 self.shiftoff = shiftoff
42
43 ##################################################
44 # Blocks
45 ##################################################
46 self.rtlsdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + args )
47 self.rtlsdr_source_0.set_sample_rate(samp_rate)
48 self.rtlsdr_source_0.set_center_freq(fc-shiftoff, 0)
49 self.rtlsdr_source_0.set_freq_corr(ppm, 0)
50 self.rtlsdr_source_0.set_dc_offset_mode(2, 0)
51 self.rtlsdr_source_0.set_iq_balance_mode(2, 0)
52 self.rtlsdr_source_0.set_gain_mode(False, 0)
53 self.rtlsdr_source_0.set_gain(gain, 0)
54 self.rtlsdr_source_0.set_if_gain(20, 0)
55 self.rtlsdr_source_0.set_bb_gain(20, 0)
56 self.rtlsdr_source_0.set_antenna('', 0)
57 self.rtlsdr_source_0.set_bandwidth(250e3+abs(shiftoff), 0)
58
59 self.gsm_sdcch8_demapper_0 = grgsm.gsm_sdcch8_demapper(
60 timeslot_nr=1,
61 )
62 self.gsm_receiver_0 = grgsm.receiver(4, ([0]), ([]), False)
63 self.gsm_message_printer_1 = grgsm.message_printer(pmt.intern(""), False,
64 False, False)
65 self.gsm_input_0 = grgsm.gsm_input(
66 ppm=ppm-int(ppm),
67 osr=4,
68 fc=fc,
69 samp_rate_in=samp_rate,
70 )
71 self.gsm_decryption_0 = grgsm.decryption(([]), 1)
72 self.gsm_control_channels_decoder_0_0 = grgsm.control_channels_decoder()
73 self.gsm_control_channels_decoder_0 = grgsm.control_channels_decoder()
74 self.gsm_clock_offset_control_0 = grgsm.clock_offset_control(fc-shiftoff, samp_rate, osr)
75 self.gsm_bcch_ccch_sdcch4_demapper_0 = grgsm.gsm_bcch_ccch_sdcch4_demapper(
76 timeslot_nr=0,
77 )
78 self.blocks_socket_pdu_0_1 = blocks.socket_pdu("UDP_CLIENT", collector, collectorport, 1500, False)
79 self.blocks_socket_pdu_0_0 = blocks.socket_pdu("UDP_SERVER", '127.0.0.1', serverport, 10000, False)
80 self.blocks_rotator_cc_0 = blocks.rotator_cc(-2*pi*shiftoff/samp_rate)
81
82 ##################################################
83 # Connections
84 ##################################################
85 self.msg_connect((self.blocks_socket_pdu_0_0, 'pdus'), (self.gsm_message_printer_1, 'msgs'))
86 self.msg_connect((self.gsm_bcch_ccch_sdcch4_demapper_0, 'bursts'), (self.gsm_control_channels_decoder_0, 'bursts'))
87 self.msg_connect((self.gsm_clock_offset_control_0, 'ctrl'), (self.gsm_input_0, 'ctrl_in'))
88 self.msg_connect((self.gsm_control_channels_decoder_0, 'msgs'), (self.blocks_socket_pdu_0_1, 'pdus'))
89 self.msg_connect((self.gsm_control_channels_decoder_0_0, 'msgs'), (self.blocks_socket_pdu_0_1, 'pdus'))
90 self.msg_connect((self.gsm_decryption_0, 'bursts'), (self.gsm_control_channels_decoder_0_0, 'bursts'))
91 self.msg_connect((self.gsm_receiver_0, 'C0'), (self.gsm_bcch_ccch_sdcch4_demapper_0, 'bursts'))
92 self.msg_connect((self.gsm_receiver_0, 'measurements'), (self.gsm_clock_offset_control_0, 'measurements'))
93 self.msg_connect((self.gsm_receiver_0, 'C0'), (self.gsm_sdcch8_demapper_0, 'bursts'))
94 self.msg_connect((self.gsm_sdcch8_demapper_0, 'bursts'), (self.gsm_decryption_0, 'bursts'))
95 self.connect((self.blocks_rotator_cc_0, 0), (self.gsm_input_0, 0))
96 self.connect((self.gsm_input_0, 0), (self.gsm_receiver_0, 0))
97 self.connect((self.rtlsdr_source_0, 0), (self.blocks_rotator_cc_0, 0))
98
99 def get_args(self):
100 return self.args
101
102 def set_args(self, args):
103 self.args = args
104
105 def get_collector(self):
106 return self.collector
107
108 def set_collector(self, collector):
109 self.collector = collector
110
111 def get_collectorport(self):
112 return self.collectorport
113
114 def set_collectorport(self, collectorport):
115 self.collectorport = collectorport
116
117 def get_fc(self):
118 return self.fc
119
120 def set_fc(self, fc):
121 self.fc = fc
122 self.rtlsdr_source_0.set_center_freq(self.fc-self.shiftoff, 0)
123 self.gsm_input_0.set_fc(self.fc)
124
125 def get_gain(self):
126 return self.gain
127
128 def set_gain(self, gain):
129 self.gain = gain
130 self.rtlsdr_source_0.set_gain(self.gain, 0)
131
132 def get_osr(self):
133 return self.osr
134
135 def set_osr(self, osr):
136 self.osr = osr
137
138 def get_ppm(self):
139 return self.ppm
140
141 def set_ppm(self, ppm):
142 self.ppm = ppm
143 self.rtlsdr_source_0.set_freq_corr(self.ppm, 0)
144 self.gsm_input_0.set_ppm(self.ppm-int(self.ppm))
145
146 def get_samp_rate(self):
147 return self.samp_rate
148
149 def set_samp_rate(self, samp_rate):
150 self.samp_rate = samp_rate
151 self.rtlsdr_source_0.set_sample_rate(self.samp_rate)
152 self.gsm_input_0.set_samp_rate_in(self.samp_rate)
153 self.blocks_rotator_cc_0.set_phase_inc(-2*pi*self.shiftoff/self.samp_rate)
154
155 def get_serverport(self):
156 return self.serverport
157
158 def set_serverport(self, serverport):
159 self.serverport = serverport
160
161 def get_shiftoff(self):
162 return self.shiftoff
163
164 def set_shiftoff(self, shiftoff):
165 self.shiftoff = shiftoff
166 self.rtlsdr_source_0.set_center_freq(self.fc-self.shiftoff, 0)
167 self.rtlsdr_source_0.set_bandwidth(250e3+abs(self.shiftoff), 0)
168 self.blocks_rotator_cc_0.set_phase_inc(-2*pi*self.shiftoff/self.samp_rate)
169
170
171def argument_parser():
172 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)'
173 parser = OptionParser(usage="%prog: [options]", option_class=eng_option, description=description)
174 parser.add_option(
175 "", "--args", dest="args", type="string", default="",
176 help="Set Device Arguments [default=%default]")
177 parser.add_option(
178 "", "--collector", dest="collector", type="string", default='localhost',
179 help="Set IP or DNS name of collector point [default=%default]")
180 parser.add_option(
181 "", "--collectorport", dest="collectorport", type="string", default='4729',
182 help="Set UDP port number of collector [default=%default]")
183 parser.add_option(
184 "-f", "--fc", dest="fc", type="eng_float", default=eng_notation.num_to_str(941.8e6),
185 help="Set GSM channel's central frequency [default=%default]")
186 parser.add_option(
187 "-g", "--gain", dest="gain", type="eng_float", default=eng_notation.num_to_str(30),
188 help="Set gain [default=%default]")
189 parser.add_option(
190 "", "--osr", dest="osr", type="intx", default=4,
191 help="Set OverSampling Ratio [default=%default]")
192 parser.add_option(
193 "-p", "--ppm", dest="ppm", type="eng_float", default=eng_notation.num_to_str(0),
194 help="Set ppm [default=%default]")
195 parser.add_option(
196 "-s", "--samp-rate", dest="samp_rate", type="eng_float", default=eng_notation.num_to_str(2000000.052982),
197 help="Set samp_rate [default=%default]")
198 parser.add_option(
199 "", "--serverport", dest="serverport", type="string", default='4729',
200 help="Set UDP server listening port [default=%default]")
201 parser.add_option(
202 "-o", "--shiftoff", dest="shiftoff", type="eng_float", default=eng_notation.num_to_str(400e3),
203 help="Set Frequency Shiftoff [default=%default]")
204 return parser
205
206
207def main(top_block_cls=grgsm_livemon_headless, options=None):
208 if options is None:
209 options, _ = argument_parser().parse_args()
210
211 tb = top_block_cls(args=options.args, collector=options.collector, collectorport=options.collectorport, fc=options.fc, gain=options.gain, osr=options.osr, ppm=options.ppm, samp_rate=options.samp_rate, serverport=options.serverport, shiftoff=options.shiftoff)
212 tb.start()
213 tb.wait()
214
215
216if __name__ == '__main__':
217 main()