示例#1
0
    def __init__(self, options, callback=None):
        """
	Hierarchical block for demodulating and deframing packets.

	The input is the complex modulated signal at baseband.
        Demodulated packets are sent to the handler.

        @param options: pass modulation options from higher layers (fft length, occupied tones, etc.)
        @param callback:  function of two args: ok, payload
        @type callback: ok: bool; payload: string
	"""
	gr.hier_block2.__init__(self, "ofdm_demod",
				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
				gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature


        self._rcvd_pktq = gr.msg_queue()          # holds packets from the PHY

        self._modulation = options.modulation
        self._fft_length = options.fft_length
        self._occupied_tones = options.occupied_tones
        self._cp_length = options.cp_length
        self._snr = options.snr

        # Use freq domain to get doubled-up known symbol for correlation in time domain
        zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0))
        ksfreq = known_symbols_4512_3[0:self._occupied_tones]
        for i in range(len(ksfreq)):
            if((zeros_on_left + i) & 1):
                ksfreq[i] = 0

        # hard-coded known symbols
        preambles = (ksfreq,)

        symbol_length = self._fft_length + self._cp_length
        self.ofdm_recv = ofdm_receiver(self._fft_length,
                                       self._cp_length,
                                       self._occupied_tones,
                                       self._snr, preambles,
                                       options.log)

        mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256}
        arity = mods[self._modulation]
        
        rot = 1
        if self._modulation == "qpsk":
            rot = (0.707+0.707j)

        # FIXME: pass the constellation objects instead of just the points
        if(self._modulation.find("psk") >= 0):
            constel = psk.psk_constellation(arity)
            rotated_const = map(lambda pt: pt * rot, constel.points())
        elif(self._modulation.find("qam") >= 0):
            constel = qam.qam_constellation(arity)
            rotated_const = map(lambda pt: pt * rot, constel.points())
        #print rotated_const

        phgain = 0.25
        frgain = phgain*phgain / 4.0
        self.ofdm_demod = digital_swig.ofdm_frame_sink(rotated_const, range(arity),
                                                       self._rcvd_pktq,
                                                       self._occupied_tones,
                                                       phgain, frgain)

        self.connect(self, self.ofdm_recv)
        self.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0))
        self.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1))

        # added output signature to work around bug, though it might not be a bad
        # thing to export, anyway
        self.connect(self.ofdm_recv.chan_filt, self)

        if options.log:
            self.connect(self.ofdm_demod,
                         gr.file_sink(gr.sizeof_gr_complex*self._occupied_tones,
                                      "ofdm_frame_sink_c.dat"))
        else:
            self.connect(self.ofdm_demod,
                         gr.null_sink(gr.sizeof_gr_complex*self._occupied_tones))

        if options.verbose:
            self._print_verbage()
            
        self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
