Example #1
0
    def __init__(self,
                 idle_silence=True,
                 traffic_msgq=None,
                 key=None,
                 key_map=None,
                 verbose=False):
        gr.hier_block2.__init__(self, "op25_decoder",
                                gr.io_signature(1, 1, gr.sizeof_float),
                                gr.io_signature(1, 1, gr.sizeof_float))

        self.traffic_msgq = traffic_msgq
        self.key = key
        self.key_map = key_map

        self.traffic_message_callback = None

        self.slicer = None
        try:
            levels = [-2.0, 0.0, 2.0, 4.0]
            self.slicer = op25.fsk4_slicer_fb(levels)
            try:
                self.p25_decoder = op25.decoder_bf(idle_silence=idle_silence,
                                                   verbose=verbose)
            except:
                print "[OP25] Extended decoder_bf constructor not available"
                self.p25_decoder = op25.decoder_bf()  # Original style
            if self.traffic_msgq is not None:
                self.p25_decoder.set_msgq(self.traffic_msgq)
            if _verbose:
                print "[OP25] Using new decoder_bf"
        except Exception, e:
            print "[OP25] New decoder_bf not available:", e
            try:
                if self.traffic_msgq is None:
                    self.traffic_msgq = gr.msg_queue(2)
                    self.traffic_message_callback = message_callback.message_callback(
                        self.traffic_msgq)
                self.p25_decoder = op25.decoder_ff(self.traffic_msgq)  # LEGACY
                if _verbose:
                    print "[OP25] Using legacy decoder_ff"
            except Exception, e:
                print e
                raise Exception("Could not find a decoder to use")
Example #2
0
 def __init__(self, idle_silence=True, traffic_msgq=None, key=None, key_map=None, verbose=False):
     gr.hier_block2.__init__(self, "op25_decoder",
                           gr.io_signature(1, 1, gr.sizeof_float),
                           gr.io_signature(1, 1, gr.sizeof_float))
     
     self.traffic_msgq = traffic_msgq
     self.key = key
     self.key_map = key_map
     
     self.traffic_message_callback = None
     
     self.slicer = None
     try:
         levels = [ -2.0, 0.0, 2.0, 4.0 ]
         self.slicer = op25.fsk4_slicer_fb(levels)
         try:
             self.p25_decoder = op25.decoder_bf(idle_silence=idle_silence, verbose=verbose)
         except:
             print "[OP25] Extended decoder_bf constructor not available"
             self.p25_decoder = op25.decoder_bf()    # Original style
         if self.traffic_msgq is not None:
             self.p25_decoder.set_msgq(self.traffic_msgq)
         if _verbose:
             print "[OP25] Using new decoder_bf"
     except Exception, e:
         print "[OP25] New decoder_bf not available:", e
         try:
             if self.traffic_msgq is None:
                 self.traffic_msgq = gr.msg_queue(2)
                 self.traffic_message_callback = message_callback.message_callback(self.traffic_msgq)
             self.p25_decoder = op25.decoder_ff(self.traffic_msgq)   # LEGACY
             if _verbose:
                 print "[OP25] Using legacy decoder_ff"
         except Exception, e:
             print e
             raise Exception("Could not find a decoder to use")
