def handle_app_pkt(self, pdu): ''' Try to put another packet on to the app_in_q. If the queue is full, don't block, just drop the packet, catch the Full exception, and continue on This function is also responsible for tagging packets with the ID of this node. The fromID and toID are added by the MAC, but since this is where packets external to the network are first added, they will need an accurate sourceID. ''' #print "handle_app_pkt: queue length is %d" % len(self.app_in_q) # make sure the pdu is a pmt pair if pmt.pmt_is_pair(pdu): #print "pmt is a pair" # get the first and last elements of the pair meta = pmt.to_python(pmt.pmt_car(pdu)) vect = pmt.to_python(pmt.pmt_cdr(pdu)) # make sure there's some metadata associated with the packet, otherwise # drop it if not (meta is None): #print "meta is not none" if len(self.app_in_q) < self.app_in_q.maxlen: # stamp each app packet with a source ID meta["sourceID"]=self.mac_config["my_id"] self.app_in_q.append((meta, vect)) else: # TODO: Include warning about dropping packet due to full queue pass
def work(self, input_items, output_items): #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 #set know_time True for useful state machines if not self.know_time: if self.found_time and self.found_rate: self.know_time = True print 'know time' else: self.time_update += (self.sample_period * ninput_items) print self.time_update return ninput_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 work(self, input_items, output_items): #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: pass #TODO:something intelligent for incoming time bcast pkts 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 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 #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.interval_start = self.time_transmit_start + self.lead_limit self.antenna_start = self.interval_start + self.guard_interval self.tx_frames() #do more than this? self.time_transmit_start += self.frame_period #TODO: add intelligence to handle slot changes safely return ninput_items
def handle_pdu(self,pdu): # print "handle pdu" # make sure the pdu is a pmt pair if pmt.pmt_is_pair(pdu): # get the first and last elements of the pair meta = pmt.to_python(pmt.pmt_car(pdu)) vect = pmt.to_python(pmt.pmt_cdr(pdu)) # make sure there's some metadata associated with the packet, otherwise # drop it if meta is not None: # self.in_packets.put( (meta,vect) ) self.in_packets.append( (meta,vect) )
def work(self, input_items, output_items): #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) if len(tags) > 0: self._dev_logger.debug("beacon consumer found new tags") for tag in tags: key_string = pmt.pmt_symbol_to_string(tag.key) if key_string == "rx_time": current_integer, current_fractional = pmt.to_python(tag.value) self.timestamp = time_spec_t(current_integer + current_fractional) self.floored_timestamp = time_spec_t(current_integer) self.time_offset = tag.offset self.found_time = True #print "rx time found: %s at offset %ld" %(self.timestamp, self.time_offset) elif key_string == "rx_rate": #print "rx rate found" self.rate = pmt.to_python(tag.value) self.sample_period = 1 / self.rate self.found_rate = True # only clear out old packets if the time and rate are known if self.found_rate & self.found_time: #print "nread: %ld ninput_items: %ld self.time_offset %ld" % (nread, ninput_items, self.time_offset) t_end = (nread + ninput_items - self.time_offset) * self.sample_period + self.timestamp #print "t_end is %s" % t_end self._beacon_lock.acquire() self.cull_stale_beacons(t_end) num_beacons = len(self._beacon_list) self._beacon_lock.release() # if there aren't any valid beacons left in the queue, declare the sync was # lost if num_beacons == 0: self.sync_lost(t_end) return ninput_items
def work(self, input_items, output_items): #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) if len(tags) > 0: self._dev_logger.debug("beacon consumer found new tags") for tag in tags: key_string = pmt.pmt_symbol_to_string(tag.key) if key_string == "rx_time": current_integer,current_fractional = pmt.to_python(tag.value) self.timestamp = time_spec_t(current_integer + current_fractional) self.floored_timestamp = time_spec_t(current_integer) self.time_offset = tag.offset self.found_time = True #print "rx time found: %s at offset %ld" %(self.timestamp, self.time_offset) elif key_string == "rx_rate": #print "rx rate found" self.rate = pmt.to_python(tag.value) self.sample_period = 1/self.rate self.found_rate = True # only clear out old packets if the time and rate are known if self.found_rate & self.found_time: #print "nread: %ld ninput_items: %ld self.time_offset %ld" % (nread, ninput_items, self.time_offset) t_end = (nread + ninput_items - self.time_offset)*self.sample_period + self.timestamp #print "t_end is %s" % t_end self._beacon_lock.acquire() self.cull_stale_beacons(t_end) num_beacons = len(self._beacon_list) self._beacon_lock.release() # if there aren't any valid beacons left in the queue, declare the sync was # lost if num_beacons == 0: self.sync_lost(t_end) return ninput_items
def write_to_network(self, payload): ''' This function accepts packets from the MAC layer and forwards them up to the network layer ''' data = str(pmt.to_python(payload)) #self.logger.debug("Write to network called. Keep going is %s", self.keep_going) # only forward packets while tunned is active if self.keep_going: self.logger.debug("sending packet to app layer, length %i", len(data)) os.write(self.tun_fd, data)
def write_to_network(self,payload): ''' This function accepts packets from the MAC layer and forwards them up to the network layer ''' data = str(pmt.to_python(payload)) #self.logger.debug("Write to network called. Keep going is %s", self.keep_going) # only forward packets while tunned is active if self.keep_going: self.logger.debug("sending packet to app layer, length %i", len(data)) os.write(self.tun_fd, data)
def work(self, input_items, output_items): try: msg = self.pop_msg_queue() key = pmt.pmt_symbol_to_string(msg.key) txt = pmt.to_python(msg.value) if key == pocsag.POCSAG_ID: self.pocsag_pagermsg.emit(txt) return 1 return 0 except: return -1
def handle_schedule_update(self, sched_pmt): ''' Add the new schedule to the schedule update queue ''' pickled_sched = pmt.to_python(sched_pmt) # make sure there's something in the schedule, otherwise # drop it if not (pickled_sched is None): self.dev_logger.debug("controller got schedule update") self.in_sched_update_q.append(cPickle.loads(pickled_sched))
def store_pkt(self, pdu): ''' Try to put another packet on to the pkt_queue. If the queue is full, don't block, just drop the packet, catch the Full exception, and continue on ''' # make sure the pdu is a pmt pair before handling it if pmt.pmt_is_pair(pdu): #print "pmt is a pair" # get the first and last elements of the pair meta = pmt.to_python(pmt.pmt_car(pdu)) data = pmt.to_python(pmt.pmt_cdr(pdu)) # make sure there's some metadata associated with the packet, otherwise # drop it if not (meta is None) and ("destinationID" in meta): # if there's any room left in the queue if len(self.pkt_queue) < self.pkt_queue.maxlen: pkt = csma_pkt_converter(my_id = self.my_id, crc_result = self.crc_result, from_id = self.my_id, to_id = int(meta["destinationID"]), pktno = self.packet_id, pad_bytes = self.pad_bytes, pkt_code = self.pkt_code, phy_code = self.phy_code, mac_code = self.mac_code, more_data = self.more_data, data = data) self.packet_id = (self.packet_id +1) % self.max_packet_id # add packaged packet to pkt queue self.pkt_queue.append(pkt)
def store_pkt(self, pdu): ''' Try to put another packet on to the pkt_queue. If the queue is full, don't block, just drop the packet, catch the Full exception, and continue on ''' # make sure the pdu is a pmt pair before handling it if pmt.pmt_is_pair(pdu): #print "pmt is a pair" # get the first and last elements of the pair meta = pmt.to_python(pmt.pmt_car(pdu)) data = pmt.to_python(pmt.pmt_cdr(pdu)) # make sure there's some metadata associated with the packet, otherwise # drop it if not (meta is None) and ("destinationID" in meta): # if there's any room left in the queue if len(self.pkt_queue) < self.pkt_queue.maxlen: pkt = csma_pkt_converter(my_id=self.my_id, crc_result=self.crc_result, from_id=self.my_id, to_id=int(meta["destinationID"]), pktno=self.packet_id, pad_bytes=self.pad_bytes, pkt_code=self.pkt_code, phy_code=self.phy_code, mac_code=self.mac_code, more_data=self.more_data, data=data) self.packet_id = (self.packet_id + 1) % self.max_packet_id # add packaged packet to pkt queue self.pkt_queue.append(pkt)
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): #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]) #print "nread in logger is " + str(nread) #print "ninput_items is " + str(ninput_items) #out = output_items[0] #out[:] = in0[:] #read all tags associated with port 0 for items in this work function tags = self.get_tags_in_range(0, nread, nread + ninput_items) #sort by key first so that this order is preserved for same offset when sorting by offset tags = sorted(tags, key=lambda tag: pmt.pmt_symbol_to_string(tag.key), reverse=True) #sort by tag.offset tags = sorted(tags, key=lambda tag: tag.offset) #call lincoln log if self._logging != -1: #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) #print "found key : " + key_string + " at offset " + str(tag.offset) if key_string == 'tx_sob': self._sob_found = True if key_string == 'tx_time': tx_time_offset = tag.offset tx_time_tuple = pmt.to_python(tag.value) tx_time_spec_t = time_spec_t(tx_time_tuple[0], tx_time_tuple[1]) #tx_time_value = tx_time_spec_t.__float__() self._tx_time_offset = tx_time_offset #self._tx_time_value = tx_time_value self._tx_time_spec_t = tx_time_spec_t #print "tx_time_value is " + str(tx_time_value) if key_string == 'tx_rate': tx_rate_offset = tag.offset tx_rate_value = float(pmt.to_python(tag.value)) self._tx_rate_value = tx_rate_value * self._upsample_factor if key_string == 'packetlog': packetlog_offset = tag.offset packetlog_value = pmt.to_python(tag.value) if self._sob_found: offset_from_sob = packetlog_offset - self._tx_time_offset time_from_sob = offset_from_sob / float( self._tx_rate_value) #packetlog_time = self._tx_time_value + time_from_sob packetlog_time_spec_t = self._tx_time_spec_t + time_spec_t( time_from_sob) #packetlog_value['timestamp'] = packetlog_time packetlog_value['timestamp'] = str( packetlog_time_spec_t) #print packetlog_value self._logging.packet(packetlog_value) #print "--------------logger------------------------" return ninput_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, ) 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): 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 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 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): #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]) #print "nread in logger is " + str(nread) #print "ninput_items is " + str(ninput_items) #out = output_items[0] #out[:] = in0[:] #read all tags associated with port 0 for items in this work function tags = self.get_tags_in_range(0, nread, nread+ninput_items) #sort by key first so that this order is preserved for same offset when sorting by offset tags = sorted(tags, key=lambda tag : pmt.pmt_symbol_to_string(tag.key), reverse=True) #sort by tag.offset tags = sorted(tags, key=lambda tag : tag.offset) #call lincoln log if self._logging != -1: #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) #print "found key : " + key_string + " at offset " + str(tag.offset) if key_string == 'tx_sob': self._sob_found = True if key_string == 'tx_time': tx_time_offset = tag.offset tx_time_tuple = pmt.to_python(tag.value) tx_time_spec_t = time_spec_t(tx_time_tuple[0],tx_time_tuple[1]) #tx_time_value = tx_time_spec_t.__float__() self._tx_time_offset = tx_time_offset #self._tx_time_value = tx_time_value self._tx_time_spec_t = tx_time_spec_t #print "tx_time_value is " + str(tx_time_value) if key_string == 'tx_rate': tx_rate_offset = tag.offset tx_rate_value = float(pmt.to_python(tag.value)) self._tx_rate_value = tx_rate_value*self._upsample_factor if key_string == 'packetlog': packetlog_offset = tag.offset packetlog_value = pmt.to_python(tag.value) if self._sob_found: offset_from_sob = packetlog_offset - self._tx_time_offset time_from_sob = offset_from_sob / float(self._tx_rate_value) #packetlog_time = self._tx_time_value + time_from_sob packetlog_time_spec_t = self._tx_time_spec_t + time_spec_t(time_from_sob) #packetlog_value['timestamp'] = packetlog_time packetlog_value['timestamp'] = str(packetlog_time_spec_t) #print packetlog_value self._logging.packet(packetlog_value) #print "--------------logger------------------------" return ninput_items
def work(self, input_items, output_items): #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: a = 0 #TODO:something intelligent for incoming time bcast pkts 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 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 #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.interval_start = self.time_transmit_start + self.lead_limit self.antenna_start = self.interval_start + self.guard_interval self.tx_frames() #do more than this? self.time_transmit_start += self.frame_period #TODO: add intelligence to handle slot changes safely return ninput_items
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 "tdma controller work" #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]) # update the starting timestamp for this block start_timestamp = self.ref_timestamp + (nread - self.ref_time_offset)/self.fs #read all tags associated with port 0 for items in this work function tags = self.get_tags_in_range(0, nread, nread+ninput_items) #print "tdma controller start of tag loop" #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.ref_time_offset = tag.offset self.ref_timestamp = time_spec_t(pmt.to_python(tag.value)) # only set host offset at the start if not self.found_time: current_time = time.time() current_time_ahead = time_spec_t(current_time) - self.ref_timestamp self.mac_sm.cq_manager.set_current_time_ahead(float(current_time_ahead)) self.dev_logger.debug("for rx time %s and host time %s, setting time ahead to %s", self.ref_timestamp, current_time, current_time_ahead) self.found_time = True self.dev_logger.debug("tdma_controller found new rx time of %s at offset %ld", self.ref_timestamp, self.ref_time_offset) #print "mobile controller found rate" # if this tag occurs at the start of the sample block, update the # starting timestamp if tag.offset == nread: start_timestamp = self.ref_timestamp + (nread - self.ref_time_offset)/self.fs elif key_string == "rx_rate": self.fs = pmt.to_python(tag.value) self.found_rate = True #print "mobile controller found time" # if this tag occurs at the start of the sample block, update the # starting timestamp if tag.offset == nread: start_timestamp = self.ref_timestamp + float(nread - self.ref_time_offset)/self.fs # self.dev_logger.debug("tag processing complete") if not (self.current_sched is None): start_timestamp = start_timestamp.round_to_sample(self.fs, self.current_sched["t0"]) #determine first transmit slot when we learn the time if not self.know_time: if self.found_time and self.found_rate: #print "mobile controller knows time" self.know_time = True # if the state machine has a command queue manager, send out a time cal # message if hasattr(self.mac_sm, "cq_manager"): # calibrate the command queue to uhd timing errors cal_ts = self.ref_timestamp + float(nread + ninput_items - self.ref_time_offset)/self.fs self.mac_sm.cq_manager.add_command_to_queue([(cal_ts, 0, "time_cal")]) if self.know_time: # set the mac to generate packets if the start of the frame occurs at any # point between now and the end of the current block plus the lead limit. # This should guarantee that packets are always submitted at least one lead # limit ahead of their transmit time end_timestamp = self.ref_timestamp + self.mac_config["lead_limit"] + float(nread + ninput_items - self.ref_time_offset)/self.fs else: end_timestamp = start_timestamp if not (self.current_sched is None): end_timestamp = end_timestamp.round_to_sample(self.fs, self.current_sched["t0"]) # only update the current timestamp if it is further along than the state machine if self.current_timestamp < start_timestamp: self.current_timestamp = start_timestamp # use this to detect endless loops loop_counter = 0 loop_max = 100 last_ts = self.current_timestamp # grab the latest schedule updates from the thread safe data struct num_scheds = len(self.in_sched_update_q) # self.dev_logger.debug("processing schedule updates") for k in range(num_scheds): self.sched_seq.append(self.in_sched_update_q.popleft()) # self.dev_logger.debug("schedule updates all appended to schedule sequence") # run the state machine if time cal is complete if self.time_cal_complete: # if self.current_sched is not None: # self.last_frame = deepcopy(self.current_sched) # handle any incoming packets self.process_raw_incoming_queue() # start timers if self.monitor_timing == True: wall_start_ts = time.time() state_start_ts = self.current_timestamp outp = None #print "mobile controller state machine loop" # iterate state machine until the current timestamp exceeds the ending timestamp while self.current_timestamp < end_timestamp: # self.dev_logger.debug("iterating state machine") last_ts = self.current_timestamp rf_in = [] while( len(self.incoming_q) > 0): rf_in.append(self.incoming_q.popleft()) inp = { "app_in":self.app_in_q, "current_ts":self.current_timestamp, "end_ts":end_timestamp, "frame_config":self.frame_config, "frame_count":self.frame_count, "mac_config":self.mac_config, "packet_count":self.packet_count, "pkt_switch_queues":self.pkt_switch_queues, "plot_lock":self.plot_lock, "rf_in":rf_in, "sched_seq":self.sched_seq, } #print "current timestamp is %s, end timestamp is %s" %(self.current_timestamp, end_timestamp) #print "iterating state machine" outp = self.mac_sm.step( (inp, False) ) # handle outputs #print "sending tx frames" self.tx_frames(**outp) #print "sending commands" self.send_commands(**outp) #print "sending application packets" self.send_app_pkts(**outp) self.log_dropped_pkts(**outp) self.log_mac_behavior(inp,outp) #print "output handling complete" # update node state with results self.current_timestamp = time_spec_t(outp["current_ts"]) self.packet_count = outp["packet_count"] self.pkt_switch_queues = outp["pkt_switch_queues"] self.frame_count = outp["frame_count"] self.frame_config = outp["frame_config"] self.sched_seq = outp["sched_seq"] # self.schedule_valid = outp["schedule_valid"] #bers = [self.active_rx_slots[num]["ber"] for num in self.active_rx_slots] #self.dev_logger.debug("active slot bers are %s", bers) if last_ts == self.current_timestamp: loop_counter+=1 else: loop_counter = 0 if loop_counter > loop_max: self.dev_logger.warn("INFINITE (PROBABLY) LOOP DETECTED - breaking out after %d loops",loop_counter) self.dev_logger.warn("current timestamp is: %s end timestamp is %s",self.current_timestamp, end_timestamp) break #print "tdma controller work complete" # self.dev_logger.debug("iteration complete") # do timer calcs at end of work function if self.monitor_timing == True: wall_end_ts = time.time() # if state machine wasn't executed at least once, outp won't be defined, # so assign something reasonable to state_end_ts if not (outp is None): state_end_ts = time_spec_t(outp["current_ts"]) else: state_end_ts = state_start_ts wall_delta_ts = wall_end_ts - wall_start_ts state_delta_ts = float(state_end_ts - state_start_ts) self.state_time_deltas += state_delta_ts self.wall_time_deltas += wall_delta_ts if self.state_time_deltas >= self.poll_interval: self.dev_logger.info("runtime ratio was %f wall seconds per state second",self.wall_time_deltas/self.state_time_deltas) self.state_time_deltas = 0 self.wall_time_deltas = 0 # we're still in time cal elif self.do_time_cal: if not self.know_time: self.dev_logger.error(("The base station does not know it's own time. " + "Cannot calibrate")) elif not self.mac_sm.is_base(): self.dev_logger.error("Only base nodes can send time calibration beacons") else: # send out cal beacon frames for k in range(self.num_cal_beacons): packet_count = self.packet_count frame_count = 0 frame_ts = (self.current_timestamp + self.mac_config["lead_limit"] + k*self.cal_frame_config["frame_len"]) # round fractional part to an integer sample so we don't break the # slot selector frame_ts = time_spec_t(frame_ts.int_s(), round(frame_ts.frac_s()*self.fs)/self.fs ) config = self.mac_config mobile_queues=defaultdict(deque) # make mac beacon frames outs = self.manage_slots.send_frame(self.mac_config, self.cal_frame_config, self.cal_schedule, frame_count, packet_count, frame_ts, mobile_queues, ) frame_count, packet_count, tx_list, mobile_queues, dropped_pkts = outs # handle outputs self.packet_count = packet_count # filter out anything that's not a beacon tx_list = [x for x in tx_list if x[0]["pktCode"] == self.mac_sm._types_to_ints["beacon"]] # add tdma headers to all the packets in the tx list tx_list = [ (meta, self.mac_sm.pack_tdma_header(data, **meta)) for meta, data in tx_list ] # send packets self.tx_frames(tx_list) self.current_timestamp = (end_timestamp + self.mac_config["lead_limit"] + self.num_cal_beacons*self.cal_frame_config["frame_len"]) self.do_time_cal = False return ninput_items