def gen_framer_info(modulation): mods = { "bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256 } arity = mods[modulation] rot = 1 if modulation == "qpsk": rot = (0.707 + 0.707j) # FIXME: pass the constellation objects instead of just the points if (modulation.find("psk") >= 0): constel = psk.psk_constellation(arity) rotated_const = map(lambda pt: pt * rot, constel.points()) elif (modulation.find("qam") >= 0): constel = qam.qam_constellation(arity) rotated_const = map(lambda pt: pt * rot, constel.points()) return rotated_const
def gen_framer_info(modulation): mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256} arity = mods[modulation] rot = 1 if modulation == "qpsk": rot = (0.707+0.707j) # FIXME: pass the constellation objects instead of just the points if(modulation.find("psk") >= 0): constel = psk.psk_constellation(arity) rotated_const = map(lambda pt: pt * rot, constel.points()) elif(modulation.find("qam") >= 0): constel = qam.qam_constellation(arity) rotated_const = map(lambda pt: pt * rot, constel.points()) return rotated_const
def __init__(self, options, msgq_limit=2, pad_for_usrp=True, coder=None): """ 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.coder = coder 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 self._pkt_accum = None self._accumulated_pkts = 0 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"))
def __init__(self, options, callback=None, coder=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.coder = coder 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, self.coder)
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 self._carrier_map = options.carrier_map # linklab self._nc_filter = options.nc_filter # linklab 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) # linklab, sanity check: check carrier_map if ((4 * len(self._carrier_map) != self._occupied_tones) & (self._carrier_map != 'FFFF')): print( "Error: --carrier-map size %d is no equal to # of --occupied-tones" ) % (4 * (len(self._carrier_map))) raise SystemExit # check occupied_tones and cp_length if ((self._fft_length < self._occupied_tones) | (self._fft_length < self._cp_length)): print( "Error: --occupied-tones or --cp-length specified must not biger than --fft-length" ) raise SystemExit # linklab, get subcarrier allocation from carrier_map self.calc_carrier_map(self._carrier_map) 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()) self._pkt_input = gr_papyrus.ofdm_mapper_bcv(rotated_const, msgq_limit, options.occupied_tones, options.fft_length, self._carrier_map) self.preambles = gr_papyrus.ofdm_insert_preamble( self._fft_length, padded_preambles) if VERBOSE: print "%s:%s" % (os.path.basename(__file__), __name__) print "**** (ofdm_mod) padded_preamble", padded_preambles self.ifft = fft.fft_vcc(self._fft_length, False, win, True) self.cp_adder = digital.ofdm_cyclic_prefixer(self._fft_length, symbol_length) self.scale = blocks.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"))
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._carrier_map = options.carrier_map # linklab self._nc_filter = options.nc_filter # linklab # linklab, sanity check carrier_map if ((4 * len(self._carrier_map) != self._occupied_tones) & (self._carrier_map != 'FFFF')): print( "Error: --carrier-map size %d is no equal to # of --occupied-tones" ) % (4 * (len(self._carrier_map))) raise SystemExit # check occupied_tones and cp_length if ((self._fft_length < self._occupied_tones) | (self._fft_length < self._cp_length)): print( "Error: --occupied-tones or --cp-length specified must not biger than --fft-length" ) raise SystemExit # 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, ) # linklab, get subcarrier allocation from carrier_map self.calc_carrier_map(self._carrier_map) symbol_length = self._fft_length + self._cp_length # linklab, add carrier_map_bin 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._carrier_map_bin, self._nc_filter, #linklab options.log) if VERBOSE: print "%s:%s" % (os.path.basename(__file__), __name__) print "(ofdm_demod) preambles= ", preambles 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 = gr_papyrus.ofdm_frame_sink( rotated_const, range(arity), self._rcvd_pktq, self._fft_length, self._occupied_tones, self._carrier_map_bin_str, 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, blocks.null_sink(gr.sizeof_gr_complex * self._occupied_tones)) if options.verbose: self._print_verbage() # linklab, add ofdm_recv to queue watcher #self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback), self._watcher = _queue_watcher_thread(self._rcvd_pktq, self.ofdm_recv, callback)
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. Args: options: pass modulation options from higher layers (fft length, occupied tones, etc.) msgq_limit: maximum number of messages in message queue (int) 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.ofdm_mapper_bcv(rotated_const, msgq_limit, options.occupied_tones, options.fft_length) self.preambles = digital.ofdm_insert_preamble(self._fft_length, padded_preambles) self.ifft = fft.fft_vcc(self._fft_length, False, win, True) self.cp_adder = digital.ofdm_cyclic_prefixer(self._fft_length, symbol_length) self.scale = blocks.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) self.nuller = blocks.null_sink(gr.sizeof_char) self.v2s = blocks.vector_to_stream(gr.sizeof_gr_complex*1,self._fft_length) self.connect((self._pkt_input, 0), self.v2s, self) self.connect((self._pkt_input, 1), self.nuller) if options.verbose: self._print_verbage() if options.log: self.connect(self._pkt_input, blocks.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_mapper_c.dat")) self.connect(self.preambles, blocks.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_preambles.dat")) self.connect(self.ifft, blocks.file_sink(gr.sizeof_gr_complex*options.fft_length, "ofdm_ifft_c.dat")) self.connect(self.cp_adder, blocks.file_sink(gr.sizeof_gr_complex, "ofdm_cp_adder_c.dat"))
def __init__(self, options, num_channels, 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. Args: options: pass modulation options from higher layers (fft length, occupied tones, etc.) callback: function of two args: ok, payload (ok: bool; payload: string) """ self.rx_channels = num_channels#len(options.args.split(',')) gr.hier_block2.__init__(self, "ofdm_demod", gr.io_signaturev(self.rx_channels, self.rx_channels, gen_multiple_ios(self.rx_channels,1) ), # Input signature gr.io_signaturev(self.rx_channels, self.rx_channels, gen_multiple_ios(self.rx_channels,options.occupied_tones) )) #[gr.sizeof_gr_complex*options.occupied_tones, gr.sizeof_gr_complex*options.occupied_tones])) # Output signature self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY from all receive channels 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.rx_channels, 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 = ofdm.ofdm_frame_sink(rotated_const, range(arity),self._rcvd_pktq,self._occupied_tones,phgain, frgain, 3) self.ofdm_demod = ofdm.ofdm_mrx_frame_sink(rotated_const, range(arity),self._rcvd_pktq,self._occupied_tones,phgain, frgain, self.rx_channels) self.mdb = blocks.message_debug() ############# CONNECTIONS ############## # Connect ofdm_receiver flag to ofdm framer flag self.connect((self.ofdm_recv, 1), (self.ofdm_demod, 0)) # Connect flag from 1st chain only # Connect frame sink msg port to debugger self.msg_connect((self.ofdm_demod, 'packet'), (self.mdb,'print')) # Connect remaining data ports port = 0 for c in range(self.rx_channels): # Connect USRP's to channel filters self.connect((self,c), (self.ofdm_recv,c)) # Add null sink object_name_ns = 'null_sink_'+str(c) setattr(self, object_name_ns, blocks.null_sink(gr.sizeof_char*1)) # Connect ofdm_receiver to ofdm framer self.connect((self.ofdm_recv, port), (self.ofdm_demod, c+1)) # Occupied tones # Connect extra port(s) to null since we dont need it now self.connect((self.ofdm_recv, port+1), (getattr(self,object_name_ns), 0)) port = port + 2 # Connect equalized signals to output self.connect((self.ofdm_demod, c), (self, c)) # 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,0)) ############## ############## if options.log: self.connect(self.ofdm_demod, blocks.file_sink(gr.sizeof_gr_complex*self._occupied_tones, "ofdm_frame_sink_c.dat")) else: self.connect(self.ofdm_demod, blocks.null_sink(gr.sizeof_gr_complex*self._occupied_tones)) if options.verbose: self._print_verbage() self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
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_signature2(2, 2, gr.sizeof_gr_complex, gr.sizeof_float)) # 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._use_coding = options.coding self._coding_block_length = options.block_length self._adaptive_coding_enabled = options.adaptive_coding self._rfcenterfreq = options.rx_freq self._bandwidth = options.my_bandwidth self._logging = lincolnlog.LincolnLog(__name__) self._expected_pkt_size = options.expected_pkt_size self._vcsthresh = options.vcsthresh # if backoff is negative, calculate backoff value from options.expected_pkt_size if options.backoff < 0: self._vcsbackoff = predict_pack_size( self._expected_pkt_size, self._use_coding, self._modulation, self._occupied_tones, self._cp_length, self._fft_length) # otherwise use the value in options.backoff else: self._vcsbackoff = options.backoff # 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, self._vcsthresh, self._vcsbackoff, options.log, options.coding) 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_ll.ofdm_frame_sink(rotated_const, range(arity), self._rcvd_pktq, self._occupied_tones, phgain, frgain) self.nsink = gr.null_sink(gr.sizeof_float) 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)) # Output the VCS signal so that the MAC layer knows when the # channel is occupied #self.connect((self.ofdm_recv, 2), gr.null_sink(gr.sizeof_float)) self.connect((self.ofdm_recv, 2), (self, 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, 0)) 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, self._use_coding, self._coding_block_length, self._adaptive_coding_enabled, self._rfcenterfreq, self._bandwidth, self._logging)
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 self._carrier_map = options.carrier_map # linklab self._nc_filter = options.nc_filter # linklab 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) # linklab, sanity check: check carrier_map if ((4*len(self._carrier_map) != self._occupied_tones) & (self._carrier_map != 'FFFF')): print("Error: --carrier-map size %d is no equal to # of --occupied-tones") %(4*(len(self._carrier_map))) raise SystemExit # check occupied_tones and cp_length if ((self._fft_length < self._occupied_tones) | (self._fft_length < self._cp_length)): print("Error: --occupied-tones or --cp-length specified must not biger than --fft-length") raise SystemExit # linklab, get subcarrier allocation from carrier_map self.calc_carrier_map(self._carrier_map) 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()) self._pkt_input = gr_papyrus.ofdm_mapper_bcv(rotated_const, msgq_limit, options.occupied_tones, options.fft_length,self._carrier_map) self.preambles = gr_papyrus.ofdm_insert_preamble(self._fft_length, padded_preambles) if VERBOSE: print "%s:%s" %(os.path.basename(__file__), __name__) print "**** (ofdm_mod) padded_preamble", padded_preambles self.ifft = fft.fft_vcc(self._fft_length, False, win, True) self.cp_adder = digital.ofdm_cyclic_prefixer(self._fft_length, symbol_length) self.scale = blocks.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"))
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._carrier_map = options.carrier_map # linklab self._nc_filter = options.nc_filter # linklab # linklab, sanity check carrier_map if ((4*len(self._carrier_map) != self._occupied_tones) & (self._carrier_map != 'FFFF')): print("Error: --carrier-map size %d is no equal to # of --occupied-tones") %(4*(len(self._carrier_map))) raise SystemExit # check occupied_tones and cp_length if ((self._fft_length < self._occupied_tones) | (self._fft_length < self._cp_length)): print("Error: --occupied-tones or --cp-length specified must not biger than --fft-length") raise SystemExit # 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,) # linklab, get subcarrier allocation from carrier_map self.calc_carrier_map(self._carrier_map) symbol_length = self._fft_length + self._cp_length # linklab, add carrier_map_bin 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._carrier_map_bin, self._nc_filter, #linklab options.log) if VERBOSE: print "%s:%s" %(os.path.basename(__file__), __name__) print "(ofdm_demod) preambles= ", preambles 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 = gr_papyrus.ofdm_frame_sink(rotated_const, range(arity), self._rcvd_pktq, self._fft_length, self._occupied_tones, self._carrier_map_bin_str, 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, blocks.null_sink(gr.sizeof_gr_complex*self._occupied_tones)) if options.verbose: self._print_verbage() # linklab, add ofdm_recv to queue watcher #self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback), self._watcher = _queue_watcher_thread(self._rcvd_pktq, self.ofdm_recv, callback)
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_signature2(2, 2, gr.sizeof_gr_complex, gr.sizeof_float)) # 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._use_coding = options.coding self._coding_block_length = options.block_length self._adaptive_coding_enabled = options.adaptive_coding self._rfcenterfreq = options.rx_freq self._bandwidth = options.my_bandwidth self._logging = lincolnlog.LincolnLog(__name__) self._expected_pkt_size = options.expected_pkt_size self._vcsthresh = options.vcsthresh # if backoff is negative, calculate backoff value from options.expected_pkt_size if options.backoff < 0: self._vcsbackoff = predict_pack_size( self._expected_pkt_size, self._use_coding, self._modulation, self._occupied_tones, self._cp_length, self._fft_length ) # otherwise use the value in options.backoff else: self._vcsbackoff = options.backoff # 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, self._vcsthresh, self._vcsbackoff, options.log, options.coding) 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_ll.ofdm_frame_sink(rotated_const, range(arity), self._rcvd_pktq, self._occupied_tones, phgain, frgain) self.nsink = gr.null_sink(gr.sizeof_float) 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)) # Output the VCS signal so that the MAC layer knows when the # channel is occupied #self.connect((self.ofdm_recv, 2), gr.null_sink(gr.sizeof_float)) self.connect((self.ofdm_recv, 2), (self, 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,0)) 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, self._use_coding, self._coding_block_length, self._adaptive_coding_enabled, self._rfcenterfreq,self._bandwidth,self._logging)