def __init__(self, uhd_sink, uhd_source=None): gr.basic_block.__init__( self, name = "Command Queue Manager Block", in_sig = None, out_sig = None) self.dev_log = logging.getLogger('developer') self.uhd_sink = uhd_sink self.uhd_source = uhd_source self.current_gain = 0.0 self.reservation = threading.BoundedSemaphore(1) #example : [(time_spec_t(1367432337,0.276619),10, 'tx_gain'), (time_spec_t(1367432338,0.276619),12, 'tx_freq')] self.time_gain_tuple_list = [] #pick maximum uhd lead time and minimum processing time in the for loop below self.period = 0.1 #make this about or less than the frame set up time self.queue_size_limit = 100 self.max_drops = 20 #reset entire queue if there are too many drops self.time_sync_done = False self.gps_offset = 0 self.current_time_ahead = 0 # set up and register input ports self.TIME_CAL_IN_PORT = pmt.from_python('time_tag_shift') self.message_port_register_in(self.TIME_CAL_IN_PORT) self.set_msg_handler(self.TIME_CAL_IN_PORT, self.store_gps_offset) # get the ll_logging set of logs so we have access to the state log self.ll_logging = lincolnlog.LincolnLog(__name__) self.statelog = self.ll_logging._statelog def _fulltime_manager(): while True: self.process_command_queue() time.sleep(0.01) #make this timer x number slots/second << 16 _manager_thread = threading.Thread(target=_fulltime_manager) _manager_thread.daemon = True _manager_thread.start()
def __init__(self, options, overwrite_metadata=False): gr.sync_block.__init__(self, name="beacon consumer", in_sig=[numpy.complex64], out_sig=None) self.dev_log = logging.getLogger('developer') self._types_to_ints = dict(tdma_types_to_ints) self._ints_to_types = dict() # map from ints back to slot types for key in self._types_to_ints: self._ints_to_types[self._types_to_ints[key]] = key # get parameters from options object self._beacon_timeout = options.beacon_sync_timeout self._min_beacons = options.min_sync_beacons self._max_beacons = options.max_sync_beacons self._base_id = options.base_station_mac_address self._beacon_error_thresh = options.max_beacon_error # if true, use measured values for metadata fields when available self._overwrite_metadata = overwrite_metadata self._beacon_list = [] self._schedule_valid = False self._beacon_lock = Semaphore() self._sched_lock = Semaphore() self._has_sync = False self.found_time = False self.found_rate = False self.in_time_cal = True self.time_sync_offset = None # add timing monitoring code self.monitor_timing = True if self.monitor_timing == True: self.wall_time_window_start = None self.wall_time_deltas = [] self.poll_interval = 5 # don't propagate any tags, this block handles them manually self.set_tag_propagation_policy(gr.gr_block.TPP_DONT) self.IN_PORT = pmt.from_python('in') self.SCHEDULE_OUT_PORT = pmt.from_python('sched_out') self.TIME_CAL_OUT_PORT = pmt.from_python('time_cal_out') # register input ports self.message_port_register_in(self.IN_PORT) self.set_msg_handler(self.IN_PORT, self.beacon_callback) # register outgoing message ports self.message_port_register_out(self.SCHEDULE_OUT_PORT) self.message_port_register_out(self.TIME_CAL_OUT_PORT) self._dev_logger = logging.getLogger('developer') self._ll_logging = lincolnlog.LincolnLog(__name__)
def initial_config(): traffic_models = ["infinite", "none", "tunnel"] # Dictionary of default variables node_defaults = dict() # Get the arg parser and add config file as an option arg_parser = ArgumentParser(add_help=False) arg_parser.add_argument("-c", "--config-file", help="set config-file name") #(known, args)=arg_parser.parse_known_args() known=arg_parser.parse_known_args()[0] # Setup dev logger # import log config template from lincolnlogs log_config = deepcopy(digital_ll.log_config) # set the log level # log_config["loggers"]["developer"]["level"] = known.log_level logging.config.dictConfig(log_config) dev_log = logging.getLogger('developer') f = digital_ll.ContextFilter() dev_log.addFilter(f) # declare config parser conf_parser = SafeConfigParser(allow_no_value=True) # if given a config file, try to parse it, otherwise, skip that step if known.config_file is not None: # load config file file_list = conf_parser.read(known.config_file) if len(file_list) == 0: print "File '%s' not found" % known.config_file sys.exit(1) sections = conf_parser.sections() # config file read successfully: Update command line defaults as needed for section in sections: # get list of all items in each section section_entries = conf_parser.options(section) # update defaults for any matching variable names # iterate through each entry in each section for key in section_entries: # update defaults from the value in the config file node_defaults[key] = conf_parser.get(section, key) # handle special case of converting string representation of bools to bools if (node_defaults[key] == "True") | (node_defaults[key] == "False"): node_defaults[key] = (node_defaults[key] == "True") # store values from arg parser into defaults of config parser, # so everything is on the same page known_dict = vars(known) for key in known_dict: node_defaults[key] = known_dict[key] mods = modulation_utils.type_1_mods() demods = modulation_utils.type_1_demods() # Create Options Parser: parser = OptionParser (option_class=eng_option, conflict_handler="resolve") expert_grp = parser.add_option_group("Expert") parser.add_option("--show-gpl", action="store_true", default=False, help="display the full GPL license for this program") # note this option is actually handled by the argparse module. This is only included # so the config file option shows up in the help file parser.add_option("-c", "--config-file", help="set config-file name") parser.add_option("--log-level", default="INFO", help="verbosity of debug log. options are %s" % log_levels) parser.add_option("","--pcktlog", default="./tdma_packetlog.xml", help="file to save packet log to") parser.add_option("","--statelog",default="./tdma_statelog.xml",help="file to save state log to") parser.add_option("","--agentlog",default="./agent.log",help="file to save state log to") parser.add_option("","--dblog",default="./database.log",help="file to save state log to") parser.add_option("--start-time", type="float", default=float(0), help=("Start time of the test, in seconds since 1970. " + "Starts immediately if start time is in the past. " + "[default=%default] " + "Hint: Use date +%s to get the current epoch time.")) parser.add_option("--run-duration", type="float", default=float(0), help=("Run time duration of the test in seconds. " + "Run forever until control-C if run time is 0. " + "[default=%default]")) parser.add_option("", "--node-role", type="choice", choices=["tdma_base", "tdma_mobile"], default='tdma_mobile', help="Select mac from: %s [default=%%default]" % (', '.join(["tdma_base", "tdma_mobile"]))) parser.add_option("", "--modulation", type="choice", choices=["gmsk"], default='gmsk', help="Select mac type from: %s [default=%%default]" % (', '.join(["gmsk"]))) parser.add_option("", "--gpsbug-cal-duration", type="float", default=10.0, help="Duration to run time calibration") # TODO: clean up this option. Store available traffic generation schemes somehow parser.add_option("--traffic-generation", type="choice", choices=traffic_models, default="none", help="Select traffic generation method: %s [default=%%default]" % (", ".join(traffic_models))) parser.add_option("", "--agent-epoch-duration", type="int", default=20, help="agent epoch length, in frames") parser.add_option("", "--agent-type", type="string", default="q_learner", help="Which agent is used") receive_path_gmsk.add_options(parser, expert_grp) # normally this would be in transmit path add option parser.add_option("", "--tx-access-code", type="string", default="1", help="set transmitter access code 64 1s and 0s [default=%default]") parser.add_option("", "--digital-scale-factor", type="float", default=0.5, help="digital amplitude control for transmit, between 0.0 and 1.0") uhd_receiver.add_options(parser) uhd_transmitter.add_options(parser) for mod in mods.values(): mod.add_options(expert_grp) for mod in demods.values(): mod.add_options(expert_grp) channelizer.rx_channelizer.add_options(parser) channelizer.tx_channelizer.add_options(parser) base_rl_agent_protocol_manager.add_options(parser,expert_grp) mobile_rl_agent_protocol_manager.add_options(parser,expert_grp) RL_Agent_Wrapper.add_options(parser,expert_grp) Q_Learner.add_options(parser,expert_grp) Sarsa_Learner.add_options(parser,expert_grp) tdma_base_sm.add_options(parser,expert_grp) tdma_mobile_sm.add_options(parser,expert_grp) tdma_controller.add_options(parser,expert_grp) Infinite_Backlog_PDU_Streamer.add_options(parser,expert_grp) Tunnel_Handler_PDU_Streamer.add_options(parser,expert_grp) beacon_consumer.add_options(parser,expert_grp) # get list of all option defaults in the current option list opt_list = parser.defaults # update defaults for node-options modules # iterate through each entry in node_defaults for key in node_defaults: #dev_log.debug('Searching opt_list for option: %s', key) # if there's a match to an entry in opt_list if key in opt_list: # update default options from the value in gr_defaults #dev_log.debug('Updating option default: %s from node_defaults', key) parser.set_default(key, node_defaults[key]) else: # print "Ini file option ", key, "doesn't have a field in parser" # assert False dev_log.warning('Option %s from ini file not present in parser',key) for key in opt_list: if key not in node_defaults: dev_log.warning('Option %s from parser not in ini file',key) (options, args) = parser.parse_args () # update log level dev_log.info("new log level is %s", options.log_level) log_config["loggers"]["developer"]["level"] = options.log_level # update agent and database file paths expanded_agentlog = os.path.expandvars(os.path.expanduser(options.agentlog)) abs_agentlog = os.path.abspath(expanded_agentlog) expanded_dblog = os.path.expandvars(os.path.expanduser(options.dblog)) abs_dblog = os.path.abspath(expanded_dblog) log_config["handlers"]["agent"]["filename"] = abs_agentlog log_config["handlers"]["database"]["filename"] = abs_dblog logging.config.dictConfig(log_config) dev_log = logging.getLogger('developer') dev_log.debug("hi") #if options.pcktlog != -1: # lincolnlog.LincolnLogLayout('debug', -1, options.pcktlog , -1, -1) #else: # lincolnlog.LincolnLogLayout('debug', -1, -1, -1, -1) lincolnlog.LincolnLogLayout('debug', -1, options.pcktlog , options.statelog, -1) ll_logging = lincolnlog.LincolnLog(__name__) if len(args) != 0: parser.print_help(sys.stderr) sys.exit(1) # parse rest of command line args if len(args) != 0: parser.print_help(sys.stderr) sys.exit(1) # cannot proceed without a config file, so exit if known.config_file is None: print "No config file provided, exiting" sys.exit(1) return(mods, demods, options, ll_logging, dev_log)
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(1, 1, gr.sizeof_char), # 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._use_coding = options.coding self._coding_block_length = options.block_length # used for non-adaptive systems self._variable_coding_block_length = dict( ) # used for adaptive systems self._adaptive_coding_enabled = options.adaptive_coding self._rfcenterfreq = options.tx_freq self._bandwidth = options.my_bandwidth self._logging = lincolnlog.LincolnLog(__name__) self._percent_bw_occupied = options.percent_bw_occupied 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)) # adding blocks needed for debug self.null_sink = gr.null_sink(gr.sizeof_char) self.message_sink = gr.message_sink(gr.sizeof_char * 1, self._pkt_input.msgq(), False) 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.connect(self, self.null_sink) 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_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, demod_class, rx_callback, options, log_index=-1, use_new_pkt=False): 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._bitrate = options.modulation_bitrate # desired bit rate self._rx_callback = rx_callback # this callback is fired when a packet arrives self._demod_class = demod_class # the demodulator_class we're using self._chbw_factor = options.chbw_factor # channel filter bandwidth factor self._access_code = options.rx_access_code self._threshold = options.access_code_threshold if self._access_code == '0': self._access_code = None elif self._access_code == '1': self._access_code = '0000010000110001010011110100011100100101101110110011010101111110' print 'rx access code: %s' % self._access_code elif self._access_code == '2': self._access_code = '1110001100101100010110110001110101100000110001011101000100001110' # Get demod_kwargs demod_kwargs = self._demod_class.extract_kwargs_from_options(options) # Build the demodulator self.demodulator = self._demod_class(**demod_kwargs) print self.demodulator self._use_coding = False self._rfcenterfreq = options.rf_rx_freq # make sure option exists before adding member variable if hasattr(options, 'my_bandwidth'): self._bandwidth = options.my_bandwidth self._logging = lincolnlog.LincolnLog(__name__) #if options.pcktlog != -1: # self._logging = lincolnlog.LincolnLog(__name__) #else: # self._logging = -1 # Make sure the channel BW factor is between 1 and sps/2 # or the filter won't work. if(self._chbw_factor < 1.0 or self._chbw_factor > self.samples_per_symbol()/2): sys.stderr.write("Channel bandwidth factor ({0}) must be within the range [1.0, {1}].\n".format(self._chbw_factor, self.samples_per_symbol()/2)) sys.exit(1) # Design filter to get actual channel we want sw_decim = 1 chan_coeffs = gr.firdes.low_pass (1.0, # gain sw_decim * self.samples_per_symbol(), # sampling rate self._chbw_factor, # midpoint of trans. band 0.5, # width of trans. band gr.firdes.WIN_HANN) # filter type self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs) # receiver self.packet_receiver = \ digital_ll.pkt2.demod_pkts(self.demodulator, options, #added on 9/28/12 access_code=self._access_code, callback=self._rx_callback, threshold=self._threshold, use_coding=self._use_coding, logging=self._logging) # Display some information about the setup if self._verbose: self._print_verbage() # connect block input to channel filter self.connect(self, self.channel_filter) # connect channel filter to the packet receiver self.connect(self.channel_filter, self.packet_receiver) # added to make logging easier self._modulation = options.modulation if "_constellation" in vars(self.demodulator): self._constellation_points = len(self.demodulator._constellation.points()) else: self._constellation_points = None if "_excess_bw" in vars(self.demodulator): self._excess_bw = self.demodulator._excess_bw else: self._excess_bw = None if "_freq_bw" in vars(self.demodulator): self._freq_bw = self.demodulator._freq_bw else: self._freq_bw = None if "_phase_bw" in vars(self.demodulator): self._phase_bw = self.demodulator._phase_bw else: self._phase_bw = None if "_timing_bw" in vars(self.demodulator): self._timing_bw = self.demodulator._timing_bw else: self._timing_bw = None
def __init__( self, options, mac_sm, manage_slots, fs, mux_name, rx_channelizer_name, fhss_flag=0, start_time=None, plot_lock=None ): """ Inputs: complex stream from USRP, app_in, pkt in Outputs: pkt out, app_out """ gr.sync_block.__init__( self, name = "tdma_controller", in_sig = [numpy.complex64], out_sig = None ) # set up loggers self.ll_logging = lincolnlog.LincolnLog(__name__) self.dev_logger = logging.getLogger('developer') self.dev_logger.debug("tdma controller init") self.plot_lock = plot_lock # TODO: get these from mac/phy? macCode = 1 phyCode = 0 # store off any inputs we'll need later self.fs = float(fs) self.mac_sm = mac_sm self.mux_name = mux_name self.rx_channelizer_name = rx_channelizer_name self.start_time = start_time self.monitor_timing = True if self.monitor_timing == True: self.state_time_deltas = 0 self.wall_time_deltas = 0 self.poll_interval = 5 if fhss_flag: self.number_digital_channels = options.digital_freq_hop_num_channels else: self.number_digital_channels = 1 # round pre_guard to nearest sample: probably ok if we do this at upsampled # sample rate, but doing this at the rate given in the fs param for now self.pre_guard = round(options.slot_pre_guard*self.fs)/self.fs if self.pre_guard != options.slot_pre_guard: self.dev_logger.warn("Rounding pre_guard from %.15f to %.15f", self.pre_guard, options.slot_pre_guard) # store off option parameters that will be needed later self.frame_file = options.frame_file self.max_app_in_q_size = options.mac_tx_packet_q_depth self.max_incoming_q_size = options.phy_rx_packet_q_depth # Queue to hold packets coming from application layer prior to processing self.app_in_q = deque([],self.max_app_in_q_size) # Queue to hold packets coming from rf interface prior to processing self.raw_incoming_q = Queue.Queue() # queue to hold incoming packets after initial processing self.incoming_q = deque([],self.max_incoming_q_size) # Queue for schedule updates from the beacon consumer self.in_sched_update_q = deque() # dictionary mapping between node ID and the queue holding packets addressed to # that ID. Using defaultdict so that deques for new toIDs are automatically # created as needed. In general, mobiles will only have one queue, since they # only communicate directly with the base, but bases will have one queue per # associated mobile self.pkt_switch_queues = defaultdict(deque) if start_time is None: self.start_time = ceil(time.time()) else: self.start_time = start_time # reference timestamp used with time_offset and fs to compute the current time # based on the number of samples received self.ref_timestamp = time_spec_t(0) self.ref_time_offset = 0 self.current_timestamp = time_spec_t(0) # used for adding a packet id field to packets self.packet_count = 0 self.frame_count = 0 self.found_time = False self.found_rate = False self.know_time = False self.time_cal_complete = False self.do_time_cal = False self.num_cal_beacons = 0 self.beacon_channel = options.gpsbug_cal_channel # don't propagate any tags self.set_tag_propagation_policy(gr.gr_block.TPP_DONT) # register output message ports self.message_port_register_out(OUTGOING_PKT_PORT) self.message_port_register_out(TO_APP_PORT) self.message_port_register_out(COMMAND_OUT_PORT) # register input message ports self.message_port_register_in(FROM_APP_PORT) # self.message_port_register_in(INCOMING_PKT_PORT) self.message_port_register_in(SCHEDULE_IN_PORT) # register message handlers for input ports self.set_msg_handler(FROM_APP_PORT, self.handle_app_pkt) # self.set_msg_handler(INCOMING_PKT_PORT, self.handle_incoming_pkt) self.set_msg_handler(SCHEDULE_IN_PORT, self.handle_schedule_update) #state machine should only be started by top level node once calibration is complete # self.mac_sm.start() # define the link direction to assign to received packets if self.mac_sm.is_base(): self.rx_pkt_dir = "up" # decide which packet stat tracking function to use self.manage_slots = manage_slots else: self.rx_pkt_dir = "down" # decide which packet stat tracking function to use self.manage_slots = manage_slots # list for the current set of schedules the state machine is operating on self.sched_seq = [] self.frame_config = None self.current_sched = None self.last_frame_slots = None # TODO: LOG THESE self.mac_config = { "app_in_q_size":self.max_app_in_q_size, "base_id":options.base_station_mac_address, "bits_per_symbol":1, # TODO: Always true for GMSK...will have to fix later "fhss_flag":fhss_flag, "fs":self.fs, "lead_limit":options.frame_lead_limit, "macCode":macCode, "mux_command":self.mux_name + ".set_schedules", "my_id":options.source_mac_address, "number_digital_channels":options.digital_freq_hop_num_channels, "beacon_channel":options.gpsbug_cal_channel, "peer_ids":options.sink_mac_addresses, "phyCode":phyCode, "pre_guard":self.pre_guard, "rx_channelizer_command":self.rx_channelizer_name + ".channelizer_command", "rx_channelizer_return_to_beacon":self.rx_channelizer_name + ".return_to_beacon_channel", "samples_per_symbol":options.modulation_samples_per_symbol, "slot_manager":self.manage_slots, } self.dev_logger.debug("tdma controller init complete")
def __init__(self, modulator_class, options): ''' See below for what options should hold ''' gr.hier_block2.__init__(self, "transmit_path", gr.io_signature(1, 1, gr.sizeof_char), gr.io_signature(1, 1, gr.sizeof_gr_complex)) options = copy.copy( options) # make a copy so we can destructively modify self._verbose = options.verbose self._tx_amplitude = options.tx_amplitude # digital amplitude sent to USRP self._bitrate = options.bitrate # desired bit rate self._modulator_class = modulator_class # the modulator_class we are using self._access_code = options.tx_access_code self._use_coding = options.coding self._rfcenterfreq = options.tx_freq self._bandwidth = options.my_bandwidth self._logging = lincolnlog.LincolnLog(__name__) #if options.pcktlog != -1: # self._logging = lincolnlog.LincolnLog(__name__) #else: # self._logging = -1 if self._access_code == 0: self._access_code = None elif self._access_code == 1: self._access_code = '0000010000110001010011110100011100100101101110110011010101111110' print 'tx access code: %s' % self._access_code elif self._access_code == 2: self._access_code = '1110001100101100010110110001110101100000110001011101000100001110' # Get mod_kwargs mod_kwargs = self._modulator_class.extract_kwargs_from_options(options) # transmitter self.modulator = self._modulator_class(**mod_kwargs) self.packet_tx = \ digital_ll.mod_pkts(self.modulator, options, #added on 9/28/12 access_code=self._access_code, msgq_limit=4, pad_for_usrp=True, use_whitener_offset=False, modulate=True, use_coding=self._use_coding, rfcenterfreq=self._rfcenterfreq, bandwidth=self._bandwidth, logging=self._logging ) self.amp = gr.multiply_const_cc(1) self.set_tx_amplitude(self._tx_amplitude) self.null_sink = gr.null_sink(gr.sizeof_char) # Display some information about the setup if self._verbose: self._print_verbage() # Connect components in the flowgraph self.connect(self.packet_tx, self.amp, self) self.connect(self, self.null_sink) # added to make logging easier self._modulation = options.modulation if "_constellation" in vars(self.modulator): self._constellation_points = len( self.modulator._constellation.points()) else: self._constellation_points = None if "_excess_bw" in vars(self.modulator): self._excess_bw = self.modulator._excess_bw else: self._excess_bw = None