What protocol number should be for RTP header compression

Asked by Wei Wang on 2013-05-22

Hi Didier,

I'm trying to use ROHC lib to compress RTP headers. It seems I can NOT compress RTP headers only because I got the error
"skip profile 'RTP/Compressor' because it only support IPv4 or IPv6". I have to combine RTP/UDP/IP headers together. Which protocol number should I use for RTP compressor? If this protocol number is set as 17 (for UDP), then RTP headers won't get compressed. RTP protocol is not an assigned number.

Thanks,
Wei

Question information

Language:
English Edit question
Status:
Answered
For:
rohc Edit question
Assignee:
No assignee Edit question
Last query:
2013-06-07
Last reply:
2013-06-07

This question was reopened

Wei Wang (eww012) said : #1

Hi Didier,

I found the reason that RTP profile was skipped because the port 1286 is not in the list of reserved ports for RTP. Looks like there is no a rigid definitions of assigned port numbers in RFC3095. So I added this number in the rtp port list. The result is not expected. Headers are not compressed at all. Can you please look at the log below and see what happened?

05-23 11:37:13.340 20184 20337 I ip.c : ip_get_totlen(): IPV4 header len = 56 bytes)
05-23 11:37:13.340 20184 20337 I rohc_comp.c: rohc_compress(): size of uncompressed packet = 56 bytes, 0
05-23 11:37:13.340 20184 20337 I rohc_comp.c: rohc_compress(): line394: proto = 17
05-23 11:37:13.340 20184 20337 I rohc_comp.c: rohc_compress(): try to find the best profile for packet with transport protocol 17, 0
05-23 11:37:13.340 20184 20337 I rohc_comp.c: c_get_profile_from_packet(): comp->profiles[0] = 1
05-23 11:37:13.340 20184 20337 I ip.c : ip_is_fragment(): is_fragment = 0, 0, 0
05-23 11:37:13.340 20184 20337 I rohc_comp.c: c_get_profile_from_packet(): UDP port = 1286
05-23 11:37:13.340 20184 20337 I rohc_comp.c: c_get_profile_from_packet(): returns 0x01
05-23 11:37:13.340 20184 20337 I rohc_comp.c: rohc_compress(): using profile 'RTP / Compressor' (0x0001)
05-23 11:37:13.340 20184 20337 I rohc_comp.c: rohc_compress(): compress the packet #538, esize = 40
05-23 11:37:13.340 20184 20337 I ip.c : ip_get_totlen(): IPV4 header len = 56 bytes)
05-23 11:37:13.340 20184 20337 I rohc_comp.c: rohc_compress(): ROHC size = 56 (feedback = 0, header = 40, payload = 16), output buffer size = 2048

Hello,

> I'm trying to use ROHC lib to compress RTP headers. It seems I can NOT
> compress RTP headers only because I got the error "skip profile
> 'RTP/Compressor' because it only support IPv4 or IPv6". I have to combine
> RTP/UDP/IP headers together.

Yes, that's right. The RTP profile does not compress RTP headers alone. The name is a shorcut. The profile compresses IP/UDP/RTP streams in fact. More especially, it compresses IPv4/UDP/RTP, IPv4/IPv4/UDP/RTP, IPv4/IPv6/UDP/RTP, IPv6/UDP/RTP, IPv6/IPv4/UDP/RTP, or IPv6/IPv6/UDP/RTP streams.

> Which protocol number should I use for RTP compressor? If this protocol
> number is set as 17 (for UDP), then RTP headers won't get compressed.
> RTP protocol is not an assigned number.

Yes, that's right again. The RTP protocol is above the UDP protocol, so the protocol number in the IP header is set to the UDP one (17). Indentifying one RTP stream among other UDP streams is not an easy task. It cannot be identified by the UDP ports since the ports are not well-known but dynamically defined by another control protocol such as SIP.

The ROHC library defines 2 ways to identify RTP streams from other UDP streams:
1/ a fixed list of UDP ports (if the port is in the list, the UDP stream is handled as one RTP stream, be it RTP or not),
2/ a user-defined callback that may parse the packet to be compressed (ie. its IP header, UDP header and UDP payload) and decide whether the UDP packet is a RTP packet or not.

The 2nd option is not available before the 1.6.0 release.

> I found the reason that RTP profile was skipped because the port 1286
> is not in the list of reserved ports for RTP. Looks like there is no a rigid
> definitions of assigned port numbers in RFC3095. So I added this number
> in the rtp port list. The result is not expected. Headers are not
> compressed at all. Can you please look at the log below and see what
> happened?

They seems recognized as RTP. They seems also compressed. What seems wrong to you?

If you are bothered by the length of the resulting ROHC packet, you shouldn't. The ROHC compression scheme is designed as described in [1]. The first packets of a stream require more information that next ones. They may even be larger than the uncompressed packets! Please compress more IP/UDP/RTP packets of the same stream. You'll see that some bytes are saved on every packets after a while.

Regards,
Didier

[1] http://rohc-lib.org/wiki/doku.php?id=rohc-protocol#main_principles

Wei Wang (eww012) said : #3

Hi Didier,

I have got the good results from the IP and UDP compressors. However, after RTP is determined to be the profile from c_get_profile_from_packet(), the result looks incorrect. I understand the first packet size may be even larger than the uncompressed one. But the size of the packet I showed you in the log is a very later packet, like about the 20th packet. That's why I think RTP compressor didn't work well.

Could you give me some hint where I can debug what happened in RTP compressor? If you need more log, please let me know.

Thanks.

Hello,

> I have got the good results from the IP and UDP compressors. However,
> after RTP is determined to be the profile from c_get_profile_from_packet(),
> the result looks incorrect. I understand the first packet size may be even
> larger than the uncompressed one. But the size of the packet I showed you
> in the log is a very later packet, like about the 20th packet. That's why I think
> RTP compressor didn't work well.

Okay. Is that packet the 20th RTP packet of the same stream (same IP addresses, same UDP ports, same RTP SSRC) or the 20th RTP packet of different RTP streams?

> Could you give me some hint where I can debug what happened in RTP compressor? If you need more log, please let me know.

Yes, print more logs. Watch whether the compressor uses the same compression context (CID) [1] for all 20 packets. Watch the type of ROHC packets [2] that the compressor decides to create and the reason of its decision. Maybe the RTP stream is not regular at all: the more the IP, UDP, RTP headers changes from one packet to another in the same stream, the less the compression is efficient [3].

Regards,
Didier

[1] http://rohc-lib.org/wiki/doku.php?id=rohc-protocol#definitions
[2] http://rohc-lib.org/wiki/doku.php?id=rohc-protocol#packet_types
[3] http://rohc-lib.org/wiki/doku.php?id=rohc-protocol#main_principles

Wei Wang (eww012) said : #5

Yes, Didier, all packets are of the same stream. In my case, IP addresses, UDP ports, SSRC/CSRC don't change. Only a few fields like the SN change.

I'll read your references. Meanwhile, in order to locate the problem, could you tell me more specifically where I can add the debug output?

Thanks.

What version of the ROHC library do you use?

Didier

Wei Wang (eww012) said : #7

1.5.1, the latest release.

