Inband packet encoding/decoding daemon

So from what I understand, a daemon has been suggested for inband packet
encoding and
decoding that is implemented as an m-block which can be connected in a
flow graph for the
encoding/decoding and interfacing with the USRP. Is this correct?

The goal would be the only have 1 of these running, correct? That way
only one is
interfacing with the USRP at a time.

If this is true, what kind of IPC mechanism are we looking at? GNU
Radio is also
compatible on Windows and if we want to keep compatibility we have to be
careful here.

I could start designing and laying this out.

  • George

Hi George,

(Yes, I know you’re waiting for me… More later on today)

On Mon, Mar 26, 2007 at 04:02:48PM -0400, George N. wrote:

So from what I understand, a daemon has been suggested for inband packet
encoding and decoding that is implemented as an m-block which can be
connected in a flow graph for the encoding/decoding and interfacing with
the USRP. Is this correct?

Right, except for the flow graph part.

There are three cases:

(1) only a flow graph (the way it is today)
(2) only mblocks (one of the future ways)
(3) mblocks + flowgraphs (the other future way)

In case (3), I’m thinking that we have a mblock class that knows how
to embedded a flow graph (and all the machinery) within itself. This
would include ways for mblock messages to get sent into the flow
graph (similar to gr.message_source) and to convert the output of the
flow graph into mblock messages (similar to gr.message_sink).

The basic idea is that there is a small piece of code that knows about
both abstractions and how to bridge between them.

The goal would be the only have 1 of these running, correct? That way only
one is interfacing with the USRP at a time.

Yes. One daemon.

If this is true, what kind of IPC mechanism are we looking at? GNU Radio
is also compatible on Windows and if we want to keep compatibility we have
to be careful here.

Probably shared memory and mutexes and/or condition variables.

For systems where that doesn’t work, then we serialize everything and
push it through sockets.

I could start designing and laying this out.

I think that’s premature. I know that you are looking for something
to get to work on. Please bear with me at least until tomorrow.
I’m right now figuring out what needs to happen to have the mblock
code be ready (at least ready enough), that we could have a real
design discussion about the host side of the new USRP interface.

Thanks!
Eric

Eric B. wrote:

The basic idea is that there is a small piece of code that knows about
both abstractions and how to bridge between them.
That seems like the best approach.

Yes. One daemon.
clicks the check box

So this daemon will be allocating the USB channels with the different
ports connected to
it? Basically what we talked about on the phone earlier… the methods
described in:
http://gnuradio.org/trac/browser/gnuradio/trunk/usrp/doc/inband-signaling-usb-host

Writing an m-block, I do not want to worry about this, I am kicking my
packets off to the
daemon, who will decide what channels to allocate and such?

  • George

Eric B. wrote:

Right, except for the flow graph part.
Actually, let me jump back a second here then… what I want to make
sure I understand is
how an m-block knows that it needs to connect to the daemon and forward
its m-block
packets to be converted in to USB packets and they are sent across the
wire

This
would include ways for mblock messages to get sent into the flow
graph (similar to gr.message_source) and to convert the output of the
flow graph into mblock messages (similar to gr.message_sink).

So I get this part, I get the part about converting the output in to
m-block messages, I’m
wondering how these m-block messages are picked up by the daemon? Since
we are using some
sort of IPC, do we have some sort of queue that these messages just get
dumped in and the
daemon can pull messages out of the queue and encode+forward them?

  • George

On Wed, Mar 28, 2007 at 08:19:24PM -0400, George N. wrote:

the USRP. Is this correct?
graph (similar to gr.message_source) and to convert the output of the
flow graph into mblock messages (similar to gr.message_sink).

Just to be keep life sane, let’s defer the part of the discussion
about mixed mblocks and flowgraphs for now…

So I get this part, I get the part about converting the output in to
m-block messages, I’m wondering how these m-block messages are picked up by
the daemon? Since we are using some sort of IPC, do we have some sort of
queue that these messages just get dumped in and the daemon can pull
messages out of the queue and encode+forward them?

  • George

For now ignore the underlying IPC mechanism. Assume that all
communication is via messages (mb_message) between mblocks (derived
from mb_mblock). Some of those mblocks may be running in a different
process, or on a different machine, but that doesn’t really change
anything. All we’ve got are mblocks passing messages to other
mblocks. In the case of mblocks in different address spaces, we’ll
need some kind of rendezvous mechanism, but don’t worry about that
now.

I want to get us thinking about the problem at an “all we’re doing is
sending and receiving messages” level of abstraction.

If you look in mb_mblock.h, mb_message.h and mb_port.h
[trunk/mblock/src/lib/…], you’ll see the interfaces available. To
send a message given a port p, use p->send(…) the message will
magically get delivered to whatever mblock is connected to the
other end of the port.

Likewise, when somebody sends an mblock a message, its
mb_mblock::handle_message method will be automagically invoked with
the message (the runtime will ensure that handle_message is not called
reentrantly. I.e., the mblock doesn’t have to worry about threading
issues). handle_message will look at the contents of the message
(including signal, data, metadata, and which port it came from) and do
whatever it likes. More than likely it’ll perform some kind of
computation and then send one or more messages.

Simple. Of course there’s lot of stuff going on behind the scenes
making this all happen (lots of threads, message queues, data
structures describing who’s connected to whom, etc.) but you, as a
writer of mblocks, don’t need to worry about any of that.

OK?

Eric

On Wed, Mar 28, 2007 at 07:37:43PM -0400, George N. wrote:

