Ejemplo n.º 1
0
    def __init__(self, config, dev, verbosity):
        sys.stderr.write('channel (dev %s): %s\n' % (dev.name, config))
        self.device = dev
        self.name = config['name']
        self.symbol_rate = _def_symbol_rate
        if 'symbol_rate' in config.keys():
            self.symbol_rate = config['symbol_rate']
        self.config = config
        self.demod = p25_demodulator.p25_demod_cb(
                         input_rate = dev.sample_rate,
                         demod_type = config['demod_type'],
                         filter_type = config['filter_type'],
                         excess_bw = config['excess_bw'],
                         relative_freq = dev.frequency + dev.offset - config['frequency'],
                         offset = dev.offset,
                         if_rate = config['if_rate'],
                         symbol_rate = self.symbol_rate)
        q = gr.msg_queue(1)
        self.decoder = op25_repeater.frame_assembler(config['destination'], verbosity, q)

        self.kill_sink = []

        if 'plot' not in config.keys():
            return

        self.sinks = []
        for plot in config['plot'].split(','):
            # fixme: allow multiple complex consumers (fft and constellation currently mutually exclusive)
            if plot == 'datascope':
                assert config['demod_type'] == 'fsk4'   ## datascope plot requires fsk4 demod type
                sink = eye_sink_f(sps=config['if_rate'] / self.symbol_rate)
                self.demod.connect_bb('symbol_filter', sink)
                self.kill_sink.append(sink)
            elif plot == 'symbol':
                sink = symbol_sink_f()
                self.demod.connect_float(sink)
                self.kill_sink.append(sink)
            elif plot == 'fft':
                i = len(self.sinks)
                self.sinks.append(fft_sink_c())
                self.demod.connect_complex('src', self.sinks[i])
                self.kill_sink.append(self.sinks[i])
                self.sinks[i].set_offset(self.device.offset)
                self.sinks[i].set_center_freq(self.device.frequency)
                self.sinks[i].set_relative_freq(self.device.frequency + self.device.offset - self.config['frequency'])
                self.sinks[i].set_width(self.device.sample_rate)
            elif plot == 'constellation':
                i = len(self.sinks)
                assert config['demod_type'] == 'cqpsk'   ## constellation plot requires cqpsk demod type
                self.sinks.append(constellation_sink_c())
                self.demod.connect_complex('diffdec', self.sinks[i])
                self.kill_sink.append(self.sinks[i])
            elif plot == 'mixer':
                i = len(self.sinks)
                self.sinks.append(mixer_sink_c())
                self.demod.connect_complex('mixer', self.sinks[i])
                self.kill_sink.append(self.sinks[i])
            else:
                sys.stderr.write('unrecognized plot type %s\n' % plot)
                return
Ejemplo n.º 2
0
 def toggle_mixer(self):
     if (self.mixer_sink is None):
         self.mixer_sink = mixer_sink_c()
         self.add_plot_sink(self.mixer_sink)
         self.lock()
         self.demod.connect_complex('mixer', self.mixer_sink)
         self.unlock()
     elif (self.mixer_sink is not None):
         self.lock()
         self.demod.disconnect_complex()
         self.unlock()
         self.mixer_sink.kill()
         self.remove_plot_sink(self.mixer_sink)
         self.mixer_sink = None
Ejemplo n.º 3
0
 def toggle_mixer_plot(self):
     if 'mixer' not in self.sinks:
         sink = mixer_sink_c(plot_name=("Ch:%s" % self.name), chan=self.msgq_id)
         self.sinks['mixer'] = (sink, self.toggle_mixer_plot)
         self.set_plot_destination('mixer')
         sink.set_width(self.config['if_rate'])
         self.tb.lock()
         self.demod.connect_complex('cutoff', sink)
         self.tb.unlock()
     else:
         (sink, fn) = self.sinks.pop('mixer')
         self.tb.lock()
         self.demod.disconnect_complex(sink)
         self.tb.unlock()
         sink.kill()