Example #3
0
	def __init__(self,infile, outfile, input_rate, channel_rate, codec_provoice, codec_p25, sslevel, svlevel):
		gr.top_block.__init__(self, "Top Block")
		
		self.input_rate = input_rate
		self.channel_rate = channel_rate
		
		self.source = blocks.file_source(gr.sizeof_gr_complex*1, infile, False)
		self.lp1_decim = int(input_rate/(channel_rate*1.6))
		print self.lp1_decim
		self.lp1 = filter.fir_filter_ccc(self.lp1_decim,firdes.low_pass( 1.0, self.input_rate, (self.channel_rate/2), ((self.channel_rate/2)*0.6), firdes.WIN_HAMMING))

		#self.audiodemod =  gr.quadrature_demod_cf(1)

		audio_pass = (input_rate/self.lp1_decim)*0.25
		audio_stop = audio_pass+2000
		self.audiodemod = analog.fm_demod_cf(channel_rate=(input_rate/self.lp1_decim), audio_decim=1, deviation=15000, audio_pass=audio_pass, audio_stop=audio_stop, gain=8, tau=75e-6)
		
		self.throttle = blocks.throttle(gr.sizeof_gr_complex*1, self.input_rate)

		self.signal_squelch = analog.pwr_squelch_cc(sslevel,0.01, 0, True)
		self.vox_squelch = analog.pwr_squelch_ff(svlevel, 0.0005, 0, True)
		
		self.audiosink = blocks.wavfile_sink(outfile, 1, 8000)

		if codec_provoice:
			self.dsd = dsd.block_ff(dsd.dsd_FRAME_PROVOICE,dsd.dsd_MOD_AUTO_SELECT,1,0,False)
			channel_rate = input_rate/self.lp1_decim
			self.resampler_in = filter.rational_resampler_fff(interpolation=48000, decimation=channel_rate, taps=None, fractional_bw=None, )
			output_rate = 8000
			resampler = filter.rational_resampler_fff(
                                        interpolation=(input_rate/self.lp1_decim),
                                        decimation=output_rate,
                                        taps=None,
                                        fractional_bw=None,
                                )
		elif codec_p25:
			symbol_deviation = 600.0
			symbol_rate = 4800
			channel_rate = input_rate/self.lp1_decim
			
		        fm_demod_gain = channel_rate / (2.0 * pi * symbol_deviation)
		        fm_demod = analog.quadrature_demod_cf(fm_demod_gain)

		        symbol_decim = 1
		        samples_per_symbol = channel_rate // symbol_rate
		        symbol_coeffs = (1.0/samples_per_symbol,) * samples_per_symbol
		        symbol_filter = filter.fir_filter_fff(symbol_decim, symbol_coeffs)

		        autotuneq = gr.msg_queue(2)
		        demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate, symbol_rate)


		        # symbol slicer
		        levels = [ -2.0, 0.0, 2.0, 4.0 ]
		        slicer = op25.fsk4_slicer_fb(levels)

			imbe = repeater.vocoder(False, True, 0, "", 0, False)
			self.decodequeue = decodequeue = gr.msg_queue(10000)
			decoder = repeater.p25_frame_assembler('', 0, 0, True, True, False, decodequeue)
	
		        float_conversion = blocks.short_to_float(1, 8192)
		        resampler = filter.rational_resampler_fff(
		                        interpolation=8000,
		                        decimation=8000,
		                        taps=None,
		                        fractional_bw=None,
		                )
	
					
		#Tone squelch, custom GRC block that rips off CTCSS squelch to detect 4800 hz tone and latch squelch after that
		if not codec_provoice and not codec_p25:
			#self.tone_squelch = gr.tone_squelch_ff(audiorate, 4800.0, 0.05, 300, 0, True)
			#tone squelch is EDACS ONLY
			self.high_pass = filter.fir_filter_fff(1, firdes.high_pass(1, (input_rate/self.lp1_decim), 300, 30, firdes.WIN_HAMMING, 6.76))
			#output_rate = channel_rate
			resampler = filter.rational_resampler_fff(
                                        interpolation=8000,
                                        decimation=(input_rate/self.lp1_decim),
                                        taps=None,
                                        fractional_bw=None,
			)
		if(codec_provoice):
			self.connect(self.source, self.throttle, self.lp1, self.audiodemod, self.resampler_in, self.dsd, self.audiosink)
		elif(codec_p25):
			self.connect(self.source, self.throttle, self.lp1, fm_demod, symbol_filter, demod_fsk4, slicer, decoder, imbe, float_conversion, resampler, self.audiosink)
		else:
			self.connect(self.source, self.throttle, self.lp1, self.signal_squelch, self.audiodemod, self.high_pass, self.vox_squelch, resampler, self.audiosink)

		self.time_open = time.time()
		self.time_tone = 0
		self.time_activity = 0
    def __init__(self, system, site_uuid, overseer_uuid):

        gr.top_block.__init__(self, "p25 receiver")

        #set globals
        self.is_locked = False
        self.system = system
        self.instance_uuid = '%s' % uuid.uuid4()

        self.log = logging.getLogger('overseer.p25_control_demod.%s' %
                                     self.instance_uuid)
        self.protocol_log = logging.getLogger('protocol.%s' %
                                              self.instance_uuid)
        self.log.info('Initializing instance: %s site: %s overseer: %s' %
                      (self.instance_uuid, site_uuid, overseer_uuid))

        self.site_uuid = site_uuid
        self.overseer_uuid = overseer_uuid

        self.control_channel = system['channels'][
            system['default_control_channel']]
        self.control_channel_i = system['default_control_channel']

        self.channel_identifier_table = {}

        try:
            self.modulation = system['modulation']
        except:
            self.modulation = 'C4FM'

        self.channel_rate = 12500
        symbol_rate = 4800

        self.site_detail = {}
        self.site_detail['WACN ID'] = None
        self.site_detail['System ID'] = None
        self.site_detail['Control Channel'] = None
        self.site_detail['System Service Class'] = None
        self.site_detail['Site ID'] = None
        self.site_detail['RF Sub-system ID'] = None
        self.site_detail['RFSS Network Connection'] = None

        self.bad_messages = 0
        self.total_messages = 0
        self.quality = []

        self.keep_running = True

        self.source = None

        # channel filter
        channel_rate = self.channel_rate * 2
        self.control_prefilter = filter.freq_xlating_fir_filter_ccc(
            1, (1, ), 0, channel_rate)

        # power squelch
        #power_squelch = gr.pwr_squelch_cc(squelch, 1e-3, 0, True)
        #self.connect(self.channel_filter, power_squelch)

        autotuneq = gr.msg_queue(2)
        self.demod_watcher = demod_watcher(self)
        self.symbol_deviation = 600.0

        if self.modulation == 'C4FM':
            # FM demodulator
            fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation)
            self.fm_demod = fm_demod = analog.quadrature_demod_cf(
                fm_demod_gain)

            moving_sum = blocks.moving_average_ff(10000, 1, 40000)
            subtract = blocks.sub_ff(1)
            divide_const = blocks.multiply_const_vff((0.0001, ))
            self.probe = blocks.probe_signal_f()
            self.connect(self.fm_demod, moving_sum, divide_const, self.probe)

            # symbol filter
            symbol_decim = 1
            samples_per_symbol = channel_rate // symbol_rate
            symbol_coeffs = (1.0 / samples_per_symbol, ) * samples_per_symbol
            symbol_filter = filter.fir_filter_fff(symbol_decim, symbol_coeffs)

            demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate,
                                            symbol_rate)
        elif self.modulation == 'CQPSK':
            # FM demodulator
            fm_demod_gain = channel_rate / (2.0 * pi * self.symbol_deviation)
            self.fm_demod = fm_demod = analog.quadrature_demod_cf(
                fm_demod_gain)

            moving_sum = blocks.moving_average_ff(10000, 1, 40000)
            subtract = blocks.sub_ff(1)
            divide_const = blocks.multiply_const_vff((0.0001, ))
            self.probe = blocks.probe_signal_f()
            self.connect(fm_demod, moving_sum, divide_const, self.probe)

            #self.resampler = filter.pfb.arb_resampler_ccf(float(48000)/float(channel_rate))
            self.resampler = blocks.multiply_const_cc(1.0)
            self.agc = analog.feedforward_agc_cc(1024, 1.0)
            self.symbol_filter_c = blocks.multiply_const_cc(1.0)

            gain_mu = 0.025
            omega = float(channel_rate) / float(symbol_rate)
            gain_omega = 0.1 * gain_mu * gain_mu

            alpha = 0.04
            beta = 0.125 * alpha * alpha
            fmax = 1200  # Hz
            fmax = 2 * pi * fmax / float(channel_rate)

            self.clock = repeater.gardner_costas_cc(omega, gain_mu, gain_omega,
                                                    alpha, beta, fmax, -fmax)
            self.diffdec = digital.diff_phasor_cc()
            self.to_float = blocks.complex_to_arg()
            self.rescale = blocks.multiply_const_ff((1 / (pi / 4)))

    # symbol slicer
        levels = [-2.0, 0.0, 2.0, 4.0]
        slicer = op25.fsk4_slicer_fb(levels)

        # frame decoder
        self.decodequeue = decodequeue = gr.msg_queue(1000)
        qsink = blocks.message_sink(gr.sizeof_char, self.decodequeue, False)
        self.decoder = decoder = repeater.p25_frame_assembler(
            '', 0, 0, False, True, True, autotuneq, False, False)

        if self.modulation == 'C4FM':
            self.connect(self.control_prefilter, fm_demod, symbol_filter,
                         demod_fsk4, slicer, decoder, qsink)
        elif self.modulation == 'CQPSK':
            self.connect(self.resampler, self.agc, self.symbol_filter_c,
                         self.clock, self.diffdec, self.to_float, self.rescale,
                         slicer, decoder, qsink)