So this daemon will be allocating the USB channels with the different ports
connected to it? Basically what we talked about on the phone earlier…
the methods described in:
http://gnuradio.org/trac/browser/gnuradio/trunk/usrp/doc/inband-signaling-usb-host

Yes.

Assume for sake of discussion that there’s a mblock called
“usrp_usb_daemon” with 8 externally visible ports:

rx0
rx1
rx2
rx3

tx0
tx1
tx2
tx3

This is probably overkill, but hey, it’s only a data structure…

For now, ignore the fact that the daemon will be running in another
address space. We’ll sort that out later. Assume that you’ve got a
application (top level mblock) that contains an mblock based
output generator with a single output port which is connected to
the usrp_usb_daemon port “tx2” (which of the tx ports it’s attached
to is arbitrary. If we ever implement “replicated ports”, there will
two ports, rx and tx, each of which are replicated).

top-block (contains these two blocks):

            "out"                      "tx2"
 output generator <------------------> usrp_usb_daemon

Writing an m-block, I do not want to worry about this, I am kicking my
packets off to the daemon, who will decide what channels to allocate and
such?

In real life there’s probably another block or two in front of the
usrp_usb_daemon that handles this kind of stuff. This would include
the “tuning/control interface” etc. In that case, the dumb signal
generator would just send packets containing sample to be transmitted.

top-block:

                      application
                      control block
                      GUI, whatever
                          ^
                          | cs
                          |
                          |
          samples         |
                          | cs (control/status port "tune", "interp" 

…)
out in v out tx1
sig_gen<--------> smart usrp front end <---------> usrp_usb_daemon

Also, we may want to compose the “smart usrp front end” and the
usrp_usb_daemon, and split the control from the data ports. Let’s make
something work, then we can revisit this when we’ve got some experience.

  • George

Eric

George N. wrote:

                          |

something work, then we can revisit this when we’ve got some experience.
Oh yeah, one more thing… what is your logic behind adding a smart usrp
front
end? Just to make sure we’re on the same page…

If I were to take a stab in the dark, the smart front end knows whether
a
channel has been allocated, and query the daemon if not? Basically it
is acting
as one central location for all of the output ports on the application,
whether
they be status or samples, and interfaces with the daemon to setup the
proper
channels and transmit the frames, etc… ?

  • George

On Thu, Mar 29, 2007 at 02:08:00AM -0400, George N. wrote:

                      GUI, whatever

application, whether they be status or samples, and interfaces with the
daemon to setup the proper channels and transmit the frames, etc… ?

It’s the glue that allows a something dumb (blind to the fact that
there’s a usrp involved) be connected to the usrp.

Eric B. wrote:

This is probably overkill, but hey, it’s only a data structure…
:smiley:

For now, ignore the fact that the daemon will be running in another
address space. We’ll sort that out later. Assume that you’ve got a
application (top level mblock) that contains an mblock based
output generator with a single output port which is connected to the
usrp_usb_daemon port “tx2” (which of the tx ports it’s attached
to is arbitrary. If we ever implement “replicated ports”, there will
two ports, rx and tx, each of which are replicated).

top-block (contains these two blocks):

            "out"                      "tx2"
 output generator <------------------> usrp_usb_daemon

Simple and straight forward, understand this now.

In real life there’s probably another block or two in front of the
usrp_usb_daemon that handles this kind of stuff. This would include
the “tuning/control interface” etc.
I like the idea of this.

In that case, the dumb signal
generator would just send packets containing sample to be
transmitted.
This “dumb signal generator” would be implemented as an m-block though,
correct?
the smart usrp front end is only dealing with m-block packets as its
input,
where you’ve marked ‘samples’ you mean the m-block packet payload
contains
samples, yes/no? Just want to make sure.

top-block:

                      application
                      control block
                      GUI, whatever
                          ^
                          | cs
                          |
                          |
          samples         |
                          | cs (control/status port "tune", 

“interp” …)

         out    in        v              out    tx1
 sig_gen<--------> smart usrp front end <---------> 

usrp_usb_daemon

Also, we may want to compose the “smart usrp front end” and the
usrp_usb_daemon, and split the control from the data ports. Let’s
make
something work, then we can revisit this when we’ve got some
experience.

  • George

Eric

Eric B. wrote:

Yes. Everything is mblocks and messages. Some of the messages
contain vectors of samples.

Once this is sorted out, embedding a flow graph in an mblock shouldn’t
be a big deal.

Perfect, we’re on the same track :slight_smile: I agree with the USRP front end
approach
for the final product after getting the basics of things flowing.

  • George

On Thu, Mar 29, 2007 at 01:45:28AM -0400, George N. wrote:

usrp_usb_daemon port “tx2” (which of the tx ports it’s attached

to is arbitrary. If we ever implement “replicated ports”, there will
two ports, rx and tx, each of which are replicated).

top-block (contains these two blocks):

            "out"                      "tx2"
 output generator <------------------> usrp_usb_daemon

Simple and straight forward, understand this now.

Good.

In real life there’s probably another block or two in front of the
usrp_usb_daemon that handles this kind of stuff. This would include
the “tuning/control interface” etc.
I like the idea of this.

OK.

In that case, the dumb signal
generator would just send packets containing sample to be transmitted.
This “dumb signal generator” would be implemented as an m-block though,
correct? the smart usrp front end is only dealing with m-block packets as
its input, where you’ve marked ‘samples’ you mean the m-block packet
payload contains samples, yes/no? Just want to make sure.

Yes. Everything is mblocks and messages. Some of the messages
contain vectors of samples.

Once this is sorted out, embedding a flow graph in an mblock shouldn’t
be a big deal.

Eric