#!/usr/bin/env python2 ################################################## # GNU Radio Python Flow Graph # Title: Gmsk9600 Test2 # Author: Andy Walls # Generated: Sun Mar 27 13:56:34 2016 ################################################## if __name__ == '__main__': import ctypes import sys if sys.platform.startswith('linux'): try: x11 = ctypes.cdll.LoadLibrary('libX11.so') x11.XInitThreads() except: print "Warning: failed to XInitThreads()" from PyQt4 import Qt from gnuradio import analog from gnuradio import blocks from gnuradio import digital from gnuradio import eng_notation from gnuradio import fft from gnuradio import filter from gnuradio import gr from gnuradio import qtgui from gnuradio.eng_option import eng_option from gnuradio.fft import window from gnuradio.filter import firdes from optparse import OptionParser import ais import math import sip import sys class gmsk9600_test2(gr.top_block, Qt.QWidget): def __init__(self): gr.top_block.__init__(self, "Gmsk9600 Test2") Qt.QWidget.__init__(self) self.setWindowTitle("Gmsk9600 Test2") 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", "gmsk9600_test2") self.restoreGeometry(self.settings.value("geometry").toByteArray()) ################################################## # Variables ################################################## self.symbol_rate = symbol_rate = 9600 self.samp_rate_2 = samp_rate_2 = 96000 self.preamble = preamble = [0]*9+[0,1]*4+[0]*4 self.preamble_nrz = preamble_nrz = [i-1+256-i*255 for i in preamble] self.mod = mod = digital.gmskmod_bc(samp_rate_2/symbol_rate, 4, 0.5) self.modulated_preamble_untrimmed = modulated_preamble_untrimmed = digital.modulate_vector_bc(mod .to_basic_block(), (preamble_nrz), ([1])) self.zero_byte_nrzi = zero_byte_nrzi = [1,0]*4 self.samp_rate_1 = samp_rate_1 = 80000 self.samp_rate_0 = samp_rate_0 = 2000000 self.one_byte_nrzi_0 = one_byte_nrzi_0 = [1]*8 self.one_byte_nrzi = one_byte_nrzi = [0]*8 self.modulated_preamble = modulated_preamble = [modulated_preamble_untrimmed[i] for i in range(int(samp_rate_2/symbol_rate*1.5),len(modulated_preamble_untrimmed)-int(samp_rate_2/symbol_rate*0.5))] self.hdlc_flag_nrzi_2 = hdlc_flag_nrzi_2 = [0,0,0,0, 0,0,0,1] self.hdlc_flag_nrzi = hdlc_flag_nrzi = [1,1,1,1, 1,1,1,0] self.flush_filler = flush_filler = [1]*2 self.fft_len = fft_len = 512 self.addr_byte_nrzi_2 = addr_byte_nrzi_2 = [0,1,1,0,1,0,1,1] self.addr_byte_nrzi = addr_byte_nrzi = [1,0,0,1,0,1,0,0] ################################################## # Blocks ################################################## self.rational_resampler_xxx_0 = filter.rational_resampler_ccf( interpolation=samp_rate_2, decimation=samp_rate_1, taps=None, fractional_bw=0.4, ) self.qtgui_time_sink_x_1 = qtgui.time_sink_f( 1024, #size samp_rate_2, #samp_rate "Freq Deviation before Timing Recovery", #name 3 #number of inputs ) self.qtgui_time_sink_x_1.set_update_time(0.10) self.qtgui_time_sink_x_1.set_y_axis(-3000, 3000) self.qtgui_time_sink_x_1.set_y_label("Deviation", "Hz") self.qtgui_time_sink_x_1.enable_tags(-1, True) self.qtgui_time_sink_x_1.set_trigger_mode(qtgui.TRIG_MODE_TAG, qtgui.TRIG_SLOPE_POS, 2500.0, 0.002, 0, "corr_start") self.qtgui_time_sink_x_1.enable_autoscale(False) self.qtgui_time_sink_x_1.enable_grid(True) self.qtgui_time_sink_x_1.enable_control_panel(False) if not True: self.qtgui_time_sink_x_1.disable_legend() labels = ["Freq Deviation", "|Correlation|^2", "|Signal|^2", "", "", "", "", "", "", ""] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ["blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "blue"] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] 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(3): if len(labels[i]) == 0: self.qtgui_time_sink_x_1.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_time_sink_x_1.set_line_label(i, labels[i]) self.qtgui_time_sink_x_1.set_line_width(i, widths[i]) self.qtgui_time_sink_x_1.set_line_color(i, colors[i]) self.qtgui_time_sink_x_1.set_line_style(i, styles[i]) self.qtgui_time_sink_x_1.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_1.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_1_win = sip.wrapinstance(self.qtgui_time_sink_x_1.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_time_sink_x_1_win, 0,1) self.qtgui_time_sink_x_0_0 = qtgui.time_sink_f( 102, #size symbol_rate, #samp_rate "Descrambled, NRZI Decoded Bits", #name 1 #number of inputs ) self.qtgui_time_sink_x_0_0.set_update_time(0.10) self.qtgui_time_sink_x_0_0.set_y_axis(-0.1, 1.1) self.qtgui_time_sink_x_0_0.set_y_label("Amplitude", "") self.qtgui_time_sink_x_0_0.enable_tags(-1, True) self.qtgui_time_sink_x_0_0.set_trigger_mode(qtgui.TRIG_MODE_TAG, qtgui.TRIG_SLOPE_POS, 0.0, 0.002, 0, "corr_start") self.qtgui_time_sink_x_0_0.enable_autoscale(False) self.qtgui_time_sink_x_0_0.enable_grid(False) self.qtgui_time_sink_x_0_0.enable_control_panel(False) if not True: self.qtgui_time_sink_x_0_0.disable_legend() labels = ["NRZI Decoded", "Source Bits", "Source Bits", "", "", "", "", "", "", ""] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ["blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "blue"] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [0, 9, 3, -1, -1, -1, -1, -1, -1, -1] 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_time_sink_x_0_0.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_time_sink_x_0_0.set_line_label(i, labels[i]) self.qtgui_time_sink_x_0_0.set_line_width(i, widths[i]) self.qtgui_time_sink_x_0_0.set_line_color(i, colors[i]) self.qtgui_time_sink_x_0_0.set_line_style(i, styles[i]) self.qtgui_time_sink_x_0_0.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_0_0.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_0_0_win = sip.wrapinstance(self.qtgui_time_sink_x_0_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_time_sink_x_0_0_win, 2,1) self.qtgui_time_sink_x_0 = qtgui.time_sink_f( 102, #size symbol_rate, #samp_rate "Bits", #name 2 #number of inputs ) self.qtgui_time_sink_x_0.set_update_time(0.10) self.qtgui_time_sink_x_0.set_y_axis(-1.1, 1.1) self.qtgui_time_sink_x_0.set_y_label("Amplitude", "") self.qtgui_time_sink_x_0.enable_tags(-1, True) self.qtgui_time_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_TAG, qtgui.TRIG_SLOPE_POS, 0.0, 0.002, 0, "corr_start") self.qtgui_time_sink_x_0.enable_autoscale(False) self.qtgui_time_sink_x_0.enable_grid(False) self.qtgui_time_sink_x_0.enable_control_panel(False) if not True: self.qtgui_time_sink_x_0.disable_legend() labels = ["Soft Bits", "Hard Bits", "Bit Time Err", "", "", "", "", "", "", ""] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ["blue", "red", "green", "black", "cyan", "magenta", "yellow", "dark red", "dark green", "blue"] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [0, 9, 3, -1, -1, -1, -1, -1, -1, -1] 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(2): if len(labels[i]) == 0: self.qtgui_time_sink_x_0.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_time_sink_x_0.set_line_label(i, labels[i]) self.qtgui_time_sink_x_0.set_line_width(i, widths[i]) self.qtgui_time_sink_x_0.set_line_color(i, colors[i]) self.qtgui_time_sink_x_0.set_line_style(i, styles[i]) self.qtgui_time_sink_x_0.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_0_win = sip.wrapinstance(self.qtgui_time_sink_x_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_time_sink_x_0_win, 1,1) self.freq_xlating_fir_filter_xxx_0_0 = filter.freq_xlating_fir_filter_ccf(samp_rate_0/samp_rate_1, (firdes.low_pass_2(1, samp_rate_0, 12000, 1000, 60, firdes.WIN_BLACKMAN)), 0, samp_rate_0) self.freq_xlating_fir_filter_xxx_0_0.declare_sample_delay(0) self.fft_vxx_0 = fft.fft_vcc(fft_len, True, (window.rectangular(fft_len)), True, 1) self.digital_msk_timing_recovery_cc_0 = digital.msk_timing_recovery_cc(samp_rate_2/symbol_rate, 0.2, 0.01, 1) self.digital_hdlc_deframer_bp_0 = digital.hdlc_deframer_bp(4, 500) self.digital_diff_decoder_bb_0 = digital.diff_decoder_bb(2) self.digital_descrambler_bb_0 = digital.descrambler_bb(0x00021, 0x00, 17-1) self.digital_correlate_access_code_tag_bb_0 = digital.correlate_access_code_tag_bb("01111110", 0, "hdlc_flag_end") self.digital_corr_est_cc_0 = digital.corr_est_cc((modulated_preamble), samp_rate_2/symbol_rate, int(samp_rate_2/symbol_rate*0.5)+1, 0.81) self.digital_binary_slicer_fb_0 = digital.binary_slicer_fb() self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, samp_rate_0,True) self.blocks_tag_gate_0_0 = blocks.tag_gate(gr.sizeof_gr_complex * 1, False) self.blocks_stream_to_vector_0 = blocks.stream_to_vector(gr.sizeof_gr_complex*1, fft_len) self.blocks_repeat_0 = blocks.repeat(gr.sizeof_float*1, fft_len) self.blocks_multiply_xx_0_0 = blocks.multiply_vcc(1) self.blocks_multiply_xx_0 = blocks.multiply_vcc(1) self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff((5000.0, )) self.blocks_message_debug_0 = blocks.message_debug() self.blocks_file_source_0 = blocks.file_source(gr.sizeof_gr_complex*1, "/home/andy/work/lpybombs/gmsk9600_data2m.bin", True) self.blocks_delay_0 = blocks.delay(gr.sizeof_float*1, len(modulated_preamble)*1) self.blocks_complex_to_mag_squared_0_0 = blocks.complex_to_mag_squared(1) self.blocks_complex_to_mag_squared_0 = blocks.complex_to_mag_squared(1) self.blocks_char_to_float_0_1 = blocks.char_to_float(1, 1.0) self.blocks_char_to_float_0 = blocks.char_to_float(1, 0.5) self.blocks_add_const_vxx_0 = blocks.add_const_vff((-1.0, )) self.analog_quadrature_demod_cf_0_0 = analog.quadrature_demod_cf((samp_rate_2/2.0)/math.pi) self.analog_quadrature_demod_cf_0 = analog.quadrature_demod_cf(((symbol_rate/2.0)/math.pi)/(symbol_rate/4.0)) self.analog_frequency_modulator_fc_0 = analog.frequency_modulator_fc(-math.pi/(samp_rate_2/2.0)) self.analog_feedforward_agc_cc_0 = analog.feedforward_agc_cc(512, 1.077) self.ais_invert_0 = ais.invert() self.ais_freqest_0 = ais.freqest(samp_rate_2, int(symbol_rate), fft_len) ################################################## # Connections ################################################## self.msg_connect((self.digital_hdlc_deframer_bp_0, 'out'), (self.blocks_message_debug_0, 'print_pdu')) self.connect((self.ais_freqest_0, 0), (self.blocks_repeat_0, 0)) self.connect((self.ais_invert_0, 0), (self.digital_correlate_access_code_tag_bb_0, 0)) self.connect((self.analog_feedforward_agc_cc_0, 0), (self.digital_corr_est_cc_0, 0)) self.connect((self.analog_frequency_modulator_fc_0, 0), (self.blocks_multiply_xx_0, 1)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.digital_binary_slicer_fb_0, 0)) self.connect((self.analog_quadrature_demod_cf_0, 0), (self.qtgui_time_sink_x_0, 0)) self.connect((self.analog_quadrature_demod_cf_0_0, 0), (self.qtgui_time_sink_x_1, 0)) self.connect((self.blocks_add_const_vxx_0, 0), (self.qtgui_time_sink_x_0, 1)) self.connect((self.blocks_char_to_float_0, 0), (self.blocks_add_const_vxx_0, 0)) self.connect((self.blocks_char_to_float_0_1, 0), (self.qtgui_time_sink_x_0_0, 0)) self.connect((self.blocks_complex_to_mag_squared_0, 0), (self.qtgui_time_sink_x_1, 1)) self.connect((self.blocks_complex_to_mag_squared_0_0, 0), (self.blocks_delay_0, 0)) self.connect((self.blocks_delay_0, 0), (self.blocks_multiply_const_vxx_0, 0)) self.connect((self.blocks_file_source_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.blocks_multiply_const_vxx_0, 0), (self.qtgui_time_sink_x_1, 2)) self.connect((self.blocks_multiply_xx_0, 0), (self.analog_feedforward_agc_cc_0, 0)) self.connect((self.blocks_multiply_xx_0, 0), (self.blocks_complex_to_mag_squared_0_0, 0)) self.connect((self.blocks_multiply_xx_0_0, 0), (self.blocks_stream_to_vector_0, 0)) self.connect((self.blocks_repeat_0, 0), (self.analog_frequency_modulator_fc_0, 0)) self.connect((self.blocks_stream_to_vector_0, 0), (self.fft_vxx_0, 0)) self.connect((self.blocks_tag_gate_0_0, 0), (self.blocks_multiply_xx_0_0, 0)) self.connect((self.blocks_tag_gate_0_0, 0), (self.blocks_multiply_xx_0_0, 1)) self.connect((self.blocks_throttle_0, 0), (self.freq_xlating_fir_filter_xxx_0_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.blocks_char_to_float_0, 0)) self.connect((self.digital_binary_slicer_fb_0, 0), (self.digital_descrambler_bb_0, 0)) self.connect((self.digital_corr_est_cc_0, 0), (self.analog_quadrature_demod_cf_0_0, 0)) self.connect((self.digital_corr_est_cc_0, 1), (self.blocks_complex_to_mag_squared_0, 0)) self.connect((self.digital_corr_est_cc_0, 0), (self.digital_msk_timing_recovery_cc_0, 0)) self.connect((self.digital_correlate_access_code_tag_bb_0, 0), (self.blocks_char_to_float_0_1, 0)) self.connect((self.digital_correlate_access_code_tag_bb_0, 0), (self.digital_hdlc_deframer_bp_0, 0)) self.connect((self.digital_descrambler_bb_0, 0), (self.digital_diff_decoder_bb_0, 0)) self.connect((self.digital_diff_decoder_bb_0, 0), (self.ais_invert_0, 0)) self.connect((self.digital_msk_timing_recovery_cc_0, 0), (self.analog_quadrature_demod_cf_0, 0)) self.connect((self.fft_vxx_0, 0), (self.ais_freqest_0, 0)) self.connect((self.freq_xlating_fir_filter_xxx_0_0, 0), (self.rational_resampler_xxx_0, 0)) self.connect((self.rational_resampler_xxx_0, 0), (self.blocks_multiply_xx_0, 0)) self.connect((self.rational_resampler_xxx_0, 0), (self.blocks_tag_gate_0_0, 0)) def closeEvent(self, event): self.settings = Qt.QSettings("GNU Radio", "gmsk9600_test2") self.settings.setValue("geometry", self.saveGeometry()) event.accept() def get_symbol_rate(self): return self.symbol_rate def set_symbol_rate(self, symbol_rate): self.symbol_rate = symbol_rate self.set_mod(digital.gmskmod_bc(self.samp_rate_2/self.symbol_rate, 4, 0.5)) self.set_modulated_preamble([self.modulated_preamble_untrimmed[i] for i in range(int(self.samp_rate_2/self.symbol_rate*1.5),len(self.modulated_preamble_untrimmed)-int(self.samp_rate_2/self.symbol_rate*0.5))]) self.analog_quadrature_demod_cf_0.set_gain(((self.symbol_rate/2.0)/math.pi)/(self.symbol_rate/4.0)) self.digital_corr_est_cc_0.set_mark_delay(int(self.samp_rate_2/self.symbol_rate*0.5)+1) self.digital_msk_timing_recovery_cc_0.set_sps(self.samp_rate_2/self.symbol_rate) self.qtgui_time_sink_x_0.set_samp_rate(self.symbol_rate) self.qtgui_time_sink_x_0_0.set_samp_rate(self.symbol_rate) def get_samp_rate_2(self): return self.samp_rate_2 def set_samp_rate_2(self, samp_rate_2): self.samp_rate_2 = samp_rate_2 self.set_mod(digital.gmskmod_bc(self.samp_rate_2/self.symbol_rate, 4, 0.5)) self.set_modulated_preamble([self.modulated_preamble_untrimmed[i] for i in range(int(self.samp_rate_2/self.symbol_rate*1.5),len(self.modulated_preamble_untrimmed)-int(self.samp_rate_2/self.symbol_rate*0.5))]) self.analog_frequency_modulator_fc_0.set_sensitivity(-math.pi/(self.samp_rate_2/2.0)) self.analog_quadrature_demod_cf_0_0.set_gain((self.samp_rate_2/2.0)/math.pi) self.digital_corr_est_cc_0.set_mark_delay(int(self.samp_rate_2/self.symbol_rate*0.5)+1) self.digital_msk_timing_recovery_cc_0.set_sps(self.samp_rate_2/self.symbol_rate) self.qtgui_time_sink_x_1.set_samp_rate(self.samp_rate_2) def get_preamble(self): return self.preamble def set_preamble(self, preamble): self.preamble = preamble self.set_preamble_nrz([i-1+256-i*255 for i in self.preamble]) def get_preamble_nrz(self): return self.preamble_nrz def set_preamble_nrz(self, preamble_nrz): self.preamble_nrz = preamble_nrz def get_mod(self): return self.mod def set_mod(self, mod): self.mod = mod def get_modulated_preamble_untrimmed(self): return self.modulated_preamble_untrimmed def set_modulated_preamble_untrimmed(self, modulated_preamble_untrimmed): self.modulated_preamble_untrimmed = modulated_preamble_untrimmed self.set_modulated_preamble([self.modulated_preamble_untrimmed[i] for i in range(int(self.samp_rate_2/self.symbol_rate*1.5),len(self.modulated_preamble_untrimmed)-int(self.samp_rate_2/self.symbol_rate*0.5))]) def get_zero_byte_nrzi(self): return self.zero_byte_nrzi def set_zero_byte_nrzi(self, zero_byte_nrzi): self.zero_byte_nrzi = zero_byte_nrzi def get_samp_rate_1(self): return self.samp_rate_1 def set_samp_rate_1(self, samp_rate_1): self.samp_rate_1 = samp_rate_1 def get_samp_rate_0(self): return self.samp_rate_0 def set_samp_rate_0(self, samp_rate_0): self.samp_rate_0 = samp_rate_0 self.blocks_throttle_0.set_sample_rate(self.samp_rate_0) self.freq_xlating_fir_filter_xxx_0_0.set_taps((firdes.low_pass_2(1, self.samp_rate_0, 12000, 1000, 60, firdes.WIN_BLACKMAN))) def get_one_byte_nrzi_0(self): return self.one_byte_nrzi_0 def set_one_byte_nrzi_0(self, one_byte_nrzi_0): self.one_byte_nrzi_0 = one_byte_nrzi_0 def get_one_byte_nrzi(self): return self.one_byte_nrzi def set_one_byte_nrzi(self, one_byte_nrzi): self.one_byte_nrzi = one_byte_nrzi def get_modulated_preamble(self): return self.modulated_preamble def set_modulated_preamble(self, modulated_preamble): self.modulated_preamble = modulated_preamble self.blocks_delay_0.set_dly(len(self.modulated_preamble)*1) def get_hdlc_flag_nrzi_2(self): return self.hdlc_flag_nrzi_2 def set_hdlc_flag_nrzi_2(self, hdlc_flag_nrzi_2): self.hdlc_flag_nrzi_2 = hdlc_flag_nrzi_2 def get_hdlc_flag_nrzi(self): return self.hdlc_flag_nrzi def set_hdlc_flag_nrzi(self, hdlc_flag_nrzi): self.hdlc_flag_nrzi = hdlc_flag_nrzi def get_flush_filler(self): return self.flush_filler def set_flush_filler(self, flush_filler): self.flush_filler = flush_filler def get_fft_len(self): return self.fft_len def set_fft_len(self, fft_len): self.fft_len = fft_len def get_addr_byte_nrzi_2(self): return self.addr_byte_nrzi_2 def set_addr_byte_nrzi_2(self, addr_byte_nrzi_2): self.addr_byte_nrzi_2 = addr_byte_nrzi_2 def get_addr_byte_nrzi(self): return self.addr_byte_nrzi def set_addr_byte_nrzi(self, addr_byte_nrzi): self.addr_byte_nrzi = addr_byte_nrzi if __name__ == '__main__': parser = OptionParser(option_class=eng_option, usage="%prog: [options]") (options, args) = parser.parse_args() from distutils.version import StrictVersion if StrictVersion(Qt.qVersion()) >= StrictVersion("4.5.0"): Qt.QApplication.setGraphicsSystem(gr.prefs().get_string('qtgui','style','raster')) qapp = Qt.QApplication(sys.argv) tb = gmsk9600_test2() tb.start() tb.show() def quitting(): tb.stop() tb.wait() qapp.connect(qapp, Qt.SIGNAL("aboutToQuit()"), quitting) qapp.exec_() tb = None # to clean up Qt widgets