def read_from_network(self): ''' This function reads packets from the network layer and puts them in a queue for the MAC layer to handle. ''' self.logger.debug("starting tuntap read from network") while self.keep_going: data = os.read(self.tun_fd, 10*1024) #print data.encode('hex') # if there's an error with the tunnel interface if not data: self.logger.error("Error reading from tunnel device") break # only add packet to queue if it is under the maximum allowed size # if len(data) < self.max_pkt_size: # map ip destination address to appropriate mac address to_id = self.read_mac_dest(data) self.logger.debug("read returned. len data is %d", len(data)) # self.logger.debug("data is %s", data) if to_id >0: self.logger.debug("sending message to mac id %d", to_id) meta= {"destinationID":to_id} self.message_port_pub(self.OUT_PKT_PORT, pmt.pmt_cons(pmt.from_python(meta), pmt.from_python(data))) # handle broadcast case elif to_id == -1: for mac_id in self.mac_id_list: if mac_id != self.mac_id: self.logger.debug("sending broadcast message to mac id %d", mac_id) meta= {"destinationID":mac_id} self.message_port_pub(self.OUT_PKT_PORT, pmt.pmt_cons(pmt.from_python(meta), pmt.from_python(data))) # else: # self.logger.debug("type of len(data) is %s. Type of max_pkt_size is %s", type(len(data)), type(self.max_pkt_size)) # msg = () # self.logger.warning("provided packet length of %s exceeds maximum " + # "allowed packet length of %s. Dropping this packet", # len(data), self.max_pkt_size) try: os.close(self.tun_fd) except OSError as e: if e.errno == os.errno.EBADF: self.logger.warning("Tunnel file descriptor is bad"); else: self.logger.error("unexpected error when closing tunnel file descriptor") raise self.logger.debug("tunnel interface read from network complete")
def __init__(self, queue_size, from_id): ''' Constructor ''' gr.basic_block.__init__(self, name="msg_queue_adapter", in_sig=None, out_sig=None) self.pkt_queue = deque(maxlen=queue_size) self.my_id = int(from_id) self.packet_id = 0 self.max_packet_id = 65535 # set up constants for packet headers self.crc_result = True self.pad_bytes = 0 self.pkt_code = 'DATA' self.phy_code = 0 self.mac_code = 0 self.more_data = 0 # set up message port self.IN_PORT = pmt.from_python("in_port") self.message_port_register_in(self.IN_PORT) # set up message port self.OUT_PORT = pmt.from_python("out_port") self.message_port_register_out(self.OUT_PORT) # register message handler for input port self.set_msg_handler(self.IN_PORT, self.store_pkt)
def work(self, input_items, output_items): in0 = input_items[0] out = output_items[0] nread = self.nitems_read(0) #number of items read on port 0 ninput_items = len(input_items[0]) noutput_items = len(output_items[0]) nitems_to_consume = min(ninput_items, noutput_items) out[:nitems_to_consume] = in0[:nitems_to_consume] # output any tags left over from the last iteration if they're ready ready_tags = [x for x in self.tag_residues if x[0] < self.nitems_written(0) + ninput_items] # test if we're writing past what we're allowed for tag in ready_tags: if tag[0] >= self.nitems_written(0) + nitems_to_consume: self.dev_logger.error("writing tags out of range. bad idea") for offset, key, value, srcid in ready_tags: # self.dev_logger.debug("adding key %s value %s source %s at offset %s", # key,value,srcid, offset) self.add_item_tag(0,offset, pmt.from_python(key), pmt.from_python(value), pmt.from_python(srcid)) # keep tags in residues that aren't ready yet self.tag_residues = [x for x in self.tag_residues if x[0] >= self.nitems_written(0) + ninput_items] #read all tags associated with port 0 for items in this work function tags = self.get_tags_in_range(0, nread, nread+nitems_to_consume) for tag in tags: if pmt.pmt_symbol_to_string(tag.key) == self.eob_key: new_offset = tag.offset + self.upsamp_factor-1 # if the new offset is still in this work block, shift the tag. # Otherwise store the tag tuple for the next call if new_offset < self.nitems_written(0) + ninput_items: # self.dev_logger.debug("adding key %s value %s source %s at offset %s", # pmt.to_python(tag.key),pmt.to_python(tag.value),pmt.to_python(tag.srcid), new_offset) self.add_item_tag(0,new_offset, tag.key, tag.value, tag.srcid) else: # turning into native python types in case seg fault issue is due to memory management self.tag_residues.append( (new_offset, pmt.to_python(tag.key), pmt.to_python(tag.value), pmt.to_python(tag.srcid)) ) else: # self.dev_logger.debug("adding key %s value %s source %s at offset %s", # pmt.to_python(tag.key),pmt.to_python(tag.value),pmt.to_python(tag.srcid), tag.offset) self.add_item_tag(0,tag.offset, tag.key, tag.value, tag.srcid) return nitems_to_consume
def __init__(self, options, query_queue_size=None): gr.basic_block.__init__(self, name="infinite_backlog_pdu", in_sig=None, out_sig=None) self.q_size = query_queue_size # pull parameters out of options self.max_queue_size = options.mac_tx_packet_q_depth self.fill_thresh = options.infinite_backlog_refill_threshold self.destination_id_list = options.sink_mac_addresses self.payload_size = options.infinite_backlog_payload_size # note: this is 1000 chars long self.data = ( "GNU Radio is a free & open-source software development toolkit that " "provides signal processing blocks to implement software radios. It can be " "used with readily-available low-cost external RF hardware to create " "software-defined radios, or without hardware in a simulation-like " "environment. It is widely used in hobbyist, academic and commercial " "environments to support both wireless communications research and real-world " "radio systems. GNU Radio applications are primarily written using the " "Python programming language, while the supplied performance-critical signal " "processing path is implemented in C++ using processor floating-point " "extensions, where available. Thus, the developer is able to implement " "real-time, high-throughput radio systems in a simple-to-use, " "rapid-application-development environment. While not primarily a " "simulation tool, GNU Radio does support development of signal processing " "algorithms using pre-recorded or generated data, avoiding the need for " "actual RF hardware.") # make as many copies of data as needed to exceed the desired payload size self.payload = self.data * int( ceil(float(self.payload_size) / float(len(self.data)))) # slice payload down to desired payload size self.payload = self.payload[:self.payload_size] # convert payload to pmt self.payload = pmt.from_python(self.payload) self.OUT_PKT_PORT = pmt.from_python("out_pkt_port") # register outgoing packet port self.message_port_register_out(self.OUT_PKT_PORT) self._traffic_trigger_thread = threading.Thread( target=self._traffic_trigger_probe) self._traffic_trigger_thread.daemon = True self._traffic_trigger_thread.start() sys.stderr.write("init complete\n")
def __init__(self, options, query_queue_size=None): gr.basic_block.__init__( self, name = "infinite_backlog_pdu", in_sig = None, out_sig = None) self.q_size = query_queue_size # pull parameters out of options self.max_queue_size = options.mac_tx_packet_q_depth self.fill_thresh = options.infinite_backlog_refill_threshold self.destination_id_list = options.sink_mac_addresses self.payload_size = options.infinite_backlog_payload_size # note: this is 1000 chars long self.data = ("GNU Radio is a free & open-source software development toolkit that " "provides signal processing blocks to implement software radios. It can be " "used with readily-available low-cost external RF hardware to create " "software-defined radios, or without hardware in a simulation-like " "environment. It is widely used in hobbyist, academic and commercial " "environments to support both wireless communications research and real-world " "radio systems. GNU Radio applications are primarily written using the " "Python programming language, while the supplied performance-critical signal " "processing path is implemented in C++ using processor floating-point " "extensions, where available. Thus, the developer is able to implement " "real-time, high-throughput radio systems in a simple-to-use, " "rapid-application-development environment. While not primarily a " "simulation tool, GNU Radio does support development of signal processing " "algorithms using pre-recorded or generated data, avoiding the need for " "actual RF hardware.") # make as many copies of data as needed to exceed the desired payload size self.payload = self.data*int(ceil(float(self.payload_size)/float(len(self.data)))) # slice payload down to desired payload size self.payload = self.payload[:self.payload_size] # convert payload to pmt self.payload = pmt.from_python(self.payload) self.OUT_PKT_PORT = pmt.from_python("out_pkt_port") # register outgoing packet port self.message_port_register_out(self.OUT_PKT_PORT) self._traffic_trigger_thread = threading.Thread(target=self._traffic_trigger_probe) self._traffic_trigger_thread.daemon = True self._traffic_trigger_thread.start() sys.stderr.write("init complete\n")
def generate_rx_tags(self): #Produce tags offset = self.nitems_written(0) + 0 key_time = pmt.pmt_string_to_symbol("rx_time") #value_time = pmt.from_python(1.0 / #self.samp_rate * self.virtual_counter) value_time = pmt.from_python(self.get_time_now()) key_rate = pmt.pmt_string_to_symbol("rx_rate") value_rate = pmt.from_python(self.samp_rate) self.add_item_tag(0, offset, key_time, value_time) self.add_item_tag(0, offset, key_rate, value_rate)
def __init__( self, fs, samples_per_symbol, bits_per_symbol, access_code=None, pad_for_usrp=True, use_whitener_offset=False, use_coding=0, packet_format='tdma', number_digital_channels=1 ): """ Create a new packet framer. @param access_code: AKA sync vector @type access_code: string of 1's and 0's between 1 and 64 long @param use_whitener_offset: If true, start of whitener XOR string is incremented each packet """ gr.sync_block.__init__( self, name = "framer", in_sig = None, out_sig = [numpy.uint8] ) self.IN_PORT = pmt.from_python('in') # self.in_packets = Queue() self.in_packets = deque() self.message_port_register_in(self.IN_PORT) self.set_msg_handler(self.IN_PORT, self.handle_pdu) self._bits_per_symbol = bits_per_symbol self._samples_per_symbol = samples_per_symbol self._pad_for_usrp = pad_for_usrp self._use_whitener_offset = use_whitener_offset self._whitener_offset = 0 self._use_coding = use_coding self._packet_format = packet_format self._fs = fs self._number_digital_channels=number_digital_channels self._dev_logger = logging.getLogger('developer') if not access_code: access_code = packet_utils2.default_access_code if not packet_utils2.is_1_0_string(access_code): raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,) self._access_code = access_code print "access code: %s" % self._access_code self._pkt = [] self.more_frame_cnt = 0 self.keep = False
def send_commands(self, command_list, **kwargs): ''' Send out commands to other components ''' # note using the double splat operator to take in a dictionary but only # pick out the keyword arguments relevant to this function #if len(command_list): # print command_list for command, params in command_list: #for i in range(0, len(command_list), 2): # command = command_list[i] # params = command_list[i+1] self.dev_logger.debug("params is %s",params) if len(params)>0: key = pmt.from_python(command) vals = pmt.from_python(([params], {})) self.message_port_pub(COMMAND_OUT_PORT, pmt.pmt_cons(key,vals))
def send_txt(self, endofmsg=False): if self.sendmsg and (self.addr != 0 or len(self.txt) > 0): self.post_msg( 0, pmt.pmt_string_to_symbol(POCSAG_ID), pmt.from_python({ "addr": self.addr, "fun": self.fun, "text": self.txt, "num": self.num, "endofmsg": endofmsg, "channel": self.channel_str }))
def tx_frames(self, tx_list, **kwargs): ''' Send out all the packets in the tx_list ''' if len(tx_list) > 0: self.dev_logger.debug("sending %d packets to framer",len(tx_list)) # note using the double splat operator to take in a dictionary but only # pick out the keyword arguments relevant to this function for meta, data in tx_list: if "tx_time" in meta: # self.dev_logger.debug("commanding slot start of %s,%s at current time %s,%s", # time.strftime("%H:%M:%S", time.localtime(meta["tx_time"][0])), # meta["tx_time"][1], # time.strftime("%H:%M:%S", time.localtime(self.current_timestamp.int_s())), # self.current_timestamp.frac_s(),) self.dev_logger.debug("commanding slot start of %s at current time %s", meta["tx_time"],self.current_timestamp) #print "sending packet with metadata %s" % meta msg = pmt.pmt_cons(pmt.from_python(meta), pmt.from_python(data)) self.message_port_pub(OUTGOING_PKT_PORT, msg)
def send_txt(self, endofmsg = False): if self.sendmsg and (self.addr != 0 or len(self.txt) > 0): self.post_msg(0, pmt.pmt_string_to_symbol(POCSAG_ID), pmt.from_python( { "addr": self.addr, "fun": self.fun, "text": self.txt, "num": self.num, "endofmsg": endofmsg, "channel": self.channel_str }) )
def compute_schedule(self, beacon_list): # compute schedule, and if no errors, set schedule valid flag to true #print "computing schedule" # get last header and beacon in list last_ts, last_meta, last_beacon = beacon_list[-1] self._dev_logger.debug( "last beacon's first frame num: %s timestamp: %s found in frame %s", last_beacon.first_frame_num, last_ts, last_meta["frameID"]) timing_deltas = [ float(ts - beacon.tx_time) for ts, meta, beacon in beacon_list ] delta_mags = [abs(x) for x in timing_deltas] timing_err = numpy.mean(timing_deltas) self._dev_logger.info("beacon_avg_err:%f", timing_err) if max(delta_mags) > 1: self._dev_logger.debug("Large beacon timing delta: %s", timing_deltas) self._dev_logger.debug("timing err %f", timing_err) # compute the start time of the next frame sched_t0 = last_ts + last_beacon.frame_offset - timing_err self._dev_logger.debug("schedule t0 is %s", sched_t0) sched_t0 = sched_t0.round_to_sample(self.rate, self.floored_timestamp) self._dev_logger.debug("rounded schedule t0 is %s", sched_t0) # sched_t0 = time_spec_t(sched_t0.int_s(), round(sched_t0.frac_s()*self.rate)/self.rate) #print "last ts", last_ts #print "schedule is now valid" #print "schedule time is: %s" % sched_t0 #print "schedule beacon is %s" % str(last_beacon) self._sched_lock.acquire() last_beacon.time_ref = sched_t0 self._dev_logger.debug("beacon t0 is %s", last_beacon.time_ref) last_beacon.valid = True self._schedule = last_beacon pickled_sched = cPickle.dumps((last_meta, self._schedule), PICKLE_PROT) self.message_port_pub(self.SCHEDULE_OUT_PORT, pmt.from_python(pickled_sched)) self._schedule_valid = True self._sched_lock.release() return True
def do_time_calibration(self, ts_error): ''' Take in the floating point time stamp error and if there's a change in the timing error calibration constant, publish a message with the new constant. This constant should be added to any rx_time tags, and subtracted from any tx_time tags. Constants will come from the set {-1,0,1} seconds, and are only used to correct for the pps ambiguity we're seeing with the gps timestamps ''' old_offset = self.time_sync_offset offset_valid = False # ts error is mobile_time - base_time # if the mobile is ahead of the base, we need to subtract a second from rx_times if (0.5 < ts_error) and (ts_error < 1.5): self.time_sync_offset = -1 offset_valid = True # else if the mobile is behind the base, we should add a second to rx_times elif (-1.5 < ts_error) and (ts_error < -0.5): self.time_sync_offset = 1 offset_valid = True # else if the mobile is synced to the base, set offset to zero elif (-self._beacon_error_thresh < ts_error) and (ts_error < self._beacon_error_thresh): self.time_sync_offset = 0 offset_valid = True # else something unexpected is going on with sync. Throw out this result and # post a warning else: offset_valid = False self._dev_logger.warn( ("beacon timestamp error of %f seconds is out of " + "anticipated bounds. Not setting a calibration " + "constant"), ts_error) # if there's a valid offset and it's different from the old one, send a time cal # update if offset_valid and (old_offset != self.time_offset): self._dev_logger.debug( ("Time Calibration Successful: Mobile adjusting " + "times by %d seconds"), self.time_sync_offset) self._ll_logging._statelog.info( "<time_calibration_constant>%f</time_calibration_constant>", self.time_sync_offset) #self.set_time_calibration_complete() self.message_port_pub(self.TIME_CAL_OUT_PORT, pmt.from_python(self.time_sync_offset))
def __init__(self, queue_size, from_id): ''' Constructor ''' gr.basic_block.__init__( self, name = "msg_queue_adapter", in_sig = None, out_sig = None) self.pkt_queue = deque(maxlen=queue_size) self.my_id = int(from_id) self.packet_id = 0 self.max_packet_id = 65535 # set up constants for packet headers self.crc_result = True self.pad_bytes = 0 self.pkt_code = 'DATA' self.phy_code = 0 self.mac_code = 0 self.more_data = 0 # set up message port self.IN_PORT = pmt.from_python("in_port") self.message_port_register_in(self.IN_PORT) # set up message port self.OUT_PORT = pmt.from_python("out_port") self.message_port_register_out(self.OUT_PORT) # register message handler for input port self.set_msg_handler(self.IN_PORT, self.store_pkt)
def compute_schedule(self, beacon_list): # compute schedule, and if no errors, set schedule valid flag to true #print "computing schedule" # get last header and beacon in list last_ts, last_meta, last_beacon = beacon_list[-1] self._dev_logger.debug("last beacon's first frame num: %s timestamp: %s found in frame %s", last_beacon.first_frame_num, last_ts, last_meta["frameID"]) timing_deltas = [float(ts - beacon.tx_time) for ts, meta, beacon in beacon_list] delta_mags = [abs(x) for x in timing_deltas] timing_err = numpy.mean(timing_deltas) self._dev_logger.info("beacon_avg_err:%f", timing_err) if max(delta_mags) > 1: self._dev_logger.debug("Large beacon timing delta: %s", timing_deltas) self._dev_logger.debug("timing err %f", timing_err) # compute the start time of the next frame sched_t0 = last_ts+last_beacon.frame_offset-timing_err self._dev_logger.debug("schedule t0 is %s", sched_t0) sched_t0 = sched_t0.round_to_sample(self.rate, self.floored_timestamp) self._dev_logger.debug("rounded schedule t0 is %s", sched_t0) # sched_t0 = time_spec_t(sched_t0.int_s(), round(sched_t0.frac_s()*self.rate)/self.rate) #print "last ts", last_ts #print "schedule is now valid" #print "schedule time is: %s" % sched_t0 #print "schedule beacon is %s" % str(last_beacon) self._sched_lock.acquire() last_beacon.time_ref=sched_t0 self._dev_logger.debug("beacon t0 is %s", last_beacon.time_ref) last_beacon.valid = True self._schedule = last_beacon pickled_sched = cPickle.dumps( (last_meta, self._schedule), PICKLE_PROT) self.message_port_pub(self.SCHEDULE_OUT_PORT, pmt.from_python(pickled_sched)) self._schedule_valid = True self._sched_lock.release() return True
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 sync_lost(self, timestamp): # if first transition after losing sync, must set state variables and # send a schedule update if self._schedule_valid: self._sched_lock.acquire() self._has_sync = False self._schedule_valid = False self._schedule = None self._sched_lock.release() self._dev_logger.info("Sync lost") sched = SimpleFrameSchedule(valid=False,time_ref=timestamp.to_tuple(), frame_config=None) pickled_sched = cPickle.dumps(( {},sched), PICKLE_PROT) self.message_port_pub(self.SCHEDULE_OUT_PORT, pmt.from_python(pickled_sched))
def do_burst(self): #sys.stderr.write("traffic gen do_burst called\n") if (self.q_size is not None) and hasattr(self.q_size, '__call__') : current_q_size = self.q_size(); else: sys.stderr.write("queue size not callable\n") current_q_size = 0 if current_q_size < self.fill_thresh: num_calls = max(0,self.max_queue_size - current_q_size ) #sys.stderr.write("adding %d packets to queue \n" % num_calls) for k in range(num_calls): meta= {"destinationID":random.choice(self.destination_id_list)} self.message_port_pub(self.OUT_PKT_PORT, pmt.pmt_cons(pmt.from_python(meta), self.payload)) return True
def do_time_calibration(self, ts_error): ''' Take in the floating point time stamp error and if there's a change in the timing error calibration constant, publish a message with the new constant. This constant should be added to any rx_time tags, and subtracted from any tx_time tags. Constants will come from the set {-1,0,1} seconds, and are only used to correct for the pps ambiguity we're seeing with the gps timestamps ''' old_offset = self.time_sync_offset offset_valid = False # ts error is mobile_time - base_time # if the mobile is ahead of the base, we need to subtract a second from rx_times if (0.5 < ts_error) and (ts_error < 1.5): self.time_sync_offset = -1 offset_valid = True # else if the mobile is behind the base, we should add a second to rx_times elif ( -1.5 < ts_error) and ( ts_error < -0.5): self.time_sync_offset = 1 offset_valid = True # else if the mobile is synced to the base, set offset to zero elif ( -self._beacon_error_thresh < ts_error ) and ( ts_error < self._beacon_error_thresh): self.time_sync_offset = 0 offset_valid = True # else something unexpected is going on with sync. Throw out this result and # post a warning else: offset_valid = False self._dev_logger.warn( ("beacon timestamp error of %f seconds is out of " + "anticipated bounds. Not setting a calibration "+ "constant"), ts_error) # if there's a valid offset and it's different from the old one, send a time cal # update if offset_valid and (old_offset != self.time_offset): self._dev_logger.debug(("Time Calibration Successful: Mobile adjusting "+ "times by %d seconds"), self.time_sync_offset) self._ll_logging._statelog.info("<time_calibration_constant>%f</time_calibration_constant>", self.time_sync_offset) #self.set_time_calibration_complete() self.message_port_pub(self.TIME_CAL_OUT_PORT, pmt.from_python(self.time_sync_offset))
def sync_lost(self, timestamp): # if first transition after losing sync, must set state variables and # send a schedule update if self._schedule_valid: self._sched_lock.acquire() self._has_sync = False self._schedule_valid = False self._schedule = None self._sched_lock.release() self._dev_logger.info("Sync lost") sched = SimpleFrameSchedule(valid=False, time_ref=timestamp.to_tuple(), frame_config=None) pickled_sched = cPickle.dumps(({}, sched), PICKLE_PROT) self.message_port_pub(self.SCHEDULE_OUT_PORT, pmt.from_python(pickled_sched))
def do_burst(self): #sys.stderr.write("traffic gen do_burst called\n") if (self.q_size is not None) and hasattr(self.q_size, '__call__'): current_q_size = self.q_size() else: sys.stderr.write("queue size not callable\n") current_q_size = 0 if current_q_size < self.fill_thresh: num_calls = max(0, self.max_queue_size - current_q_size) #sys.stderr.write("adding %d packets to queue \n" % num_calls) for k in range(num_calls): meta = { "destinationID": random.choice(self.destination_id_list) } self.message_port_pub( self.OUT_PKT_PORT, pmt.pmt_cons(pmt.from_python(meta), self.payload)) return True
def send_app_pkts(self, app_out_list, **kwargs): ''' Forward packets to application layer ''' frame_nums = set() # note using the double splat operator to take in a dictionary but only # pick out the keyword arguments relevant to this function for pkt in app_out_list: try: meta,data = pkt except ValueError: self.dev_logger.error("Value error for pkt: %s", pkt) raise ValueError self.message_port_pub(TO_APP_PORT, pmt.from_python(data)) frame_nums.add(meta["frameID"]) if len(app_out_list) > 0: self.dev_logger.info("sending %d packets from frames %s to app layer", len(app_out_list), list(frame_nums))
def work(self, input_items, output_items): while not len(self._pkt): try: msg = self.pop_msg_queue() except: return -1 if not pmt.pmt_is_blob(msg.value): self.tx_time,data,self.more_frame_cnt = pmt.to_python(msg.value) self.has_tx_time = True #print data #print tx_time #print data.tostring() else: data = pmt.pmt_blob_data(msg.value) #print data self.has_tx_time = False pkt = packet_utils.make_packet( data.tostring(), self._samples_per_symbol, self._bits_per_symbol, self._access_code, False, #pad_for_usrp, self._whitener_offset, ) pkt += "".join(map(chr, [0x55] * 64)) self._pkt = numpy.fromstring(pkt, numpy.uint8) if self._use_whitener_offset: self._whitener_offset = (self._whitener_offset + 1) % 16 #shouldn't really need to send start of burst #only need to do sob if looking for timed transactions num_items = min(len(self._pkt), len(output_items[0])) output_items[0][:num_items] = self._pkt[:num_items] self._pkt = self._pkt[num_items:] #residue for next work() if len(self._pkt) == 0 : item_index = num_items #which output item gets the tag? offset = self.nitems_written(0) + item_index source = pmt.pmt_string_to_symbol("framer") #print 'frame cnt',self.more_frame_cnt if self.has_tx_time: key = pmt.pmt_string_to_symbol("tx_sob") self.add_item_tag(0, self.nitems_written(0), key, pmt.PMT_T, source) key = pmt.pmt_string_to_symbol("tx_time") self.add_item_tag(0, self.nitems_written(0), key, pmt.from_python(self.tx_time), source) #if self.keep: # print 'bad order' #self.keep = True if self.more_frame_cnt == 0: key = pmt.pmt_string_to_symbol("tx_eob") self.add_item_tag(0, offset - 1, key, pmt.PMT_T, source) #if self.keep: # print 'good order' #self.keep = False else: self.more_frame_cnt -= 1 return num_items
def work(self, input_items, output_items): if self.rx_state == RX_INIT: self.post_msg( CTRL_PORT, pmt.pmt_string_to_symbol('usrp_source.set_center_freq'), pmt.from_python( ((self.rx_freq_list[self.rx_hop_index], ), {})), pmt.pmt_string_to_symbol('fhss')) self.rx_state == RX_SEARCH #check for msg inputs when work function is called if self.check_msg_queue(): try: msg = self.pop_msg_queue() except: return -1 if msg.offset == OUTGOING_PKT_PORT: self.queue.put(msg) #if outgoing, put in queue for processing elif msg.offset == INCOMING_PKT_PORT: if self.know_time: if self.rx_state == RX_SEARCH: self.rx_state = RX_FOUND self.pkt_received = True self.next_tune_time = self.time_update + self.hop_interval - self.tune_lead self.start_hop = self.next_tune_time - self.lead_limit print 'pkt_rcved', self.time_update, self.start_hop, self.next_tune_time else: self.pkt_received = True print 'pkt_rcved', self.time_update, self.start_hop, self.next_tune_time else: pass #CONTROL port #process streaming samples and tags here in0 = input_items[0] nread = self.nitems_read(0) #number of items read on port 0 ninput_items = len(input_items[0]) #read all tags associated with port 0 for items in this work function tags = self.get_tags_in_range(0, nread, nread + ninput_items) #lets find all of our tags, making the appropriate adjustments to our timing for tag in tags: key_string = pmt.pmt_symbol_to_string(tag.key) if key_string == "rx_time": self.samples_since_last_rx_time = 0 self.current_integer, self.current_fractional = pmt.to_python( tag.value) self.time_update = self.current_integer + self.current_fractional self.found_time = True elif key_string == "rx_rate": self.rate = pmt.to_python(tag.value) self.sample_period = 1 / self.rate self.found_rate = True #determine first transmit slot when we learn the time if not self.know_time: if self.found_time and self.found_rate: self.know_time = True #TODO: this stuff is left over from tdma.py, see if we can re-use this somehow #self.frame_period = self.slot_interval * self.num_slots #my_fraction_frame = ( self.initial_slot * 1.0 ) / ( self.num_slots) #frame_count = math.floor(self.time_update / self.frame_period) #current_slot_interval = ( self.time_update % self.frame_period ) / self.frame_period #self.time_transmit_start = (frame_count + 2) * self.frame_period + ( my_fraction_frame * self.frame_period ) - self.lead_limit self.time_transmit_start = self.time_update + ( self.lead_limit * 10.0) self.interval_start = self.time_transmit_start + self.lead_limit #get current time self.time_update += (self.sample_period * ninput_items) #determine if it's time for us to start tx'ing, start process self.lead_limit seconds #before our slot actually begins (i.e. deal with latency) if self.time_update > self.time_transmit_start: self.antenna_start = self.interval_start + self.post_guard self.tx_frames() #do more than this? #print self.interval_start,self.antenna_start self.interval_start += self.hop_interval self.time_transmit_start = self.interval_start - self.lead_limit if self.rx_state == RX_FOUND: if self.time_update > self.start_hop: #self.post_msg(CTRL_PORT,pmt.pmt_string_to_symbol('usrp_source.set_command_time'),pmt.from_python( ( ( self.next_tune_time , ), { } ) ),pmt.pmt_string_to_symbol('fhss')) #self.post_msg(CTRL_PORT,pmt.pmt_string_to_symbol('usrp_source.set_center_freq'),pmt.from_python( ( ( self.rx_freq_list[self.rx_hop_index] , ), { } ) ),pmt.pmt_string_to_symbol('fhss')) #self.post_msg(CTRL_PORT,pmt.pmt_string_to_symbol('usrp_source.clear_command_time'),pmt.from_python( ( ( 0 , ), { } ) ),pmt.pmt_string_to_symbol('fhss')) self.rx_hop_index = (self.rx_hop_index + 1) % self.rx_freq_list_length self.start_hop += self.hop_interval self.next_tune_time += self.next_tune_time #self.next_rx_interval += self.hop_interval - self.tune_lead if self.pkt_received: self.consecutive_miss = 0 else: self.consecutive_miss += 1 if self.consecutive_miss > LOST_SYNC_THRESHOLD: self.rx_state = RX_INIT print 'reset' self.pkt_received = False return ninput_items
def work(self, input_items, output_items): while not len(self._pkt): try: msg = self.pop_msg_queue() except: return -1 if not pmt.pmt_is_blob(msg.value): self.tx_time, data, self.more_frame_cnt = pmt.to_python( msg.value) self.has_tx_time = True #print data #print tx_time #print data.tostring() else: data = pmt.pmt_blob_data(msg.value) #print data self.has_tx_time = False pkt = packet_utils.make_packet( data.tostring(), self._samples_per_symbol, self._bits_per_symbol, self._access_code, False, #pad_for_usrp, self._whitener_offset, ) self._pkt = numpy.fromstring(pkt, numpy.uint8) if self._use_whitener_offset: self._whitener_offset = (self._whitener_offset + 1) % 16 #shouldn't really need to send start of burst #only need to do sob if looking for timed transactions num_items = min(len(self._pkt), len(output_items[0])) output_items[0][:num_items] = self._pkt[:num_items] self._pkt = self._pkt[num_items:] #residue for next work() if len(self._pkt) == 0: item_index = num_items #which output item gets the tag? offset = self.nitems_written(0) + item_index source = pmt.pmt_string_to_symbol("framer") #print 'frame cnt',self.more_frame_cnt if self.has_tx_time: key = pmt.pmt_string_to_symbol("tx_sob") self.add_item_tag(0, self.nitems_written(0), key, pmt.PMT_T, source) key = pmt.pmt_string_to_symbol("tx_time") self.add_item_tag(0, self.nitems_written(0), key, pmt.from_python(self.tx_time), source) #if self.keep: # print 'bad order' #self.keep = True if self.more_frame_cnt == 0: key = pmt.pmt_string_to_symbol("tx_eob") self.add_item_tag(0, offset - 1, key, pmt.PMT_T, source) #if self.keep: # print 'good order' #self.keep = False else: self.more_frame_cnt -= 1 return num_items
def tx_frames(self): #send_sob #self.post_msg(TO_FRAMER_PORT, pmt.pmt_string_to_symbol('tx_sob'), pmt.PMT_T, pmt.pmt_string_to_symbol('tx_sob')) #get all of the packets we want to send total_byte_count = 0 frame_count = 0 #put residue from previous execution if self.has_old_msg: length = len(pmt.pmt_blob_data(self.old_msg.value)) + self.overhead total_byte_count += length self.tx_queue.put(self.old_msg) frame_count += 1 self.has_old_msg = False print 'old msg' #fill outgoing queue until empty or maximum bytes queued for slot while (not self.queue.empty()): msg = self.queue.get() length = len(pmt.pmt_blob_data(msg.value)) + self.overhead total_byte_count += length if total_byte_count >= self.bytes_per_slot: self.has_old_msg = True self.old_msg = msg print 'residue' continue else: self.has_old_msg = False self.tx_queue.put(msg) frame_count += 1 time_object = int(math.floor( self.antenna_start)), (self.antenna_start % 1) #if no data, send a single pad frame #TODO: add useful pad data, i.e. current time of SDR if frame_count == 0: #pad_d = struct.pack('!H', self.pktno & 0xffff) + (self.bytes_per_slot - 100) * chr(self.pktno & 0xff) #zeros = 64*chr(0x00) if self.initial_slot == 0: prefix = pn511s[0] else: prefix = pn511s[1] #for i in range(self.prefix_len): # if i == self.prefix_loc: # seg = zeros + pn511s[i] #put the PN code to the prefix # else: # seg = 128*chr(0x00) # the prefix looks like 0000000...0000PPPPPP...PPPP0000000.....000000 # |___512bit_||____512bit_||___M*1024bit_____| # M+N+1 := num_slots # N+1 := prefix_loc # prefix = prefix + seg rdata = '' if self.from_file == 1 and self.sfile != 0: rdata = self.sfile.read(self.bytes_per_slot - 64 * self.prefix_len - 100) if len(rdata) > 0: pad_d = rdata elif self.from_file == 2 and self.sfile != 0: #repeated sending the same packets for Virtual MIMO testing self.sfile.seek(0) #go the beginning of file rdata = self.sfile.read(self.bytes_per_slot - 64 * self.prefix_len - 100) if len(rdata) > 0: pad_d = rdata else: if self.initial_slot == 0: # use the unique PN code to specify the first slot pad_d = 16 * pn511_0 #+ (self.bytes_per_slot - 64) * chr(self.pktno & 0xff) else: pad_d = 16 * pn511_1 pad_d = prefix + pad_d #send PN and data at different slots for MIMO postmsg = True if self.mimo == True: postmsg = True if self.pktno % 3 == self.prefix_loc: pad_d = pn511_0 elif self.pktno % 3 == 2: pad_d = rdata else: postmsg = False data = numpy.fromstring(pad_d, dtype='uint8') #data = self.pad_data #data = pad_d more_frames = 0 tx_object = time_object, data, more_frames print 'prefix_loc = %d' % (self.prefix_loc) print 'antenna_start = %7f' % (self.antenna_start) if postmsg: self.post_msg(TO_FRAMER_PORT, pmt.pmt_string_to_symbol('full'), pmt.from_python(tx_object), pmt.pmt_string_to_symbol('tdma')) self.pktno += 1 #print 'tx_frames:post message from the pad data' else: #print frame_count,self.queue.qsize(), self.tx_queue.qsize() #send first frame w tuple for tx_time and number of frames to put in slot blob = self.mgr.acquire(True) #block more_frames = frame_count - 1 msg = self.tx_queue.get() data = pmt.pmt_blob_data(msg.value) tx_object = time_object, data, more_frames self.post_msg(TO_FRAMER_PORT, pmt.pmt_string_to_symbol('full'), pmt.from_python(tx_object), pmt.pmt_string_to_symbol('tdma')) frame_count -= 1 old_data = [] #print 'frame count: ',frame_count #send remining frames, blob only while (frame_count > 0): msg = self.tx_queue.get() data = pmt.pmt_blob_data(msg.value) blob = self.mgr.acquire(True) #block pmt.pmt_blob_resize(blob, len(data)) pmt.pmt_blob_rw_data(blob)[:] = data self.post_msg(TO_FRAMER_PORT, pmt.pmt_string_to_symbol('d_only'), blob, pmt.pmt_string_to_symbol('tdma')) frame_count -= 1
from digital_ll import lincolnlog from digital_ll import packet_utils2 from digital_ll import SimpleFrameSchedule from digital_ll import SlotParamTuple from digital_ll import time_spec_t from digital_ll.beacon_utils import TDMA_HEADER_MAX_FIELD_VAL from digital_ll.lincolnlog import dict_to_xml from mac_ll import tdma_mobile_sm #block port definitions - inputs FROM_APP_PORT = pmt.from_python('from_app') # packets coming from the application layer INCOMING_PKT_PORT = pmt.from_python('incoming_pkt') # packets arriving from the rf interface SCHEDULE_IN_PORT = pmt.from_python('sched_in') #block port definitions - outputs OUTGOING_PKT_PORT = pmt.from_python('outgoing_pkt') # packets being sent out the rf interface TO_APP_PORT = pmt.from_python('to_app') # packets being forwarded out to the application layer COMMAND_OUT_PORT = pmt.from_python('command_out') #Time state machine LOOKING_FOR_TIME = 0 HAVE_TIME = 0 # ///////////////////////////////////////////////////////////////////////////// # TDMA MAC
def work(self, input_items, output_items): while(1):#for simplicty, we'll loop. Blocks on self.pop call try: msg = self.pop_msg_queue() except: return -1 #test to make sure this is a blob if not pmt.pmt_is_blob(msg.value): continue if msg.offset == DATA_IN: #recall that a pmt includes a key, source, offset, and value key = pmt.pmt_symbol_to_string(msg.key) print "Key: ",key #now lets get the actual data blob = pmt.pmt_blob_data(msg.value) print "Blob Value: ",blob.tostring() else: pkt_str = "I've seen an event" key_str = "event_report" src_str = "my_first_msg_block" blob = self.mgr.acquire(True) #block pmt.pmt_blob_resize(blob, len(pkt_str)) pmt.pmt_blob_rw_data(blob)[:] = numpy.fromstring(pkt_str, dtype='uint8') self.post_msg(DATA_OUT, pmt.pmt_string_to_symbol(key_str), msg.value, pmt.pmt_string_to_symbol(src_str)) print self.freq_list[self.index] self.post_msg(CTRL_OUT,pmt.pmt_string_to_symbol('usrp_source.set_center_freq'),pmt.from_python( ( ( self.freq_list[self.index] , ), { } ) ),pmt.pmt_string_to_symbol('2nd_block')) self.index = ( self.index + 1 ) % self.freq_list_len
def work(self, input_items, output_items): if self.rx_state == RX_INIT: self.post_msg(CTRL_PORT,pmt.pmt_string_to_symbol('usrp_source.set_center_freq'),pmt.from_python( ( ( self.rx_freq_list[self.rx_hop_index] , ), { } ) ),pmt.pmt_string_to_symbol('fhss')) self.rx_state == RX_SEARCH #check for msg inputs when work function is called if self.check_msg_queue(): try: msg = self.pop_msg_queue() except: return -1 if msg.offset == OUTGOING_PKT_PORT: self.queue.put(msg) #if outgoing, put in queue for processing elif msg.offset == INCOMING_PKT_PORT: if self.know_time: if self.rx_state == RX_SEARCH: self.rx_state = RX_FOUND self.pkt_received = True self.next_tune_time = self.time_update + self.hop_interval - self.tune_lead self.start_hop = self.next_tune_time - self.lead_limit print 'pkt_rcved',self.time_update,self.start_hop,self.next_tune_time else: self.pkt_received = True print 'pkt_rcved',self.time_update,self.start_hop,self.next_tune_time else: pass #CONTROL port #process streaming samples and tags here in0 = input_items[0] nread = self.nitems_read(0) #number of items read on port 0 ninput_items = len(input_items[0]) #read all tags associated with port 0 for items in this work function tags = self.get_tags_in_range(0, nread, nread+ninput_items) #lets find all of our tags, making the appropriate adjustments to our timing for tag in tags: key_string = pmt.pmt_symbol_to_string(tag.key) if key_string == "rx_time": self.samples_since_last_rx_time = 0 self.current_integer,self.current_fractional = pmt.to_python(tag.value) self.time_update = self.current_integer + self.current_fractional self.found_time = True elif key_string == "rx_rate": self.rate = pmt.to_python(tag.value) self.sample_period = 1/self.rate self.found_rate = True #determine first transmit slot when we learn the time if not self.know_time: if self.found_time and self.found_rate: self.know_time = True #TODO: this stuff is left over from tdma.py, see if we can re-use this somehow #self.frame_period = self.slot_interval * self.num_slots #my_fraction_frame = ( self.initial_slot * 1.0 ) / ( self.num_slots) #frame_count = math.floor(self.time_update / self.frame_period) #current_slot_interval = ( self.time_update % self.frame_period ) / self.frame_period #self.time_transmit_start = (frame_count + 2) * self.frame_period + ( my_fraction_frame * self.frame_period ) - self.lead_limit self.time_transmit_start = self.time_update + ( self.lead_limit * 10.0 ) self.interval_start = self.time_transmit_start + self.lead_limit #get current time self.time_update += (self.sample_period * ninput_items) #determine if it's time for us to start tx'ing, start process self.lead_limit seconds #before our slot actually begins (i.e. deal with latency) if self.time_update > self.time_transmit_start: self.antenna_start = self.interval_start + self.post_guard self.tx_frames() #do more than this? #print self.interval_start,self.antenna_start self.interval_start += self.hop_interval self.time_transmit_start = self.interval_start - self.lead_limit if self.rx_state == RX_FOUND: if self.time_update > self.start_hop: #self.post_msg(CTRL_PORT,pmt.pmt_string_to_symbol('usrp_source.set_command_time'),pmt.from_python( ( ( self.next_tune_time , ), { } ) ),pmt.pmt_string_to_symbol('fhss')) #self.post_msg(CTRL_PORT,pmt.pmt_string_to_symbol('usrp_source.set_center_freq'),pmt.from_python( ( ( self.rx_freq_list[self.rx_hop_index] , ), { } ) ),pmt.pmt_string_to_symbol('fhss')) #self.post_msg(CTRL_PORT,pmt.pmt_string_to_symbol('usrp_source.clear_command_time'),pmt.from_python( ( ( 0 , ), { } ) ),pmt.pmt_string_to_symbol('fhss')) self.rx_hop_index = (self.rx_hop_index + 1 ) % self.rx_freq_list_length self.start_hop += self.hop_interval self.next_tune_time += self.next_tune_time #self.next_rx_interval += self.hop_interval - self.tune_lead if self.pkt_received: self.consecutive_miss = 0 else: self.consecutive_miss += 1 if self.consecutive_miss > LOST_SYNC_THRESHOLD: self.rx_state = RX_INIT print 'reset' self.pkt_received = False return ninput_items
def tx_frames(self): #send_sob #self.post_msg(TO_FRAMER_PORT, pmt.pmt_string_to_symbol('tx_sob'), pmt.PMT_T, pmt.pmt_string_to_symbol('tx_sob')) #get all of the packets we want to send total_byte_count = 0 frame_count = 0 #put residue from previous execution if self.has_old_msg: length = len(pmt.pmt_blob_data(self.old_msg.value)) + self.overhead total_byte_count += length self.tx_queue.put(self.old_msg) frame_count += 1 self.has_old_msg = False print 'old msg' #fill outgoing queue until empty or maximum bytes queued for slot while (not self.queue.empty()): msg = self.queue.get() length = len(pmt.pmt_blob_data(msg.value)) + self.overhead total_byte_count += length if total_byte_count >= self.bytes_per_slot: self.has_old_msg = True self.old_msg = msg print 'residue' continue else: self.has_old_msg = False self.tx_queue.put(msg) frame_count += 1 time_object = int(math.floor( self.antenna_start)), (self.antenna_start % 1) #if no data, send a single pad frame #TODO: add useful pad data, i.e. current time of SDR if frame_count == 0: data = self.pad_data more_frames = 0 tx_object = time_object, data, more_frames self.post_msg(TO_FRAMER_PORT, pmt.pmt_string_to_symbol('full'), pmt.from_python(tx_object), pmt.pmt_string_to_symbol('tdma')) else: #print frame_count,self.queue.qsize(), self.tx_queue.qsize() #send first frame w tuple for tx_time and number of frames to put in slot blob = self.mgr.acquire(True) #block more_frames = frame_count - 1 msg = self.tx_queue.get() data = pmt.pmt_blob_data(msg.value) tx_object = time_object, data, more_frames self.post_msg(TO_FRAMER_PORT, pmt.pmt_string_to_symbol('full'), pmt.from_python(tx_object), pmt.pmt_string_to_symbol('tdma')) frame_count -= 1 old_data = [] #print 'frame count: ',frame_count #send remining frames, blob only while (frame_count > 0): msg = self.tx_queue.get() data = pmt.pmt_blob_data(msg.value) blob = self.mgr.acquire(True) #block pmt.pmt_blob_resize(blob, len(data)) pmt.pmt_blob_rw_data(blob)[:] = data self.post_msg(TO_FRAMER_PORT, pmt.pmt_string_to_symbol('d_only'), blob, pmt.pmt_string_to_symbol('tdma')) frame_count -= 1
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 send_pkt(self, data): self.message_port_pub(self.OUT_PORT, pmt.from_python(data))
def work(self, input_items, output_items): if self.rx_state == RX_INIT: self.rx_hop_index = 0 self.rx_state = RX_SEARCH self.post_msg( CTRL_PORT, pmt.pmt_string_to_symbol("usrp_source.set_center_freq"), pmt.from_python(((self.rx_freq_list[self.rx_hop_index],), {})), pmt.pmt_string_to_symbol("fhss"), ) self.rx_hop_index = (self.rx_hop_index + 1) % self.rx_freq_list_length print "Initialized to channel 0. Searching..." # check for msg inputs when work function is called if self.check_msg_queue(): try: msg = self.pop_msg_queue() except: return -1 if msg.offset == INCOMING_PKT_PORT: pkt = pmt.pmt_blob_data(msg.value) if pkt[0]: blob = self.mgr.acquire(True) # block pmt.pmt_blob_resize(blob, len(pkt) - 1) pmt.pmt_blob_rw_data(blob)[:] = pkt[1:] self.post_msg(APP_PORT, pmt.pmt_string_to_symbol("rx"), blob, pmt.pmt_string_to_symbol("fhss")) if self.know_time: if self.rx_state == RX_SEARCH: self.rx_state = RX_FOUND self.pkt_received = True self.next_tune_time = self.time_update + self.hop_interval - self.tune_lead self.start_hop = self.next_tune_time - self.lead_limit print "Received packet. Locked. Hopping initialized." else: self.pkt_received = True # print 'pkt_rcved_2',self.time_update,self.start_hop,self.next_tune_time else: a = 0 # CONTROL port # process streaming samples and tags here in0 = input_items[0] nread = self.nitems_read(0) # number of items read on port 0 ninput_items = len(input_items[0]) # read all tags associated with port 0 for items in this work function tags = self.get_tags_in_range(0, nread, nread + ninput_items) # lets find all of our tags, making the appropriate adjustments to our timing for tag in tags: key_string = pmt.pmt_symbol_to_string(tag.key) if key_string == "rx_time": self.samples_since_last_rx_time = 0 self.current_integer, self.current_fractional = pmt.to_python(tag.value) self.time_update = self.current_integer + self.current_fractional self.found_time = True elif key_string == "rx_rate": self.rate = pmt.to_python(tag.value) self.sample_period = 1 / self.rate self.found_rate = True # determine first transmit slot when we learn the time if not self.know_time: if self.found_time and self.found_rate: self.know_time = True else: # get current time self.time_update += self.sample_period * ninput_items if self.rx_state == RX_FOUND: if self.time_update > self.start_hop: # print 'set: ', self.rx_freq_list[self.rx_hop_index], self.time_update, self.next_tune_time self.post_msg( CTRL_PORT, pmt.pmt_string_to_symbol("usrp_source.set_command_time"), pmt.from_python(((self.next_tune_time,), {})), pmt.pmt_string_to_symbol("fhss"), ) self.post_msg( CTRL_PORT, pmt.pmt_string_to_symbol("usrp_source.set_center_freq"), pmt.from_python(((self.rx_freq_list[self.rx_hop_index],), {})), pmt.pmt_string_to_symbol("fhss"), ) self.post_msg( CTRL_PORT, pmt.pmt_string_to_symbol("usrp_source.clear_command_time"), pmt.from_python(((0,), {})), pmt.pmt_string_to_symbol("fhss"), ) self.rx_hop_index = (self.rx_hop_index + 1) % self.rx_freq_list_length self.start_hop += self.hop_interval self.next_tune_time += self.hop_interval # self.next_rx_interval += self.hop_interval - self.tune_lead if self.pkt_received: self.consecutive_miss = 0 else: self.consecutive_miss += 1 if self.consecutive_miss > LOST_SYNC_THRESHOLD: self.consecutive_miss = 0 self.rx_state = RX_INIT print "Lost Sync: Re-Initializing" self.pkt_received = False return ninput_items
def work(self, input_items, output_items): #print "in work" offset = self.nitems_written(0) item_index = 0 while not len(self._pkt): # try: meta, payload = self.in_packets.get(True,.1) try: meta, payload = self.in_packets.popleft() if len(payload) == 0: payload = "" # FIXME meta["frequency"] will be baseband frequency. except IndexError: #print "can't pop yet" return 0 if "tx_time" in meta: self.tx_time = meta["tx_time"] self.more_frame_cnt = meta["more_pkt_cnt"] self.has_tx_time = True # clear tx_time and more_pkt_count from the packet metadata, since # they shouldn't go in the logs del meta["tx_time"] del meta["more_pkt_cnt"] #print payload #print tx_time #print payload.tostring() else: #print payload self.has_tx_time = False pkt = packet_utils2.make_packet(payload, self._samples_per_symbol, self._bits_per_symbol, None, # options self._access_code, False, #pad_for_usrp self._use_coding, None, # logging self._whitener_offset) # add any metadata params that don't belong in the over the air packet meta["direction"] = "transmit" # packet framer is always in transmit direction meta["messagelength"] = len(pkt) self._pkt = numpy.fromstring(pkt, numpy.uint8) if self._use_whitener_offset: self._whitener_offset = (self._whitener_offset + 1) % 16 #shouldn't really need to send start of burst #only need to do sob if looking for timed transactions num_items = min(len(self._pkt), len(output_items[0])) output_items[0][item_index:item_index+num_items] = self._pkt[:num_items] self._pkt = self._pkt[num_items:] #residue for next work() # print "num items: %d length _pkt: %d" %(num_items, len(self._pkt)) if len(self._pkt) == 0 : #which output item gets the tag? source = pmt.pmt_string_to_symbol("framer") # add tx rate tag if this is the first packet in the run if offset + item_index == 0: key = pmt.pmt_string_to_symbol("tx_rate") val = pmt.from_python(self._fs) self.add_item_tag(0, offset+item_index, key, val, source) if self.has_tx_time: key = pmt.pmt_string_to_symbol("tx_sob") self.add_item_tag(0, offset+item_index, key, pmt.PMT_T, source) key = pmt.pmt_string_to_symbol("tx_time") self.add_item_tag(0, offset+item_index, key, pmt.from_python(self.tx_time), source) # FIXME Add tx_new_channel tag which specifies the channel key = pmt.pmt_string_to_symbol("tx_new_channel") #if "frequency" in meta.keys(): # meta["frequency"] = self.convert_channel_to_hz(meta["frequency"]) self.add_item_tag(0, offset+item_index, key, pmt.from_python(meta["frequency"]), source) self._dev_logger.debug("adding tx_sob with time %s at offset %ld", self.tx_time,offset+item_index) #if self.keep: # print 'bad order' #self.keep = True # add packet metadata tag key = pmt.pmt_string_to_symbol("packetlog") val = pmt.from_python(meta) #print "sending packet %d bytes" % meta["messagelength"] # print "adding packet log tag at offset %ld" %( offset+item_index) self.add_item_tag(0, offset+item_index, key, val, source) # add length of current packet to item index item_index+=num_items if self.more_frame_cnt == 0: # print "adding tx_eob tag at offset %ld" %( offset+item_index) key = pmt.pmt_string_to_symbol("tx_eob") self.add_item_tag(0, offset + item_index-1, key, pmt.PMT_T, source) self._dev_logger.debug("adding tx_eob at offset %ld", offset + item_index-1) #if self.keep: # print 'good order' #self.keep = False else: self.more_frame_cnt -= 1 return item_index else: #print "self._pkt had residue" num_items = min(len(self._pkt), len(output_items[0])) output_items[0][:num_items] = self._pkt[:num_items] self._pkt = self._pkt[num_items:] #residue for next work() return item_index + num_items
def work(self, input_items, output_items): in0 = input_items[0] out = output_items[0] nread = self.nitems_read(0) #number of items read on port 0 ninput_items = len(input_items[0]) noutput_items = len(output_items[0]) nitems_to_consume = min(ninput_items, noutput_items) out[:nitems_to_consume] = in0[:nitems_to_consume] # output any tags left over from the last iteration if they're ready ready_tags = [ x for x in self.tag_residues if x[0] < self.nitems_written(0) + ninput_items ] # test if we're writing past what we're allowed for tag in ready_tags: if tag[0] >= self.nitems_written(0) + nitems_to_consume: self.dev_logger.error("writing tags out of range. bad idea") for offset, key, value, srcid in ready_tags: # self.dev_logger.debug("adding key %s value %s source %s at offset %s", # key,value,srcid, offset) self.add_item_tag(0, offset, pmt.from_python(key), pmt.from_python(value), pmt.from_python(srcid)) # keep tags in residues that aren't ready yet self.tag_residues = [ x for x in self.tag_residues if x[0] >= self.nitems_written(0) + ninput_items ] #read all tags associated with port 0 for items in this work function tags = self.get_tags_in_range(0, nread, nread + nitems_to_consume) for tag in tags: if pmt.pmt_symbol_to_string(tag.key) == self.eob_key: new_offset = tag.offset + self.upsamp_factor - 1 # if the new offset is still in this work block, shift the tag. # Otherwise store the tag tuple for the next call if new_offset < self.nitems_written(0) + ninput_items: # self.dev_logger.debug("adding key %s value %s source %s at offset %s", # pmt.to_python(tag.key),pmt.to_python(tag.value),pmt.to_python(tag.srcid), new_offset) self.add_item_tag(0, new_offset, tag.key, tag.value, tag.srcid) else: # turning into native python types in case seg fault issue is due to memory management self.tag_residues.append( (new_offset, pmt.to_python(tag.key), pmt.to_python(tag.value), pmt.to_python(tag.srcid))) else: # self.dev_logger.debug("adding key %s value %s source %s at offset %s", # pmt.to_python(tag.key),pmt.to_python(tag.value),pmt.to_python(tag.srcid), tag.offset) self.add_item_tag(0, tag.offset, tag.key, tag.value, tag.srcid) return nitems_to_consume
def __init__(self, options): gr.basic_block.__init__( self, name = "tunnel_handler_pdu", in_sig = None, out_sig = None) # store initial vars from constructor self.tun_device_filename = options.tuntap_device_filename self.tun_device_name = options.tuntap_device_name self.max_pkt_size = int(options.tuntap_mtu) # TODO: Don't set up interface if options are wrong # process the mac and IP address lists from strings to lists self.mac_id = options.source_mac_address self.mac_id_list = options.sink_mac_addresses self.ip_string_list = options.tuntap_sink_ip_addresses.split(',') self.mac_high_bytes = 0xc6ffffff # get this node's mac address in hex hex_str = '%12x' % ( (self.mac_high_bytes<<16) + self.mac_id) self.mac_hex = ':'.join( [ hex_str[0:2], hex_str[2:4], hex_str[4:6], hex_str[6:8], hex_str[8:10], hex_str[10:12] ] ) self.ip_address = options.tuntap_source_ip_address self.use_persistent_tunnel = options.tuntap_use_persistent_device self.logger = logging.getLogger('developer') # define initial values for tun_fd and self.tun_ifname in case the node source # address is invalid self.tun_fd = -1; self.tun_ifname = "error" self.keep_going = False #self.ip_address = "0.0.0.0" self.keep_going = True self.OUT_PKT_PORT = pmt.from_python("out_pkt_port") self.IN_PKT_PORT = pmt.from_python("in_pkt_port") # register outgoing packet port self.message_port_register_out(self.OUT_PKT_PORT) # register incoming packet port self.message_port_register_in(self.IN_PKT_PORT) # register message handler for input port self.set_msg_handler(self.IN_PKT_PORT, self.write_to_network) # open the TUN/TAP interface (self.tun_fd, self.tun_ifname) = self.open_tun_interface() # set up the mac and ip address for the tunnel device self.configure_tun_device() # set up the arp cache self.add_arp_entries() self._network_read_thread = threading.Thread(target=self.read_from_network) # mark this thread as a daemon so the program doesn't wait for it when # closing self._network_read_thread.daemon = True # don't start the thread until you're ready to deal with traffic self._network_read_thread.start()
def __init__(self, options): gr.basic_block.__init__(self, name="tunnel_handler_pdu", in_sig=None, out_sig=None) # store initial vars from constructor self.tun_device_filename = options.tuntap_device_filename self.tun_device_name = options.tuntap_device_name self.max_pkt_size = int(options.tuntap_mtu) # TODO: Don't set up interface if options are wrong # process the mac and IP address lists from strings to lists self.mac_id = options.source_mac_address self.mac_id_list = options.sink_mac_addresses self.ip_string_list = options.tuntap_sink_ip_addresses.split(',') self.mac_high_bytes = 0xc6ffffff # get this node's mac address in hex hex_str = '%12x' % ((self.mac_high_bytes << 16) + self.mac_id) self.mac_hex = ':'.join([ hex_str[0:2], hex_str[2:4], hex_str[4:6], hex_str[6:8], hex_str[8:10], hex_str[10:12] ]) self.ip_address = options.tuntap_source_ip_address self.use_persistent_tunnel = options.tuntap_use_persistent_device self.logger = logging.getLogger('developer') # define initial values for tun_fd and self.tun_ifname in case the node source # address is invalid self.tun_fd = -1 self.tun_ifname = "error" self.keep_going = False #self.ip_address = "0.0.0.0" self.keep_going = True self.OUT_PKT_PORT = pmt.from_python("out_pkt_port") self.IN_PKT_PORT = pmt.from_python("in_pkt_port") # register outgoing packet port self.message_port_register_out(self.OUT_PKT_PORT) # register incoming packet port self.message_port_register_in(self.IN_PKT_PORT) # register message handler for input port self.set_msg_handler(self.IN_PKT_PORT, self.write_to_network) # open the TUN/TAP interface (self.tun_fd, self.tun_ifname) = self.open_tun_interface() # set up the mac and ip address for the tunnel device self.configure_tun_device() # set up the arp cache self.add_arp_entries() self._network_read_thread = threading.Thread( target=self.read_from_network) # mark this thread as a daemon so the program doesn't wait for it when # closing self._network_read_thread.daemon = True # don't start the thread until you're ready to deal with traffic self._network_read_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 read_from_network(self): ''' This function reads packets from the network layer and puts them in a queue for the MAC layer to handle. ''' self.logger.debug("starting tuntap read from network") while self.keep_going: data = os.read(self.tun_fd, 10 * 1024) #print data.encode('hex') # if there's an error with the tunnel interface if not data: self.logger.error("Error reading from tunnel device") break # only add packet to queue if it is under the maximum allowed size # if len(data) < self.max_pkt_size: # map ip destination address to appropriate mac address to_id = self.read_mac_dest(data) self.logger.debug("read returned. len data is %d", len(data)) # self.logger.debug("data is %s", data) if to_id > 0: self.logger.debug("sending message to mac id %d", to_id) meta = {"destinationID": to_id} self.message_port_pub( self.OUT_PKT_PORT, pmt.pmt_cons(pmt.from_python(meta), pmt.from_python(data))) # handle broadcast case elif to_id == -1: for mac_id in self.mac_id_list: if mac_id != self.mac_id: self.logger.debug( "sending broadcast message to mac id %d", mac_id) meta = {"destinationID": mac_id} self.message_port_pub( self.OUT_PKT_PORT, pmt.pmt_cons(pmt.from_python(meta), pmt.from_python(data))) # else: # self.logger.debug("type of len(data) is %s. Type of max_pkt_size is %s", type(len(data)), type(self.max_pkt_size)) # msg = () # self.logger.warning("provided packet length of %s exceeds maximum " + # "allowed packet length of %s. Dropping this packet", # len(data), self.max_pkt_size) try: os.close(self.tun_fd) except OSError as e: if e.errno == os.errno.EBADF: self.logger.warning("Tunnel file descriptor is bad") else: self.logger.error( "unexpected error when closing tunnel file descriptor") raise self.logger.debug("tunnel interface read from network complete")
def tx_frames(self): #send_sob #self.post_msg(TO_FRAMER_PORT, pmt.pmt_string_to_symbol('tx_sob'), pmt.PMT_T, pmt.pmt_string_to_symbol('tx_sob')) #get all of the packets we want to send total_byte_count = 0 frame_count = 0 #put residue from previous execution if self.has_old_msg: length = len(pmt.pmt_blob_data(self.old_msg.value)) + self.overhead total_byte_count += length self.tx_queue.put(self.old_msg) frame_count += 1 self.has_old_msg = False print 'old msg' #fill outgoing queue until empty or maximum bytes queued for slot while(not self.queue.empty()): msg = self.queue.get() length = len(pmt.pmt_blob_data(msg.value)) + self.overhead total_byte_count += length if total_byte_count >= self.bytes_per_slot: self.has_old_msg = True self.old_msg = msg print 'residue' continue else: self.has_old_msg = False self.tx_queue.put(msg) frame_count += 1 time_object = int(math.floor(self.antenna_start)),(self.antenna_start % 1) #if no data, send a single pad frame #TODO: add useful pad data, i.e. current time of SDR if frame_count == 0: data = self.pad_data more_frames = 0 tx_object = time_object,data,more_frames self.post_msg(TO_FRAMER_PORT,pmt.pmt_string_to_symbol('full'),pmt.from_python(tx_object),pmt.pmt_string_to_symbol('tdma')) else: #print frame_count,self.queue.qsize(), self.tx_queue.qsize() #send first frame w tuple for tx_time and number of frames to put in slot blob = self.mgr.acquire(True) #block more_frames = frame_count - 1 msg = self.tx_queue.get() data = pmt.pmt_blob_data(msg.value) tx_object = time_object,data,more_frames self.post_msg(TO_FRAMER_PORT,pmt.pmt_string_to_symbol('full'),pmt.from_python(tx_object),pmt.pmt_string_to_symbol('tdma')) frame_count -= 1 old_data = [] #print 'frame count: ',frame_count #send remining frames, blob only while(frame_count > 0): msg = self.tx_queue.get() data = pmt.pmt_blob_data(msg.value) blob = self.mgr.acquire(True) #block pmt.pmt_blob_resize(blob, len(data)) pmt.pmt_blob_rw_data(blob)[:] = data self.post_msg(TO_FRAMER_PORT,pmt.pmt_string_to_symbol('d_only'),blob,pmt.pmt_string_to_symbol('tdma')) frame_count -= 1
def tx_frames(self): #send_sob #self.post_msg(TO_FRAMER_PORT, pmt.pmt_string_to_symbol('tx_sob'), pmt.PMT_T, pmt.pmt_string_to_symbol('tx_sob')) #get all of the packets we want to send total_byte_count = 0 frame_count = 0 #put residue from previous execution if self.has_old_msg: length = len(pmt.pmt_blob_data(self.old_msg.value)) + self.overhead total_byte_count += length self.tx_queue.put(self.old_msg) frame_count += 1 self.has_old_msg = False print 'old msg' #fill outgoing queue until empty or maximum bytes queued for slot while(not self.queue.empty()): msg = self.queue.get() length = len(pmt.pmt_blob_data(msg.value)) + self.overhead total_byte_count += length if total_byte_count >= self.bytes_per_slot: self.has_old_msg = True self.old_msg = msg print 'residue' continue else: self.has_old_msg = False self.tx_queue.put(msg) frame_count += 1 time_object = int(math.floor(self.antenna_start)),(self.antenna_start % 1) #if no data, send a single pad frame #TODO: add useful pad data, i.e. current time of SDR if frame_count == 0: #pad_d = struct.pack('!H', self.pktno & 0xffff) + (self.bytes_per_slot - 100) * chr(self.pktno & 0xff) #zeros = 64*chr(0x00) if self.initial_slot == 0: prefix = pn511s[0] else: prefix = pn511s[1] #for i in range(self.prefix_len): # if i == self.prefix_loc: # seg = zeros + pn511s[i] #put the PN code to the prefix # else: # seg = 128*chr(0x00) # the prefix looks like 0000000...0000PPPPPP...PPPP0000000.....000000 # |___512bit_||____512bit_||___M*1024bit_____| # M+N+1 := num_slots # N+1 := prefix_loc # prefix = prefix + seg rdata = '' if self.from_file == 1 and self.sfile != 0: rdata = self.sfile.read(self.bytes_per_slot - 64*self.prefix_len -100) if len(rdata) > 0: pad_d = rdata elif self.from_file == 2 and self.sfile != 0: #repeated sending the same packets for Virtual MIMO testing self.sfile.seek(0) #go the beginning of file rdata = self.sfile.read(self.bytes_per_slot - 64*self.prefix_len -100) if len(rdata) > 0: pad_d = rdata else: if self.initial_slot == 0: # use the unique PN code to specify the first slot pad_d = 16*pn511_0 #+ (self.bytes_per_slot - 64) * chr(self.pktno & 0xff) else: pad_d = 16*pn511_1 pad_d = prefix + pad_d #send PN and data at different slots for MIMO postmsg = True if self.mimo == True: postmsg = True if self.pktno % 3 == self.prefix_loc: pad_d = pn511_0 elif self.pktno % 3 == 2: pad_d = rdata else: postmsg = False data = numpy.fromstring(pad_d, dtype='uint8') #data = self.pad_data #data = pad_d more_frames = 0 tx_object = time_object,data,more_frames print 'prefix_loc = %d' %(self.prefix_loc) print 'antenna_start = %7f' %(self.antenna_start) if postmsg: self.post_msg(TO_FRAMER_PORT,pmt.pmt_string_to_symbol('full'),pmt.from_python(tx_object),pmt.pmt_string_to_symbol('tdma')) self.pktno += 1 #print 'tx_frames:post message from the pad data' else: #print frame_count,self.queue.qsize(), self.tx_queue.qsize() #send first frame w tuple for tx_time and number of frames to put in slot blob = self.mgr.acquire(True) #block more_frames = frame_count - 1 msg = self.tx_queue.get() data = pmt.pmt_blob_data(msg.value) tx_object = time_object,data,more_frames self.post_msg(TO_FRAMER_PORT,pmt.pmt_string_to_symbol('full'),pmt.from_python(tx_object),pmt.pmt_string_to_symbol('tdma')) frame_count -= 1 old_data = [] #print 'frame count: ',frame_count #send remining frames, blob only while(frame_count > 0): msg = self.tx_queue.get() data = pmt.pmt_blob_data(msg.value) blob = self.mgr.acquire(True) #block pmt.pmt_blob_resize(blob, len(data)) pmt.pmt_blob_rw_data(blob)[:] = data self.post_msg(TO_FRAMER_PORT,pmt.pmt_string_to_symbol('d_only'),blob,pmt.pmt_string_to_symbol('tdma')) frame_count -= 1
def work(self, input_items, output_items): if self.rx_state == RX_INIT: self.rx_hop_index = 0 self.rx_state = RX_SEARCH self.post_msg( CTRL_PORT, pmt.pmt_string_to_symbol('usrp_source.set_center_freq'), pmt.from_python( ((self.rx_freq_list[self.rx_hop_index], ), {})), pmt.pmt_string_to_symbol('fhss')) self.rx_hop_index = (self.rx_hop_index + 1) % self.rx_freq_list_length print 'Initialized to channel 0. Searching...' #check for msg inputs when work function is called if self.check_msg_queue(): try: msg = self.pop_msg_queue() except: return -1 if msg.offset == INCOMING_PKT_PORT: pkt = pmt.pmt_blob_data(msg.value) if pkt[0]: blob = self.mgr.acquire(True) #block pmt.pmt_blob_resize(blob, len(pkt) - 1) pmt.pmt_blob_rw_data(blob)[:] = pkt[1:] self.post_msg(APP_PORT, pmt.pmt_string_to_symbol('rx'), blob, pmt.pmt_string_to_symbol('fhss')) if self.know_time: if self.rx_state == RX_SEARCH: self.rx_state = RX_FOUND self.pkt_received = True self.next_tune_time = self.time_update + self.hop_interval - self.tune_lead self.start_hop = self.next_tune_time - self.lead_limit print 'Received packet. Locked. Hopping initialized.' else: self.pkt_received = True #print 'pkt_rcved_2',self.time_update,self.start_hop,self.next_tune_time else: a = 0 #CONTROL port #process streaming samples and tags here in0 = input_items[0] nread = self.nitems_read(0) #number of items read on port 0 ninput_items = len(input_items[0]) #read all tags associated with port 0 for items in this work function tags = self.get_tags_in_range(0, nread, nread + ninput_items) #lets find all of our tags, making the appropriate adjustments to our timing for tag in tags: key_string = pmt.pmt_symbol_to_string(tag.key) if key_string == "rx_time": self.samples_since_last_rx_time = 0 self.current_integer, self.current_fractional = pmt.to_python( tag.value) self.time_update = self.current_integer + self.current_fractional self.found_time = True elif key_string == "rx_rate": self.rate = pmt.to_python(tag.value) self.sample_period = 1 / self.rate self.found_rate = True #determine first transmit slot when we learn the time if not self.know_time: if self.found_time and self.found_rate: self.know_time = True else: #get current time self.time_update += (self.sample_period * ninput_items) if self.rx_state == RX_FOUND: if self.time_update > self.start_hop: #print 'set: ', self.rx_freq_list[self.rx_hop_index], self.time_update, self.next_tune_time self.post_msg( CTRL_PORT, pmt.pmt_string_to_symbol('usrp_source.set_command_time'), pmt.from_python(((self.next_tune_time, ), {})), pmt.pmt_string_to_symbol('fhss')) self.post_msg( CTRL_PORT, pmt.pmt_string_to_symbol('usrp_source.set_center_freq'), pmt.from_python( ((self.rx_freq_list[self.rx_hop_index], ), {})), pmt.pmt_string_to_symbol('fhss')) self.post_msg( CTRL_PORT, pmt.pmt_string_to_symbol('usrp_source.clear_command_time'), pmt.from_python(((0, ), {})), pmt.pmt_string_to_symbol('fhss')) self.rx_hop_index = (self.rx_hop_index + 1) % self.rx_freq_list_length self.start_hop += self.hop_interval self.next_tune_time += self.hop_interval #self.next_rx_interval += self.hop_interval - self.tune_lead if self.pkt_received: self.consecutive_miss = 0 else: self.consecutive_miss += 1 if self.consecutive_miss > LOST_SYNC_THRESHOLD: self.consecutive_miss = 0 self.rx_state = RX_INIT print 'Lost Sync: Re-Initializing' self.pkt_received = False return ninput_items