Ejemplo n.º 4
0
 def toggle_mixer(self):
     if (self.mixer_sink is None):
         self.mixer_sink = mixer_sink_c()
         self.add_plot_sink(self.mixer_sink)
         self.lock()
         self.demod.connect_complex('cutoff', self.mixer_sink)
         self.mixer_sink.set_width(self.basic_rate)
         self.unlock()
     elif (self.mixer_sink is not None):
         self.lock()
         self.demod.disconnect_complex(self.mixer_sink)
         self.unlock()
         self.mixer_sink.kill()
         self.remove_plot_sink(self.mixer_sink)
         self.mixer_sink = None
Ejemplo n.º 5
0
    def __build_graph(self, source, capture_rate):
        global speeds
        global WIRESHARK_PORT

        sps = 5  # samples / symbol
        if_rate = sps * 4800

        self.rx_q = gr.msg_queue(100)
        udp_port = 0

        vocoder = self.options.vocoder
        wireshark = self.options.wireshark
        wireshark_host = self.options.wireshark_host
        if self.options.udp_player:
            vocoder = True
            wireshark = True
            wireshark_host = "127.0.0.1"

        if wireshark or (wireshark_host != "127.0.0.1"):
            udp_port = self.options.wireshark_port

        self.tdma_state = False
        self.xor_cache = {}

        if self.baseband_input:
            self.demod = p25_demodulator.p25_demod_fb(
                input_rate=capture_rate,
                excess_bw=self.options.excess_bw,
                if_rate=if_rate)
        else:  # complex input
            # local osc
            self.lo_freq = self.options.offset
            if self.options.audio_if or self.options.ifile or self.options.input:
                self.lo_freq += self.options.calibration
            self.demod = p25_demodulator.p25_demod_cb(
                input_rate=capture_rate,
                demod_type=self.options.demod_type,
                relative_freq=self.lo_freq,
                offset=self.options.offset,
                if_rate=if_rate,
                gain_mu=self.options.gain_mu,
                costas_alpha=self.options.costas_alpha,
                excess_bw=self.options.excess_bw,
                symbol_rate=self.symbol_rate)

        num_ambe = 0
        if self.options.phase2_tdma:
            num_ambe = 1

        self.decoder = p25_decoder.p25_decoder_sink_b(
            dest='audio',
            do_imbe=vocoder,
            num_ambe=num_ambe,
            wireshark_host=wireshark_host,
            udp_port=udp_port,
            do_msgq=True,
            msgq=self.rx_q,
            audio_output=self.options.audio_output,
            debug=self.options.verbosity)

        # connect it all up
        self.connect(source, self.demod, self.decoder)

        if self.baseband_input:
            sps = if_rate // 4800
        plot_modes = []
        if self.options.plot_mode is not None:
            plot_modes = self.options.plot_mode.split(',')
        for plot_mode in plot_modes:
            if plot_mode == 'constellation':
                assert self.options.demod_type == 'cqpsk'  ## constellation requires cqpsk demod-type
                sink = constellation_sink_c()
                self.plot_sinks.append(sink)
                self.demod.connect_complex('diffdec', sink)
            elif plot_mode == 'symbol':
                sink = symbol_sink_f()
                self.plot_sinks.append(sink)
                self.demod.connect_float(sink)
            elif plot_mode == 'fft':
                sink = fft_sink_c()
                self.plot_sinks.append(sink)
                self.spectrum_decim = filter.rational_resampler_ccf(
                    1, self.options.decim_amt)
                self.connect(self.spectrum_decim, sink)
                self.demod.connect_complex('src', self.spectrum_decim)
            elif plot_mode == 'mixer':
                sink = mixer_sink_c()
                self.plot_sinks.append(sink)
                self.demod.connect_complex('mixer', sink)
            elif plot_mode == 'datascope':
                assert self.options.demod_type == 'fsk4'  ## datascope requires fsk4 demod-type
                sink = eye_sink_f(sps=sps)
                self.plot_sinks.append(sink)
                self.demod.connect_bb('symbol_filter', sink)
            elif plot_mode == 'correlation':
                assert self.options.demod_type == 'fsk4'  ## correlation plot requires fsk4 demod type
                self.plot_sinks += setup_correlation(sps, "",
                                                     self.demod.connect_bb)
            else:
                raise ValueError('unsupported plot type: %s' % plot_mode)
        if self.is_http_term():
            for sink in self.plot_sinks:
                sink.gnuplot.set_interval(_def_interval)
                sink.gnuplot.set_output_dir(_def_file_dir)

        if self.options.raw_symbols:
            self.sink_sf = blocks.file_sink(gr.sizeof_char,
                                            self.options.raw_symbols)
            self.connect(self.demod, self.sink_sf)

        logfile_workers = []
        if self.options.phase2_tdma:
            num_ambe = 2
        if self.options.logfile_workers:
            for i in range(self.options.logfile_workers):
                demod = p25_demodulator.p25_demod_cb(
                    input_rate=capture_rate,
                    demod_type=self.options.demod_type,
                    offset=self.options.offset)
                decoder = p25_decoder.p25_decoder_sink_b(
                    debug=self.options.verbosity,
                    do_imbe=vocoder,
                    num_ambe=num_ambe)
                logfile_workers.append({
                    'demod': demod,
                    'decoder': decoder,
                    'active': False
                })
                self.connect(source, demod, decoder)

        self.trunk_rx = trunking.rx_ctl(frequency_set=self.change_freq,
                                        debug=self.options.verbosity,
                                        conf_file=self.options.trunk_conf_file,
                                        logfile_workers=logfile_workers)

        self.du_watcher = du_queue_watcher(self.rx_q,
                                           self.trunk_rx.process_qmsg)