示例#2
0
    def __init__(self, options, msgq_limit=2, pad_for_usrp=True):
        """
	Hierarchical block for sending packets

        Packets to be sent are enqueued by calling send_pkt.
        The output is the complex modulated signal at baseband.

        @param options: pass modulation options from higher layers (fft length, occupied tones, etc.)
        @param msgq_limit: maximum number of messages in message queue
        @type msgq_limit: int
        @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
        """

	gr.hier_block2.__init__(self, "ofdm_mod",
				gr.io_signature(0, 0, 0),       # Input signature
				gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature

        self._pad_for_usrp = pad_for_usrp
        self._modulation = options.modulation
        self._fft_length = options.fft_length
        self._occupied_tones = options.occupied_tones
        self._cp_length = options.cp_length

        win = [] #[1 for i in range(self._fft_length)]

        # Use freq domain to get doubled-up known symbol for correlation in time domain
        zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0))
        ksfreq = known_symbols_4512_3[0:self._occupied_tones]
        for i in range(len(ksfreq)):
            if((zeros_on_left + i) & 1):
                ksfreq[i] = 0

        # hard-coded known symbols
        preambles = (ksfreq,)
                
        padded_preambles = list()
        for pre in preambles:
            padded = self._fft_length*[0,]
            padded[zeros_on_left : zeros_on_left + self._occupied_tones] = pre
            padded_preambles.append(padded)
            
        symbol_length = options.fft_length + options.cp_length
        
        mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256}
        arity = mods[self._modulation]
        
        rot = 1
        if self._modulation == "qpsk":
            rot = (0.707+0.707j)
            
        # FIXME: pass the constellation objects instead of just the points
        if(self._modulation.find("psk") >= 0):
            constel = psk.psk_constellation(arity)
            rotated_const = map(lambda pt: pt * rot, constel.points())
        elif(self._modulation.find("qam") >= 0):
            constel = qam.qam_constellation(arity)
            rotated_const = map(lambda pt: pt * rot, constel.points())
        #print rotated_const
        self._pkt_input = digital_swig.ofdm_mapper_bcv(rotated_const,
                                                       msgq_limit,
                                                       options.occupied_tones,
                                                       options.fft_length)
        
        self.preambles = digital_swig.ofdm_insert_preamble(self._fft_length,
                                                           padded_preambles)
        self.ifft = gr.fft_vcc(self._fft_length, False, win, True)
        self.cp_adder = digital_swig.ofdm_cyclic_prefixer(self._fft_length,
                                                          symbol_length)
        self.scale = gr.multiply_const_cc(1.0 / math.sqrt(self._fft_length))
        
        self.connect((self._pkt_input, 0), (self.preambles, 0))
        self.connect((self._pkt_input, 1), (self.preambles, 1))
        self.connect(self.preambles, self.ifft, self.cp_adder, self.scale, self)
        
        if options.verbose:
            self._print_verbage()

        if options.log:
            self.connect(self._pkt_input, gr.file_sink(gr.sizeof_gr_complex*options.fft_length,
                                                       "ofdm_mapper_c.dat"))
            self.connect(self.preambles, gr.file_sink(gr.sizeof_gr_complex*options.fft_length,
                                                      "ofdm_preambles.dat"))
            self.connect(self.ifft, gr.file_sink(gr.sizeof_gr_complex*options.fft_length,
                                                 "ofdm_ifft_c.dat"))
            self.connect(self.cp_adder, gr.file_sink(gr.sizeof_gr_complex,
                                                     "ofdm_cp_adder_c.dat"))
示例#3
0
    def __init__(self, options, msgq_limit=2, pad_for_usrp=True):
        """
	Hierarchical block for sending packets

        Packets to be sent are enqueued by calling send_pkt.
        The output is the complex modulated signal at baseband.

        @param options: pass modulation options from higher layers (fft length, occupied tones, etc.)
        @param msgq_limit: maximum number of messages in message queue
        @type msgq_limit: int
        @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
        """

	gr.hier_block2.__init__(self, "ofdm_mod",
				gr.io_signature(0, 0, 0),       # Input signature
				gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature

        self._pad_for_usrp = pad_for_usrp
        self._modulation = options.modulation
        self._fft_length = options.fft_length
        self._occupied_tones = options.occupied_tones
        self._cp_length = options.cp_length

        win = [] #[1 for i in range(self._fft_length)]

        # Use freq domain to get doubled-up known symbol for correlation in time domain
        zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0))
        ksfreq = known_symbols_4512_3[0:self._occupied_tones]
        for i in range(len(ksfreq)):
            if((zeros_on_left + i) & 1):
                ksfreq[i] = 0

        # hard-coded known symbols
        preambles = (ksfreq,)

#	print preambles
        padded_preambles = list()
        for pre in preambles:
            padded = self._fft_length*[0,]
            padded[zeros_on_left : zeros_on_left + self._occupied_tones] = pre
            padded_preambles.append(padded)
