Search code examples
redhawksdr

Is there an equivalent to matchAllocationIdToStreamId for TX?


I am trying to finish a FE device for a radio with two independent TX channels. The wizard generated a device with 2 short input ports for the TX data. When I allocate a TX channel as a user of the device I have no idea which port is used by the allocation. What is the best way to handle this as I will have to read data from the proper ports to send to the TX channels?

If I reduce the number of input ports to one, I could have properties that set the stream ID (as a filter) for each route and have the user tie the stream ID to a tuner index. This would have to be done after an allocation.


Solution

  • You have the right idea. There should be a single input BulkIO port that can handle multiple streams, rather than multiple input ports. The wizard allows the developer to specify how many input ports to generate, so you must have chosen two. There's not much reason for an FEI Tuner Device to ever have two input ports of the same type meant for ingesting data streams. The USRP_UHD is an example of when multiple input ports does make sense, but that's only because it supports multiple data types (short and float) and it has an input port for each type.

    So now let's assume you have a single input port that is used to send data to both TX channels. You should map the Stream ID of the input data to the Allocation ID of the TX tuner. You suggested using the tuner index, but I recommend using Allocation ID instead. There are (at least) three ways to map the input stream to a specific allocated tuner:

    1. Use a struct sequence Property to map input Stream IDs to the Allocation ID of the target TX tuner (this is similar to your suggestion). The connectionTable Property is typically used for multi-out ports, but the same concept can be applied to multi-in ports. Each struct entry would map an input Stream ID to an Allocation ID (and perhaps the port name of the input port, though leaving off the port name may be preferable in this case). This would have to be configured externally like any other Property, as opposed to when it's used for multi-out ports and it's configured during allocation by the FEI device itself. When data is received on the input port, the developer code would have to check the connectionTable Property to know which tuner the data stream is associated with, if any.
    2. Another possibility is to define an SRI keyword that identifies the target TX tuner using the Allocation ID (e.g. key="TUNER_ID" and value=<actual allocation id of TX tuner>) and add this to the input data stream's SRI. Again, the developer code will need to check the SRI keyword to know which tuner the data stream is associated with, if any.
    3. And of course another option is to require the Allocation ID to be the same as the Stream ID, such that the allocation would be made using the Stream ID as the Allocation ID (rather than changing the Stream ID to match whatever Allocation ID was used... though either would work).

    Note that for multi-out ports the connection to the port is made using a Connection ID that matches the Allocation ID, and that together with the connectionTable Property (which maps Allocation/Connection ID to Stream ID) enables the output port to only send data streams to the appropriate connections. Input ports (or "provides" ports, as they're called) don't actually have any knowledge of the Connection IDs, so a similar method cannot be employed.

    There are pros and cons of each proposed solution above:

    • Option 1 requires configuration of the Device Properties. This is not really a big deal if who-/what-ever is making the allocation also has knowledge of the Stream ID. If the allocation is made via a uses-device relationship in a waveform where the allocation is handled by the framework, it's a little more tricky. Also, you must take extra care when configuring the connectionTable Property since it would be very easy to wipe out existing connectionTable configuration. You have to query the Property to get the current configuration, modify as appropriate, then configure the Property using the modified value. Simply configuring with the Stream ID and Allocation ID mapping will wipe out any existing config. An easy way around this is to create a struct Property named something like addStreamMapping that when configured adds the value to the connectionTable struct sequence (using a Property listener). The same technique can be used for removal of connectionTable entries. This allows the FEI Device to synchronize adding/removing entries.
    • Option 2 requires a keyword be injected, which is not always desired. The data processing path must have knowledge of the Allocation ID for this to work. Use of a keyword injector component makes this more feasible.
    • Option 3 requires that either: the Stream ID be known at the time of allocation, or the Stream ID be set to the Allocation ID.

    Ideally, you could even support all three. FEI does not define how to map input data streams to specific TX tuners, so until it has been defined and documented, use whichever method works best for your use case.