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
Beispiel #2
0
    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
Beispiel #3
0
    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			
Beispiel #4
0
    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
Beispiel #5
0
    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) )
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #8
0
 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)
Beispiel #9
0
 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)
Beispiel #10
0
	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
Beispiel #11
0
 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
Beispiel #12
0
 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))
Beispiel #13
0
 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)
Beispiel #14
0
    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)
Beispiel #15
0
    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
Beispiel #16
0
    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
Beispiel #17
0
    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
Beispiel #18
0
    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
Beispiel #19
0
    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
Beispiel #20
0
    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
Beispiel #21
0
    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
Beispiel #22
0
    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
Beispiel #23
0
    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
Beispiel #24
0
    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
Beispiel #25
0
    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