#	print
#	print padded_preambles
            
        symbol_length = options.fft_length + options.cp_length
        
        mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256}
        arity = mods[self._modulation]
        
        rot = 1
        if self._modulation == "qpsk":
            rot = (0.707+0.707j)
            
        # FIXME: pass the constellation objects instead of just the points
        if(self._modulation.find("psk") >= 0):
            constel = psk.psk_constellation(arity)
            rotated_const = map(lambda pt: pt * rot, constel.points())
        elif(self._modulation.find("qam") >= 0):
            constel = qam.qam_constellation(arity)
            rotated_const = map(lambda pt: pt * rot, constel.points())
        #print rotated_const
        self._pkt_input = digital_swig.ofdm_mapper_bcv(rotated_const,
                                                       msgq_limit,
                                                       options.occupied_tones,
                                                       options.fft_length)
        
        self.preambles = digital_swig.ofdm_insert_preamble(self._fft_length,
                                                           padded_preambles)
        self.ifft = gr.fft_vcc(self._fft_length, False, win, True)
        self.cp_adder = digital_swig.ofdm_cyclic_prefixer(self._fft_length,
                                                          symbol_length)
        self.scale = gr.multiply_const_cc(1.0 / math.sqrt(self._fft_length))
        self.v2s = gr.vector_to_stream(gr.sizeof_gr_complex, self._fft_length+self._cp_length)
        self.connect((self._pkt_input, 0), (self.preambles, 0))
        self.connect((self._pkt_input, 1), (self.preambles, 1))
        self.connect((self._pkt_input, 2), (self.preambles, 2))
        self.connect(self.preambles, self.ifft, self.cp_adder)
        self.connect((self.preambles, 1), gr.null_sink(gr.sizeof_char))
        self.connect((self.preambles, 2), (self.cp_adder, 1))
        self.connect(self.cp_adder, self.scale, self)
        
        if options.verbose:
            self._print_verbage()

        if options.log:
            self.connect(self._pkt_input, gr.file_sink(gr.sizeof_gr_complex*options.fft_length,
                                                       "ofdm_mapper_c.dat"))
            self.connect(self.preambles, gr.file_sink(gr.sizeof_gr_complex*options.fft_length,
                                                      "ofdm_preambles.dat"))
            self.connect((self.preambles, 2), gr.file_sink(gr.sizeof_char, "ofdm_preambles_debug.dat"))
            self.connect(self.ifft, gr.file_sink(gr.sizeof_gr_complex*options.fft_length,
                                                 "ofdm_ifft_c.dat"))
            self.connect(self.cp_adder, gr.file_sink(gr.sizeof_gr_complex,
                                                     "ofdm_cp_adder_c.dat"))
示例#4
0
    def __init__(self, options, callback=None):
        """
	Hierarchical block for demodulating and deframing packets.

	The input is the complex modulated signal at baseband.
        Demodulated packets are sent to the handler.

        @param options: pass modulation options from higher layers (fft length, occupied tones, etc.)
        @param callback:  function of two args: ok, payload
        @type callback: ok: bool; payload: string
	"""
	gr.hier_block2.__init__(self, "ofdm_demod",
				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
				gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature


        self._rcvd_pktq = gr.msg_queue()          # holds packets from the PHY

        self._modulation = options.modulation
        self._fft_length = options.fft_length
        self._occupied_tones = options.occupied_tones
        self._cp_length = options.cp_length
        self._snr = options.snr
        self._bandwidth = options.bandwidth
        self._precoding = False #options.precoding

        # Use freq domain to get doubled-up known symbol for correlation in time domain
        zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0))
        ksfreq = known_symbols_4512_3[0:self._occupied_tones]
        for i in range(len(ksfreq)):
            if((zeros_on_left + i) & 1):
                ksfreq[i] = 0

        # hard-coded known symbols
        preambles = (ksfreq,)

        symbol_length = self._fft_length + self._cp_length
        self.ofdm_recv = ofdm_receiver(self._bandwidth,
                                       self._fft_length,
                                       self._cp_length,
                                       self._occupied_tones,
                                       self._snr, preambles,
                                       options.log, options.mode)

        mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256}
        arity = mods[self._modulation]
        
        rot = 1
        if self._modulation == "qpsk":
            rot = (0.707+0.707j)

        # FIXME: pass the constellation objects instead of just the points
        if(self._modulation.find("psk") >= 0):
            constel = psk.psk_constellation(arity)
            rotated_const = map(lambda pt: pt * rot, constel.points())
        elif(self._modulation.find("qam") >= 0):
            constel = qam.qam_constellation(arity)
            rotated_const = map(lambda pt: pt * rot, constel.points())
        #print rotated_const

        phgain = 0.25
        frgain = phgain*phgain / 4.0
        self.ofdm_demod = digital_swig.ofdm_frame_sink(rotated_const, range(arity),
                                                       self._rcvd_pktq,
                                                       self._occupied_tones,
                                                       phgain, frgain)

        self.connect(self, self.ofdm_recv)
        self.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0))
        self.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1))
        if self._precoding:
            self.connect((self.ofdm_recv, 2), (self.ofdm_demod, 2))    # output CFO value

        # added output signature to work around bug, though it might not be a bad
        # thing to export, anyway
        self.connect(self.ofdm_recv.chan_filt, self)

        if options.log:
            self.connect(self.ofdm_demod,
                         gr.file_sink(gr.sizeof_gr_complex*self._occupied_tones,
                                      "ofdm_frame_sink_c.dat"))
        else:
            self.connect(self.ofdm_demod,
                         gr.null_sink(gr.sizeof_gr_complex*self._occupied_tones))

        if options.verbose:
            self._print_verbage()
            
        self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