Ejemplo n.º 6
0
    def __init__(self,
                 config,
                 dev,
                 verbosity,
                 msgq=None,
                 process_msg=None,
                 msgq_id=-1,
                 role=''):
        sys.stderr.write('channel (dev %s): %s\n' % (dev.name, config))
        self.device = dev
        self.name = config['name']
        self.symbol_rate = _def_symbol_rate
        self.process_msg = process_msg
        self.role = role
        self.dev = ''
        self.sysid = []
        self.nac = []
        if 'symbol_rate' in config.keys():
            self.symbol_rate = config['symbol_rate']
        self.config = config
        self.verbosity = verbosity
        self.frequency = 0
        self.tdma_state = False
        self.xor_cache = {}

        self.tuning_error = 0
        self.freq_correction = 0
        self.error_band = 0
        self.last_error_update = 0
        self.last_set_freq_at = time.time()
        self.warned_frequencies = {}
        self.msgq_id = msgq_id
        self.next_band_change = time.time()

        self.audio_port = _def_audio_port
        self.audio_output = _def_audio_output
        self.audio_gain = 1.0
        if 'audio_gain' in config:
            self.audio_gain = float(config['audio_gain'])

        if dev.args.startswith('audio:'):
            self.demod = p25_demodulator.p25_demod_fb(
                input_rate=dev.sample_rate,
                filter_type=config['filter_type'],
                if_rate=config['if_rate'],
                symbol_rate=self.symbol_rate)
        else:
            self.demod = p25_demodulator.p25_demod_cb(
                input_rate=dev.sample_rate,
                demod_type=config['demod_type'],
                filter_type=config['filter_type'],
                excess_bw=config['excess_bw'],
                relative_freq=dev.frequency + dev.offset - config['frequency'],
                offset=dev.offset,
                if_rate=config['if_rate'],
                symbol_rate=self.symbol_rate)
        if msgq is not None:
            q = msgq
        else:
            q = gr.msg_queue(20)
        if 'decode' in config.keys() and config['decode'].startswith(
                'p25_decoder'):
            num_ambe = 1
            (proto, wireshark_host,
             udp_port) = config['destination'].split(':')
            assert proto == 'udp'
            wireshark_host = wireshark_host.replace('/', '')
            udp_port = int(udp_port)
            if role == 'vc':
                self.audio_port = udp_port
            if 'audio_output' in config.keys():
                self.audio_output = config['audio_output']

            self.decoder = p25_decoder.p25_decoder_sink_b(
                dest='audio',
                do_imbe=True,
                num_ambe=num_ambe,
                wireshark_host=wireshark_host,
                udp_port=udp_port,
                do_msgq=True,
                msgq=q,
                audio_output=self.audio_output,
                debug=verbosity,
                msgq_id=self.msgq_id)
        else:
            self.decoder = op25_repeater.frame_assembler(
                config['destination'], verbosity, q, self.msgq_id)

        if self.symbol_rate == 6000 and role == 'cc':
            sps = config['if_rate'] // self.symbol_rate
            self.demod.set_symbol_rate(
                self.symbol_rate)  # this and the foll. call should be merged?
            self.demod.clock.set_omega(float(sps))
            self.demod.clock.set_tdma(True)
            sys.stderr.write(
                'initializing TDMA control channel %s channel ID %d\n' %
                (self.name, self.msgq_id))

        if self.process_msg is not None and msgq is None:
            self.q_watcher = du_queue_watcher(
                q, lambda msg: self.process_msg(msg, sender=self))

        self.kill_sink = []

        if 'blacklist' in config.keys():
            for g in config['blacklist'].split(','):
                self.decoder.insert_blacklist(int(g))

        if 'whitelist' in config.keys():
            for g in config['whitelist'].split(','):
                self.decoder.insert_whitelist(int(g))

        self.sinks = []
        if 'plot' not in config.keys():
            return

        for plot in config['plot'].split(','):
            if plot == 'datascope':
                assert config[
                    'demod_type'] == 'fsk4'  ## datascope plot requires fsk4 demod type
                sink = eye_sink_f(sps=config['if_rate'] // self.symbol_rate)
                sink.set_title(self.name)
                self.sinks.append(sink)
                self.demod.connect_bb('symbol_filter', sink)
                self.kill_sink.append(sink)
            elif plot == 'symbol':
                sink = symbol_sink_f()
                sink.set_title(self.name)
                self.sinks.append(sink)
                self.demod.connect_float(sink)
                self.kill_sink.append(sink)
            elif plot == 'fft':
                assert config[
                    'demod_type'] == 'cqpsk'  ## fft plot requires cqpsk demod type
                i = len(self.sinks)
                sink = fft_sink_c()
                sink.set_title(self.name)
                self.sinks.append(sink)
                self.demod.connect_complex('src', self.sinks[i])
                self.kill_sink.append(self.sinks[i])
            elif plot == 'mixer':
                assert config[
                    'demod_type'] == 'cqpsk'  ## mixer plot requires cqpsk demod type
                i = len(self.sinks)
                sink = mixer_sink_c()
                sink.set_title(self.name)
                self.sinks.append(sink)
                self.demod.connect_complex('mixer', self.sinks[i])
                self.kill_sink.append(self.sinks[i])
            elif plot == 'constellation':
                i = len(self.sinks)
                assert config[
                    'demod_type'] == 'cqpsk'  ## constellation plot requires cqpsk demod type
                sink = constellation_sink_c()
                sink.set_title(self.name)
                self.sinks.append(sink)
                self.demod.connect_complex('diffdec', self.sinks[i])
                self.kill_sink.append(self.sinks[i])
            elif plot == 'correlation':
                assert config[
                    'demod_type'] == 'fsk4'  ## correlation plot requires fsk4 demod type
                assert config[
                    'symbol_rate'] == 4800  ## 4800 required for correlation plot
                sps = config['if_rate'] // self.symbol_rate
                sinks = setup_correlation(sps, self.name,
                                          self.demod.connect_bb)
                self.kill_sink += sinks
                self.sinks += sinks
            else:
                sys.stderr.write('unrecognized plot type %s\n' % plot)
                return
Ejemplo n.º 7
0
    def __init__(self, config, dev, verbosity, msgq = None):
        sys.stderr.write('channel (dev %s): %s\n' % (dev.name, config))
        self.device = dev
        self.name = config['name']
        self.symbol_rate = _def_symbol_rate
        if 'symbol_rate' in config.keys():
            self.symbol_rate = config['symbol_rate']
        self.config = config
        if dev.args.startswith('audio:'):
            self.demod = p25_demodulator.p25_demod_fb(
                         input_rate = dev.sample_rate,
                         filter_type = config['filter_type'],
                         if_rate = config['if_rate'],
                         symbol_rate = self.symbol_rate)
        else:
            self.demod = p25_demodulator.p25_demod_cb(
                         input_rate = dev.sample_rate,
                         demod_type = config['demod_type'],
                         filter_type = config['filter_type'],
                         excess_bw = config['excess_bw'],
                         relative_freq = dev.frequency + dev.offset - config['frequency'],
                         offset = dev.offset,
                         if_rate = config['if_rate'],
                         symbol_rate = self.symbol_rate)
        if msgq is None:
            q = gr.msg_queue(1)
        else:
            q = msgq
        self.decoder = op25_repeater.frame_assembler(config['destination'], verbosity, q)

        self.kill_sink = []

        if 'blacklist' in config.keys():
            for g in config['blacklist'].split(','):
                self.decoder.insert_blacklist(int(g))

        if 'whitelist' in config.keys():
            for g in config['whitelist'].split(','):
                self.decoder.insert_whitelist(int(g))

        if 'plot' not in config.keys():
            return

        self.sinks = []
        for plot in config['plot'].split(','):
            if plot == 'datascope':
                assert config['demod_type'] == 'fsk4'   ## datascope plot requires fsk4 demod type
                sink = eye_sink_f(sps=config['if_rate'] // self.symbol_rate)
                self.demod.connect_bb('symbol_filter', sink)
                self.kill_sink.append(sink)
            elif plot == 'symbol':
                sink = symbol_sink_f()
                self.demod.connect_float(sink)
                self.kill_sink.append(sink)
            elif plot == 'fft':
                assert config['demod_type'] == 'cqpsk'   ## fft plot requires cqpsk demod type
                i = len(self.sinks)
                self.sinks.append(fft_sink_c())
                self.demod.connect_complex('src', self.sinks[i])
                self.kill_sink.append(self.sinks[i])
            elif plot == 'mixer':
                assert config['demod_type'] == 'cqpsk'   ## mixer plot requires cqpsk demod type
                i = len(self.sinks)
                self.sinks.append(mixer_sink_c())
                self.demod.connect_complex('mixer', self.sinks[i])
                self.kill_sink.append(self.sinks[i])
            elif plot == 'constellation':
                i = len(self.sinks)
                assert config['demod_type'] == 'cqpsk'   ## constellation plot requires cqpsk demod type
                self.sinks.append(constellation_sink_c())
                self.demod.connect_complex('diffdec', self.sinks[i])
                self.kill_sink.append(self.sinks[i])
            elif plot == 'correlation':
                assert config['demod_type'] == 'fsk4'   ## correlation plot requires fsk4 demod type
                assert config['symbol_rate'] == 4800	## 4800 required for correlation plot
                sps=config['if_rate'] // self.symbol_rate
                sinks = setup_correlation(sps, self.name, self.demod.connect_bb)
                self.kill_sink += sinks
                self.sinks += sinks
            else:
                sys.stderr.write('unrecognized plot type %s\n' % plot)
                return