Program hangs when trying to switch between two flow graphs that use the same USRP2 source (but not

Hi

I am using gnuradio3.3 and USRP2 f/w: Raw Ethernet, with
XCVR2450http://code.ettus.com/redmine/ettus/attachments/71.
with XCVR2450 board.

My application is based upon benchmark_rx.py in gnuradio-examples and
usrp_spectrum_sense.py. In a lab setup with a benchmark_tx.py and
benchmark_rx.py, I want to sense my channel every time I receive a
command
to do so on my control channel (TCP/IP socket thread) while receiving
packets using benchmark_rx.py

The result of sensing is used for reconfiguring my packet receiver flow
graph. Before beginning to receive any packets, I try to sense the
channel
and start my receiver flowgraph with the sensed result incorporated for
the
first time, which works fine.

But when the receiver program comes back via rx_callback(), I want to do
the
same operations (sense channel and reconfigure receiver_path) every time
I
get the ‘sense now’ command on my control channel and my program hangs
indefinitely. (perhaps after attempting to sense the channel…)

I found a thread posted “Clarification of lock() and unlock() in Dynamic
Flow graph reconfiguration…” last year, but my problem seems to be a
little
different as I am using callback and also trying to use the same USRP2
source for two flow graphs. I want to be able to change the role of
USRP2
source dynamically every time inside the callback routine.

I also read in the wiki that two top_block() objects cannot run in
parallel.
Therefore, I changed my sensor object to hier_block2, but then it
doesn’t
allow to lock() or stop() and restart the flow graph.

Relevant sections of the program is attached below:

###############################################################################################################################

import usrp_receive_path
import nc_ofdm

Tx_mask = “”
CommonMask = “”
global Final_mask

StartSensor = threading.Event()
StartSensor.clear()

some event flags to synchronize the two threads

class tune(gr.feval_dd):
def init(self, tb):
gr.feval_dd.init(self)
self.tb = tb
def eval(self, ignore):
try:
return center_freq
except Exception, e:
print "tune: Exception: ", e
class parse_msg(object):
def init(self, msg):
self.center_freq = msg.arg1()
self.vlen = int(msg.arg2())
assert(msg.length() == self.vlen * gr.sizeof_float)
t = msg.to_string()
self.raw_data = t
self.data = struct.unpack(‘%df’ % (self.vlen,), t)

###MY RECEIVER BLOCK###
class my_rx_block(gr.top_block):
def init(self, callback, options):
gr.top_block.init(self)
# Set up receive path
self.options = options
self.rxpath = usrp_receive_path.usrp_receive_path(callback,
options)
self.connect(self.rxpath)

###RECONFIGURING METHOD###
def set_new_mask(self, new_mask):
self.options.carrier_mask = new_mask
self.disconnect(self.rxpath)
self.txpath = usrp_receive_path.usrp_receive_path(self.options)
self.connect(self.rxpath)

###SENSOR OBJECT###
class my_sense_block(gr.hier_block2):
def init(self, options):
gr.hier_block2.init(self, “sensor”,
gr.io_signature(0, 0, 0),
gr.io_signature(0, 0, 0))
self.options = options
self.u =
usrp2.source_32fc(options.interface,options.mac_addr)
adc_rate = self.u.adc_rate()

# SETS UP MY SOURCE AND OTHER BLOCK REQUIRED TO SENSE

            ......
            self.connect(self.u, self._agc, s2v, fft, c2mag, stats)

def sense_loop(sb):
m = parse_msg(sb.msgq.delete_head())

CALCULATES THE RESULT OF SENSING

    return Mask

CONTROL THREAD THAT RAISES SOME FLAGS TO CONTROL THE FLOW OF MAIN

THREAD #
def openServerSock(host, port):
global Tx_mask
serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Raises the appropriate flags based on what is received on the
control
channel #

/////////////////////////////////////////////////////////////////////////////

main

/////////////////////////////////////////////////////////////////////////////

def main():

global n_rcvd, n_right

n_rcvd = 0
n_right = 0

global CommonMask

host = ''
port = 5555
# Fork a new thread for control channel on TCP sockets, this thread

raises a
# few flags that will be read by my_rx_block and appropriate actions
will be
# taken upon the flow-graph
thread.start_new_thread(openServerSock, (host, port))

  • def rx_callback(ok, payload):*
  •    global n_rcvd, n_right*
    
  • if(StartSensor.is_set()):*
  • tb.lock()*
  • tb.disconnect(tb.rxpath)*
  • sb = my_sense_block(options)*
  • Rx_mask = sense_loop(sb)*
  • StartSensor.clear()*
  • TxMaskRecvd.wait()*
  • CommonMask = bin_to_hex(hex_to_bin(Tx_mask) & hex_to_bin(Rx_mask))*
  • CommonMaskReady.set()*
  • TxMaskRecvd.clear() *
  • set_new_mask(CommonMask)*
  •     tb.rxpath = usrp_receive_path.usrp_receive_path(tb.options)*
    
  •     tb.connect(tb.rxpath)*
    
  • tb.unlock()*

n_rcvd += 1
(pktno,) = struct.unpack(‘!H’, payload[0:2])
if ok:
n_right += 1
print “ok: %r \t pktno: %d \t n_rcvd: %d \t n_right: %d” % (ok, pktno,
n_rcvd, n_right)
if 0:
printlst = list()
for x in payload[2:]:
t = hex(ord(x)).replace(‘0x’, ‘’)
if(len(t) == 1):
t = ‘0’ + t
printlst.append(t)
printable = ‘’.join(printlst)

print printable
print "\n"

parser = OptionParser(option_class=eng_option,

conflict_handler=“resolve”)
expert_grp = parser.add_option_group(“Expert”)
parser.add_option(“”,“–discontinuous”, action=“store_true”,
default=False,
help=“enable discontinuous”)
parser.add_option(“”, “–snr”, type=“eng_float”, default=30,

#ADD OPTIONS#

usrp_receive_path.add_options(parser, expert_grp)
nc_ofdm.nc_ofdm_demod.add_options(parser, expert_grp)

(options, args) = parser.parse_args ()

# build the sensor flowgraph
sb = my_sense_block(options)

# build the receiver flowgraph
tb = my_rx_block(rx_callback, options)

StartSensor.wait()
Rx_mask = sense_loop(sb)
StartSensor.clear()

TxMaskRecvd.wait()
CommonMask = bin_to_hex( (hex_to_bin(Tx_mask)) & 

(hex_to_bin(Rx_mask)))
CommonMaskReady.set()
TxMaskRecvd.clear()

options.carrier_mask = CommonMask
tb.start()

r = gr.enable_realtime_scheduling()
if r != gr.RT_OK:
    print "Warning: failed to enable realtime scheduling"

tb.wait()

if name == ‘main’:
try:
main()
except KeyboardInterrupt:
pass

#########################################################################################################################

The output is as follows:

./RxSense_ver3.py -f 2.49G -v
nc_ofdm: carrier_mask = FFFFFFFFFFFF000000000FFFFFFFFFFFFFFF
nc_ofdm_mod: occupied carriers = 144

gr_fir_ccf: using SSE
gr_fir_fff: using SSE

OFDM Demodulator:
Modulation Type: qpsk
FFT length: 256
Occupied Tones: 144
CP length: 18

Receive Path:
USRP Source: Interface: eth0 MAC Address: 00:50:c2:85:31:43
D-Board
ID: 0x61
Requested RX Bitrate: 100k
Actual Bitrate: 1.92308M

Receiver is at (‘10.10.21.2’, 47566)
waiting for ‘SenseNow’…
Request: S
Raising Sensor flag
M: Sensed Rx mask:
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC081FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

waiting for ‘SenseNow’…
Request:
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
T: Tx_mask:
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
Raising TxMaskRecvd flag
Waiting for CommonMaskReady flag
M: Recvd Tx mask:
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
M: Calculated CommonMask:
ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff
ST: CommonMask:
ffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff

Waiting for CommonMaskReady flag
T: CommonMask:
ff000000000000000000000000000000000000000000000000000fffffffffff
ok: False pktno: 4184 n_rcvd: 1 n_right: 0
ok: False pktno: 28 n_rcvd: 2 n_right: 0
ok: False pktno: 5213 n_rcvd: 3 n_right: 0
ok: False pktno: 14 n_rcvd: 4 n_right: 0
ok: False pktno: 4217 n_rcvd: 5 n_right: 0
ok: False pktno: 4122 n_rcvd: 6 n_right: 0
ok: False pktno: 16412 n_rcvd: 7 n_right: 0
ok: False pktno: 4221 n_rcvd: 8 n_right: 0

waiting for ‘SenseNow’…
Request: S
Raising Sensor flag

usrp2: channel 0 already streaming
TIMEOUT

waiting for ‘SenseNow’…
Request:
FFFFFFFFFFFFFFFFFFFFE6000000000080000000000FFFFFFFFFFFFFFFFFFFFF
T: Tx_mask:
FFFFFFFFFFFFFFFFFFFFE6000000000080000000000FFFFFFFFFFFFFFFFFFFFF
Raising TxMaskRecvd flag
Waiting for CommonMaskReady flag
gr_block_executor: source <gr_block usrp2_source_32fc (39)> produced no
output. We’re marking it DONE.

#############################################################

Any comments or suggestions are greatly appreciated.

thanks in advance