示例#5
0
    def __init__(self, options, msgq_limit=2, pad_for_usrp=True):
	"""
	Hierarchical block for sending packets

	Packets to be sent are enqueued by calling send_pkt.
	The output is the complex modulated signal at baseband.

	@param options: pass modulation options from higher layers (fft length, occupied tones, etc.)
        @param msgq_limit: maximum number of messages in message queue
        @type msgq_limit: int
        @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
        """

	gr.hier_block2.__init__(self, "ofdm_mod",
				gr.io_signature(0, 0, 0),       # Input signature
				gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature

        self._pad_for_usrp = pad_for_usrp
        self._modulation = options.modulation
        self._fft_length = options.fft_length
        self._occupied_tones = options.occupied_tones
        self._cp_length = options.cp_length

	# apurv++ start #
	self._id = options.id
        self._fec_n = options.fec_n
        self._fec_k = options.fec_k
	self._batch_size = options.batch_size
	self._ack = options.ack

        if(self._fec_n < self._fec_k):
            print "ERROR: K > N in FEC!\n"
            exit(0);
	# apurv++ end #

        win = [] #[1 for i in range(self._fft_length)]

        # Use freq domain to get doubled-up known symbol for correlation in time domain
        zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0))

        # apurv: use the preamble as a function of hop number #
        #ksfreq = known_symbols_4512_3[0:self._occupied_tones]
        start_index = (options.hop) * self._occupied_tones
        ksfreq = known_symbols_4512_3[start_index:start_index + self._occupied_tones]

        # allow another full preamble (no intermediate 0s for accurate channel estimate/snr measurement)
        preamble2_offset = 10*self._occupied_tones;
        ksfreq2 = known_symbols_4512_3[preamble2_offset:preamble2_offset+self._occupied_tones]

	'''
	# inserting zeros in every other frequency bin #
        for i in range(len(ksfreq)):
            if((zeros_on_left + i) & 1):
                ksfreq[i] = 0
	'''

        # hard-coded known symbols
        preambles = (ksfreq, ksfreq2, ksfreq2)
                
        padded_preambles = list()
        for pre in preambles:
            padded = self._fft_length*[0,]
            padded[zeros_on_left : zeros_on_left + self._occupied_tones] = pre
            padded_preambles.append(padded)
            
        symbol_length = options.fft_length + options.cp_length
        
        mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256}

        hdr_rot = 1
        hdr_arity = mods["bpsk"]
        hdr_constel = psk.psk_constellation(hdr_arity)
        hdr_rotated_const = map(lambda pt: pt * hdr_rot, hdr_constel.points())

        data_rot = 1
        data_arity = mods[self._modulation]
        if self._modulation == "qpsk":
            data_rot = (0.707+0.707j)
        if(self._modulation.find("psk") >= 0):
            data_constel = psk.psk_constellation(data_arity)
            data_rotated_const = map(lambda pt: pt * data_rot, data_constel.points())
        elif(self._modulation.find("qam") >= 0):
            data_constel = qam.qam_constellation(data_arity)
            data_rotated_const = map(lambda pt: pt * data_rot, data_constel.points())
        self._bits_per_symbol = int(math.log(mods[self._modulation], 2))                # just a useless parameter now #

        self._pkt_input = digital_swig.ofdm_mapper_bcv(hdr_rotated_const, data_rotated_const, 
					     padded_preambles,msgq_limit,
                                             options.occupied_tones, options.fft_length,
					     options.tdma, options.proto, options.ack,
                                             options.id, options.src,
                                             options.batch_size,
					     options.dst_id,
					     options.fec_n, options.fec_k)	

        self.ifft = gr.fft_vcc(self._fft_length, False, win, True)

        self.cp_adder = digital_swig.ofdm_cyclic_prefixer(self._fft_length, symbol_length)
        self.scale = gr.multiply_const_cc(1.0 / math.sqrt(self._fft_length))

        self.burst_tagger = gr.burst_tagger(gr.sizeof_gr_complex)					# 1 sample
	use_burst_tagger = 1

        manual = options.tx_manual
        if manual == 0:
           if use_burst_tagger == 0:
	       self.connect((self._pkt_input, 0), self.ifft, self.cp_adder, self.scale, self)
	   else:
	       # some burst tagger connections #
	       self.connect((self._pkt_input, 0), self.ifft, self.cp_adder, self.burst_tagger, self.scale, self)
               self.connect((self._pkt_input, 1), (self.cp_adder, 1), (self.burst_tagger,1))   # Connect Apurv's trigger data to the burst tagger
	       self.connect((self._pkt_input, 2), (self.cp_adder, 2))                          # CDD

        elif manual == 1:
	   # punt the pkt_input and use file source # 
           self.connect(gr.file_source(gr.sizeof_gr_complex*options.fft_length, "fwd_tx_data.dat"), self.cp_adder, self.scale, self)


	self.connect(self.scale, gr.file_sink(gr.sizeof_gr_complex, "ofdm_fwd.dat"))

        if options.verbose:
            self._print_verbage()

        if options.log:
            self.connect(self._pkt_input, gr.file_sink(gr.sizeof_gr_complex*options.fft_length,
                                                       "ofdm_mapper_c.dat"))
            self.connect(self.ifft, gr.file_sink(gr.sizeof_gr_complex*options.fft_length,
                                                 "ofdm_ifft_c.dat"))
            self.connect(self.cp_adder, gr.file_sink(gr.sizeof_gr_complex,
                                                     "ofdm_cp_adder_c.dat"))

	#self.connect(self.cp_adder, gr.file_sink(gr.sizeof_gr_complex, "ofdm_cp_adder_c.dat"))
	self.connect(self._pkt_input, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, "symbols_src.dat"))
	self.connect((self._pkt_input, 3), gr.file_sink(gr.sizeof_char, "timing.dat"))
        self.connect((self._pkt_input, 4), gr.file_sink(gr.sizeof_char*options.fft_length, "timing_src.dat"))
