← Back to team overview

rohc team mailing list archive

Re: rohc_feedback in 1.7

 

Yakir,

> I am attempting a brave move from 1.7 to 2.1 on ARM.
> One thing that has popped up straight away was the absence of the
> rohc_feedback. The following snippet is from 1.7,
> 
> [snip code]
> 
> Post 1.7, has the feedback handling been made implicit?

You're right, feedback handling changed between 1.6.x and 1.7.x. The
1.7.x versions also handled the old API, but versions 2.0.0 (or any
later version) dropped it.

The new way to handle feedback is now more flexible: handling both
piggy-backing or feedback-only channels becomes possible.

The API changes are described on the wiki:
https://rohc-lib.org/wiki/doku.php?id=library-migration#api_changes_between_16x_and_17x

However, the feedback changes are not described. Here are some
explanations. If you find them helpful, I'll add them to the wiki.


The feedbacks are transmitted in two ways:
 * piggybacked with one ROHC packet that goes in the other direction
 * sent alone.
 
Piggybacking may saves bandwidth, however it requires some return
traffic. If there is no return traffic, the feedbacks shall be sent
alone in order to avoid adding jitter. The behaviour might be controlled
by an application with a timeout: queue the feedbacks until a return
packet arrives or the times out.

When feedback are piggybacked, the decompressor is associated to a
local compressor that will transmit the feedback over the network. The
remote decompressor will extract the feedback and give it to the local
compressor that will interpret it.
 
 comp. A    ----[ROHC for A + feedback for B]--->  decomp. A
   /\                                                |
   |                                                 | feedback for comp. A
   | feedback for comp. B                            |   +
   |   +                                             | feedback for comp. B
   | feedback for comp. A                            |
   |                                                 \/
 decomp. B  <---[ROHC for B + feedback for A]----  comp. B

The rohc_decompress3() function allows you to perform both
transmission ways. The function returns two feedbacks:
 * The 4th parameter is the feedback sent by the remote decompressor
   that shall be delivered to the local compressor. The function
   rohc_comp_deliver_feedback2() may be used for the delivery.
 * The 5th parameter is the feedback that the local decompressor wants
   to transmit to its remote compressor. That packet may be sent as-is
   over the network, or it may be prepended to any ROHC packet
   generated by the local compressor.
 
The test/non_regression/test_non_regression.c uses two couples of ROHC
compressor/decompressor that use each other for piggybacking.

A more complete application than the non-regression test should handle
the case in which there is no traffic in the other direction. To
achieve that, the application may store all generated feedbacks
locally. Then:
 1/ If a packet goes the reverse way, then you build a ROHC packet with:
       a/ the stored feedbacks
       b/ the ROHC packet generated by the rohc_compress4() function.
    You may concatenate them together: 1 or more feedbacks first then
    the ROHC packet itself. The only limit is the MTU of your link
    layer.
 2/ If no packet goes the reverse way for a long time, then you send
    all the stored feedbacks to your link layer. The decompressor will
    handle them fine: the rohc_decompress3() function returns
    ROHC_STATUS_OK and an empty decompressed packet (3rd argument of the
    function).



You are not the only one struggling with feedback handling. I should
maybe add a "simple" API that makes easy to create a couple of local
compressor and decompressor. It could hide the details and handle
feedback between the local (de)compressors transparently for the
library users. Something that could look like:

/* create couple */
rohc_couple = rohc_couple_new(ROHC_SMALL_CID, ROHC_SMALL_CID_MAX, random_cb, NULL);
if(rohc_couple == NULL)
{
  /* handle error */
}

/* decompress one ROHC packet:
    - internally deliver the feedback sent by the remote decompressor to
      the local compressor,
    - decompress any compressed packet into the provided
      'uncompressed_packet' buffer (some ROHC packets may contains only
      feedback, resulting in no uncompressed packet),
    - internally store the feedback that the local decompressor wants
      to transmit to its remote compressor.
*/
status = rohc_couple_decompress(rohc_couple, rohc_packet, &uncompressed_packet);
if(status != ROHC_STATUS_OK)
{
  /* handle error */
}
if(uncompressed_packet.len != 0)
{
  /* uncompressed packet is available, do something with it */
}

/* sometimes later, compress one uncompressed packet */
status = rohc_couple_compress(rohc_couple, uncompressed_packet, &rohc_packet);
if(status != ROHC_STATUS_OK)
{
  /* handle error */
}
/* compressed packet is available with piggybacked feedback, send it to
   the remote node */

/* if there is no packet to compress, one may flush the stored feedback */
status = rohc_couple_flush(rohc_couple, &rohc_packet);
if(status != ROHC_STATUS_OK)
{
  /* handle error */
}
/* compressed packet is available with feedback information only, send
   it to the remote node */


What do you think of?


> PS. BTW, thanks for other 32bit CPU kernel div64 fix --- will test
> this soon

OK. Keep me informed please.


Regards,
Didier



Follow ups

References