Build the ROHC library with the --enable-rohc-debug=3 option for the configure script.

Didier

Friedrich (hitlbs) said : #9

Hi Wei,

I experienced some problem with compressing RTP packets. But the problem was to choose the profile. Once the correct profile was chosen, there was no issue to compress the packets.
rohc_compress() using profile 'RTP / compressor' (0x0001)

Good luck,
Friedrich

Wei Wang (eww012) said : #10

Hi Friedrich,

I activated all profiles, IP, UDP, and RTP before compressing packets. You can see from the log that only RTP profile was checked and was used to compress. In your case, were all profiles used or just RTP profiles was used? I guess RTP profile is enough to compress all IP/UDP/RTP headers at one time.

Thanks.

Wei Wang (eww012) said : #11

 Hi Friedrich and Didier,

I just modified the simple_rohc_program.c file so that the packet has all IP/UDP/RTP headers included. How can I upload this file to you so you can try on your side and find out where the problem is?

Thanks.

Friedrich (hitlbs) said : #12

Hi Wei, only RTP profile was used.
rohc_compress() using profile 'RTP / compressor' (0x0001)

Wei Wang (eww012) said : #13

Hi Friedrich,

I just copy/paste the main function of the simple_rohc_program.c file here since there is no way to upload it.

~~~~~~~~~~~~~~~~~~~
int main(int argc, char **argv)
{
 struct rohc_comp *compressor; /* the ROHC compressor */
    struct rohc_decomp *decompressor;
 unsigned char ip_packet[BUFFER_SIZE]; /* the buffer that will contain
                                            the IPv4 packet to compress */
 unsigned int ip_packet_len; /* the length (in bytes) of the
                                            IPv4 packet */
 unsigned char rohc_packet[BUFFER_SIZE]; /* the buffer that will contain
                                            the resulting ROHC packet */
 int rohc_packet_len; /* the length (in bytes) of the
                                            resulting ROHC packet */
 unsigned int seed;
 unsigned int i;

    unsigned char udp_packet[BUFFER_SIZE];
    unsigned int udp_packet_len;
    unsigned char rtp_header[BUFFER_SIZE];
    unsigned char decomp_packet[BUFFER_SIZE];

 /* initialize the random generator */
 seed = time(NULL);
 srand(seed);

 /* Create a ROHC compressor with small CIDs, no jamming and no adaptation
  * to encapsulation frames.
  *
  * See http://rohc-lib.org/doc/latest/group__rohc__comp.html#ga721fd34fc0cd9e1d789b693eb6bb6485
  * for details about rohc_alloc_compressor in the API documentation.
  */
 printf("\ncreate the ROHC compressor\n");
 compressor = rohc_alloc_compressor(ROHC_SMALL_CID_MAX, 0, 0, 0);
 if(compressor == NULL)
 {
  fprintf(stderr, "failed create the ROHC compressor\n");
  goto error;
 }
    decompressor = rohc_alloc_decompressor(compressor);

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

 /* Enable the compression profiles you need (comment or uncomment some lines).
  *
  * See http://rohc-lib.org/doc/latest/group__rohc__comp.html#ga1a444eb91681521f726712a60a4df867
  * for details about rohc_activate_profile in the API documentation.
  */
 printf("\nenable several ROHC compression profiles\n");
 rohc_activate_profile(compressor, ROHC_PROFILE_UNCOMPRESSED);
 rohc_activate_profile(compressor, ROHC_PROFILE_UDP);
 rohc_activate_profile(compressor, ROHC_PROFILE_IP);
 //rohc_activate_profile(compressor, ROHC_PROFILE_UDPLITE);
 rohc_activate_profile(compressor, ROHC_PROFILE_RTP);
 //rohc_activate_profile(comp, ROHC_PROFILE_ESP);

 /* create a fake IP packet for the purpose of this simple program */
 printf("\nbuild a fake IP packet\n");
 ip_packet[0] = 4 << 4; /* IP version 4 */
 ip_packet[0] |= 5; /* IHL: minimal IPv4 header length (in 32-bit words) */
 ip_packet[1] = 0; /* TOS */
 ip_packet_len = 56; //5 * 4 + strlen(FAKE_PAYLOAD);
 ip_packet[2] = (htons(ip_packet_len) >> 8) & 0xff; /* Total Length */
 ip_packet[3] = htons(ip_packet_len) & 0xff;
 //ip_packet[2] = (ip_packet_len >> 8) & 0xff; /* Total Length */
 //ip_packet[3] = ip_packet_len & 0xff;
 ip_packet[4] = 0; /* IP-ID */
 ip_packet[5] = 0;
 ip_packet[6] = 0; /* Fragment Offset and IP flags */
 ip_packet[7] = 0;
 ip_packet[8] = 1; /* TTL */
 ip_packet[9] = 17; /* Protocol: unassigned number */
 ip_packet[10] = 0xbe; /* fake Checksum */
 ip_packet[11] = 0xef;
 ip_packet[12] = 0x01; /* Source address */
 ip_packet[13] = 0x02;
 ip_packet[14] = 0x03;
 ip_packet[15] = 0x04;
 ip_packet[16] = 0x05; /* Destination address */
 ip_packet[17] = 0x06;
 ip_packet[18] = 0x07;
 ip_packet[19] = 0x08;

    /* fake UDP headers, 8 bytes */
 udp_packet[0] = 0x01; /* Source address */
 udp_packet[1] = 0x02;
 udp_packet[2] = 0x05; /* Destination address */
 udp_packet[3] = 0x06;
    udp_packet_len = 8;
 udp_packet[4] = (udp_packet_len >> 8) & 0xff; /* Total Length */
 udp_packet[5] = udp_packet_len & 0xff;
 udp_packet[6] = 0xbe; /* fake Checksum */
 udp_packet[7] = 0xef;

    /* fake RTP headers, 12 bytes, and payload 16 bytes */
    rtp_header[ 0 ] = 0x80;
    rtp_header[ 1 ] = 0x1;
    rtp_header[ 2 ] = 0xb9;
    rtp_header[ 3 ] = 0x40;
    rtp_header[ 4 ] = 0x4b;
    rtp_header[ 5 ] = 0x82;
    rtp_header[ 6 ] = 0xe5;
    rtp_header[ 7 ] = 0x6c;
    rtp_header[ 8 ] = 0x50;
    rtp_header[ 9 ] = 0x68;
    rtp_header[ 10 ] = 0xe5;
    rtp_header[ 11 ] = 0x2b;
    rtp_header[ 12 ] = 0xc;
    rtp_header[ 13 ] = 0x3e;
    rtp_header[ 14 ] = 0x8e;
    rtp_header[ 15 ] = 0x4a;
    rtp_header[ 16 ] = 0x69;
    rtp_header[ 17 ] = 0x52;
    rtp_header[ 18 ] = 0x1b;
    rtp_header[ 19 ] = 0xfa;
    rtp_header[ 20 ] = 0x2;
    rtp_header[ 21 ] = 0xe0;
    rtp_header[ 22 ] = 0xb0;
    rtp_header[ 23 ] = 0x37;
    rtp_header[ 24 ] = 0x9f;
    rtp_header[ 25 ] = 0xd8;
    rtp_header[ 26 ] = 0x74;
    rtp_header[ 27 ] = 0x10;

 /* copy the payload just after the IP header */
 //memcpy(ip_packet + 5 * 4, FAKE_PAYLOAD, strlen(FAKE_PAYLOAD));
 memcpy(ip_packet + 20, udp_packet, 8);
 memcpy(ip_packet + 28, rtp_header, 28);

 /* dump the newly-created IP packet on terminal */
 for(i = 0; i < ip_packet_len; i++)
 {
  printf("0x%02x ", ip_packet[i]);
  if(i != 0 && ((i + 1) % 8) == 0)
  {
   printf("\n");
  }
 }
 if(i != 0 && ((i + 1) % 8) != 0) /* be sure to go to the line */
 {
  printf("\n");
 }

 /* Now, compress this fake IP packet.
  *
  * See http://rohc-lib.org/doc/latest/group__rohc__comp.html#ga99be8242b7bc4f442f4519461a99726b
  * for details about rohc_compress in the API documentation.
  */
    for (int j = 0; j < 30; j++ ){
 printf("\ncompress the fake IP packet, j = %d\n", j);
 rohc_packet_len = rohc_compress(compressor,
                                 ip_packet, ip_packet_len,
                                 rohc_packet, BUFFER_SIZE);
 if(rohc_packet_len <= 0)
 {
  fprintf(stderr, "compression of fake IP packet failed\n");
  goto release_compressor;
 }

 /* dump the ROHC packet on terminal */
 printf("\nROHC packet resulting from the ROHC compression:\n");
 for(i = 0; i < ((unsigned int) rohc_packet_len); i++)
 {
  printf("0x%02x ", rohc_packet[i]);
  if(i != 0 && ((i + 1) % 8) == 0)
  {
   printf("\n");
  }
 }
 if(i != 0 && ((i + 1) % 8) != 0) /* be sure to go to the line */
 {
  printf("\n");
 }

 int decomp_size = rohc_decompress(decompressor,
                      rohc_packet, rohc_packet_len,
                      decomp_packet, BUFFER_SIZE);

 if(0 == decomp_size)
 {
  printf("\ndecompression of fake IP packet failed.\n");
 }
    else {
     printf("\nROHC packet resulting from the ROHC decompression:\n");
        for (int i = 0; i< decomp_size; i++) {
      printf("0x%02x ", decomp_packet[i]);
      if(i != 0 && ((i + 1) % 8) == 0)
      {
       printf("\n");
      }
        }
    }

} // end of 10 times loop
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Wei,

> Yes, Didier, all packets are of the same stream. In my case, IP addresses,
> UDP ports, SSRC/CSRC don't change. Only a few fields like the SN change.
> [...]

> I just copy/paste the main function of the simple_rohc_program.c file here
> since there is no way to upload it.
> [...]

The program you copied/pasted compresses 30 times the same packet. All of those packets belong to the same RTP stream (same IP addrs, same UDP ports, same SSRC), but they also got the same RTP SN. That's not expected for one RTP stream. That might well explain the low compression efficiency that you got. Please change the SN in the for loop between 2 compressions. You should also change the RTP TimeStamp (TS): make it increase of the same delta for every new packet (300, 600, 900, 1200.. for example).

Regards,
Didier

Wei Wang (eww012) said : #15

Hi Didier,

I followed your suggestion and update sequence (increase by 1 each time) and timestamp (increase 300 each time). The result is better, see the log below:

[rohc_comp.c:564 rohc_compress()] ROHC size = 54 (feedback = 0, header = 38, payload = 16), output buffer size = 2048

But it seems that it still can be improved more. Is there anywhere can be modified in other headers as well?

Thanks.

Wei Wang (eww012) said : #16

Here is code change and result:

/* before compression loop */
    /* calculate initial sequence number and timestamp */
    unsigned short sequence = ((unsigned short)rtp_header[2] << 8) | ((unsigned short)rtp_header[3] & 0xff);
    unsigned long timestamp = ((unsigned long)rtp_header[4] << 24) |
                            ((unsigned long)rtp_header[5] << 16) |
                            ((unsigned long)rtp_header[6] << 8) |
                            (unsigned long)rtp_header[7];

/* inside compression loop */
    /* update sequence number and timestamp */
    sequence += 1;
    timestamp += 300;
    ip_packet[30] = (char)(sequence >> 8);
    ip_packet[31] = (char)(sequence & 0xff); // Sequence Number.
    ip_packet[32] = (char)(timestamp >> 24);
    ip_packet[33] = (char)((timestamp >> 16) & 0xff);
    ip_packet[34] = (char)((timestamp >> 8) & 0xff);
    ip_packet[35] = (char)(timestamp & 0xff); // RTP Timestamp

ip_packet before compression:
0x45 0x00 0x00 0x38 0x00 0x00 0x00 0x00
0x01 0x11 0xa9 0xa2 0x01 0x02 0x03 0x04
0x05 0x06 0x07 0x08 0x01 0x02 0x05 0x06
0x00 0x24 0xbe 0xef 0x80 0x01 0xb9 0x5e
0x4b 0x82 0xfc 0xdc 0x50 0x68 0xe5 0x2b
0x0c 0x3e 0x8e 0x4a 0x69 0x52 0x1b 0xfa
0x02 0xe0 0xb0 0x37 0x9f 0xd8 0x74 0x10

ROHC packet resulting from the ROHC compression:
0xfd 0x01 0x52 0x40 0x11 0x01 0x02 0x03
0x04 0x05 0x06 0x07 0x08 0x01 0x02 0x05
0x06 0x50 0x68 0xe5 0x2b 0x00 0x01 0x00
0x00 0x60 0x00 0xbe 0xef 0x80 0x01 0xb9
0x5e 0x4b 0x82 0xfc 0xdc 0x00 0x0c 0x3e
0x8e 0x4a 0x69 0x52 0x1b 0xfa 0x02 0xe0
0xb0 0x37 0x9f 0xd8 0x74 0x10

Hello,

The ROHC packet is of type IR. That's the worst compression level. There is something stopping the compressor to use better packet types. Please send me the full traces generated when the library is built with --enable-rohc-debug=3

Regards,
Didier

Wei Wang (eww012) said : #18

Hi Didier,

Below is the log of the last(30th) packet compression process.

compress the fake IP packet, j = 29
[ip.c:437 ip_get_totlen()] IP header v4 total len = 56, 14336
[rohc_comp.c:381 rohc_compress()] size of uncompressed packet = 56 bytes
[rohc_comp.c:409 rohc_compress()] try to find the best profile for packet with transport protocol 17
[ip.c:405 ip_is_fragment()] ip_is_fragment(): is_fragment = 0, 0, 0
[rohc_comp.c:1563 c_get_profile_from_packet()] UDP port = 0x506 (1286)
[rohc_comp.c:416 rohc_compress()] using profile 'RTP / Compressor' (0x0001)
[rohc_comp.c:1795 c_find_context()] using context CID = 0
[rohc_comp.c:1963 rohc_feedback_get()] add 0 byte(s) of feedback data
[rohc_comp.c:481 rohc_compress()] compress the packet #30
[c_rtp.c:1225 rtp_changed_rtp_dynamic()] find changes in RTP dynamic fields
[c_rtp.c:1309 rtp_changed_rtp_dynamic()] 0 RTP dynamic fields changed
[c_generic.c:5370 detect_ip_id_behaviour()] 1) old_id = 0x0000 new_id = 0x0000
[c_generic.c:5383 detect_ip_id_behaviour()] 2) old_id = 0x0000 new_id = 0x0000
[c_generic.c:5392 detect_ip_id_behaviour()] RND detected
[c_generic.c:5400 detect_ip_id_behaviour()] NBO = 1, RND = 1
[c_generic.c:788 c_generic_encode()] SN = 47454
[c_generic.c:5069 changed_dynamic_both_hdr()] check for changed fields in the outer IP header
[c_generic.c:809 c_generic_encode()] send_static = 0, send_dynamic = 0
[c_generic.c:820 c_generic_encode()] ip_id = 0x0000, context_sn = 47454
[c_generic.c:5477 encode_uncomp_fields()] compressor is in state 1
[c_generic.c:5481 encode_uncomp_fields()] new SN = 47454 / 0xb95e
[c_generic.c:5489 encode_uncomp_fields()] IR state: force using 16 bits to encode new SN
[c_generic.c:5504 encode_uncomp_fields()] 16 bits are required to encode new SN
[c_generic.c:5528 encode_uncomp_fields()] new outer IP-ID delta = 0x46a2 / 18082 (NBO = 1, RND = 1)
[c_generic.c:5536 encode_uncomp_fields()] IR state: force using 16 bits to encode new outer IP-ID delta
[c_generic.c:5552 encode_uncomp_fields()] 16 bits are required to encode new outer IP-ID delta
[ts_sc_comp.c:98 c_add_ts()] Timestamp = 1266875612
[ts_sc_comp.c:110 c_add_ts()] TS delta = 200
[ts_sc_comp.c:169 c_add_ts()] state SEND_SCALED
[ts_sc_comp.c:193 c_add_ts()] ts_stride calculated = 200
[ts_sc_comp.c:194 c_add_ts()] previous ts_stride = 200
[ts_sc_comp.c:235 c_add_ts()] ts_stride = 200
[ts_sc_comp.c:239 c_add_ts()] ts_offset = 1266875612 modulo 200 = 12
[ts_sc_comp.c:243 c_add_ts()] ts_scaled = (1266875612 - 12) / 200 = 6334378
[ts_sc_comp.c:250 c_add_ts()] TS can be deducted from SN (old TS_SCALED = 6334377, new TS_SCALED = 6334378, old SN = 47453, new SN = 47454)
[c_rtp.c:946 rtp_encode_uncomp_fields()] ts_scaled = 6334378 on 0 bits
[c_rtp.c:950 rtp_encode_uncomp_fields()] 0 bits are required to encode new TS
[c_generic.c:1220 decide_packet()] IR state
[c_generic.c:1263 decide_packet()] packet 'IR' chosen
[c_generic.c:1456 code_IR_packet()] code IR packet (CID = 0)
[cid.c:76 code_cid_values()] CID = 0 => no add-CID
[c_generic.c:1475 code_IR_packet()] type of packet + D flag = 0xfd
[c_generic.c:1479 code_IR_packet()] profile ID = 0x01
[c_generic.c:1485 code_IR_packet()] CRC = 0x00 for CRC calculation
[c_generic.c:1781 code_ipv4_static_part()] version = 0x40
[c_generic.c:1786 code_ipv4_static_part()] protocol = 0x11
[c_generic.c:1795 code_ipv4_static_part()] src addr = 01020304 (1.2.3.4)
[c_generic.c:1802 code_ipv4_static_part()] dst addr = 05060708 (5.6.7.8)
[c_udp.c:521 udp_code_static_udp_part()] UDP source port = 0x201
[c_udp.c:526 udp_code_static_udp_part()] UDP dest port = 0x605
[c_rtp.c:1003 rtp_code_static_rtp_part()] RTP SSRC = 0x2be56850
[c_generic.c:2002 code_ipv4_dynamic_part()] TOS = 0x00, TTL = 0x01, IP-ID = 0x0000, df_rnd_nbo = 0x60 (DF = 0, RND = 1, NBO = 1)
[c_rtp.c:1071 rtp_code_dynamic_rtp_part()] UDP checksum = 0xefbe
[c_rtp.c:1088 rtp_code_dynamic_rtp_part()] part 2 = 0x80
[c_rtp.c:1096 rtp_code_dynamic_rtp_part()] part 3 = 0x01
[c_rtp.c:1102 rtp_code_dynamic_rtp_part()] part 4 = 0xb9 0x5e
[c_rtp.c:1108 rtp_code_dynamic_rtp_part()] part 5 = 0x4b 0x82 0xfc 0xdc
[c_rtp.c:1114 rtp_code_dynamic_rtp_part()] Generic CSRC list not supported yet, put a 0x00 byte
[c_generic.c:1565 code_IR_packet()] CRC (header length = 38, crc = 0x52)
[ip.c:437 ip_get_totlen()] IP header v4 total len = 56, 14336
[rohc_comp.c:564 rohc_compress()] ROHC size = 54 (feedback = 0, header = 38, payload = 16), output buffer size = 2048

