def __init__(self, source, destination, framenr_ge=None, framenr_le=None, timeslot=None, subslot=None, filter_dummy_bursts=False): gr.top_block.__init__(self, "Top Block") self.burst_file_source = grgsm.burst_file_source(source) self.burst_file_sink = grgsm.burst_file_sink(destination) lastblock = self.burst_file_source if framenr_ge is not None: self.burst_fnr_filterge = grgsm.burst_fnr_filter(grgsm.FILTER_GREATER_OR_EQUAL, framenr_ge) self.msg_connect((lastblock, 'out'), (self.burst_fnr_filterge, 'in')) lastblock = self.burst_fnr_filterge if framenr_le is not None: self.burst_fnr_filterle = grgsm.burst_fnr_filter(grgsm.FILTER_LESS_OR_EQUAL, framenr_le) self.msg_connect((lastblock, 'out'), (self.burst_fnr_filterle, 'in')) lastblock = self.burst_fnr_filterle if timeslot is not None: self.burst_timeslot_filter = grgsm.burst_timeslot_filter(timeslot) self.msg_connect((lastblock, 'out'), (self.burst_timeslot_filter, 'in')) lastblock = self.burst_timeslot_filter if subslot is not None: self.burst_sdcch_subslot_filter = grgsm.burst_sdcch_subslot_filter(grgsm.SS_FILTER_SDCCH8, subslot) self.msg_connect((lastblock, 'out'), (self.burst_sdcch_subslot_filter, 'in')) lastblock = self.burst_sdcch_subslot_filter if filter_dummy_bursts: self.dummy_burst_filter = grgsm.dummy_burst_filter() self.msg_connect((lastblock, 'out'), (self.dummy_burst_filter, 'in')) lastblock = self.dummy_burst_filter self.msg_connect((lastblock, 'out'), (self.burst_file_sink, 'in'))
def __init__(self, fc=943.6e6, shiftoff=400e3, ppm=0, gain=30, samp_rate=2000000.052982): gr.top_block.__init__(self, "Capture Bursts Nogui") ################################################## # Parameters ################################################## self.fc = fc self.shiftoff = shiftoff self.ppm = ppm self.gain = gain self.samp_rate = samp_rate ################################################## # Blocks ################################################## self.rtlsdr_source_0 = osmosdr.source( args="numchan=" + str(1) + " " + "" ) self.rtlsdr_source_0.set_sample_rate(samp_rate) self.rtlsdr_source_0.set_center_freq(fc-shiftoff, 0) self.rtlsdr_source_0.set_freq_corr(ppm, 0) self.rtlsdr_source_0.set_dc_offset_mode(2, 0) self.rtlsdr_source_0.set_iq_balance_mode(2, 0) self.rtlsdr_source_0.set_gain_mode(False, 0) self.rtlsdr_source_0.set_gain(gain, 0) self.rtlsdr_source_0.set_if_gain(20, 0) self.rtlsdr_source_0.set_bb_gain(20, 0) self.rtlsdr_source_0.set_antenna("", 0) self.rtlsdr_source_0.set_bandwidth(250e3+abs(shiftoff), 0) self.gsm_receiver_0 = grgsm.receiver(4, ([0]), ([])) self.gsm_input_0 = grgsm.gsm_input( ppm=0, osr=4, fc=fc, samp_rate_in=samp_rate, ) self.gsm_clock_offset_control_0 = grgsm.clock_offset_control(fc-shiftoff) self.gsm_burst_file_sink_0 = grgsm.burst_file_sink("/tmp/bursts") self.blocks_rotator_cc_0 = blocks.rotator_cc(-2*pi*shiftoff/samp_rate) ################################################## # Connections ################################################## self.connect((self.blocks_rotator_cc_0, 0), (self.gsm_input_0, 0)) self.connect((self.gsm_input_0, 0), (self.gsm_receiver_0, 0)) self.connect((self.rtlsdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) ################################################## # Asynch Message Connections ################################################## self.msg_connect(self.gsm_clock_offset_control_0, "ppm", self.gsm_input_0, "ppm_in") self.msg_connect(self.gsm_receiver_0, "measurements", self.gsm_clock_offset_control_0, "measurements") self.msg_connect(self.gsm_receiver_0, "C0", self.gsm_burst_file_sink_0, "in")
def __init__(self, fc, gain, samp_rate, ppm, arfcn, cfile=None, burst_file=None, band=None, verbose=False, rec_length=None): gr.top_block.__init__(self, "Gr-gsm Capture") ################################################## # Parameters ################################################## self.fc = fc self.gain = gain self.samp_rate = samp_rate self.ppm = ppm self.arfcn = arfcn self.cfile = cfile self.burst_file = burst_file self.band = band self.verbose = verbose self.shiftoff = shiftoff = 400e3 self.rec_length = rec_length ################################################## # Processing Blocks ################################################## self.rtlsdr_source = osmosdr.source( args="numchan=" + str(1) + " " + "" ) self.rtlsdr_source.set_sample_rate(samp_rate) self.rtlsdr_source.set_center_freq(fc - shiftoff, 0) self.rtlsdr_source.set_freq_corr(ppm, 0) self.rtlsdr_source.set_dc_offset_mode(2, 0) self.rtlsdr_source.set_iq_balance_mode(2, 0) self.rtlsdr_source.set_gain_mode(True, 0) self.rtlsdr_source.set_gain(gain, 0) self.rtlsdr_source.set_if_gain(20, 0) self.rtlsdr_source.set_bb_gain(20, 0) self.rtlsdr_source.set_antenna("", 0) self.rtlsdr_source.set_bandwidth(250e3+abs(shiftoff), 0) self.blocks_rotator = blocks.rotator_cc(-2*pi*shiftoff/samp_rate) if self.rec_length is not None: self.blocks_head_0 = blocks.head(gr.sizeof_gr_complex, int(samp_rate*rec_length)) if self.verbose or self.burst_file: self.gsm_receiver = grgsm.receiver(4, ([self.arfcn]), ([])) self.gsm_input = grgsm.gsm_input( ppm=0, osr=4, fc=fc, samp_rate_in=samp_rate, ) self.gsm_clock_offset_control = grgsm.clock_offset_control(fc-shiftoff) if self.burst_file: self.gsm_burst_file_sink = grgsm.burst_file_sink(self.burst_file) if self.cfile: self.blocks_file_sink = blocks.file_sink(gr.sizeof_gr_complex*1, self.cfile, False) self.blocks_file_sink.set_unbuffered(False) if self.verbose: self.gsm_bursts_printer_0 = grgsm.bursts_printer(pmt.intern(""), False, False, False, False) ################################################## # Connections ################################################## if self.rec_length is not None: #if recording length is defined connect head block after the source self.connect((self.rtlsdr_source, 0), (self.blocks_head_0, 0)) self.connect((self.blocks_head_0, 0), (self.blocks_rotator, 0)) else: self.connect((self.rtlsdr_source, 0), (self.blocks_rotator, 0)) if self.cfile: self.connect((self.blocks_rotator, 0), (self.blocks_file_sink, 0)) if self.verbose or self.burst_file: self.connect((self.gsm_input, 0), (self.gsm_receiver, 0)) self.connect((self.blocks_rotator, 0), (self.gsm_input, 0)) self.msg_connect(self.gsm_clock_offset_control, "ppm", self.gsm_input, "ppm_in") self.msg_connect(self.gsm_receiver, "measurements", self.gsm_clock_offset_control, "measurements") if self.burst_file: self.msg_connect(self.gsm_receiver, "C0", self.gsm_burst_file_sink, "in") if self.verbose: self.msg_connect(self.gsm_receiver, "C0", self.gsm_bursts_printer_0, "bursts")
def __init__(self, fc, gain, samp_rate, ppm, arfcn, cfile=None, burst_file=None, band=None, verbose=False, rec_length=None, args=""): gr.top_block.__init__(self, "Gr-gsm Capture") ################################################## # Parameters ################################################## self.fc = fc self.gain = gain self.samp_rate = samp_rate self.ppm = ppm self.arfcn = arfcn self.cfile = cfile self.burst_file = burst_file self.band = band self.verbose = verbose self.shiftoff = shiftoff = 400e3 self.rec_length = rec_length ################################################## # Processing Blocks ################################################## self.rtlsdr_source = osmosdr.source( args="numchan=" + str(1) + " " + "" ) self.rtlsdr_source.set_sample_rate(samp_rate) self.rtlsdr_source.set_center_freq(fc - shiftoff, 0) self.rtlsdr_source.set_freq_corr(ppm, 0) self.rtlsdr_source.set_dc_offset_mode(2, 0) self.rtlsdr_source.set_iq_balance_mode(2, 0) self.rtlsdr_source.set_gain_mode(True, 0) self.rtlsdr_source.set_gain(gain, 0) self.rtlsdr_source.set_if_gain(20, 0) self.rtlsdr_source.set_bb_gain(20, 0) self.rtlsdr_source.set_antenna("", 0) self.rtlsdr_source.set_bandwidth(250e3+abs(shiftoff), 0) self.blocks_rotator = blocks.rotator_cc(-2*pi*shiftoff/samp_rate) if self.rec_length is not None: self.blocks_head_0 = blocks.head(gr.sizeof_gr_complex, int(samp_rate*rec_length)) if self.verbose or self.burst_file: self.gsm_receiver = grgsm.receiver(4, ([self.arfcn]), ([])) self.gsm_input = grgsm.gsm_input( ppm=0, osr=4, fc=fc, samp_rate_in=samp_rate, ) self.gsm_clock_offset_control = grgsm.clock_offset_control(fc-shiftoff) if self.burst_file: self.gsm_burst_file_sink = grgsm.burst_file_sink(self.burst_file) if self.cfile: self.blocks_file_sink = blocks.file_sink(gr.sizeof_gr_complex*1, self.cfile, False) self.blocks_file_sink.set_unbuffered(False) if self.verbose: self.gsm_bursts_printer_0 = grgsm.bursts_printer(pmt.intern(""), False, False, False, False) ################################################## # Connections ################################################## if self.rec_length is not None: #if recording length is defined connect head block after the source self.connect((self.rtlsdr_source, 0), (self.blocks_head_0, 0)) self.connect((self.blocks_head_0, 0), (self.blocks_rotator, 0)) else: self.connect((self.rtlsdr_source, 0), (self.blocks_rotator, 0)) if self.cfile: self.connect((self.blocks_rotator, 0), (self.blocks_file_sink, 0)) if self.verbose or self.burst_file: self.connect((self.gsm_input, 0), (self.gsm_receiver, 0)) self.connect((self.blocks_rotator, 0), (self.gsm_input, 0)) self.msg_connect(self.gsm_clock_offset_control, "ppm", self.gsm_input, "ppm_in") self.msg_connect(self.gsm_receiver, "measurements", self.gsm_clock_offset_control, "measurements") if self.burst_file: self.msg_connect(self.gsm_receiver, "C0", self.gsm_burst_file_sink, "in") if self.verbose: self.msg_connect(self.gsm_receiver, "C0", self.gsm_bursts_printer_0, "bursts")
def __init__(self, gain=None, samp_rate=None, ppm=None, arfcn=None, capture_id=None, udp_ports=[], max_timeslot=0, store_capture=True, verbose=False, band=None, rec_length=None, test=False, args=""): """ capture_id = identifier for the capture used to store the files (e.g. <capture_id>.cfile) store_capture = boolean indicating if the capture should be stored on disk or not rec_length = capture time in seconds max_timeslot = timeslot 0...max_timeslot will be decoded udp_ports = a list of udp ports to send the captured GSMTap frames to """ gr.top_block.__init__(self, "Gr-gsm Capture") ################################################## # Parameters ################################################## self.arfcn = arfcn for band in grgsm.arfcn.get_bands(): if grgsm.arfcn.is_valid_arfcn(self.arfcn, band): self.fc = grgsm.arfcn.arfcn2downlink(arfcn, band) break self.gain = gain self.samp_rate = samp_rate self.ppm = ppm self.arfcn = arfcn self.band = band self.shiftoff = shiftoff = 400e3 self.rec_length = rec_length self.store_capture = store_capture self.capture_id = capture_id self.udp_ports = udp_ports self.verbose = verbose ################################################## # Processing Blocks ################################################## self.rtlsdr_source = osmosdr.source( args="numchan=" + str(1) + " " + "" ) self.rtlsdr_source.set_sample_rate(samp_rate) self.rtlsdr_source.set_center_freq(self.fc - shiftoff, 0) self.rtlsdr_source.set_freq_corr(ppm, 0) self.rtlsdr_source.set_dc_offset_mode(2, 0) self.rtlsdr_source.set_iq_balance_mode(2, 0) self.rtlsdr_source.set_gain_mode(True, 0) self.rtlsdr_source.set_gain(gain, 0) self.rtlsdr_source.set_if_gain(20, 0) self.rtlsdr_source.set_bb_gain(20, 0) self.rtlsdr_source.set_antenna("", 0) self.rtlsdr_source.set_bandwidth(250e3+abs(shiftoff), 0) self.blocks_rotator = blocks.rotator_cc(-2*pi*shiftoff/samp_rate) #RUn for the specified amount of seconds or indefenitely if self.rec_length is not None: self.blocks_head_0 = blocks.head(gr.sizeof_gr_complex, int(samp_rate*rec_length)) self.gsm_receiver = grgsm.receiver(4, ([self.arfcn]), ([])) self.gsm_input = grgsm.gsm_input( ppm=0, osr=4, fc=self.fc, samp_rate_in=samp_rate, ) self.gsm_clock_offset_control = grgsm.clock_offset_control(self.fc-shiftoff) #Control channel demapper for timeslot 0 #self.gsm_bcch_ccch_demapper_0 = grgsm.universal_ctrl_chans_demapper(0, ([2,6,12,16,22,26,32,36,42,46]), ([1,2,2,2,2,2,2,2,2,2])) self.gsm_bcch_ccch_demapper_0 = grgsm.gsm_bcch_ccch_demapper(0) #For all other timeslots are assumed to contain sdcch8 logical channels, this demapping may be incorrect if max_timeslot >= 1 and max_timeslot <= 8: self.gsm_sdcch8_demappers = [] for i in range(1,max_timeslot + 1): #self.gsm_sdcch8_demappers.append(grgsm.universal_ctrl_chans_demapper(i, ([0,4,8,12,16,20,24,28,32,36,40,44]), ([8,8,8,8,8,8,8,8,136,136,136,136]))) self.gsm_sdcch8_demappers.append(grgsm.gsm_sdcch8_demapper(i)) #Control channel decoder (extracts the packets), one for each timeslot self.gsm_control_channels_decoders = [] for i in range(0,max_timeslot + 1): self.gsm_control_channels_decoders.append(grgsm.control_channels_decoder()) # self.blocks_socket_pdu_0 = blocks.socket_pdu("UDP_CLIENT", "127.0.0.1", "4729", 10000, False)# self.blocks_socket_pdu_0 = blocks.socket_pdu("UDP_CLIENT", "127.0.0.1", "4729", 10000, False) #UDP client that sends all decoded C0T0 packets to the specified port on localhost if requested self.client_sockets = [] self.server_sockets = [] for udp_port in self.udp_ports: #The server is for testing only #WARNING remove the server if you want connect to a different one if test: self.server_sockets.append(blocks.socket_pdu("UDP_SERVER", "127.0.0.1", str(udp_port), 10000)) self.client_sockets.append(blocks.socket_pdu("UDP_CLIENT", "127.0.0.1", str(udp_port), 10000)) #Sinks to store the capture file if requested if self.store_capture: self.gsm_burst_file_sink = grgsm.burst_file_sink(str(self.capture_id) + ".burstfile") self.blocks_file_sink = blocks.file_sink(gr.sizeof_gr_complex*1, str(self.capture_id) + ".cfile", False) self.blocks_file_sink.set_unbuffered(False) #Printer for printing messages when verbose flag is True if self.verbose: self.gsm_message_printer = grgsm.message_printer(pmt.intern(""), False) """ if self.verbose: self.gsm_bursts_printer_0 = grgsm.bursts_printer(pmt.intern(""), False, False, False, False) """ ################################################## # Connections ################################################## if self.rec_length is not None: #if recording length is defined connect head block after the source self.connect((self.rtlsdr_source, 0), (self.blocks_head_0, 0)) self.connect((self.blocks_head_0, 0), (self.blocks_rotator, 0)) else: self.connect((self.rtlsdr_source, 0), (self.blocks_rotator, 0)) #Connect the file sinks if self.store_capture: self.connect((self.blocks_rotator, 0), (self.blocks_file_sink, 0)) self.msg_connect(self.gsm_receiver, "C0", self.gsm_burst_file_sink, "in") #Connect the GSM receiver self.connect((self.gsm_input, 0), (self.gsm_receiver, 0)) self.connect((self.blocks_rotator, 0), (self.gsm_input, 0)) self.msg_connect(self.gsm_clock_offset_control, "ppm", self.gsm_input, "ppm_in") self.msg_connect(self.gsm_receiver, "measurements", self.gsm_clock_offset_control, "measurements") #Connect the demapper and decoder for timeslot 0 self.msg_connect((self.gsm_receiver, 'C0'), (self.gsm_bcch_ccch_demapper_0, 'bursts')) self.msg_connect((self.gsm_bcch_ccch_demapper_0, 'bursts'), (self.gsm_control_channels_decoders[0], 'bursts')) #Connect the demapper and decoders for the other timeslots for i in range(1,max_timeslot +1): self.msg_connect((self.gsm_receiver, 'C0'), (self.gsm_sdcch8_demappers[i-1], 'bursts')) self.msg_connect((self.gsm_sdcch8_demappers[i-1], 'bursts'), (self.gsm_control_channels_decoders[i], 'bursts')) #Connect the UDP clients if requested for client_socket in self.client_sockets: for i in range(0,max_timeslot + 1): self.msg_connect((self.gsm_control_channels_decoders[i], 'msgs'), (client_socket, 'pdus')) #Connect the printer is self.verbose is True if self.verbose: for i in range(0,max_timeslot + 1): self.msg_connect((self.gsm_control_channels_decoders[i], 'msgs'), (self.gsm_message_printer, 'msgs')) """
def __init__(self, gain=30, ppm=0, samp_rate=2000000.052982, shiftoff=400e3, fc=943.6e6): gr.top_block.__init__(self, "Capture Bursts") Qt.QWidget.__init__(self) self.setWindowTitle("Capture Bursts") try: self.setWindowIcon(Qt.QIcon.fromTheme("gnuradio-grc")) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "capture_bursts") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Parameters ################################################## self.gain = gain self.ppm = ppm self.samp_rate = samp_rate self.shiftoff = shiftoff self.fc = fc ################################################## # Variables ################################################## self.ppm_slider = ppm_slider = ppm self.g_slider = g_slider = gain self.fc_slider = fc_slider = fc ################################################## # Blocks ################################################## self._ppm_slider_layout = Qt.QHBoxLayout() self._ppm_slider_layout.addWidget(Qt.QLabel("PPM Offset" + ": ")) class qwt_counter_pyslot(Qwt.QwtCounter): def __init__(self, parent=None): Qwt.QwtCounter.__init__(self, parent) @pyqtSlot("double") def setValue(self, value): super(Qwt.QwtCounter, self).setValue(value) self._ppm_slider_counter = qwt_counter_pyslot() self._ppm_slider_counter.setRange(-150, 150, 1) self._ppm_slider_counter.setNumButtons(2) self._ppm_slider_counter.setMinimumWidth(100) self._ppm_slider_counter.setValue(self.ppm_slider) self._ppm_slider_layout.addWidget(self._ppm_slider_counter) self._ppm_slider_counter.valueChanged.connect(self.set_ppm_slider) self.top_layout.addLayout(self._ppm_slider_layout) self._g_slider_layout = Qt.QHBoxLayout() self._g_slider_layout.addWidget(Qt.QLabel("Gain" + ": ")) class qwt_counter_pyslot(Qwt.QwtCounter): def __init__(self, parent=None): Qwt.QwtCounter.__init__(self, parent) @pyqtSlot("double") def setValue(self, value): super(Qwt.QwtCounter, self).setValue(value) self._g_slider_counter = qwt_counter_pyslot() self._g_slider_counter.setRange(0, 50, 0.5) self._g_slider_counter.setNumButtons(2) self._g_slider_counter.setMinimumWidth(100) self._g_slider_counter.setValue(self.g_slider) self._g_slider_layout.addWidget(self._g_slider_counter) self._g_slider_counter.valueChanged.connect(self.set_g_slider) self.top_layout.addLayout(self._g_slider_layout) self._fc_slider_layout = Qt.QVBoxLayout() self._fc_slider_tool_bar = Qt.QToolBar(self) self._fc_slider_layout.addWidget(self._fc_slider_tool_bar) self._fc_slider_tool_bar.addWidget(Qt.QLabel("Frequency" + ": ")) class qwt_counter_pyslot(Qwt.QwtCounter): def __init__(self, parent=None): Qwt.QwtCounter.__init__(self, parent) @pyqtSlot("double") def setValue(self, value): super(Qwt.QwtCounter, self).setValue(value) self._fc_slider_counter = qwt_counter_pyslot() self._fc_slider_counter.setRange(925e6, 1990e6, 2e5) self._fc_slider_counter.setNumButtons(2) self._fc_slider_counter.setValue(self.fc_slider) self._fc_slider_tool_bar.addWidget(self._fc_slider_counter) self._fc_slider_counter.valueChanged.connect(self.set_fc_slider) self._fc_slider_slider = Qwt.QwtSlider(None, Qt.Qt.Horizontal, Qwt.QwtSlider.BottomScale, Qwt.QwtSlider.BgSlot) self._fc_slider_slider.setRange(925e6, 1990e6, 2e5) self._fc_slider_slider.setValue(self.fc_slider) self._fc_slider_slider.setMinimumWidth(100) self._fc_slider_slider.valueChanged.connect(self.set_fc_slider) self._fc_slider_layout.addWidget(self._fc_slider_slider) self.top_layout.addLayout(self._fc_slider_layout) self.rtlsdr_source_0 = osmosdr.source(args="numchan=" + str(1) + " " + "") self.rtlsdr_source_0.set_sample_rate(samp_rate) self.rtlsdr_source_0.set_center_freq(fc_slider - shiftoff, 0) self.rtlsdr_source_0.set_freq_corr(ppm_slider, 0) self.rtlsdr_source_0.set_dc_offset_mode(2, 0) self.rtlsdr_source_0.set_iq_balance_mode(2, 0) self.rtlsdr_source_0.set_gain_mode(False, 0) self.rtlsdr_source_0.set_gain(g_slider, 0) self.rtlsdr_source_0.set_if_gain(20, 0) self.rtlsdr_source_0.set_bb_gain(20, 0) self.rtlsdr_source_0.set_antenna("", 0) self.rtlsdr_source_0.set_bandwidth(250e3 + abs(shiftoff), 0) self.qtgui_freq_sink_x_0 = qtgui.freq_sink_c( 1024, # size firdes.WIN_BLACKMAN_hARRIS, # wintype fc_slider, # fc samp_rate, # bw "", # name 1, # number of inputs ) self.qtgui_freq_sink_x_0.set_update_time(0.10) self.qtgui_freq_sink_x_0.set_y_axis(-140, 10) self.qtgui_freq_sink_x_0.enable_autoscale(False) self.qtgui_freq_sink_x_0.enable_grid(False) self.qtgui_freq_sink_x_0.set_fft_average(1.0) labels = ["", "", "", "", "", "", "", "", "", ""] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ["blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "dark blue"] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] for i in xrange(1): if len(labels[i]) == 0: self.qtgui_freq_sink_x_0.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_freq_sink_x_0.set_line_label(i, labels[i]) self.qtgui_freq_sink_x_0.set_line_width(i, widths[i]) self.qtgui_freq_sink_x_0.set_line_color(i, colors[i]) self.qtgui_freq_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_freq_sink_x_0_win = sip.wrapinstance(self.qtgui_freq_sink_x_0.pyqwidget(), Qt.QWidget) self.top_layout.addWidget(self._qtgui_freq_sink_x_0_win) self.gsm_receiver_0 = grgsm.receiver(4, ([0]), ([])) self.gsm_input_0 = grgsm.gsm_input(ppm=0, osr=4, fc=fc, samp_rate_in=samp_rate) self.gsm_clock_offset_control_0 = grgsm.clock_offset_control(fc - shiftoff) self.gsm_burst_file_sink_0 = grgsm.burst_file_sink("/tmp/bursts") self.blocks_rotator_cc_0 = blocks.rotator_cc(-2 * pi * shiftoff / samp_rate) ################################################## # Connections ################################################## self.connect((self.blocks_rotator_cc_0, 0), (self.gsm_input_0, 0)) self.connect((self.blocks_rotator_cc_0, 0), (self.qtgui_freq_sink_x_0, 0)) self.connect((self.gsm_input_0, 0), (self.gsm_receiver_0, 0)) self.connect((self.rtlsdr_source_0, 0), (self.blocks_rotator_cc_0, 0)) ################################################## # Asynch Message Connections ################################################## self.msg_connect(self.gsm_clock_offset_control_0, "ppm", self.gsm_input_0, "ppm_in") self.msg_connect(self.gsm_receiver_0, "measurements", self.gsm_clock_offset_control_0, "measurements") self.msg_connect(self.gsm_receiver_0, "C0", self.gsm_burst_file_sink_0, "in")
def __init__(self, gain=None, samp_rate=None, ppm=None, arfcn=None, capture_id=None, udp_ports=[], max_timeslot=0, store_capture=True, verbose=False, band=None, rec_length=None, test=False, args=""): """ capture_id = identifier for the capture used to store the files (e.g. <capture_id>.cfile) store_capture = boolean indicating if the capture should be stored on disk or not rec_length = capture time in seconds max_timeslot = timeslot 0...max_timeslot will be decoded udp_ports = a list of udp ports to send the captured GSMTap frames to """ gr.top_block.__init__(self, "Gr-gsm Capture") ################################################## # Parameters ################################################## self.arfcn = arfcn for band in grgsm.arfcn.get_bands(): if grgsm.arfcn.is_valid_arfcn(self.arfcn, band): self.fc = grgsm.arfcn.arfcn2downlink(arfcn, band) break self.gain = gain self.samp_rate = samp_rate self.ppm = ppm self.arfcn = arfcn self.band = band self.shiftoff = shiftoff = 400e3 self.rec_length = rec_length self.store_capture = store_capture self.capture_id = capture_id self.udp_ports = udp_ports self.verbose = verbose ################################################## # Processing Blocks ################################################## self.rtlsdr_source = osmosdr.source(args="numchan=" + str(1) + " " + "") self.rtlsdr_source.set_sample_rate(samp_rate) self.rtlsdr_source.set_center_freq(self.fc - shiftoff, 0) self.rtlsdr_source.set_freq_corr(ppm, 0) self.rtlsdr_source.set_dc_offset_mode(2, 0) self.rtlsdr_source.set_iq_balance_mode(2, 0) self.rtlsdr_source.set_gain_mode(True, 0) self.rtlsdr_source.set_gain(gain, 0) self.rtlsdr_source.set_if_gain(20, 0) self.rtlsdr_source.set_bb_gain(20, 0) self.rtlsdr_source.set_antenna("", 0) self.rtlsdr_source.set_bandwidth(250e3 + abs(shiftoff), 0) self.blocks_rotator = blocks.rotator_cc(-2 * pi * shiftoff / samp_rate) #RUn for the specified amount of seconds or indefenitely if self.rec_length is not None: self.blocks_head_0 = blocks.head(gr.sizeof_gr_complex, int(samp_rate * rec_length)) self.gsm_receiver = grgsm.receiver(4, ([self.arfcn]), ([])) self.gsm_input = grgsm.gsm_input( ppm=0, osr=4, fc=self.fc, samp_rate_in=samp_rate, ) self.gsm_clock_offset_control = grgsm.clock_offset_control(self.fc - shiftoff) #Control channel demapper for timeslot 0 #self.gsm_bcch_ccch_demapper_0 = grgsm.universal_ctrl_chans_demapper(0, ([2,6,12,16,22,26,32,36,42,46]), ([1,2,2,2,2,2,2,2,2,2])) self.gsm_bcch_ccch_demapper_0 = grgsm.gsm_bcch_ccch_demapper(0) #For all other timeslots are assumed to contain sdcch8 logical channels, this demapping may be incorrect if max_timeslot >= 1 and max_timeslot <= 8: self.gsm_sdcch8_demappers = [] for i in range(1, max_timeslot + 1): #self.gsm_sdcch8_demappers.append(grgsm.universal_ctrl_chans_demapper(i, ([0,4,8,12,16,20,24,28,32,36,40,44]), ([8,8,8,8,8,8,8,8,136,136,136,136]))) self.gsm_sdcch8_demappers.append(grgsm.gsm_sdcch8_demapper(i)) #Control channel decoder (extracts the packets), one for each timeslot self.gsm_control_channels_decoders = [] for i in range(0, max_timeslot + 1): self.gsm_control_channels_decoders.append( grgsm.control_channels_decoder()) # self.blocks_socket_pdu_0 = blocks.socket_pdu("UDP_CLIENT", "127.0.0.1", "4729", 10000, False)# self.blocks_socket_pdu_0 = blocks.socket_pdu("UDP_CLIENT", "127.0.0.1", "4729", 10000, False) #UDP client that sends all decoded C0T0 packets to the specified port on localhost if requested self.client_sockets = [] self.server_sockets = [] for udp_port in self.udp_ports: #The server is for testing only #WARNING remove the server if you want connect to a different one if test: self.server_sockets.append( blocks.socket_pdu("UDP_SERVER", "127.0.0.1", str(udp_port), 10000)) self.client_sockets.append( blocks.socket_pdu("UDP_CLIENT", "127.0.0.1", str(udp_port), 10000)) #Sinks to store the capture file if requested if self.store_capture: self.gsm_burst_file_sink = grgsm.burst_file_sink( str(self.capture_id) + ".burstfile") self.blocks_file_sink = blocks.file_sink( gr.sizeof_gr_complex * 1, str(self.capture_id) + ".cfile", False) self.blocks_file_sink.set_unbuffered(False) #Printer for printing messages when verbose flag is True if self.verbose: self.gsm_message_printer = grgsm.message_printer( pmt.intern(""), False) """ if self.verbose: self.gsm_bursts_printer_0 = grgsm.bursts_printer(pmt.intern(""), False, False, False, False) """ ################################################## # Connections ################################################## if self.rec_length is not None: #if recording length is defined connect head block after the source self.connect((self.rtlsdr_source, 0), (self.blocks_head_0, 0)) self.connect((self.blocks_head_0, 0), (self.blocks_rotator, 0)) else: self.connect((self.rtlsdr_source, 0), (self.blocks_rotator, 0)) #Connect the file sinks if self.store_capture: self.connect((self.blocks_rotator, 0), (self.blocks_file_sink, 0)) self.msg_connect(self.gsm_receiver, "C0", self.gsm_burst_file_sink, "in") #Connect the GSM receiver self.connect((self.gsm_input, 0), (self.gsm_receiver, 0)) self.connect((self.blocks_rotator, 0), (self.gsm_input, 0)) self.msg_connect(self.gsm_clock_offset_control, "ppm", self.gsm_input, "ppm_in") self.msg_connect(self.gsm_receiver, "measurements", self.gsm_clock_offset_control, "measurements") #Connect the demapper and decoder for timeslot 0 self.msg_connect((self.gsm_receiver, 'C0'), (self.gsm_bcch_ccch_demapper_0, 'bursts')) self.msg_connect((self.gsm_bcch_ccch_demapper_0, 'bursts'), (self.gsm_control_channels_decoders[0], 'bursts')) #Connect the demapper and decoders for the other timeslots for i in range(1, max_timeslot + 1): self.msg_connect((self.gsm_receiver, 'C0'), (self.gsm_sdcch8_demappers[i - 1], 'bursts')) self.msg_connect((self.gsm_sdcch8_demappers[i - 1], 'bursts'), (self.gsm_control_channels_decoders[i], 'bursts')) #Connect the UDP clients if requested for client_socket in self.client_sockets: for i in range(0, max_timeslot + 1): self.msg_connect( (self.gsm_control_channels_decoders[i], 'msgs'), (client_socket, 'pdus')) #Connect the printer is self.verbose is True if self.verbose: for i in range(0, max_timeslot + 1): self.msg_connect( (self.gsm_control_channels_decoders[i], 'msgs'), (self.gsm_message_printer, 'msgs')) """