##################################################
# Threads
##################################################
        self.connector = frontend_connector()
        self.client_redis = client_redis()
        self.redis_demod_publisher = redis_demod_publisher(parent_demod=self)

        quality_check_0 = threading.Thread(target=self.quality_check)
        quality_check_0.daemon = True
        quality_check_0.start()
        # Adjust the channel offset
        #
        self.tune_next_control_channel()

        #self.receive_engine()

        receive_engine = threading.Thread(target=self.receive_engine)
        receive_engine.daemon = True
        receive_engine.start()
Example #5
0
    def configure_blocks(self, protocol):
        if protocol == 'provoice' or protocol == 'analog_edacs':
            protocol = 'analog'
        self.log.debug('configure_blocks(%s)' % protocol)
        if not (protocol == 'p25' or protocol == 'p25_tdma'
                or protocol == 'p25_cqpsk' or protocol == 'p25_cqpsk_tdma'
                or protocol == 'provoice' or protocol == 'dsd_p25'
                or protocol == 'analog' or protocol == 'none'):
            raise Exception('Invalid protocol %s' % protocol)
        if self.protocol == protocol:
            return True
        self.lock()
        if self.protocol == 'analog':
            self.disconnect(self.source, self.signal_squelch, self.audiodemod,
                            self.high_pass, self.resampler, self.sink)
            self.signal_squelch = None
            self.audiodemod = None
            self.high_pass = None
            self.resampler = None

        elif self.protocol == 'p25' or 'p25_tdma':
            try:
                self.disconnect(self.source, self.prefilter,
                                self.fm_demod)  #, (self.subtract,0))
                self.disconnect(self.fm_demod, self.symbol_filter,
                                self.demod_fsk4, self.slicer, self.decoder,
                                self.float_conversion, self.sink)
                self.disconnect(self.slicer, self.decoder2, self.qsink)
                self.demod_watcher.keep_running = False

            except:
                pass
            #self.disconnect(self.fm_demod, self.avg, self.mult, (self.subtract,1))

            self.prefilter = None
            self.fm_demod = None
            #self.avg = None
            #self.mult = None
            #self.subtract = None
            self.symbol_filter = None
            self.demod_fsk4 = None
            self.slicer = None
            self.decoder = None
            self.decoder2 = None
            self.qsink = None
            self.imbe = None
            self.float_conversion = None
            self.resampler = None
        elif self.protocol == 'p25_cqpsk' or self.protocol == 'p25_cqpsk_tdma':
            self.disconnect(self.source, self.resampler, self.agc,
                            self.symbol_filter_c, self.clock, self.diffdec,
                            self.to_float, self.rescale, self.slicer,
                            self.decoder2, self.qsink)  #, (self.subtract,0))
            self.disconnect(self.slicer, self.decoder, self.float_conversion,
                            self.sink)

            self.prefilter = None
            self.resampler = None
            self.agc = None
            self.symbol_filter_c = None
            self.clock = None
            self.diffdec = None
            self.to_float = None
            self.rescale = None
            self.slicer = None

            self.imbe = None
            self.decodequeue3 = None
            self.decodequeue2 = None
            self.decodequeue = None

            self.demod_watcher = None
            self.decoder = None
            self.decoder2 = None
            self.qsink = None
            self.float_conversion = None

        elif self.protocol == 'provoice':
            self.disconnect(self.source, self.fm_demod, self.resampler_in,
                            self.dsd, self.out_squelch, self.sink)
            self.fm_demod = None
            self.resampler_in = None
            self.dsd = None
            self.out_squelch = None
        elif self.protocol == 'dsd_p25':
            self.disconnect(self.source, self.fm_demod, self.resampler_in,
                            self.dsd, self.sink)
            self.fm_demod = None
            self.resampler_in = None
            self.dsd = None
        self.protocol = protocol

        if protocol == 'analog':
            self.signal_squelch = analog.pwr_squelch_cc(-100, 0.01, 0, True)
            #self.tone_squelch = gr.tone_squelch_ff(audiorate, 4800.0, 0.05, 300, 0, True)
            #tone squelch is EDACS ONLY
            self.audiodemod = analog.fm_demod_cf(
                channel_rate=self.input_rate,
                audio_decim=1,
                deviation=15000,
                audio_pass=(self.input_rate * 0.25),
                audio_stop=((self.input_rate * 0.25) + 2000),
                gain=8,
                tau=75e-6)
            self.high_pass = filter.fir_filter_fff(
                1,
                firdes.high_pass(1, self.input_rate, 300, 30,
                                 firdes.WIN_HAMMING, 6.76))
            self.resampler = filter.rational_resampler_fff(
                interpolation=8000,
                decimation=self.input_rate,
                taps=None,
                fractional_bw=None,
            )
            self.connect(self.source, self.signal_squelch, self.audiodemod,
                         self.high_pass, self.resampler, self.sink)
        elif protocol == 'p25' or protocol == 'p25_tdma':
            self.symbol_deviation = symbol_deviation = 600.0
            if protocol == 'p25_tdma':
                symbol_rate = 6000
            else:
                symbol_rate = 4800
            channel_rate = self.input_rate

            self.prefilter = filter.freq_xlating_fir_filter_ccc(
                1, (1, ), 0, self.input_rate)

            fm_demod_gain = channel_rate / (2.0 * pi * symbol_deviation)
            self.fm_demod = analog.quadrature_demod_cf(fm_demod_gain)

            #self.avg = blocks.moving_average_ff(1000, 1, 4000)
            #self.mult = blocks.multiply_const_vff((0.001, ))
            #self.subtract = blocks.sub_ff(1)

            symbol_decim = 1
            samples_per_symbol = channel_rate // symbol_rate
            symbol_coeffs = (1.0 / samples_per_symbol, ) * samples_per_symbol
            self.symbol_filter = filter.fir_filter_fff(symbol_decim,
                                                       symbol_coeffs)

            autotuneq = gr.msg_queue(2)
            self.demod_fsk4 = op25.fsk4_demod_ff(autotuneq, channel_rate,
                                                 symbol_rate)

            # symbol slicer
            levels = [-2.0, 0.0, 2.0, 4.0]
            self.slicer = op25.fsk4_slicer_fb(levels)

            self.imbe = repeater.vocoder(False, True, 0, "", 0, False)
            self.decodequeue3 = decodequeue3 = gr.msg_queue(10000)
            self.decodequeue2 = decodequeue2 = gr.msg_queue(10000)
            self.decodequeue = decodequeue = gr.msg_queue(10000)

            self.demod_watcher = None  #demod_watcher(decodequeue2, self.adjust_channel_offset)

            self.decoder = repeater.p25_frame_assembler(
                '', 0, 0, True, True, False, decodequeue2, True,
                (True if protocol == 'p25_tdma' else False))
            self.decoder2 = repeater.p25_frame_assembler(
                '', 0, 0, False, True, False, decodequeue3, False, False)

            self.qsink = blocks.message_sink(gr.sizeof_char, self.decodequeue,
                                             False)

            self.float_conversion = blocks.short_to_float(1, 8192)

            self.connect(self.source, self.prefilter,
                         self.fm_demod)  #, (self.subtract,0))
            #self.connect(self.fm_demod, self.symbol_filter, self.demod_fsk4, self.slicer, self.decoder, self.imbe, self.float_conversion, self.sink)
            self.connect(self.fm_demod, self.symbol_filter, self.demod_fsk4,
                         self.slicer, self.decoder, self.float_conversion,
                         self.sink)
            self.connect(self.slicer, self.decoder2, self.qsink)
            #self.connect(self.fm_demod, self.avg, self.mult, (self.subtract,1))
        elif protocol == 'p25_cqpsk' or protocol == 'p25_cqpsk_tdma':
            self.symbol_deviation = symbol_deviation = 600.0
            self.resampler = blocks.multiply_const_cc(1.0)
            self.agc = analog.feedforward_agc_cc(1024, 1.0)
            self.symbol_filter_c = blocks.multiply_const_cc(1.0)

            gain_mu = 0.025
            if protocol == 'p25_cqpsk_tdma':
                symbol_rate = 6000
            else:
                symbol_rate = 4800
            omega = float(self.input_rate) / float(symbol_rate)
            gain_omega = 0.1 * gain_mu * gain_mu

            alpha = 0.04
            beta = 0.125 * alpha * alpha
            fmax = 1200  # Hz
            fmax = 2 * pi * fmax / float(self.input_rate)

            self.clock = repeater.gardner_costas_cc(omega, gain_mu, gain_omega,
                                                    alpha, beta, fmax, -fmax)
            self.diffdec = digital.diff_phasor_cc()
            self.to_float = blocks.complex_to_arg()
            self.rescale = blocks.multiply_const_ff((1 / (pi / 4)))

            # symbol slicer
            levels = [-2.0, 0.0, 2.0, 4.0]
            self.slicer = op25.fsk4_slicer_fb(levels)

            #self.imbe = repeater.vocoder(False, True, 0, "", 0, False)
            self.decodequeue3 = decodequeue3 = gr.msg_queue(2)
            self.decodequeue2 = decodequeue2 = gr.msg_queue(2)
            self.decodequeue = decodequeue = gr.msg_queue(10000)

            #self.demod_watcher = demod_watcher(decodequeue2, self.adjust_channel_offset)
            self.decoder = repeater.p25_frame_assembler(
                '', 0, 0, True, True, False, decodequeue2, True,
                (False if protocol == 'p25_cqpsk' else True))
            self.decoder2 = repeater.p25_frame_assembler(
                '', 0, 0, False, True, True, decodequeue3, False, False)

            #temp for debug
            #self.debug_sink = blocks.file_sink(1, '/dev/null')
            #self.connect(self.slicer, self.debug_sink)

            self.qsink = blocks.message_sink(gr.sizeof_char, self.decodequeue,
                                             False)

            self.float_conversion = blocks.short_to_float(1, 8192)

            self.connect(self.source, self.resampler, self.agc,
                         self.symbol_filter_c, self.clock, self.diffdec,
                         self.to_float, self.rescale, self.slicer,
                         self.decoder2, self.qsink)  #, (self.subtract,0))
            self.connect(self.slicer, self.decoder, self.float_conversion,
                         self.sink)
        elif protocol == 'provoice':
            fm_demod_gain = 0.6
            self.fm_demod = analog.quadrature_demod_cf(fm_demod_gain)

            self.resampler_in = filter.rational_resampler_fff(
                interpolation=48000,
                decimation=self.input_rate,
                taps=None,
                fractional_bw=None,
            )
            self.dsd = dsd.block_ff(dsd.dsd_FRAME_PROVOICE,
                                    dsd.dsd_MOD_AUTO_SELECT, 3, 0, False)
            self.out_squelch = analog.pwr_squelch_ff(-100, 0.01, 0, True)

            self.connect(self.source, self.fm_demod, self.resampler_in,
                         self.dsd, self.out_squelch, self.sink)
        elif protocol == 'dsd_p25':
            symbol_deviation = 600.0
            fm_demod_gain = 0.4  #self.input_rate / (2.0 * pi * symbol_deviation)
            self.fm_demod = analog.quadrature_demod_cf(fm_demod_gain)

            self.resampler_in = filter.rational_resampler_fff(
                interpolation=48000,
                decimation=self.input_rate,
                taps=None,
                fractional_bw=None,
            )
            self.dsd = dsd.block_ff(dsd.dsd_FRAME_P25_PHASE_1,
                                    dsd.dsd_MOD_AUTO_SELECT, 3, 3, False)

            self.connect(self.source, self.fm_demod, self.resampler_in,
                         self.dsd, self.sink)
        self.unlock()