示例#6
0
    def __init__(self, options, callback=None, fwd_callback=None):
        """
	Hierarchical block for demodulating and deframing packets.

	The input is the complex modulated signal at baseband.
        Demodulated packets are sent to the handler.

        @param options: pass modulation options from higher layers (fft length, occupied tones, etc.)
        @param callback:  function of two args: ok, payload
        @type callback: ok: bool; payload: string
		"""
	gr.hier_block2.__init__(self, "ofdm_demod",
				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
				gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature


        self._rcvd_pktq = gr.msg_queue()          # holds packets from the PHY

	# apurv++ queues # 
	self._out_pktq = gr.msg_queue()
	
        self._modulation = options.modulation
        self._fft_length = options.fft_length
        self._occupied_tones = options.occupied_tones
        self._cp_length = options.cp_length
        self._snr = options.snr

        # apurv++ start #
	self._id = options.id
        self._fec_n = options.fec_n
        self._fec_k = options.fec_k
        self._batch_size = options.batch_size
	self._threshold = options.threshold
	self._size = options.size
        if(self._fec_n < self._fec_k):
            print "ERROR: K > N in FEC!\n"
            exit(0);
        # apurv++ end #

        # Use freq domain to get doubled-up known symbol for correlation in time domain
        zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0))

	# apurv: use the preamble as a function of hop number #
        #ksfreq = known_symbols_4512_3[0:self._occupied_tones]
	start_index = (options.hop-1) * self._occupied_tones
	ksfreq = known_symbols_4512_3[start_index:start_index + self._occupied_tones]

	# allow another full preamble (no intermediate 0s for accurate channel estimate/snr measurement)
	preamble2_offset = 10*self._occupied_tones;
	ksfreq2 = known_symbols_4512_3[preamble2_offset:preamble2_offset+self._occupied_tones]

	'''
	# inserting zeros in every other frequency bin #
        for i in range(len(ksfreq)):
            if((zeros_on_left + i) & 1):
                ksfreq[i] = 0
	'''

        # hard-coded known symbols
        preambles = (ksfreq, ksfreq2) #, ksfreq2, ksfreq2, ksfreq2)			# coarse_offset from 1st preamble, equalizer from the rest
        
        symbol_length = self._fft_length + self._cp_length
        self.ofdm_recv = ofdm_receiver(self._fft_length, self._cp_length,
                                       self._occupied_tones, self._snr, preambles,
				       self._threshold, options, options.log)

        mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256}

	# apurv: support for other modulations, pass 2 constellation objects #
	hdr_rot = 1
 	hdr_arity = mods["bpsk"]
	hdr_constel = psk.psk_constellation(hdr_arity)
	hdr_rotated_const = map(lambda pt: pt * hdr_rot, hdr_constel.points())	


	data_rot = 1
	data_arity = mods[self._modulation]
	if self._modulation == "qpsk":
            data_rot = (0.707+0.707j)
        if(self._modulation.find("psk") >= 0):
            data_constel = psk.psk_constellation(data_arity)
            data_rotated_const = map(lambda pt: pt * data_rot, data_constel.points())
        elif(self._modulation.find("qam") >= 0):
            data_constel = qam.qam_constellation(data_arity)
            data_rotated_const = map(lambda pt: pt * data_rot, data_constel.points())
	self._bits_per_symbol = int(math.log(mods[self._modulation], 2))		# just a useless parameter now #

        phgain = 0.25
        frgain = phgain*phgain / 4.0

	# preambles contains all the 'preambles' used in frame_acquisition + 1 (for snr calculation)
	preambles = (ksfreq, ksfreq2, ksfreq2) #, ksfreq2, ksfreq2, ksfreq2)						# send the extra symbol for snr calculation
        self.ofdm_demod = digital_swig.ofdm_frame_sink(hdr_rotated_const, range(hdr_arity),
					     data_rotated_const, range(data_arity),
					     preambles,
                                             self._rcvd_pktq, self._out_pktq,
                                             self._occupied_tones, self._fft_length, options.proto, options.ack,
                                             phgain, frgain, self._id,
                                             self._batch_size, 
                                             self._size, self._fec_n, self._fec_k)

        self.connect(self, self.ofdm_recv)

	manual = options.rx_manual								# apurv++: manual testing flag
	if manual==0:
           	self.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0))
           	self.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1))
   	   	self.connect((self.ofdm_recv, 2), (self.ofdm_demod, 2))			# apurv++, hestimates #
	elif manual==1: 
           	self.connect(gr.file_source(gr.sizeof_gr_complex*self._occupied_tones, "out-tx.dat"), (self.ofdm_demod, 0))
           	self.connect(gr.file_source(gr.sizeof_char, "out-timing.dat"), (self.ofdm_demod, 1))

        # added output signature to work around bug, though it might not be a bad thing to export, anyway #
        self.connect(self.ofdm_recv.chan_filt, self)

	'''	
	# sink some stuff #
	self.connect((self.ofdm_recv, 0), gr.null_sink(gr.sizeof_gr_complex*self._occupied_tones))		# symbols 
	self.connect((self.ofdm_recv, 1), gr.null_sink(gr.sizeof_char))						# timing
	self.connect((self.ofdm_recv, 2), gr.null_sink(gr.sizeof_gr_complex*self._occupied_tones))		# hestimates
	'''

        if options.verbose:
            self._print_verbage()

        self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback, self._fec_n, self._fec_k, self._bits_per_symbol, self._size)
	self._watcher_fwd = _queue_watcher_thread(self._out_pktq, fwd_callback)			# apurv++
