Decompressor configuration when compressor is in an independent process

Asked by Carlos

Hello,

I am working in my home university in a LTE simulator which implements the radio access protocols, including PDCP, the protocol layer which can use ROHC if configured. For testing purposes, I am simulating the communication between an eNodeB and a UE and the user periodically sending pings to the Internet. On the contrary to the library examples where compression and decompression are performed by the same program, in my setup the compressor and decompresor are not running in the same process, so it is essential that the compressor in the user sends to its associated decompressor some context somehow to successfully decompress the IP packets. The 3GPP specification defines a special message for feedback exchange called interspersed ROCH feedback packet. However, this library seems to me that only the decompressor uses a feedback channel to acknoledge the compressed packets reception. Is it possible to transmit a compression context to the decompressor? And how?

Thanks in advance

BR

Carlos

Question information

Language:
English Edit question
Status:
Expired
For:
rohc Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Didier Barvaux (didier-barvaux) said :
#1

Hi Carlos,

I'm not sure to fully understand you. I do not known the LTE specifications very well, especially the "interspersed ROHC feedback packet". I'll explain you how the library works for feedbacks. I hope it will help you. Feel free to ask questions.

When used in bi-directional mode, the ROHC compressor transmits ROHC packets to the ROHC decompressor, and the ROHC decompressor transmits ROHC feedbacks to the ROHC compressor. See http://rohc-lib.org/wiki/lib/exe/fetch.php?media=wiki:rohc_rmode.png for a figure.

However the ROHC decompressor does not transmit the ROHC feedbacks itself. It uses an associated ROHC compressor to transmit them. The associated compressor is not the same compressor that transmitted ROHC packets to the ROHC decompressor. See the ASCII figure at http://bazaar.launchpad.net/~didier-barvaux/rohc/main/view/head:/test/non_regression/test_non_regression.c#L34 . On the figure, you got 2 ROHC compressor/decompressor pairs. Compressor 1 transmits ROHC packets to decompressor 1. Compressor 2 transmits ROHC packets to decompressor 2. Decompressor 1 uses compressor 2 to transmit feedbacks. Decompressor 2 uses compressor 1 to transmit feedbacks.

One ROHC compressor may transmit ROHC feedbacks in one of the following 2 ways: 1/ as a standalone packet, 2/ by using piggybacking (= ROHC feedback put at the very beginning of any ROHC packet).