ROHC packet resulting from the ROHC compression:
0xfd 0x01 0x52 0x40 0x11 0x01 0x02 0x03
0x04 0x05 0x06 0x07 0x08 0x01 0x02 0x05
0x06 0x50 0x68 0xe5 0x2b 0x00 0x01 0x00
0x00 0x60 0x00 0xbe 0xef 0x80 0x01 0xb9
0x5e 0x4b 0x82 0xfc 0xdc 0x00 0x0c 0x3e
0x8e 0x4a 0x69 0x52 0x1b 0xfa 0x02 0xe0
0xb0 0x37 0x9f 0xd8 0x74 0x10
[rohc_decomp.c:420 rohc_decompress()] decompress the 54-byte packet #30
[rohc_decomp.c:1636 d_decode_feedback_first()] skip 0 byte(s) of padding
[rohc_decomp.c:1568 rohc_decomp_decode_cid()] no add-CID found, CID defaults to 0
[rohc_decomp.c:651 d_decode_header()] ROHC packet is an IR packet
[rohc_decomp.c:664 d_decode_header()] profile 0x0001 found in IR packet
[rohc_decomp.c:672 d_decode_header()] context with CID 0 already exists and matches profile 0x0001 found in IR packet
[d_generic.c:3501 d_generic_decode()] decode packet as 'IR'
[d_generic.c:2886 decode_ir()] CRC-8 found in packet = 0x52
[d_generic.c:3185 parse_static_part_ipv4()] IP Version = 4
[d_generic.c:3192 parse_static_part_ipv4()] Protocol = 0x11
[d_generic.c:3200 parse_static_part_ipv4()] Source Address = 01020304 (1.2.3.4)
[d_generic.c:3208 parse_static_part_ipv4()] Destination Address = 05060708 (5.6.7.8)
[d_udp.c:223 udp_parse_static_udp()] UDP source port = 0x0102
[d_udp.c:229 udp_parse_static_udp()] UDP destination port = 0x0506
[d_rtp.c:513 rtp_parse_static_rtp()] SSRC = 0x2be56850
[d_generic.c:3349 parse_dynamic_part_ipv4()] TOS = 0x00
[d_generic.c:3356 parse_dynamic_part_ipv4()] TTL = 0x01
[d_generic.c:3363 parse_dynamic_part_ipv4()] IP-ID = 0x0000
[d_generic.c:3379 parse_dynamic_part_ipv4()] DF = 0, RND = 1, NBO = 1
[d_rtp.c:558 rtp_parse_dynamic_rtp()] UDP checksum = 0xbeef
[d_rtp.c:577 rtp_parse_dynamic_rtp()] version = 0x2
[d_rtp.c:580 rtp_parse_dynamic_rtp()] padding = 0x0
[d_rtp.c:583 rtp_parse_dynamic_rtp()] CSRC Count = 0x0
[d_rtp.c:585 rtp_parse_dynamic_rtp()] RX = 0x0
[d_rtp.c:593 rtp_parse_dynamic_rtp()] M = 0x0
[d_rtp.c:596 rtp_parse_dynamic_rtp()] payload type = 0x1
[d_rtp.c:607 rtp_parse_dynamic_rtp()] SN = 47454 (0xb95e)
[d_rtp.c:616 rtp_parse_dynamic_rtp()] timestamp = 0x4b82fcdc
[d_generic.c:3013 decode_ir()] ROHC payload (length = 16 bytes) starts at offset 38
[d_generic.c:7332 check_ir_crc()] CRC-8 on compressed ROHC header = 0x52
[d_generic.c:7567 decode_values_from_bits()] decoded SN = 47454 / 0xb95e (nr bits = 16, bits = 47454 / 0xb95e)
[d_generic.c:7653 decode_ip_values_from_bits()] decoded outer TOS/TC = 0
[d_generic.c:7666 decode_ip_values_from_bits()] decoded outer TTL/HL = 1
[d_generic.c:7679 decode_ip_values_from_bits()] decoded outer protocol/NH = 17
[d_generic.c:7695 decode_ip_values_from_bits()] decoded outer NBO = 1
[d_generic.c:7708 decode_ip_values_from_bits()] decoded outer RND = 1
[d_generic.c:7733 decode_ip_values_from_bits()] decoded outer IP-ID = 0x0000 (nr bits = 16, bits = 0x0)
[d_generic.c:7746 decode_ip_values_from_bits()] decoded outer DF = 0
[d_generic.c:7762 decode_ip_values_from_bits()] decoded outer source address = 01020304 (1.2.3.4)
[d_generic.c:7778 decode_ip_values_from_bits()] decoded outer source address = 05060708 (5.6.7.8)
[d_rtp.c:811 rtp_decode_values_from_bits()] decoded UDP source port = 0x0102
[d_rtp.c:826 rtp_decode_values_from_bits()] decoded UDP destination port = 0x0506
[d_rtp.c:858 rtp_decode_values_from_bits()] decoded UDP checksum = 0xbeef (checksum present = 1)
[d_rtp.c:872 rtp_decode_values_from_bits()] decoded RTP version = 2
[d_rtp.c:886 rtp_decode_values_from_bits()] decoded R-P flag = 0
[d_rtp.c:900 rtp_decode_values_from_bits()] decoded R-X flag = 0
[d_rtp.c:914 rtp_decode_values_from_bits()] decoded CC = 0
[d_rtp.c:930 rtp_decode_values_from_bits()] decoded RTP M flag = 0
[d_rtp.c:944 rtp_decode_values_from_bits()] decoded R-PT = 1
[d_rtp.c:947 rtp_decode_values_from_bits()] 32-bit TS delta = 0x4b82fcdc
[d_rtp.c:952 rtp_decode_values_from_bits()] TS is not scaled
[ts_sc_decomp.c:296 ts_decode_unscaled()] decode unscaled TS bits 1266875612 with context TS_STRIDE 200
[ts_sc_decomp.c:305 ts_decode_unscaled()] TS_OFFSET = 1266875612 modulo 200 = 12
[ts_sc_decomp.c:310 ts_decode_unscaled()] TS_SCALED = (1266875612 - 12) / 200 = 6334378
[d_rtp.c:993 rtp_decode_values_from_bits()] decoded timestamp = 1266875612 / 0x4b82fcdc (nr bits = 32, bits = 1266875612 / 0x4b82fcdc)
[d_rtp.c:1007 rtp_decode_values_from_bits()] decoded SSRC = 736454736
[d_generic.c:7086 build_uncomp_hdrs()] length of transport header = 20 bytes
[d_generic.c:7202 build_uncomp_ipv4()] Total Length = 0x0038 (IHL * 4 + 36)
[d_generic.c:7205 build_uncomp_ipv4()] IP checksum = 0xa9a2
[d_rtp.c:1045 rtp_build_uncomp_rtp()] UDP + RTP length = 0x0024
[ts_sc_decomp.c:154 ts_update_context()] old SN 47453 replaced by new SN 47454
[ts_sc_decomp.c:155 ts_update_context()] old TS 1266875412 replaced by new TS 1266875612
[ts_sc_decomp.c:162 ts_update_context()] old TS_SCALED 6334377 replaced by new TS_SCALED 6334378
[ts_sc_decomp.c:177 ts_update_context()] old TS_STRIDE 200 kept unchanged
[ts_sc_decomp.c:187 ts_update_context()] old TS_OFFSET 12 kept unchanged
[d_generic.c:3589 d_generic_decode()] uncompressed packet length = 56 bytes
[rohc_decomp.c:706 d_decode_header()] 56 bytes of payload copied to uncompressed packet
[rohc_decomp.c:434 rohc_decompress()] state in decompressor = 3
[rohc_decomp.c:506 rohc_decompress()] feedback curr 64
[rohc_decomp.c:517 rohc_decompress()] feedback curr 64

