示例#1
0
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)
示例#2
0
    def __init__(self, modulator, demodulator, options, ll_logging, dev_log, start_tb_time, time_cal_timeout, start_controller_time):
        gr.top_block.__init__(self)
        
        # Get the modulation's bits_per_symbol
        args = modulator.extract_kwargs_from_options(options)
        symbol_rate = options.modulation_bitrate / modulator(**args).bits_per_symbol()
        
        # all subsequent code expects list of ints, so convert from 
        # comma separated string
        sink_addresses = options.sink_mac_addresses
        options.sink_mac_addresses = [int(x) for x in sink_addresses.split(',')]        

        # Direct asynchronous notifications to callback function
        if True:#self.options.show_async_msg:
            self.async_msgq = gr.msg_queue(0)
            self.async_src = uhd.amsg_source("", self.async_msgq)
            self.async_rcv = gru.msgq_runner(self.async_msgq, self.async_callback)

        self.dev_log = dev_log
        
        # how much time should be spent calibrating time sync?
        self.cal_time = time_cal_timeout      

        self.rx_channelizer = channelizer.rx_channelizer(options, dev_log)
        self.tx_channelizer = channelizer.tx_channelizer(options, dev_log)
        self.rx_channelizer.set_beacon_channel(options.gpsbug_cal_channel)
        upsampled_symbol_rate = symbol_rate*options.digital_freq_hop_num_channels
        upsample_factor_usrp = options.digital_freq_hop_num_channels

        #setting up USRP RX
        self.source = uhd_receiver(options.usrp_args, upsampled_symbol_rate,
                                       options.modulation_samples_per_symbol,
                                       options.rf_rx_freq, options.rf_rx_gain,
                                       options.usrp_spec, "RX2",
                                       options.verbose)
            
        #setting up USRP TX
        self.sink = uhd_transmitter(options.usrp_args, upsampled_symbol_rate,
                                        options.modulation_samples_per_symbol,
                                        options.rf_tx_freq, options.rf_tx_gain,
                                        options.usrp_spec, "TX/RX",
                                        options.verbose)

        if self.source._sps != options.modulation_samples_per_symbol:
            self.dev_log.warning("The USRP does not support the requested sample rate of %f. Using %f instead",
                                    options.modulation_samples_per_symbol*upsampled_symbol_rate,
                                    self.source._sps*upsampled_symbol_rate)

        options.modulation_samples_per_symbol = self.source._sps
        
        self.digital_scaling = gr.multiply_const_vcc((options.digital_scale_factor,))
        
        # moved down here (after reassignment of self.source._sps so we can use
        # the actual sample rate the UHD is using
        self.fs = options.modulation_samples_per_symbol*upsampled_symbol_rate/upsample_factor_usrp
        
        self.pmt_rpc = digital_ll.pmt_rpc(obj=self,result_msg=False)
        
        self.start_tb_time = start_tb_time
        self.start_controller_time = start_controller_time
        
        # this helps control dc tone problem (Use to be burst_gate now eob_shifter)
        # TODO: Only programmed for GMSK. Other modulations will need additional work.
        upsample_factor = 8*options.modulation_samples_per_symbol*options.digital_freq_hop_num_channels
        self.eob        = digital_ll.eob_shifter(upsample_factor)

        num_d_chans = options.digital_freq_hop_num_channels
      
        if  options.tx_access_code == '0':
            tx_access_code = None
        elif options.tx_access_code == '1':
            tx_access_code = '0000010000110001010011110100011100100101101110110011010101111110'
        elif options.tx_access_code == '2':
            tx_access_code = '1110001100101100010110110001110101100000110001011101000100001110'   
        else:
            tx_access_code = options.tx_access_code
            
        print 'tx access code: %s' % tx_access_code   
   
        self.packet_framer = digital_ll.packet_framer(
            fs=self.fs,
            samples_per_symbol=options.modulation_samples_per_symbol,
            bits_per_symbol=1,
            access_code=tx_access_code,
            number_digital_channels=num_d_chans
        )
        
        if options.node_role == "tdma_base":
            self.tdma_mac_sm = tdma_base_sm(options, self.sink, self.source, 
                                            self.packet_framer.num_bytes_to_num_samples)
                
                
        else:
            self.tdma_mac_sm = tdma_mobile_sm(options, self.sink, self.source,
                                              self.packet_framer.num_bytes_to_num_samples)
        


        base_rl_agent_protocol_manager.configure_action_space(options, self.fs)

        num_mobiles = len(options.sink_mac_addresses)
        pfs = PatternFrameSchedule()
        num_actions = pfs.num_actions
        num_stochastic_states = num_mobiles + 1
        num_action_states = num_actions
        num_states = num_stochastic_states*num_action_states
        
        
        if self.tdma_mac_sm.is_base():
            
            epoch_len = options.agent_epoch_duration
            discount_factor = options.discount_factor
            learning_rate = options.learning_rate
            greedy_epsilon = options.greedy_epsilon
            use_dynamic_alpha = bool(options.agent_use_adaptive_alpha)
            use_dynamic_epsilon = bool(options.agent_use_adaptive_greedy_epsilon)

            use_change_detection = bool(options.agent_use_reward_change_detection)            
            reward_history_len = (options.agent_reward_oldbuffer_size,
                                  options.agent_reward_guardbuffer_size,
                                  options.agent_reward_newbuffer_size )
            
            change_delay = options.slot_assignment_leadtime
            mobile_ids = options.sink_mac_addresses
            
            if options.agent_type == "q_learner":
            
                agent = Q_Learner(num_states, num_actions, learning_rate, 
                     discount_factor, greedy_epsilon, q_mask=None, q_seed=None, 
                     dynamic_alpha=use_dynamic_alpha, dynamic_epsilon=use_dynamic_epsilon,
                     reward_history_len=reward_history_len,
                     use_change_detection=use_change_detection,
                     min_visit_count=options.agent_epsilon_adaptation_threshold)
                
            elif options.agent_type == "sarsa":
                
                agent = Sarsa_Learner(num_states, num_actions, learning_rate, 
                     discount_factor, greedy_epsilon, q_mask=None, q_seed=None, 
                     dynamic_alpha=use_dynamic_alpha, dynamic_epsilon=use_dynamic_epsilon,)
            
            
            agent_wrapper = RL_Agent_Wrapper(agent, 
                                               epoch_len, 
                                               num_stochastic_states,
                                               num_action_states, 
                                               change_delay, 
                                               mobile_ids,
                                               tdma_types_to_ints,
                                               reward_lookup_states=options.agent_reward_states, 
                                               reward_lookup_vals=options.agent_reward_vals,
                                               num_channels=options.digital_freq_hop_num_channels,
                                               do_episodic_learning=False,
                                               lock_buffer_len=options.agent_lock_buffer_len,
                                               lock_policy=options.agent_lock_policy)
                
            manage_slots = base_rl_agent_protocol_manager(tdma_types_to_ints, 
                                                         options=options,
                                                         tdma_mac=self.tdma_mac_sm,
                                                         initial_time_ref=start_controller_time,
                                                         agent_wrapper=agent_wrapper)

        else:
            manage_slots = mobile_rl_agent_protocol_manager(tdma_types_to_ints, 
                                                           options=options,
                                                           tdma_mac = self.tdma_mac_sm,)


            
        self.dev_log.info("starting at time %s", start_tb_time)
        self.tdma_controller = tdma_controller(options=options, 
                                               mac_sm=self.tdma_mac_sm,
                                               manage_slots=manage_slots, 
                                               fs=self.fs, 
                                               mux_name="scheduled_mux",
                                               rx_channelizer_name="rx_channelizer",
                                               fhss_flag=1, 
                                               start_time=start_controller_time,
                                               )
        
        
        if options.traffic_generation == "infinite": 
            self.traffic = Infinite_Backlog_PDU_Streamer( options, 
                                                 self.tdma_controller.app_queue_size )
            self.msg_connect(self.traffic, "out_pkt_port", self.tdma_controller,'from_app')
        
        elif options.traffic_generation == "tunnel":
            self.traffic = Tunnel_Handler_PDU_Streamer(options)
            self.msg_connect(self.traffic, "out_pkt_port", self.tdma_controller,'from_app')
            self.msg_connect(self.tdma_controller,'to_app', self.traffic, "in_pkt_port")

        else:
            self.traffic = None

        
        self.tdma_logger = tdma_logger(ll_logging, upsample_factor_usrp)
        
        # set up receive path
        packet_rx_callback = self.tdma_controller.incoming_packet_callback
        self.rx_path = receive_path_gmsk(demodulator, packet_rx_callback, options, 
                                               log_index=-2, use_new_pkt=True)
   

   
        self.gmsk_mod = digital_ll.gmsk_mod(
            samples_per_symbol=options.modulation_samples_per_symbol,
            bt=options.bt, 
            verbose=False,
            log=False,
        )
   
        # declare time tag shifters
        is_receive = True
        self.rx_time_tag_shifter = time_tag_shifter(is_receive, gr.sizeof_gr_complex)
        self.tx_time_tag_shifter = time_tag_shifter(not is_receive, gr.sizeof_gr_complex)
   
   
        # handle base node specific setup
        if self.tdma_mac_sm.is_base():
            t0 = time.time()
            t0_int = int(t0)-10
            t0_frac = t0-t0_int
            beacon_sched = (1,1,0,(t0_int, t0_frac),(t0_int, t0_frac))
            
            self.scheduled_mux = digital_ll.scheduled_mux(gr.sizeof_gr_complex,1,
                                                          self.fs, [beacon_sched])
 
            self.connect(self.source, self.rx_time_tag_shifter, self.rx_channelizer,self.scheduled_mux,self.rx_path)
              
            
        # handle mobile node specific setup    
        else:
            t0 = time.time()
            t0_int = int(t0)-10
            t0_frac = t0-t0_int
            beacon_sched = (options.beacon_sense_block_size,
                            options.beacon_sense_block_size,
                            0,(t0_int, t0_frac),(t0_int, t0_frac))

            self.scheduled_mux = digital_ll.scheduled_mux(gr.sizeof_gr_complex,2,self.fs)
            
            self.rx_channelizer.switch_channels(options.gpsbug_cal_channel)
            # Set up receive path for beacon
            
            # set up beacon consumer
            self.beacon_consumer = beacon_consumer(options, overwrite_metadata=True)
            
            beacon_rx_callback = self.beacon_consumer.beacon_callback
            self.beacon_rx_path = receive_path_gmsk(demodulator, beacon_rx_callback, options,log_index=-1,use_new_pkt=True)
         
            self.connect(self.source, self.rx_time_tag_shifter,self.rx_channelizer,self.scheduled_mux,self.beacon_consumer)
            self.connect(self.scheduled_mux,self.beacon_rx_path)
            self.connect((self.scheduled_mux,1),self.rx_path)

            
            self.msg_connect(self.beacon_consumer, "sched_out", self.tdma_controller, "sched_in")
                    
                    
            # add in time tag shifter block message connections
            self.msg_connect(self.beacon_consumer, 'time_cal_out', self.rx_time_tag_shifter, 'time_tag_shift')
            self.msg_connect(self.beacon_consumer, 'time_cal_out', self.tx_time_tag_shifter, 'time_tag_shift')
            self.msg_connect(self.beacon_consumer, 'time_cal_out', self.tdma_mac_sm.cq_manager, 'time_tag_shift')
            

        self.connect(self.rx_channelizer,self.tdma_controller)
        self.connect(self.packet_framer, self.gmsk_mod, self.digital_scaling, 
                     self.tx_channelizer, self.tx_time_tag_shifter, self.eob, self.sink)
            
            

            
        #self.connect(self.gmsk_mod, self.tdma_logger)
        self.connect(self.eob, self.tdma_logger)


        self.msg_connect(self.tdma_controller, "command_out", self.pmt_rpc, "in")
        self.msg_connect(self.tdma_controller, "outgoing_pkt", self.packet_framer, "in")   
        
        # store off params for logging 
        self.get_usrp_params(options)
