def hop(self): """ Hop to next slot in frequency list. """ usrps = ['uhd_sink', 'uhd_source'] for usrp in usrps: self.post_msg( CTRL_PORT, pmt.string_to_symbol(usrp + '.set_command_time'), pmt.from_python( (('#!\nfrom gnuradio import uhd\narg = uhd.time_spec_t(' + repr(self.interval_start) + ')', ), {})), pmt.string_to_symbol('fhss')) self.post_msg( CTRL_PORT, pmt.string_to_symbol(usrp + '.set_center_freq'), pmt.from_python(((self.freq_list[self.hop_index], ), {})), pmt.string_to_symbol('fhss')) self.post_msg(CTRL_PORT, pmt.string_to_symbol(usrp + '.clear_command_time'), pmt.from_python(((0, ), {})), pmt.string_to_symbol('fhss')) self.freq_msg = "--------Since %s at: %s" % ( self.interval_start, self.freq_list[self.hop_index]) self.hop_index = (self.hop_index + 1) % self.freq_list_length
def work(self, input_items, output_items): while True: try: msg = self.pop_msg_queue() except: return -1 result = self.handle_request(pmt.to_python(msg.key), pmt.to_python(msg.value)) try: msg.value = pmt.from_python(result) except Exception as ex: msg.value = pmt.from_python(str(ex)) if self._result_msg: self.post_msg(0, msg)
def tag_to_pmt(tag): """ Convert a Python-readable object to a stream tag """ newtag = gr.tag_t() newtag.offset = tag.offset newtag.key = pmt.to_python(tag.key) newtag.value = pmt.from_python(tag.value) newtag.srcid = pmt.from_python(tag.srcid) return newtag
def test_basic_types(self): self.assertEqual(42, pmt.to_python(pmt.pmt_from_long(42))) self.assertTrue(pmt.pmt_equal(pmt.pmt_from_long(42), pmt.from_python(42))) self.assertEqual(4.2, pmt.to_python(pmt.pmt_from_double(4.2))) self.assertTrue(pmt.pmt_equal(pmt.pmt_from_double(4.2), pmt.from_python(4.2))) self.loopback(None) self.loopback(42) self.loopback(4.2) self.loopback(4.2j) self.loopback("42")
def work(self, input_items, output_items): self.post_msg(0, pmt.from_python("multx2"), pmt.from_python(((42,), None))) msg = self.pop_msg_queue() assert(pmt.to_python(msg.key) == "multx2") request, result, error = pmt.to_python(msg.value) print(error) assert(not error) print(result) assert(result == 42*2) return -1
def work(self, input_items, output_items): self.post_msg(0, pmt.from_python("multx2"), pmt.from_python(((42, ), None))) msg = self.pop_msg_queue() assert (pmt.to_python(msg.key) == "multx2") request, result, error = pmt.to_python(msg.value) print(error) assert (not error) print(result) assert (result == 42 * 2) return -1
def test_basic_types(self): self.assertEqual(42, pmt.to_python(pmt.pmt_from_long(42))) self.assertTrue( pmt.pmt_equal(pmt.pmt_from_long(42), pmt.from_python(42))) self.assertEqual(4.2, pmt.to_python(pmt.pmt_from_double(4.2))) self.assertTrue( pmt.pmt_equal(pmt.pmt_from_double(4.2), pmt.from_python(4.2))) self.loopback(None) self.loopback(42) self.loopback(4.2) self.loopback(4.2j) self.loopback("42")
def tx_data(self): """ Put messages from input into tx_queue. """ #TODO: Enable multi-hop transmissions -> less overhead! msg = self.queue.get() msg_byte_count = len(pmt.blob_data(msg.value)) + self.overhead if msg_byte_count >= self.bytes_per_slot: print "ERROR: Message too long!" else: #self.got_cts = False self.state = IDLE time_object = int(math.floor(self.antenna_start)), (self.antenna_start % 1) more_frames = 0 data = numpy.concatenate([HAS_DATA, self._to_byte_array(self.own_adr), self._to_byte_array(self.dst_adr), pmt.blob_data(msg.value)]) #print "DATA-SEND: %s" % data tx_object = time_object, data, more_frames #print "DEBUG: Sending DATA at", time_object #print "-----fre_list %s - hop-index %s" % (self.freq_list, self.hop_index) #print self.freq_msg self.post_msg(TO_FRAMER_PORT, pmt.string_to_symbol('full'), pmt.from_python(tx_object), pmt.string_to_symbol('tdma'))
def tx_signaling(self, max_delay_in_slot, msg_type, dst_adr): """ Send signaling/control frames (no data). """ # Send after random amount of time in this bin/slot/hop delay = random.uniform(0, max_delay_in_slot) ant_start = self.antenna_start + delay time_msg = self._time_to_msg(self.interval_start) next_hop_index = numpy.array([self.hop_index], dtype='uint8') time_object = int(math.floor(ant_start)), (ant_start % 1) #print "DEBUG: Sending %s at %s" % (msg_type, time_object) #print "-----fre_list %s - hop-index %s" % (self.freq_list, self.hop_index) #print self.freq_msg # Create msg and add to tx_queue before calling transmit data = numpy.concatenate([msg_type, self._to_byte_array(self.own_adr), self._to_byte_array(dst_adr), time_msg, next_hop_index]) more_frames = 0 tx_object = time_object, data, more_frames self.post_msg(TO_FRAMER_PORT, pmt.string_to_symbol('full'), pmt.from_python(tx_object), pmt.string_to_symbol('tdma'))
def tx_signaling(self, max_delay_in_slot, msg_type, dst_adr): """ Send signaling/control frames (no data). """ # Send after random amount of time in this bin/slot/hop delay = random.uniform(0, max_delay_in_slot) ant_start = self.antenna_start + delay time_msg = self._time_to_msg(self.interval_start) next_hop_index = numpy.array([self.hop_index], dtype='uint8') time_object = int(math.floor(ant_start)), (ant_start % 1) #print "DEBUG: Sending %s at %s" % (msg_type, time_object) #print "-----fre_list %s - hop-index %s" % (self.freq_list, self.hop_index) #print self.freq_msg # Create msg and add to tx_queue before calling transmit data = numpy.concatenate([ msg_type, self._to_byte_array(self.own_adr), self._to_byte_array(dst_adr), time_msg, next_hop_index ]) more_frames = 0 tx_object = time_object, data, more_frames self.post_msg(TO_FRAMER_PORT, pmt.string_to_symbol('full'), pmt.from_python(tx_object), pmt.string_to_symbol('tdma'))
def tx_data(self): """ Put messages from input into tx_queue. """ #TODO: Enable multi-hop transmissions -> less overhead! msg = self.queue.get() msg_byte_count = len(pmt.blob_data(msg.value)) + self.overhead if msg_byte_count >= self.bytes_per_slot: print "ERROR: Message too long!" else: #self.got_cts = False self.state = IDLE time_object = int(math.floor( self.antenna_start)), (self.antenna_start % 1) more_frames = 0 data = numpy.concatenate([ HAS_DATA, self._to_byte_array(self.own_adr), self._to_byte_array(self.dst_adr), pmt.blob_data(msg.value) ]) #print "DATA-SEND: %s" % data tx_object = time_object, data, more_frames #print "DEBUG: Sending DATA at", time_object #print "-----fre_list %s - hop-index %s" % (self.freq_list, self.hop_index) #print self.freq_msg self.post_msg(TO_FRAMER_PORT, pmt.string_to_symbol('full'), pmt.from_python(tx_object), pmt.string_to_symbol('tdma'))
def __init__(self, obj, result_msg = True): """ Make the PMT RPC. @param obj the object to make function calls on @param result_msg true to produce result messages """ self._obj = obj self._result_msg = result_msg gr.basic_block.__init__( self, name = "pmt rpc", in_sig = None, out_sig = None ) self.IN_PORT = pmt.from_python('in') self.OUT_PORT = pmt.from_python('out') self.message_port_register_out(self.OUT_PORT) self.message_port_register_in(self.IN_PORT) self.set_msg_handler(self.IN_PORT, self.handle_request)
def hop(self): """ Hop to next slot in frequency list. """ usrps = ['uhd_sink', 'uhd_source'] for usrp in usrps: self.post_msg(CTRL_PORT, pmt.string_to_symbol(usrp + '.set_command_time'), pmt.from_python((('#!\nfrom gnuradio import uhd\narg = uhd.time_spec_t(' + repr(self.interval_start) + ')', ), {})), pmt.string_to_symbol('fhss')) self.post_msg(CTRL_PORT, pmt.string_to_symbol(usrp + '.set_center_freq'), pmt.from_python(((self.freq_list[self.hop_index], ), {})), pmt.string_to_symbol('fhss')) self.post_msg(CTRL_PORT, pmt.string_to_symbol(usrp + '.clear_command_time'), pmt.from_python(((0, ), {})), pmt.string_to_symbol('fhss')) self.freq_msg = "--------Since %s at: %s" % (self.interval_start, self.freq_list[self.hop_index]) self.hop_index = (self.hop_index + 1) % self.freq_list_length
def handle_request(self, pdu ): if pmt.pmt_is_pair(pdu): # get the first and last elements of the pair fcn_name = pmt.to_python(pmt.pmt_car(pdu)) request = pmt.to_python(pmt.pmt_cdr(pdu)) #try to parse the request try: args, kwargs = request if args is None: args = tuple() if kwargs is None: kwargs = dict() except: err = 'cannot parse request for %s, expected tuple of args, kwargs'%fcn_name print err #return request, None, err return #exec python code and squash down to objects args = map(self._exec_arg, args) for key, val in kwargs.iteritems(): kwargs[key] = self._exec_arg(val) #fly through dots to get the fcn pointer try: fcn_ptr = self._obj for name in fcn_name.split('.'): fcn_ptr = getattr(fcn_ptr, name) except: err = 'cannot find function %s in %s'%(fcn_name, self._obj) print err #return request, None, err return #try to execute the request try: ret = fcn_ptr(*args, **kwargs) except Exception as ex: err = 'cannot execute request for %s, got error %s'%(fcn_name, ex) print err #return request, None, err return #return the sucess result #return request, ret, None self.message_port_pub(self.OUT_PORT, pmt.from_python(ret))
def work(self, input_items, output_items): self.post_msg(0, pmt.from_python("multx2"), pmt.from_python(((42,), None))) msg = self.pop_msg_queue() assert(pmt.to_python(msg.key) == "multx2") request, result, error = pmt.to_python(msg.value) print(error) assert(not error) print(result) assert(result == 42*2) self.post_msg(0, pmt.from_python("_control_block.test_print"), pmt.from_python((('hello',), None))) self.post_msg(0, pmt.from_python("_control_block.test_print"), pmt.from_python(((my_mini_prog,), None))) return -1
def work(self, input_items, output_items): self.post_msg(0, pmt.from_python("multx2"), pmt.from_python(((42, ), None))) msg = self.pop_msg_queue() assert (pmt.to_python(msg.key) == "multx2") request, result, error = pmt.to_python(msg.value) print(error) assert (not error) print(result) assert (result == 42 * 2) self.post_msg(0, pmt.from_python("_control_block.test_print"), pmt.from_python((('hello', ), None))) self.post_msg(0, pmt.from_python("_control_block.test_print"), pmt.from_python(((my_mini_prog, ), None))) return -1
def work(self, input_items, output_items): if self.rx_state == RX_INIT: for usrp in ['uhd_source', 'uhd_sink']: self.post_msg( CTRL_PORT, pmt.string_to_symbol(usrp + '.set_center_freq'), pmt.from_python(((self.freq_list[self.hop_index], ), {})), pmt.string_to_symbol('fhss')) #print "DEBUG: Set frequency" 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 # Check for pkts from higher layer (pkts to transmit) if msg.offset == OUTGOING_PKT_PORT: dst = int(pmt.blob_data(msg.value).tostring()[0]) if dst > self.max_neighbors: print "ERROR: DST-adr > number of channels!" elif self.neighbors[dst - 1] and dst != self.own_adr: self.dst_adr = dst self.queue.put( msg) # if outgoing, put in queue for processing else: print "ERROR: DST Node not in known neighborhood or own adr!" # Check for received pkts from deframer elif msg.offset == INCOMING_PKT_PORT: pkt = pmt.blob_data(msg.value) pkt_type, pkt_src, pkt_dst = pkt[0:3] handle_pkts = { HAS_DATA[0]: self.received_data, IS_RTS[0]: self.received_rts, IS_CTS[0]: self.received_cts, IS_BCN[0]: self.received_bcn } #print "DEBUG: MSG from ", pkt[1], " - to ", pkt[2], " type: ", pkt[0] if pkt_src != self.own_adr and pkt_dst in [ self.own_adr, self.bcst_adr ]: try: handle_pkts[pkt_type](pkt) except KeyError: print "ERROR: Wrong packet type detected!" #else: # print "Not addressed to this station - adr to: ", pkt[2] nread = self.nitems_read(0) # number of items read on port 0 ninput_items = len(input_items[0]) if not self.know_time: print "Waiting for time..." #process streaming samples and tags here #read all tags associated with port 0 for items tags = self.get_tags_in_range(0, nread, nread + ninput_items) #find all of our tags, making the adjustments to our timing for tag in tags: key_string = pmt.symbol_to_string(tag.key) if key_string == "rx_time": self.current_integer, self.current_fractional = pmt.to_python( tag.value) self.time_update = self.current_integer + self.current_fractional self.found_time = True print repr(self.time_update) elif key_string == "rx_rate": self.rate = pmt.to_python(tag.value) self.sample_period = 1.0 / self.rate self.found_rate = True if self.found_time and self.found_rate: self.know_time = True else: #get/update current time self.time_update += (self.sample_period * ninput_items) #print "DEBUG: time_update:", self.time_update, " - input_items:", ninput_items, " - samp-period", self.sample_period # Set first tuning time 20 sec in future (hope that we receive beacon # pkg within this time for sync -> assume that we're the only node if not) if self.time_tune_start == 0: print "Searching for neighbors..." self.interval_start = self.time_update + self.discovery_time self.time_tune_start = self.interval_start - (10 * self.post_guard) #determine if it's time for us to start tx'ing, start process #10 * self.post_guard before our slot actually begins (deal with latency) if self.time_update > self.time_tune_start: # Check for neighbors -> get free address if not self.discovery_finished: self.discovery_finished = True i = 0 while self.neighbors[i]: i += 1 self.own_adr = i + 1 print "Set own address to:", self.own_adr if self.own_adr != 1: # Wait another 20 sec for synchronization print "Waiting for synchronization..." self.interval_start = self.time_update + self.sync_time else: self.antenna_start = self.interval_start + self.pre_guard self.hop() # TODO: MOve most of the following stuff before # time_tune_start! handle_state = { IDLE: self.idle, GOT_RTS: self.got_rts, GOT_CTS: self.got_cts, WAITING_FOR_CTS: self.waiting_for_cts, WAITING_FOR_DATA: self.waiting_for_data } handle_state[self.state]() self.hops_to_beacon -= 1 self.interval_start += self.hop_interval self.time_tune_start = self.interval_start - (10 * self.post_guard) #print "Next Hop: ", int(math.floor(self.interval_start)), " - ", self.interval_start % 1, " ----- INDEX: ", self.hop_index return ninput_items
def test_numpy(self): python_data = numpy.array([1, 2, 3], numpy.uint8) as_a_pmt = pmt.from_python(python_data) back_to_python = pmt.to_python(as_a_pmt) self.assertTrue((python_data == back_to_python).all())
def work(self, input_items, output_items): if self.rx_state == RX_INIT: for usrp in ['uhd_source', 'uhd_sink']: self.post_msg(CTRL_PORT, pmt.string_to_symbol(usrp + '.set_center_freq'), pmt.from_python(((self.freq_list[self.hop_index], ), {})), pmt.string_to_symbol('fhss')) #print "DEBUG: Set frequency" 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 # Check for pkts from higher layer (pkts to transmit) if msg.offset == OUTGOING_PKT_PORT: dst = int(pmt.blob_data(msg.value).tostring()[0]) if dst > self.max_neighbors: print "ERROR: DST-adr > number of channels!" elif self.neighbors[dst - 1] and dst != self.own_adr: self.dst_adr = dst self.queue.put(msg) # if outgoing, put in queue for processing else: print "ERROR: DST Node not in known neighborhood or own adr!" # Check for received pkts from deframer elif msg.offset == INCOMING_PKT_PORT: pkt = pmt.blob_data(msg.value) pkt_type, pkt_src, pkt_dst = pkt[0:3] handle_pkts = {HAS_DATA[0]: self.received_data, IS_RTS[0]: self.received_rts, IS_CTS[0]: self.received_cts, IS_BCN[0]: self.received_bcn} #print "DEBUG: MSG from ", pkt[1], " - to ", pkt[2], " type: ", pkt[0] if pkt_src != self.own_adr and pkt_dst in [self.own_adr, self.bcst_adr]: try: handle_pkts[pkt_type](pkt) except KeyError: print "ERROR: Wrong packet type detected!" #else: # print "Not addressed to this station - adr to: ", pkt[2] nread = self.nitems_read(0) # number of items read on port 0 ninput_items = len(input_items[0]) if not self.know_time: print "Waiting for time..." #process streaming samples and tags here #read all tags associated with port 0 for items tags = self.get_tags_in_range(0, nread, nread + ninput_items) #find all of our tags, making the adjustments to our timing for tag in tags: key_string = pmt.symbol_to_string(tag.key) if key_string == "rx_time": self.current_integer, self.current_fractional = pmt.to_python(tag.value) self.time_update = self.current_integer + self.current_fractional self.found_time = True print repr(self.time_update) elif key_string == "rx_rate": self.rate = pmt.to_python(tag.value) self.sample_period = 1.0 / self.rate self.found_rate = True if self.found_time and self.found_rate: self.know_time = True else: #get/update current time self.time_update += (self.sample_period * ninput_items) #print "DEBUG: time_update:", self.time_update, " - input_items:", ninput_items, " - samp-period", self.sample_period # Set first tuning time 20 sec in future (hope that we receive beacon # pkg within this time for sync -> assume that we're the only node if not) if self.time_tune_start == 0: print "Searching for neighbors..." self.interval_start = self.time_update + self.discovery_time self.time_tune_start = self.interval_start - (10 * self.post_guard) #determine if it's time for us to start tx'ing, start process #10 * self.post_guard before our slot actually begins (deal with latency) if self.time_update > self.time_tune_start: # Check for neighbors -> get free address if not self.discovery_finished: self.discovery_finished = True i = 0 while self.neighbors[i]: i += 1 self.own_adr = i + 1 print "Set own address to:", self.own_adr if self.own_adr != 1: # Wait another 20 sec for synchronization print "Waiting for synchronization..." self.interval_start = self.time_update + self.sync_time else: self.antenna_start = self.interval_start + self.pre_guard self.hop() # TODO: MOve most of the following stuff before # time_tune_start! handle_state = {IDLE: self.idle, GOT_RTS: self.got_rts, GOT_CTS: self.got_cts, WAITING_FOR_CTS: self.waiting_for_cts, WAITING_FOR_DATA: self.waiting_for_data} handle_state[self.state]() self.hops_to_beacon -= 1 self.interval_start += self.hop_interval self.time_tune_start = self.interval_start - (10 * self.post_guard) #print "Next Hop: ", int(math.floor(self.interval_start)), " - ", self.interval_start % 1, " ----- INDEX: ", self.hop_index return ninput_items
def work(self, input_items, output_items): while not len(self._pkt): try: msg = self.pop_msg_queue() except: return -1 if not pmt.pmt_is_blob(msg.value): self.tx_time,data,self.more_frame_cnt = pmt.to_python(msg.value) self.has_tx_time = True #print data #print tx_time #print data.tostring() else: data = pmt.pmt_blob_data(msg.value) #print data self.has_tx_time = False pkt = packet_utils.make_packet( data.tostring(), self._samples_per_symbol, self._bits_per_symbol, self._access_code, False, #pad_for_usrp, self._whitener_offset, ) self._pkt = numpy.fromstring(pkt, numpy.uint8) if self._use_whitener_offset: self._whitener_offset = (self._whitener_offset + 1) % 16 #shouldn't really need to send start of burst #only need to do sob if looking for timed transactions num_items = min(len(self._pkt), len(output_items[0])) output_items[0][:num_items] = self._pkt[:num_items] self._pkt = self._pkt[num_items:] #residue for next work() if len(self._pkt) == 0 : item_index = num_items #which output item gets the tag? offset = self.nitems_written(0) + item_index source = pmt.pmt_string_to_symbol("framer") #print 'frame cnt',self.more_frame_cnt if self.has_tx_time: key = pmt.pmt_string_to_symbol("tx_sob") self.add_item_tag(0, self.nitems_written(0), key, pmt.PMT_T, source) key = pmt.pmt_string_to_symbol("tx_time") self.add_item_tag(0, self.nitems_written(0), key, pmt.from_python(self.tx_time), source) #if self.keep: # print 'bad order' #self.keep = True if self.more_frame_cnt == 0: key = pmt.pmt_string_to_symbol("tx_eob") self.add_item_tag(0, offset - 1, key, pmt.PMT_T, source) #if self.keep: # print 'good order' #self.keep = False else: self.more_frame_cnt -= 1 return num_items
def loopback(self, python_data): as_a_pmt = pmt.from_python(python_data) back_to_python = pmt.to_python(as_a_pmt) self.assertEqual(python_data, back_to_python)
def test_null(self): self.assertEqual(None, pmt.to_python(pmt.PMT_NIL)) self.assertTrue(pmt.pmt_equal(pmt.PMT_NIL, pmt.from_python(None)))