ROHC packet resulting from the ROHC decompression:
0x45 0x00 0x00 0x38 0x00 0x00 0x00 0x00
0x01 0x11 0xa9 0xa2 0x01 0x02 0x03 0x04
0x05 0x06 0x07 0x08 0x01 0x02 0x05 0x06
0x00 0x24 0xbe 0xef 0x80 0x01 0xb9 0x5e
0x4b 0x82 0xfc 0xdc 0x50 0x68 0xe5 0x2b
0x0c 0x3e 0x8e 0x4a 0x69 0x52 0x1b 0xfa
0x02 0xe0 0xb0 0x37 0x9f 0xd8 0x74 0x10

Wei,

The compressor context didn't leave the first state (IR). It cannot compress packet more without going into deeper states (FO and SO). The reason staying in state IR is not in the traces above. Please search for traces with the words "decide_state" or "rtp_decide_state" in previous packets.

Regards,
Didier

Wei Wang (eww012) said : #20

Hi Didier,

"rtp_decide_state" shows in the 2nd, 3rd, and 4th packets. I just copied and pasted the log of the 2nd packet.

compress the fake IP packet, j = 1
[ip.c:437 ip_get_totlen()] IP header v4 total len = 56, 14336
[rohc_comp.c:381 rohc_compress()] size of uncompressed packet = 56 bytes
[rohc_comp.c:409 rohc_compress()] try to find the best profile for packet with transport protocol 17
[ip.c:405 ip_is_fragment()] ip_is_fragment(): is_fragment = 0, 0, 0
[rohc_comp.c:1563 c_get_profile_from_packet()] UDP port = 0x506 (1286)
[rohc_comp.c:416 rohc_compress()] using profile 'RTP / Compressor' (0x0001)
[rohc_comp.c:1795 c_find_context()] using context CID = 0
[rohc_comp.c:1936 rohc_feedback_get()] use 1-byte form factor for feedback length
[rohc_comp.c:1963 rohc_feedback_get()] add 6 byte(s) of feedback data: 0x20 0xb9 0x41 0x41 0x11 0x21
[rohc_comp.c:1963 rohc_feedback_get()] add 0 byte(s) of feedback data
[rohc_comp.c:481 rohc_compress()] compress the packet #2
[c_rtp.c:1225 rtp_changed_rtp_dynamic()] find changes in RTP dynamic fields
[c_rtp.c:1241 rtp_changed_rtp_dynamic()] UDP checksum field did not change but changed in the last few packets
[c_rtp.c:1291 rtp_changed_rtp_dynamic()] RTP Payload Type (PT) field did not change but changed in the last few packets
[c_rtp.c:1305 rtp_changed_rtp_dynamic()] TS_STRIDE changed now or in the last few packets
[c_rtp.c:1309 rtp_changed_rtp_dynamic()] 2 RTP dynamic fields changed
[c_generic.c:5370 detect_ip_id_behaviour()] 1) old_id = 0x0000 new_id = 0x0000
[c_generic.c:5383 detect_ip_id_behaviour()] 2) old_id = 0x0000 new_id = 0x0000
[c_generic.c:5392 detect_ip_id_behaviour()] RND detected
[c_generic.c:5400 detect_ip_id_behaviour()] NBO = 1, RND = 1
[c_generic.c:788 c_generic_encode()] SN = 47426
[c_generic.c:5037 changed_static_one_hdr()] protocol_count 1
[c_generic.c:5069 changed_dynamic_both_hdr()] check for changed fields in the outer IP header
[c_generic.c:5150 changed_dynamic_one_hdr()] TTL/HL changed in the last few packets
[c_generic.c:5186 changed_dynamic_one_hdr()] RND changed (0 -> 1) in the current packet
[c_generic.c:5211 changed_dynamic_one_hdr()] NBO changed in the last few packets
[c_generic.c:809 c_generic_encode()] send_static = 1, send_dynamic = 2
[c_rtp.c:800 rtp_decide_state()] go back to IR state because UDP checksum behaviour changed in the last few packets
[c_generic.c:820 c_generic_encode()] ip_id = 0x0000, context_sn = 47426
[c_generic.c:5477 encode_uncomp_fields()] compressor is in state 1
[c_generic.c:5481 encode_uncomp_fields()] new SN = 47426 / 0xb942
[c_generic.c:5489 encode_uncomp_fields()] IR state: force using 16 bits to encode new SN
[c_generic.c:5504 encode_uncomp_fields()] 16 bits are required to encode new SN
[c_generic.c:5528 encode_uncomp_fields()] new outer IP-ID delta = 0x46be / 18110 (NBO = 1, RND = 1)
[c_generic.c:5536 encode_uncomp_fields()] IR state: force using 16 bits to encode new outer IP-ID delta
[c_generic.c:5552 encode_uncomp_fields()] 16 bits are required to encode new outer IP-ID delta
[ts_sc_comp.c:98 c_add_ts()] Timestamp = 1266870252
[ts_sc_comp.c:110 c_add_ts()] TS delta = 320
[ts_sc_comp.c:122 c_add_ts()] state INIT_STRIDE
[ts_sc_comp.c:147 c_add_ts()] /!\ TS_STRIDE changed
[ts_sc_comp.c:151 c_add_ts()] ts_stride = 320
[ts_sc_comp.c:156 c_add_ts()] ts_offset = 1266870252 modulo 320 = 172
[ts_sc_comp.c:159 c_add_ts()] ts_scaled = (1266870252 - 172) / 320 = 3958969
[c_rtp.c:914 rtp_encode_uncomp_fields()] cannot send TS scaled, send TS and TS_STRIDE
[c_rtp.c:950 rtp_encode_uncomp_fields()] 32 bits are required to encode new TS
[c_generic.c:1220 decide_packet()] IR state
[c_generic.c:1263 decide_packet()] packet 'IR' chosen
[c_generic.c:1456 code_IR_packet()] code IR packet (CID = 0)
[cid.c:76 code_cid_values()] CID = 0 => no add-CID
[c_generic.c:1475 code_IR_packet()] type of packet + D flag = 0xfd
[c_generic.c:1479 code_IR_packet()] profile ID = 0x01
[c_generic.c:1485 code_IR_packet()] CRC = 0x00 for CRC calculation
[c_generic.c:1781 code_ipv4_static_part()] version = 0x40
[c_generic.c:1786 code_ipv4_static_part()] protocol = 0x11
[c_generic.c:1795 code_ipv4_static_part()] src addr = 01020304 (1.2.3.4)
[c_generic.c:1802 code_ipv4_static_part()] dst addr = 05060708 (5.6.7.8)
[c_udp.c:521 udp_code_static_udp_part()] UDP source port = 0x201
[c_udp.c:526 udp_code_static_udp_part()] UDP dest port = 0x605
[c_rtp.c:1003 rtp_code_static_rtp_part()] RTP SSRC = 0x2be56850
[c_generic.c:2002 code_ipv4_dynamic_part()] TOS = 0x00, TTL = 0x01, IP-ID = 0x0000, df_rnd_nbo = 0x60 (DF = 0, RND = 1, NBO = 1)
[c_rtp.c:1071 rtp_code_dynamic_rtp_part()] UDP checksum = 0xefbe
[c_rtp.c:1088 rtp_code_dynamic_rtp_part()] part 2 = 0x90
[c_rtp.c:1096 rtp_code_dynamic_rtp_part()] part 3 = 0x01
[c_rtp.c:1102 rtp_code_dynamic_rtp_part()] part 4 = 0xb9 0x42
[c_rtp.c:1108 rtp_code_dynamic_rtp_part()] part 5 = 0x4b 0x82 0xe7 0xec
[c_rtp.c:1114 rtp_code_dynamic_rtp_part()] Generic CSRC list not supported yet, put a 0x00 byte
[c_rtp.c:1133 rtp_code_dynamic_rtp_part()] part 7 = 0x05
[c_rtp.c:1158 rtp_code_dynamic_rtp_part()] send ts_stride = 0x00000140 encoded with SDVL on 2 bytes
[c_rtp.c:1187 rtp_code_dynamic_rtp_part()] TS_STRIDE transmitted only 1 times, so stay in state INIT_STRIDE (at least 3 times are required to change to state SEND_SCALED)
[c_generic.c:1565 code_IR_packet()] CRC (header length = 41, crc = 0x69)
[ip.c:437 ip_get_totlen()] IP header v4 total len = 56, 14336
[rohc_comp.c:564 rohc_compress()] ROHC size = 64 (feedback = 0, header = 41, payload = 16), output buffer size = 2048