示例#3
0
    def __init__(self, modulator, demodulator, options, ll_logging, dev_log,
                 start_tb_time, time_cal_timeout, start_controller_time):
        gr.top_block.__init__(self)

        # Get the modulation's bits_per_symbol
        args = modulator.extract_kwargs_from_options(options)
        symbol_rate = options.modulation_bitrate / modulator(
            **args).bits_per_symbol()

        # all subsequent code expects list of ints, so convert from
        # comma separated string
        sink_addresses = options.sink_mac_addresses
        options.sink_mac_addresses = [
            int(x) for x in sink_addresses.split(',')
        ]

        # Direct asynchronous notifications to callback function
        if True:  #self.options.show_async_msg:
            self.async_msgq = gr.msg_queue(0)
            self.async_src = uhd.amsg_source("", self.async_msgq)
            self.async_rcv = gru.msgq_runner(self.async_msgq,
                                             self.async_callback)

        self.dev_log = dev_log

        # how much time should be spent calibrating time sync?
        self.cal_time = time_cal_timeout

        #setting up USRP RX
        self.source = uhd_receiver(options.usrp_args, symbol_rate,
                                   options.modulation_samples_per_symbol,
                                   options.rf_rx_freq, options.rf_rx_gain,
                                   options.usrp_spec, "RX2", options.verbose)

        #setting up USRP TX
        self.sink = uhd_transmitter(options.usrp_args, symbol_rate,
                                    options.modulation_samples_per_symbol,
                                    options.rf_tx_freq, options.rf_tx_gain,
                                    options.usrp_spec, "TX/RX",
                                    options.verbose)

        if self.source._sps != options.modulation_samples_per_symbol:
            self.dev_log.warning(
                "The USRP does not support the requested sample rate of %f. Using %f instead",
                options.modulation_samples_per_symbol * symbol_rate,
                self.source._sps * symbol_rate)

        options.modulation_samples_per_symbol = self.source._sps

        self.digital_scaling = gr.multiply_const_vcc(
            (options.digital_scale_factor, ))

        # moved down here (after reassignment of self.source._sps so we can use
        # the actual sample rate the UHD is using
        self.fs = options.modulation_samples_per_symbol * symbol_rate

        self.pmt_rpc = digital_ll.pmt_rpc(obj=self, result_msg=False)

        self.start_tb_time = start_tb_time
        self.start_controller_time = start_controller_time

        upsample_factor = 8 * options.modulation_samples_per_symbol
        self.eob = digital_ll.eob_shifter(upsample_factor)
        options.digital_freq_hop_num_channels = 1

        if options.tx_access_code == '0':
            tx_access_code = None
        elif options.tx_access_code == '1':
            tx_access_code = '0000010000110001010011110100011100100101101110110011010101111110'
        elif options.tx_access_code == '2':
            tx_access_code = '1110001100101100010110110001110101100000110001011101000100001110'
        else:
            tx_access_code = options.tx_access_code

        print 'tx access code: %s' % tx_access_code

        self.packet_framer = digital_ll.packet_framer(
            fs=self.fs,
            samples_per_symbol=options.modulation_samples_per_symbol,
            bits_per_symbol=1,
            access_code=tx_access_code,
            number_digital_channels=1)

        if options.node_role == "tdma_base":
            self.tdma_mac_sm = tdma_base_sm(
                options, self.sink, self.source,
                self.packet_framer.num_bytes_to_num_samples)

            self.frame_sched = parse_frame_file(options.frame_file,
                                                start_controller_time, self.fs)

            for k, slot in enumerate(self.frame_sched["slots"]):
                self.frame_sched["slots"][k] = slot._replace()

                # replace the rf_freq field with the value of tx_freq from the ini or
                # command line for the slots transmitted by the base
                if (slot.type == "downlink") or (slot.type == "beacon"):
                    self.frame_sched["slots"][k] = slot._replace(
                        rf_freq=options.rf_tx_freq,
                        tx_gain=options.rf_tx_gain,
                        bw=self.fs)

                # replace the rf_freq field with the value of rx_freq from the ini or
                # command line for the slots received by the base
                elif slot.type == "uplink":
                    self.frame_sched["slots"][k] = slot._replace(
                        rf_freq=options.rf_rx_freq,
                        tx_gain=options.rf_tx_gain,
                        bw=self.fs)

            # for simple case, force all slot baseband frequencies to 0
            for k, slot in enumerate(self.frame_sched["slots"]):
                self.frame_sched["slots"][k] = slot._replace(bb_freq=0)

        else:
            self.tdma_mac_sm = tdma_mobile_sm(
                options, self.sink, self.source,
                self.packet_framer.num_bytes_to_num_samples)
            self.frame_sched = None

        if self.tdma_mac_sm.is_base():

            manage_slots = base_slot_manager_static(
                types_to_ints=tdma_types_to_ints,
                options=options,
                tdma_mac=self.tdma_mac_sm,
                initial_schedule=self.frame_sched)

        else:

            manage_slots = mobile_slot_manager_static(
                types_to_ints=tdma_types_to_ints,
                options=options,
                tdma_mac=self.tdma_mac_sm,
            )

        self.dev_log.info("starting at time %s", start_tb_time)
        self.tdma_controller = tdma_controller(
            options=options,
            mac_sm=self.tdma_mac_sm,
            manage_slots=manage_slots,
            fs=self.fs,
            mux_name="scheduled_mux",
            rx_channelizer_name="rx_channelizer",
            fhss_flag=0,  # No hopping
            start_time=start_controller_time,
        )

        if options.traffic_generation == "infinite":
            self.traffic = Infinite_Backlog_PDU_Streamer(
                options, self.tdma_controller.app_queue_size)
            self.msg_connect(self.traffic, "out_pkt_port",
                             self.tdma_controller, 'from_app')

        elif options.traffic_generation == "tunnel":
            self.traffic = Tunnel_Handler_PDU_Streamer(options)
            self.msg_connect(self.traffic, "out_pkt_port",
                             self.tdma_controller, 'from_app')
            self.msg_connect(self.tdma_controller, 'to_app', self.traffic,
                             "in_pkt_port")

        else:
            self.traffic = None

        self.tdma_logger = tdma_logger(ll_logging, 1)

        # set up receive path
        packet_rx_callback = self.tdma_controller.incoming_packet_callback
        self.rx_path = receive_path_gmsk(demodulator,
                                         packet_rx_callback,
                                         options,
                                         log_index=-2,
                                         use_new_pkt=True)

        self.gmsk_mod = digital_ll.gmsk_mod(
            samples_per_symbol=options.modulation_samples_per_symbol,
            bt=options.bt,
            verbose=False,
            log=False,
        )

        # declare time tag shifters
        is_receive = True
        self.rx_time_tag_shifter = time_tag_shifter(is_receive,
                                                    gr.sizeof_gr_complex)
        self.tx_time_tag_shifter = time_tag_shifter(not is_receive,
                                                    gr.sizeof_gr_complex)

        # handle base node specific setup
        if self.tdma_mac_sm.is_base():
            t0 = time.time()
            t0_int = int(t0) - 10
            t0_frac = t0 - t0_int
            beacon_sched = (1, 1, 0, (t0_int, t0_frac), (t0_int, t0_frac))

            self.scheduled_mux = digital_ll.scheduled_mux(
                gr.sizeof_gr_complex, 1, self.fs, [beacon_sched])

            self.connect(self.source, self.rx_time_tag_shifter,
                         self.scheduled_mux, self.rx_path)

        # handle mobile node specific setup
        else:
            t0 = time.time()
            t0_int = int(t0) - 10
            t0_frac = t0 - t0_int
            beacon_sched = (options.beacon_sense_block_size,
                            options.beacon_sense_block_size, 0,
                            (t0_int, t0_frac), (t0_int, t0_frac))

            self.scheduled_mux = digital_ll.scheduled_mux(
                gr.sizeof_gr_complex, 2, self.fs)

            # Set up receive path for beacon

            # set up beacon consumer
            self.beacon_consumer = beacon_consumer(options,
                                                   overwrite_metadata=True)

            beacon_rx_callback = self.beacon_consumer.beacon_callback
            self.beacon_rx_path = receive_path_gmsk(demodulator,
                                                    beacon_rx_callback,
                                                    options,
                                                    log_index=-1,
                                                    use_new_pkt=True)

            self.connect(self.source, self.rx_time_tag_shifter,
                         self.scheduled_mux, self.beacon_consumer)
            self.connect(self.scheduled_mux, self.beacon_rx_path)
            self.connect((self.scheduled_mux, 1), self.rx_path)

            self.msg_connect(self.beacon_consumer, "sched_out",
                             self.tdma_controller, "sched_in")

            # add in time tag shifter block message connections
            self.msg_connect(self.beacon_consumer, 'time_cal_out',
                             self.rx_time_tag_shifter, 'time_tag_shift')
            self.msg_connect(self.beacon_consumer, 'time_cal_out',
                             self.tx_time_tag_shifter, 'time_tag_shift')
            self.msg_connect(self.beacon_consumer, 'time_cal_out',
                             self.tdma_mac_sm.cq_manager, 'time_tag_shift')

        self.connect(self.rx_time_tag_shifter, self.tdma_controller)
        self.connect(self.packet_framer, self.gmsk_mod, self.digital_scaling,
                     self.tx_time_tag_shifter, self.eob, self.sink)

        #self.connect(self.gmsk_mod, self.tdma_logger)
        self.connect(self.eob, self.tdma_logger)

        self.msg_connect(self.tdma_controller, "command_out", self.pmt_rpc,
                         "in")
        self.msg_connect(self.tdma_controller, "outgoing_pkt",
                         self.packet_framer, "in")

        # store off params for logging
        self.get_usrp_params(options)