Passing the payload to the application level

I am trying to pass the payload from the layer where it is obtained back
to
the application level. However, I’m having some problems. When examining
benchmark_gmsk_rx.py, I see that the rx_callback funstion is passed into
the
receive_path class. Going further, I see that the function is passed
from
benchmark_gmsk_rx.py to the receive_path class to the gmsk_demod_pkts
class,
which I understand to be in
/usr/local/lib/python2.4/site-packages/gnuradio/blksimpl/gmsk2_pkt.py.
Here,
the function is finally called in a class called _queue_watcher_thread.
However, no matter what I do, I can’t get the payload data back to the
app
layer. Just to test things, I commented out the instance of
_queue_watcher_thread that is instantiated by the gmsk2_demod_pkts()
class,
and the rx_callback function is still running, which leads me to believe
that I’m not looking in the right place. Also, when I try to make a
member
variable of the _queue_watcher_thread class called self.thepayload and
make
a a return of the payload in the rx_callback function, and then try to
print
self.thepayload from the watcher class, nothing happens. If I make a
print
statement in the rx_callback function, the payload prints.

-Michael F.-

On Wed, Sep 20, 2006 at 11:49:27PM -0500, Michael F. wrote:

_queue_watcher_thread that is instantiated by the gmsk2_demod_pkts() class,
and the rx_callback function is still running, which leads me to believe
that I’m not looking in the right place. Also, when I try to make a member
variable of the _queue_watcher_thread class called self.thepayload and make
a a return of the payload in the rx_callback function, and then try to print
self.thepayload from the watcher class, nothing happens. If I make a print
statement in the rx_callback function, the payload prints.

-Michael F.-

First off, I’m assuming that you are running the svn trunk code.
If not, please start there.

When you run the unmolested benchmark_gmsk_tx.py and
benchmark_gmsk_tx.rx on two machines do they work? That is, does the
rx code report that it’s receiving packets correctly? I typically get
100% correct packet reception.

If not, what daughterboards are you using?
They need to be RFX-'s. Basic Tx and Rx won’t work.
Long story, it’s in the archives somewhere. Also, keep the boards at
least 3m apart.

Now, assuming that that’s working, what’s the question?
Basically, packets are getting from the C++ to the python code by
virtue of a message queues and messages.

You are correct, this is set up in gmsk2_pkt.py.
framer_sink_1 is handed the message queue in its constructor and then at
runtime inserts messages into it. The _queue_watcher_thread
hangs a blocking read on the queue by doing:

msg = self.rcvd_pktq.delete_head()

Eric

Packet reception is great, no problems there at all.

The prblem is that since the rx_callback function is called within the
_queue_watcher_thread class, I figured I could return the payload to
benchmark_gmsk2_tx.py from there (as opposed to simply printing the
payload). However, when I create a member variable in the
_queue_watcher_thread class called self.thepayload, and return the
payload
from the rx_callback function into said member variable, and then try to
pass it back to the app layer, I get errors saying that the
_queue_watcher_thread class has no such member. Also, when I try to
directly
print the payload obtained from the calls

def run(self):
while self.keep_running:
msg = self.rcvd_pktq.delete_head()
ok, payload = packet_utils.unmake_packet(msg.to_string())
print payload #added by me
if self.callback:
self.callback(ok, payload)

nothing happens.

But perhaps the most baffling thing is that no matter what I do to the
_queue_watcher_thread class, even totally comment it out, rx_callback
still
runs. Also, printing the payload from within the rx_callback function
works,
and that is the only place it works. I am under the impression that
rx_callback is passed down to the _queue_watcher_thread class and is
called
from there. Why would it still output to the screen if I comment out the
class?

I am basically trying to use the contents of the payload as a
conditional,
but I can’t pass the payload back up to benchmark_gmsk_rx.py to save my
life.

Sorry if I’m not clear.

On Thu, Sep 21, 2006 at 01:05:58AM -0500, Michael F. wrote:

print the payload obtained from the calls