ROHC packet resulting from the ROHC compression:
0xf6 0x20 0xb9 0x41 0x41 0x11 0x21 0xfd
0x01 0x69 0x40 0x11 0x01 0x02 0x03 0x04
0x05 0x06 0x07 0x08 0x01 0x02 0x05 0x06
0x50 0x68 0xe5 0x2b 0x00 0x01 0x00 0x00
0x60 0x00 0xbe 0xef 0x90 0x01 0xb9 0x42
0x4b 0x82 0xe7 0xec 0x00 0x05 0x81 0x40
0x0c 0x3e 0x8e 0x4a 0x69 0x52 0x1b 0xfa
0x02 0xe0 0xb0 0x37 0x9f 0xd8 0x74 0x10

Wei Wang (eww012) said : #21

Hi Didier,
Another question is, in the result from the decompression, the checksum bytes are different from the original. Is this expected?

Wei Wang (eww012) said : #22

Hi Didier,

It seems the problem is the UDP checksum bytes. I just copied the values from the IP headers. After I changed them to 0, I can see many compressed packet sizes are 19, which means, 40 header bytes are compressed to 3 bytes, great!! Still need your confirm this result is expected.

However, another problem rises. The decompressed packet size is negative. There is an error line in log.
[ERROR] [d_generic.c:3508 d_generic_decode()] non-IR packet (2) received in No Context state

