Review Board 1.7.16


Asterisk 13 PJSIP sends RTP packets in wrong byte order on Intel platform when using slin codec

Review Request #4505 - Created March 16, 2015 and updated

Frankie Chin
http://svn.asterisk.org/svn/asterisk/tags/13.2.0
ASTERISK-24858
Reviewers
asterisk-dev
Asterisk
In Asterisk 13.2.0 when SLIN codec is used in two Asterisk servers registered to one another via PJSIP, the RTP payload is sent in the wrong byte order. The patch addresses the following based on the correct behavior in Asterisk 12.8.1:
1) Save ptime = 20 as the framing in the ast_rtp_codecs structure when creating outgoing SDP packet (res_pjsip_sdp_rtp.c)
2) Do not copy the framing when copying the payload (rtp_engine.c)
3) Introduce the new "smoother_be" flagin the ast_codec structure. Set this flag = 1 for all the SLIN codecs (codec_builtin.c).
4) Check for this "smoother_be" flag before using the smoother on the data (res_rtp_asterisk.c)
The patch was tested using the scenario described in ASTERISK-24858
Review request changed
Updated (March 16, 2015, 10:36 p.m.)
  • In Asterisk 13.2.0 when SLIN codec is used in two Asterisk servers registered to one another via PJSIP, the RTP payload is sent in the wrong byte order. The patch addresses the following based on the correct behavior in Asterisk 12.8.1:
    1) Save ptime = 20 as the framing in the ast_rtp_codecs structure when creating outgoing SDP packet (res_pjsip_sdp_rtp.c)
    2) Do not copy the framing when copying the payload (rtp_engine.c)
    3) Introduce the new "smoother_be" flagin the ast_codec structure. Set this flag = 1 for all the SLINcodecs.
    4) Check for this "smoother_be" flag before using the smoother on the data.

    In Asterisk 13.2.0 when SLIN codec is used in two Asterisk servers registered to one another via PJSIP, the RTP payload is sent in the wrong byte order. The patch addresses the following based on the correct behavior in Asterisk 12.8.1:
    1) Save ptime = 20 as the framing in the ast_rtp_codecs structure when creating outgoing SDP packet (res_pjsip_sdp_rtp.c)
    2) Do not copy the framing when copying the payload (rtp_engine.c)
    3) Introduce the new "smoother_be" flagin the ast_codec structure. Set this flag = 1 for all the SLIN codecs (codec_builtin.c).
    4) Check for this "smoother_be" flag before using the smoother on the data (res_rtp_asterisk.c)
Posted (March 17, 2015, 11:57 a.m.)

   

  
/tags/13.2.0/include/asterisk/codec.h (Diff revision 1)
 
 
 
 
 
I don't think you can trust that the codec will know its endianness. Looking at the resample code, I don't _think_ it actually determines the endianness of its encoding/decoding, and instead relies on the underlying machine to make that determination. As such, I don't think this should be a property on the codec structure.
  1. Matt, I actually followed the implementation in Asterisk 12.8.1 where the AST_SMOOTHER_FLAG_BE was defined for all the SLIN codecs in main/format.c under the format_list_init() method. Do you mean this implementation back in 12.8.1 was inappropriate? FYI, slin codec used to work fine in Asterisk 12.8.1 for our application.
  2. Apologies; you are absolutely correct about that.
    
    I'll need a day or two to think about whether or not this is the right way to handle passing smoother flags in. A part of me dislikes having an explicit BE byte order integer, but I'm also not a giant fan of storing a bunch of smoother properties directly on the codec. There may just not be a better place for it.
  3. After looking at 12 some more, I think handling this in the same manner as Asterisk 12 is probably the best way forward. That would mean adding a 'smoother_flags' option 
    
    struct ast_codec {
        ...
    
        unsigned int smooth;
    
        unsigned int smoother_flags;
    
    }
    
    That would change the API call from ast_format_smoothed_with_be to ast_format_get_smoother_flags (or something similar). That way, any additional smoother flags can be obtained without needing additional APIs added.
/tags/13.2.0/include/asterisk/format.h (Diff revision 1)
 
 
 
 
 
 
 
 
 
 
 
 
 
Since the smoother already has flags that determine the endianness, an additional API call in the format API feels wrong. If anything, the need for a different endianness on the smoother should be determined up front when the smoother is created, and not through the format API.
/tags/13.2.0/res/res_rtp_asterisk.c (Diff revision 1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
I think your issue should be solved here.

When you care a new smoother, you can specify whether or not it is BE or LE via the ast_smoother_set_flags call. The real issue is determining whether or not your machine is BE or LE.

What distro/environment did you produce this issue on?
  1. This issue was produced using Ubuntu 14.04.1 on Intel x86 platform. In Asterisk 12.8.1 I notice that when a smoother is created, the ast_smoother_set_flags() method is used to set the format flags into the smoother. Hence it is not deciding on BE/LE based on the machine platform.
/tags/13.2.0/res/res_rtp_asterisk.c (Diff revision 1)
 
 
 
 
I don't think this flag is needed. 

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.