示例#7
0
    def __init__(self, rx_callback, options):

	gr.hier_block2.__init__(self, "receive_path",
				gr.io_signature(1, 1, gr.sizeof_gr_complex),
				gr.io_signature(0, 0, 0))


        options = copy.copy(options)    # make a copy so we can destructively modify

        self._verbose     = options.verbose
        self._log         = options.log
        self._rx_callback = rx_callback      # this callback is fired when there's a packet available

        self._rcvd_pktq = gr.msg_queue()          # holds packets from the PHY

        self._modulation = options.modulation
        self._fft_length = options.fft_length
        self._occupied_tones = options.occupied_tones
        self._cp_length = options.cp_length
        self._snr = options.snr


        # Use freq domain to get doubled-up known symbol for correlation in time domain
        zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0))

        preamble_sequence = known_symbols_4512_3[0:self._occupied_tones]
        training_sequence = ( known_symbols_4512_3[self._occupied_tones:self._occupied_tones*2], \
                            known_symbols_4512_3[self._occupied_tones*2:self._occupied_tones*3] )

        for i in range(len(preamble_sequence)):
            if((zeros_on_left + i) & 1):
                preamble_sequence[i] = 0

        # hard-coded known symbols
        preambles = (preamble_sequence,)

        symbol_length = self._fft_length + self._cp_length
        self.ofdm_recv = ofdm_receiver(self._fft_length,
                                       self._cp_length,
                                       self._occupied_tones,
                                       self._snr, 
                                       preambles,
                                       training_sequence,
                                       options.log)

        mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256}
        arity = mods[self._modulation]
        
        rot = 1
        if self._modulation == "qpsk":
            rot = (0.707+0.707j)

        # FIXME: pass the constellation objects instead of just the points
        if(self._modulation.find("psk") >= 0):
            constel = psk.psk_constellation(arity)
            rotated_const = map(lambda pt: pt * rot, constel.points())
        elif(self._modulation.find("qam") >= 0):
            constel = qam.qam_constellation(arity)
            rotated_const = map(lambda pt: pt * rot, constel.points())
        #print rotated_const

        phgain = 0.25
        frgain = phgain*phgain / 4.0
        self.ofdm_demod = gtlib.ofdm_frame_sink(rotated_const, range(arity),
                                                       self._rcvd_pktq,
                                                       self._occupied_tones,
                                                       phgain, frgain)


        """
        # receiver
        self.ofdm_rx = ofdm.ofdm_demod(options,
                                          callback=self._rx_callback)
        """

        # Carrier Sensing Blocks
        alpha = 0.001
        thresh = 30   # in dB, will have to adjust
        self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)


        self.connect(self, self.ofdm_recv)
        self.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0))
        self.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1))

        # added output signature to work around bug, though it might not be a bad
        # thing to export, anyway
        self.connect(self.ofdm_recv.chan_filt, self.probe)

        if options.log:
            self.connect(self.ofdm_demod,
                         gr.file_sink(gr.sizeof_gr_complex*self._occupied_tones,
                                      "ofdm_frame_sink_c.dat"))
        else:
            self.connect(self.ofdm_demod,
                         gr.null_sink(gr.sizeof_gr_complex*self._occupied_tones))


        # Display some information about the setup
        if self._verbose:
            self._print_verbage()

        self._watcher = _queue_watcher_thread(self._rcvd_pktq, self._rx_callback)