Here is a part of log:
[rohc_comp.c:564 rohc_compress()] ROHC size = 19 (feedback = 0, header = 3, payload = 16), output buffer size = 2048

ROHC packet resulting from the ROHC compression:
0x54 0x00 0x00 0x0c 0x3e 0x8e 0x4a 0x69
0x52 0x1b 0xfa 0x02 0xe0 0xb0 0x37 0x9f
0xd8 0x74 0x10
[rohc_decomp.c:420 rohc_decompress()] decompress the 19-byte packet #26
[rohc_decomp.c:1636 d_decode_feedback_first()] skip 0 byte(s) of padding
[rohc_decomp.c:1568 rohc_decomp_decode_cid()] no add-CID found, CID defaults to 0
[rohc_decomp.c:727 d_decode_header()] ROHC packet is not an IR packet
[rohc_decomp.c:742 d_decode_header()] context with CID 0 found
[d_generic.c:3501 d_generic_decode()] decode packet as 'UO-0'
[ERROR] [d_generic.c:3508 d_generic_decode()] non-IR packet (2) received in No Context state
[rohc_decomp.c:434 rohc_decompress()] state in decompressor = 1
[rohc_decomp.c:923 d_optimistic_feedback()] send a STATIC NACK feedback
[feedback.c:76 f_feedback2()] FEEDBACK-2: first 4 bits = 0xa0 (ACK type = 2, mode = 2)
[feedback.c:92 f_feedback2()] FEEDBACK-2: transmit SN = 0x0000b951 on 20 bits (12 bits in base header, 8 bits in SN option)
[feedback.c:96 f_feedback2()] FEEDBACK-2: 4 bits of SN = 0x0
[feedback.c:98 f_feedback2()] FEEDBACK-2: 8 bits of SN = 0xb9
[feedback.c:107 f_feedback2()] FEEDBACK-2: 8 bits of SN option = 0x51
[feedback.c:387 f_wrap_feedback()] add CRC option to feedback
[rohc_comp.c:1149 c_piggyback_feedback()] try to add 6 byte(s) of feedback to the next outgoing ROHC packet
[rohc_comp.c:1181 c_piggyback_feedback()] 6 byte(s) of feedback added to the next outgoing ROHC packet