def run(self):
while self.keep_running:
msg = self.rcvd_pktq.delete_head()
ok, payload = packet_utils.unmake_packet(msg.to_string())
print payload #added by me
if self.callback:
self.callback(ok, payload)

nothing happens.

Perhaps you’re neglecting to do a “make install” after editing in
gnuradio-core?
Are you editing in the build tree? That is
…/gnuradio-core/src/python/gnuradio/blksimpl/gmsk2_pkt.py ?

That would be correct, but you’ll need to be sure to perform a

$ make install

To get it put in the place that it’ll be seen when you run the
example.

FWIW, when I’m messing with this and the stuff in gnuradio-examples at
the same time, I usually have my current directory in
gnuradio-examples/python/gmsk2, but after I edit something in
gnuradio-core/…/blksimpl I execute

$ (cd /gnuradio-core/src/python; make install)

Then run my test code

$ ./benchmark_rx.py …

but I can’t pass the payload back up to benchmark_gmsk_rx.py to save my
life.

Sorry if I’m not clear.

No, this is clear. Please let me know if this solved the problem of
not seeing your changes.

However, I still don’t understand why you want to mess with the code
in gmsk2_pkt.py. It fires the callback which is provided in
benchmark_gmsk2_rx. You have complete control of what happens from
there.

E.g., in benchmark_gmsk2_rx, instead of passing the existing callback
like this:

# build the graph
fg = my_graph(blks.gmsk2_demod,
              options.rx_subdev_spec, options.bitrate,
              options.decim, options.spb, rx_callback,
              options, demod_kwargs)

You could either redefine the existing callback, or compose the
existing callback with a function that performs the conditional.
E.g.,

def filter_based_on_payload(callback):
def wrapped_callback(ok, payload):
if my_conditional(ok, payload): # whatever you want here
callback(ok, payload) # fire callback passed
in
else:
pass # ignore the payload, or whatever

return wrapped_callback          # return the closure

Then,

# build the graph
fg = my_graph(blks.gmsk2_demod,
              options.rx_subdev_spec, options.bitrate,
              options.decim, options.spb, 

filter_based_on_callback(rx_callback),
options, demod_kwargs)

Eric

Eric,

I’ve been editing
/usr/local/lib/python2.4/site-packages/gnuradio/blksimpl/gmsk2_pkt.py

From what I’m reading, it sounds like this is incorrect. I’m going to edit
the file that you suggest before I explore your other options.

-Michael F.-

Actually, I just realized - that’s the only copy of gmsk2_pkt.py that
exists
for me. I’m not in the lab right now, but I remember doing searches for
that
file and having it only show up in the root directory. Is that a
problem?

On Thu, Sep 21, 2006 at 02:56:12PM -0500, Michael F. wrote:

Actually, I just realized - that’s the only copy of gmsk2_pkt.py that exists
for me. I’m not in the lab right now, but I remember doing searches for that
file and having it only show up in the root directory. Is that a problem?

Are you building from the svn trunk?

If so, then that file isn’t being used anymore. That would explain
why your modifications aren’t being seen.

Look at gnuradio-examples/python/gmsk/receive_path.py
It should look like this:

# receiver
    self.packet_receiver = \
        blks.demod_pkts(fg,
                        demod_class(fg, spb=self._spb, 

**demod_kwargs),
access_code=None,
callback=rx_callback,
threshold=-1)

It’s using the mostly modulation-independent packet handling
code. Note that the demod_class is passed into blks.demod_pkts.

demod_pkts is defined in
gnuradio-core/src/python/gnuradio/blksimpl/pkt.py
but as I said before, I really don’t think that’s the code you ought
to be editing :wink:

Also, as a heads up, we’re going to merge in several substantial
changes to this code in the next day or so. Those mods will result in
there being a benchmark_tx.py, a benchmark_rx.py and tunnel.py that
work with any of gmsk, dbpsk or dqpsk. These will replace the
existing benchmark_gmsk_{tx,rx}.py and tunnel.py

Eric

Eric,

Thanx for your concern about me editing that part of the code - I’ll
continue messing with it for now. I’ll admit that I lose you when you
refer
to the svn trunk.

-Michael F.-