In the ROHC library, a ROHC compressor tries to piggyback ROHC feedbacks whenever it compresses then transmits a ROHC packet. This is performed in a transparent way. You do nothing. If there is no traffic on which to piggyback ROHC feedbacks, one can extract the ROHC feedbacks from the ROHC compressor, and transmit them manually. This is performed by the rohc_feedback_flush() function (see http://rohc-lib.org/doc/rohc-doc-1.5.0/group__rohc__comp.html#gaa018058bb0ab4a1419264d8dd2434f7a).

So, if you want not to use piggybacking and send the feedbacks on your own: a/ create a 2nd ROHC compressor, b/ associate it to the decompressor, c/ call rohc_feedback_flush() on the 2nd compressor after every call to rohc_decompress() on the decompressor, d/ send the returned feedback data on your own.

Hope it helps!

Regards,
Didier

Revision history for this message
Carlos (carhercl) said :
#2

Hi Didier,

Thank you very much for your answer. It really helped me to understand how to integrate the standalone feedback mode in my compression test. I am following the 4-step process you recommend in your message. However, I have some troubles decompressing packets. The decompressor fails to decompress every packet. An error message "no profile found for decompression" always displays . Am I forgetting anyhing? By the way, IP and no compresion modes are only enabled.
Below I include the code lines that initialize both compressor and decompressor.

Best regards,

Carlos

 /* Initialize entity's RoHC compressor. Suggestion: set max_cid = 15 */
 comp = rohc_alloc_compressor(max_cid, 0, 0, 0);
 if(comp == NULL)
 {
  fprintf(stderr, "cannot create the ROHC compressor\n");
  /* manage the error here */
 }

 /*
  * Load selected profiles. List of supported modes below:
 rohc_activate_profile(comp, ROHC_PROFILE_UNCOMPRESSED);
 /* Uncompressed mode must always be enabled, in case compression is
  * not possible */
 if(ROHC_profile != ROHC_PROFILE_UNCOMPRESSED)
  rohc_activate_profile(comp,ROHC_profile);

 /* Set MAX CID */
 rohc_c_set_large_cid(comp, 0);
 if(max_cid > 15)
 {
  rohc_c_set_large_cid(comp, 1);
  rohc_c_set_max_cid(comp, ROHC_LARGE_CID_MAX);
 }

 /* set the callback for random numbers */
 if(!rohc_comp_set_random_cb(comp, gen_random_num, NULL))
 {
  fprintf(stderr, "failed to set the callback for random numbers\n");
 }

decomp = rohc_alloc_decompressor(comp);
 if(decomp == NULL)
 {
     fprintf(stderr, "cannot create the ROHC decompressor\n");
     /* manage the error here */
 }

 /* set CID type and MAX_CID for decompressor */
 if(max_cid > 15)
 {
  if(!rohc_decomp_set_cid_type(decomp, ROHC_LARGE_CID))
  {
   fprintf(stderr, "failed to set CID type to large CIDs for "
     "decompressor\n");
  }
  if(!rohc_decomp_set_max_cid(decomp, ROHC_LARGE_CID_MAX))
  {
   fprintf(stderr, "failed to set MAX_CID to %d for "
     "decompressor\n", ROHC_LARGE_CID_MAX);
  }
 }
 else
 {
  if(!rohc_decomp_set_cid_type(decomp, ROHC_SMALL_CID))
  {
   fprintf(stderr, "failed to set CID type to small CIDs for "
     "decompressor\n");
  }
  if(!rohc_decomp_set_max_cid(decomp, ROHC_SMALL_CID_MAX))
  {
   fprintf(stderr, "failed to set MAX_CID to %d for "
     "decompressor\n", ROHC_SMALL_CID_MAX);
  }
 }

Following, the relevant code from the decompressor part:

 int ip_size = rohc_decompress(
   decomp,
   (u8*)(*sdu)->getDataField(),
   (*sdu)->get_packet_size(),
   ip_packet,
   MAXLENGTH
 );

 /*
  * If the packet is not successfully uncompressed, the value of ip_size
  * is negative. Manage the error and erase the pdu.
  */
 if(ip_size < 0)
 {
  //TODO: error managing if needed. Have a look at all the possible negative values of ip_size
  //-------------------------------------------------

#ifdef DEBUG
  std::cout << "Packet decompression failed. Returned value = "
    << ip_size << std::endl;
#endif
  /* Delete the SDU */
  delete *sdu;
  *sdu = NULL;
  return;
 }

 /* Send feedback to peer compressor */
 u8 feedback_buffer[MAXLENGTH];
 int feedback_size = rohc_feedback_flush(comp,feedback_buffer,MAXLENGTH);

 std::cout << "Feedback size = " << feedback_size << std::endl;
 if(feedback_size > 0)
 {
  Protocol_Packet* interspersed_pdu = new Protocol_Packet();
  interspersed_pdu->addDataBytes(feedback_buffer,feedback_size);

  /* Create interspersed ROHC feedback packet */
  addHeader(interspersed_pdu, PDCP_Control_PDU_interspersed, 0); //SN deprecated here

  /* Deliver to peer */
  p_layer->generate_rlc_message(0, this->getRbId(), interspersed_pdu);

 }

Revision history for this message
Didier Barvaux (didier-barvaux) said :
#3

Seems like the decompressor does not find the correct profile ID in the ROHC packet. Could you please copy/paste the full output of the ROHC library?

Didier

Revision history for this message
Carlos (carhercl) said :
#4

Hi Didier,

This are the relevant logs from my program execution. I must say that there are two kind of output:

1. Decompression
Received SDU to uncompress: aa9f59a647eb265e103318aa82d95fc5141b6b965316f843f3eb6f37ccc2e2aae946a6e5fa7eabcd6516e8becb024eb3238a8307d1e629b42cc732ac7a2a457add
[../sources/rohc/rohc_decomp.cpp:412 rohc_decompress()] decompress the 68-byte packet #22
[../sources/rohc/rohc_decomp.cpp:1630 d_decode_feedback_first()] skip 0 byte(s) of padding
[../sources/rohc/rohc_decomp.cpp:1588 rohc_decomp_decode_cid()] 2-byte large CID = 8025 (0x1f59)
[../sources/rohc/rohc_decomp.cpp:721 d_decode_header()] ROHC packet is not an IR packet
[ERROR] [../sources/rohc/rohc_decomp.cpp:730 d_decode_header()] context with CID 8025 either does not exist or no profile is associated with the context
Packet decompression failed. Returned value = -1

2. Decompression + feedback
Received SDU to uncompress: 8950be8a86ca8268ec44fba3c55f83a2d84d6caf6f8f75d3f488439a1634f63f6564c1c584078b884d920863e5b68ef74990a7ee444ad44c7efe90d8a1786a014442b
[../sources/rohc/rohc_decomp.cpp:412 rohc_decompress()] decompress the 68-byte packet #24
[../sources/rohc/rohc_decomp.cpp:1630 d_decode_feedback_first()] skip 0 byte(s) of padding
[../sources/rohc/rohc_decomp.cpp:1588 rohc_decomp_decode_cid()] 1-byte large CID = 80 (0x50)
[../sources/rohc/rohc_decomp.cpp:721 d_decode_header()] ROHC packet is not an IR packet
[ERROR] [../sources/rohc/rohc_decomp.cpp:730 d_decode_header()] context with CID 80 either does not exist or no profile is associated with the context
[../sources/rohc/rohc_decomp.cpp:878 d_optimistic_feedback()] send a STATIC NACK feedback
[../sources/rohc/feedback.cpp:76 f_feedback2()] FEEDBACK-2: first 4 bits = 0xffffffa0 (ACK type = 2, mode = 2)
[../sources/rohc/feedback.cpp:80 f_feedback2()] FEEDBACK-2: transmit SN = 0x00000000 on 12 bits
[../sources/rohc/feedback.cpp:82 f_feedback2()] FEEDBACK-2: 4 bits of SN = 0x0
[../sources/rohc/feedback.cpp:84 f_feedback2()] FEEDBACK-2: 8 bits of SN = 0x00
[../sources/rohc/feedback.cpp:291 f_append_cid()] add 1 bytes for large CID to feedback
[../sources/rohc/rohc_comp.cpp:1162 c_piggyback_feedback()] try to add 4 byte(s) of feedback to the next outgoing ROHC packet
[../sources/rohc/rohc_comp.cpp:1194 c_piggyback_feedback()] 4 byte(s) of feedback added to the next outgoing ROHC packet
Packet decompression failed. Returned value = -1

Thanks in advance

Regards,

Carlos

Revision history for this message
Carlos (carhercl) said :
#5

It also looks like the CID value is different for every packet in the decompressor. Is this normal? Here I provide some examples:

Received SDU to uncompress: f3524ffd82bb2da50f53fd81e35d8ef85c7e562d779851233e3a18bd910ddbea28222cdb8b78dba30bccc8bd282aa1a1316aebc678677276ba7dba5a805ef2559bd17c
[../sources/rohc/rohc_decomp.cpp:412 rohc_decompress()] decompress the 71-byte packet #4
[../sources/rohc/rohc_decomp.cpp:1630 d_decode_feedback_first()] skip 0 byte(s) of padding
[../sources/rohc/rohc_decomp.cpp:1701 d_decode_feedback()] feedback present (header = 1 bytes, data = 3 bytes)
[../sources/rohc/rohc_comp.cpp:1223 c_deliver_feedback()] deliver 3 byte(s) of feedback to the right context
[../sources/rohc/rohc_comp.cpp:1259 c_deliver_feedback()] feedback size = 2
[ERROR] [../sources/rohc/rohc_comp.cpp:1286 c_deliver_feedback()] context not found (CID = 82)
[../sources/rohc/rohc_decomp.cpp:1588 rohc_decomp_decode_cid()] 2-byte large CID = 15149 (0x3b2d)
[../sources/rohc/rohc_decomp.cpp:721 d_decode_header()] ROHC packet is not an IR packet
[ERROR] [../sources/rohc/rohc_decomp.cpp:730 d_decode_header()] context with CID 15149 either does not exist or no profile is associated with the context
Packet decompression failed. Returned value = -1

Received SDU to uncompress: ae39bc428ae43cb31b367ad6c1e87d2cf639cb21bc26b1a0d0ebbb2f7fbe168b5ebe5bfdf1862ec3b3cfd6ce6c1542ca9dba8a2e0d8fa2f8f49f4845eb39ac9a1a9e3
[../sources/rohc/rohc_decomp.cpp:412 rohc_decompress()] decompress the 69-byte packet #5
[../sources/rohc/rohc_decomp.cpp:1630 d_decode_feedback_first()] skip 0 byte(s) of padding
[../sources/rohc/rohc_decomp.cpp:1588 rohc_decomp_decode_cid()] 1-byte large CID = 57 (0x39)
[../sources/rohc/rohc_decomp.cpp:721 d_decode_header()] ROHC packet is not an IR packet
[ERROR] [../sources/rohc/rohc_decomp.cpp:730 d_decode_header()] context with CID 57 either does not exist or no profile is associated with the context
Packet decompression failed. Returned value = -1

cf189ddbe7f1a4c81587865ea6f83c51f32865caa4227dcbd42d4781f776b43faa2cb7f832296d56a216dff0229c4a56f915368e1eb888d7eab7783269d5f4ef225ace
[../sources/rohc/rohc_decomp.cpp:412 rohc_decompress()] decompress the 68-byte packet #8
[../sources/rohc/rohc_decomp.cpp:1630 d_decode_feedback_first()] skip 0 byte(s) of padding
[../sources/rohc/rohc_decomp.cpp:1588 rohc_decomp_decode_cid()] 1-byte large CID = 24 (0x18)
[../sources/rohc/rohc_decomp.cpp:721 d_decode_header()] ROHC packet is not an IR packet
[ERROR] [../sources/rohc/rohc_decomp.cpp:730 d_decode_header()] context with CID 24 either does not exist or no profile is associated with the context
Packet decompression failed. Returned value = -1

Revision history for this message
Didier Barvaux (didier-barvaux) said :
#6

The CID may be different for every packet if every packet is part of a different stream. If you test with some ICMP messages, an UDP flow or a TCP connection, this is probably not the case.

The other possible source for your problem may be that the data you give to the ROHC decompressor is not the ROHC packet. Could you check that you parse the SDU correctly? If you miss the ROHC data by one or two bytes, the ROHC decompressor could throw that kind of errors.

Regards,
Didier

Revision history for this message
Launchpad Janitor (janitor) said :
#7

This question was expired because it remained in the 'Needs information' state without activity for the last 15 days.