decompression of fake IP packet failed. decompressed size = -5

> "rtp_decide_state" shows in the 2nd, 3rd, and 4th packets. I just
> copied and pasted the log of the 2nd packet.

Please send me the traces for the 3rd, 4th and 5th packets.

> Another question is, in the result from the decompression, the
> checksum bytes are different from the original. Is this expected?

It should not in normal cases. Maybe the checksums are wrong in the source packets. The ROHC library does not check them before compression and it does not transmit the checksums to the decompressor: the decompressor computes them on its own. So, if there are wrong at source, they may be different in the decompressed packets.

Regards,
Didier

> It seems the problem is the UDP checksum bytes. I just copied the values
> from the IP headers. After I changed them to 0, I can see many compressed
> packet sizes are 19, which means, 40 header bytes are compressed to 3 bytes,
> great!! Still need your confirm this result is expected.

UDP checksums are not the same as IP checksums, you cannot copy them. The
ROHC library can compress RTP streams with non-zero UDP checksums well.
Maybe your bad checksums caused some side effect...

Setting UDP checksums to 0 kind of solves your problem because zero checkums are not transmitted at all by the ROHC compressor.

> However, another problem rises. The decompressed packet size is negative.
> There is an error line in log.
> [ERROR] [d_generic.c:3508 d_generic_decode()] non-IR packet (2) received in
> No Context state

It happens if you decompress some ROHC packets with a decompressor that knows nothing about your stream. It cannot decompress 40-byte headers from 3 bytes without the information from the larger IR packets sent at the beginning of the stream. Did you decompress the first 25 ROHC packets you compressed? If yes, did you use the same decompressor?

Regards,
Didier

Wei Wang (eww012) said : #25

Hi Didier,

Looks like UDP headers can't be randomly defined. Below is how I defined.
    /* fake UDP headers, 8 bytes */
 udp_packet[0] = 0x05; /* Source address */
 udp_packet[1] = 0x06;
 udp_packet[2] = 0x05; /* Destination address */
 udp_packet[3] = 0x06;
        udp_packet_len = 36; // 8 bytes UDP headers, 12 bytes RTP headers, and 16 bytes payload
 udp_packet[4] = (udp_packet_len >> 8) & 0xff; /* Total Length */
 udp_packet[5] = udp_packet_len & 0xff;
 udp_packet[6] = 0x00; /* fake Checksum */
 udp_packet[7] = 0x00;

In fact, the checksum will be recalculated based on RFC768 in each loop. I occasionally gave some values to udp headers and got ideal results, 21 bytes after compression and decompression was successful as well. But this doesn't make sense.

Yes, I used the same decompressor. I just used the compressed result as the input of the decompressor. If the compressed packet size was 21 or 24, then decompress failed.

Please show me the full code source of your small program. Do not copy/paste it here, it would be mangled. Use http://pastebin.com/ or any similar service, and send me the link.

Regards,
Didier

Wei Wang (eww012) said : #27

Here is the link to the modified simple_rohc_program.c

Wei Wang (eww012) said : #28

Sorry, link is here.
http://pastebin.com/Vqs80mkc

Wei Wang (eww012) said : #29

Wei,

There were several mistakes:
 1/ wrong IP Total Length (Host Byte Order instead of Network Byte Order),
 2/ wrong IP checksum (you altered the IP header but didn't update the checksum),
 3/ wrong UDP port (I changed for 1234 for UDP to be recognized as RTP).

The ROHC compressor didn't use the RTP profile because of problems 1 and 3. The ROHC decompressor failed to decompress some ROHC packets because of problem 3.

Once the problems were fixed, I got the following ROHC packet lengths:
54, 64, 57, 57, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19
(the 2nd packet is larger than the 1st because of 7 bytes of feedback data)

Please find the changes in the code here: http://pastebin.com/bVvqvjhd

Regards,
Didier

Wei Wang (eww012) said : #31

Hi Didier,

I got the good result, except the stable compressed packet size is 21, instead of 19.

Thanks,
Weijian

Hello,

> I got the good result, except the stable compressed packet size is 21, instead of 19.

If you used a 1.5.x version, that's fine. I tested with the main dev branch that got some enhancements, such as support for constant IP-ID.

Regards,
Didier

Wei Wang (eww012) said : #33

Hi Didier,

I got another problem in real communication. Now I'm applying comp/decomp on a pair of devices that communicate with each other over the air. To be simple, let's say, device A and device B. The decompressed packet size of the first received packet is -1. I checked the reason is that the return size of function d_decode_header(...) is -1.

  if(profile == NULL)
  {
   rohc_debugf(0, "failed to find profile identified by 0x%04x\n",
               profile_id);
   return ROHC_ERROR_NO_CONTEXT;
  }

The difference between the example and this real application is the definition of compressor and decompressor. Here is how decompressor is defined on the receiver(RX) side:

            decompressor = rohc_alloc_decompressor(compressor);

It depends on the compressor. However, this compressor should be the one that is defined on the transmitter(TX) side. Looks like the RX needs the compressor data from TX. I think some info like profile should be synced up between two sides. Am I right?

Thanks.

Wei,

> The difference between the example and this real application is
> the definition of compressor and decompressor. Here is how
> decompressor is defined on the receiver(RX) side:
>
> decompressor = rohc_alloc_decompressor(compressor);
>
> It depends on the compressor. However, this compressor should
> be the one that is defined on the transmitter(TX) side. Looks like
> the RX needs the compressor data from TX. I think some info like
> profile should be synced up between two sides. Am I right?

Sorry, you're totally wrong. The parameter of the rohc_alloc_decompressor() function is a related compressor on the same side as the decompressor. That compressor is used by the decompressor for its feedback channel (see RFC 3095 for the definition of feedback channels).

                         host A host B

----IP-----> comp #1 -----ROHC-----> decomp #1 ----IP---->
                             ^ |
                              | feedback | feedbacks
                              | V
                    decomp #2 <-----feedback----- comp #2

On host A:
  comp1 = rohc_alloc_compressor()
  decomp2 = rohc_alloc_decompressor(comp1)

On host B:
  comp2 = rohc_alloc_compressor()
  decomp1 = rohc_alloc_decompressor(comp2)

Regards,
Didier

Wei Wang (eww012) said : #35

Hi Didier,

If so, if data packet is compressed by host A and then sent to host B, host B should be able to decompress it, not depending on any information from host A. Right? How can host B know what profile host A used in its compressor? Decomp algorithm can determine it itself?

Thanks.

Hi,

The profile ID is specified in the first ROHC packets (IR type). The decompressor associates the profile with the contest ID (CID). Then next ROHC packets contain the CID only.

The first paragraphs of RFC 3095 are worth reading for general information about ROHC principles.

Regards,
Didier

Wei Wang (eww012) said : #37

Hi Didier,

So far, there is no problem on compressor. But, I still haven't got good result from decompressor yet. See the log, please. My data length is 48, plus 40 bytes of IP/UDP/RTP headers, total packet length is 88 bytes.

The compressed lengths from the compressor are: 86, 89, 89, 89, 53, 53, 53, 53, 53, ...

On the decompressor side, the first 4 packets are decompressed successfully. However, since the 5th packet, the decompress failed. The fifth and later packets should not be IR packets. But how come the rohc_decompress() returns ROHC_ERROR_CRC(-4) and ROHC_ERROR (-5)? Since the 8th packet on, the decompress returned ROHC_ERROR(-5) all the time. Your comment on level #30 says UDP port may be the reason why decompressor failed. It shouldn't apply here.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OnPakcetReceived(): received packet length is 53
packet# 5
rohc_decomp.c: rohc_decompress(): decompress the 53-byte packet #5
I rohc_decomp.c: d_decode_header(): line607
I rohc_decomp.c: d_decode_header(): line741, ROHC packet is not a IR packet
I rohc_decomp.c: rohc_decompress(): line426: ret = -4
I rohc_decomp.c: rohc_decompress(): 435: ret = -4
I rohc_decomp.c: rohc_decompress(): line438, 9
I rohc_decomp.c: rohc_decompress(): state in decompressor = 3
rohc_decomp.c: rohc_decompress(): line444: ret = -4
decompression of fake IP packet failed, decomp packet length = -4

OnPakcetReceived(): received packet length is 53
packet# 6
rohc_decomp.c: rohc_decompress(): decompress the 53-byte packet #6
rohc_decomp.c: d_decode_header(): line741, ROHC packet is not a IR packet
rohc_decomp.c: rohc_decompress(): line426: ret = -4
rohc_decomp.c: rohc_decompress(): 435: ret = -4
rohc_decomp.c: rohc_decompress(): line438, 11
rohc_decomp.c: rohc_decompress(): state in decompressor = 3
rohc_decomp.c: rohc_decompress(): line444: ret = -4
decompression of fake IP packet failed, decomp packet length = -4

OnPakcetReceived(): received packet length is 53
packet# 8
rohc_decomp.c: rohc_decompress(): decompress the 53-byte packet #8
rohc_decomp.c: d_decode_header(): line741, ROHC packet is not a IR packet
rohc_decomp.c: rohc_decompress(): line426: ret = -5
rohc_decomp.c: rohc_decompress(): 435: ret = -5
rohc_decomp.c: rohc_decompress(): line438, 15
rohc_decomp.c: rohc_decompress(): state in decompressor = 2
rohc_decomp.c: rohc_decompress(): line444: ret = -5

Wei,

There is a typo in my comment #30 (option 3 is given twice, option 2 never). Option 2 is probably the root of your problem, ie. wrong IP or UDP checksum.

Regards,
Didier

Wei Wang (eww012) said : #39

Hi Didier,

Yes, you are right. I need to recalculate checksum bytes.

Thanks very much for your kindly help.
Wei

Wei Wang (eww012) said : #40

Hi Didier,

I have another question about the buffer size for the compressed and decompressed packets. In your example, it is defined as 2048. I'm wondering if this value depends on the packet size or not. I'm trying to assign a value as small as possible. In my opinion, this buffer is used to (1) store the data that will NOT be compressed, and (2) swap or exchange variables during the process. Since only 3~4 extra bytes are appended in the first several compressed packets, can I just define this buffer size as data size + 2 * header size? For example, in my case, data size = 48, header size = 40, can I defined buffer size as 48 + 40 *2 = 128?

Thanks,
Wei

Wei,

That seems fine.

Regards,
Didier

Can you help with this problem?

Provide an answer of your own, or ask Wei Wang for more information if necessary.

To post a message you must log in.