Summary:ASTERISK-08856: [patch] RTP packetization won't work under P2P bridging mode
Reporter:phsultan (phsultan)Labels:
Date Opened:2007-02-21 07:55:20.000-0600Date Closed:2007-07-06 19:18:18
Versions:Frequency of
Environment:Attachments:( 0) rtp-no-p2p-on-framing-difference.txt
( 1) rtp-no-p2p-on-framing-difference-6.diff
( 2) rtp-no-p2p-on-framing-difference-v2.txt
( 3) rtp-no-p2p-on-framing-difference-v3.diff
( 4) rtp-no-p2p-on-framing-difference-v4.txt
( 5) rtp-no-p2p-on-framing-difference-v5.txt
( 6) trunk-disable_p2p-1.diff
( 7) trunk-disable_p2p-2.diff
Description:When a P2P bridge is set up, Asterisk does not smooth the traffic as it used to (default inter transmission time is 20 ms for ulaw).

My Cisco gateway discards large packets coming from a Jingle client (Jabbin, ITT 30 ms) in the following configuration :
Jabbin -> Asterisk -> Cisco SIP/PSTN gateway

The attached patch adds a 'disablep2p' option to make Asterisk set up a raw, old fashioned bridge (with traffic smoothing) between peers/users, and thus not modifying the way packets are handled in P2P mode.


This is a 'one way audio' problem, that won't happen with other Jingle clients such as GoogleTalk (ITT 20 ms).
Comments:By: dea (dea) 2007-02-21 12:55:52.000-0600

I like the idea.  What about making it dynamic as well as a user/peer option?

P2P is permitted if both sides are using a common codec, it would be trivial
to extend the test to also include common framing (packetization).

By: dea (dea) 2007-02-21 17:16:21.000-0600

Proof of concept patch that should accomplish the same thing.

All changes are localized to rtp.c

Compile tested and very limited run-time tested.

disclaimer on file.

** Edit **
Ignore the patch.  It only works as far as always disabling P2P.
I have another patch in process, but oddly the calling leg does
not appear to have the pref structure populated, so that patch
also succeeds in always disabling P2P.  Still looking...

By: dea (dea) 2007-02-21 23:11:24.000-0600

V2 of the patch is what I think should work.

Now while tracking this I found other issues, which may keep this
from working, or more accurately which will have the effect of
disabling P2P bridging (but at least we get smoothers back)

Now the issues I THINK I found-

1.  chan_sip sets the framing on an incoming call, but if
canreinvite is set to no, the result will be an invite from
* with no framing values set. The function
transmit_response_with_sdp()tests the call direction and only
sets framing on incoming calls.  The issue may be here or
near where the function is called from

2.  A re-invite to an endpoint with more codecs enabled in the
endpoint than in * will use the codec list the endpoint offered.
SIP only permits one ptime: attribute in the SDP, so chan_sip
has to pick a value that makes sense.  In this case the codecs
that the endpoint offered that the user/peer is not configured
to use will have their default framing options.  Example:
         PhoneA offers ulaw, G729, alaw in an invite
         */chan_sip is set up to use ulaw:30,g729:30
         canreinvite = no

The resulting SDP will have ulaw and g729, but with ptime:20
Adding alaw:30 to the peer/user settings causes the SDP to
be properly constructed.

Item 2 could be considered an endpoint issue, except we do not
always have control over the endpoints we communicate with.

I am raising these issues here instead of in a seperate bug as they
impact our ability to resolve this bug and are perhaps most interesting
in the contect of this bug

By: phsultan (phsultan) 2007-02-22 12:26:55.000-0600

I think your idea of making this more dynamic should definitly be the way to go... but it looks like it is hard to achieve, for the following reason.

Asterisk is the media interface between a Gtalk and a SIP client in my case. I tested your patch (modified it not to trigger a native bridge though, because Gtalk cannot do it, see attached file), and the codec framing size I get from either GoogleTalk, Jabbin, whatever Jingle client is always 0. Therefore, P2P bridge will *never* be set up, even though GoogleTalk for example has a codec framing size perfectly compatible with my Cisco gateway. So this does not work for me.

Maybe this issue needs further investigation towards your idea though, rather than roughly disabling P2P as I initially proposed it, even if this works. Let's work on it!

By: dea (dea) 2007-02-22 13:18:29.000-0600

Yup.  I am seeing the framing set to 0 on incoming calls as well.

This is bogus, and something that was working.  I am busy adding
ridiculous levels of logging to see where we are losing the
framing settings on an incoming call.

I do think the basic patch it right, and there are other bugs that
need tracking.  I'll try to have an update later today.

By: dea (dea) 2007-02-22 14:21:09.000-0600


The incoming prefs were not being reset.  My first couple of attempts
were looking for framing based on the codec list per channel and not
the selected codec per channel.

V4 addressed this (perhaps too simply)

I have confirmed that I get Native bridging if the framing sizes do not
match and P2P if they do.

There is a small logging change to frame.c, but otherwise all changes
are localized to rtp.c

By: Serge Vecher (serge-v) 2007-02-22 14:26:04.000-0600

Dan, is this change necessary?
- if (audio_p0_res == AST_RTP_TRY_PARTIAL || audio_p1_res == AST_RTP_TRY_PARTIAL) {
+ if ((audio_p0_res == AST_RTP_TRY_PARTIAL || audio_p1_res == AST_RTP_TRY_PARTIAL)) {

By: dea (dea) 2007-02-22 15:22:23.000-0600

Nope.  That was from an earlier attempt to move the test closer to the
calls to bridge_*_loop.

It's harmless, but if you'd like I can fix it and cut a new patch.

By: Serge Vecher (serge-v) 2007-02-22 15:35:12.000-0600

might as well, seems superfluous.

By: dea (dea) 2007-02-22 15:51:42.000-0600

Fixed redundant parans per Serge-V, and cleaned up a DEBUG message that was
not controlled by option_debug

Oh, there is one extra bit in this patch that fixes up a missed flag
change in chan_sip (SIP_OUTGOING changed to SIP_PAGE2_OUTGOING_CALL)
This section is/was related to this bug and changes to device state
tracking in chan_sip (commit 55914 explains it)

By: Joshua C. Colp (jcolp) 2007-02-22 17:07:36.000-0600

I don't agree with changing it so that it tries native if the framing is different... what if native is specifically disabled? This would then try it anyway. I can see this only coming in to play when it finally decides on P2P, if the framing doesn't match then go through the core. I also have a second question - is it okay to have reinvites when the framing is different?

By: dea (dea) 2007-02-22 18:04:54.000-0600

   Good questions.  I'll try to answer them.

1.  What happens if native bridging is disabled and different framing
is used and media streams have to go through * (most likely NAT related,
not DTMF differences)

   It won't work.  I did not know that native bridging could be disabled,
   so at least a log message should be generated if this combination occurs
   to allow the system administrator to take action.

2.  Are re-invites with different framing OK?
   Conceptually?  sure.  In practice there are minor issues relating to
   limitations in SIP (single ptime: attribute) and how * copes with that
   issue.  See add_codec_to_sdp(), we are currently setting the ptime:
   attribute to the lowest value in our preference set.  Not good, but no
   worse than setting it to the framing value of our 1st preference.  
   Arguably the 1st preference is better if we have a reasonable idea of
   what the endpoint will offer/accept.

   This is further complicated by the current codec selection process.
   A Cisco SIP phone is moderalty complicated to disable codecs in.  In
   my case I need to add alaw to my SIP user/peer with proper framing.
   If * would re-invite the phone with the configured codecs and not the
   full list that the phone offered, re-invites would be performed with
   framing values as set in the config file.

If I may, I'd like to ask what happens if p2p is disabled?  (I don't believe
that it can be today).  phsultan did identify a valid bug, in that p2p does
not work if the endpoints do not agree on a framing value, while native does.
If p2p were to be extended to support smoothers, would there be any real
remaining difference between it and native bridging?

  1.  Add a feature to disable P2P bridging (phsultan's patch)
  2.  Make the selection between P2P and native a little smarter (my goal)
  3.  Extend P2P to support smoothers

I can keep working on this if I have an idea of what changes you'd like to
see and some idea of where they should occur in the code

By: phsultan (phsultan) 2007-02-23 06:03:44.000-0600

I think we should be clearer on the words here. Here is what I understand :
- native bridging allows media traffic to bypass Asterisk, and flow directly between endpoints
 this is implemented in chan_sip with SIP re-invites, it is not implemented in  chan_gtalk, and maybe other RTP channels. It can be explicitly disabled/enabled in chan_sip through the 'canreinvite' option. This kind of bridge cannot occur between two channel endpoints of different technologies (ex. SIP and Gtalk)

- P2P bridging is the new 'default' bridging method
 no smoothers available in this mode

- core bridging is the former 'default' bridging mode
 smoothers are available, but Asterisk cannot be configured to access this mode. It is accessed when basic transcoding is needed (ulaw/alaw for example).

Please correct if I'm wrong here.

My initial idea was to simply avoid P2P when dynamically chosen by Asterisk, if configured for a given SIP user/peer, and revert to a core (I called it 'raw' in my initial patch) bridging mode. Native bridging mode in this particular case cannot be taken into account as it is currently impossible to set a direct media path between a Gtalk client and a SIP phone.

I agree with file's saying P2P, when excluded because of a framing mismatch, should be replaced with core bridging mode, not native bridging. This was the purpose of my modifications to DEA's patch in (rtp-no-p2p-on-framing-difference-v3.diff), which I am now updating.

DEA: I attached another modification to your latest patch in order to reflect the preference of core bridging over native bridging, after you solved the issue mentioned in note ASTERISK-5826820.

However, I still have a one-way audio problem. Now instead of 0, I get what looks like a default packetization time value for cur_ms (20 ms), whereas my Jabbin client sends RTP packets every 30 ms. This wrongly leads to a P2P bridge (all compared values are identical).

By: phsultan (phsultan) 2007-02-23 09:02:56.000-0600

new version of P2P disabling patch (conflicts detected).

By: dea (dea) 2007-02-23 12:23:36.000-0600

Yup.  I had my head wrapped around the bridge type incorrectly.

I was thinking that native == core.  phsultan's last patch works
the way I think it should.

   Check to see what codecs the client is offering.  There is a
major quirk in the re-invite process that will use the full list
of codecs that the endpoint offered, and any that are in that list
that are not in the allow= settings will be set to their default
value, which is 20ms for most codecs.  The ugly work-around is to
add the offered codecs to the allow= list, at the end of course to
make them less likely to be used.

** edit **
I also just realized that I did not ask if the jabber user/peer
has packetization set in your jabber.conf?  What does the allow=
line look like?

By: phsultan (phsultan) 2007-02-26 10:53:34.000-0600

Hi DEA, here are my testing results and observations.

The Jingle client I'm here using does not send any framing related information in the call setup messages, although the (optional) 'ptime' attribute exists in the standard (JEP-167). So I can't think of any way to tell Asterisk the packetization time used by the Jingle client.

I also patched Asterisk's Gtalk client in order to include a 'maxptime' attribute in its responses to the Jingle client, and set its value to 20, without any effect on the traffic coming from the Jingle client (eg. still one large packet every 30 ms). I thought I could limit the packetization time on the traffic coming from the Jingle client.

As for the 'allow=' attribute in gtalk.conf, documentation in doc/rtp-packetization.txt does not refer to Gtalk as being a candidate channel for this option. Moreover, I think it would be useless to have it implemented, as the option would just smooth the traffic from Asterik to the Jingle endpoint, without affecting the opposite way.

Here is my sip.conf :
; INRIA PSTN gateway :
; Cisco 3620 : IOS (tm) 3600 Software (C3620-IS-M), Version 12.2(10a)

And my gtalk.conf :

By: dea (dea) 2007-02-26 11:23:06.000-0600

I've looked over both chan_jingle and chan_gtalk, and while they
to not impliment the 'advertisement' component of packetization,
they still have the infrastructure to support it.

Packetization preferences are set when loading the config files.
Any channel that uses the ast_parse_allow_disallow() function will
be able to have their prefered packetization values stored.

In the case of chan_jingle and chan_gtalk, this will not effect
their outbound framing (but it wouldn't take much to add support
for this), but it will allow Asterisk to make decisions based on
the config.

Try this-

Your gtalk.conf :

By: phsultan (phsultan) 2007-02-26 13:34:04.000-0600

DEA, I got it working for the following configuration :
A (SIP) -> Asterisk -> C (SIP gateway)
but still nothing for a B (Gtalk) -> Asterisk -> C (SIP gateway).

In sip.conf
A : allow=ulaw:30
C : allow=ulaw:20

In gtalk.conf
B : allow=ulaw:30

In a SIP to SIP call (first configuration), P2P is disabled by Asterisk (what we want), and packetization is :
A -> Asterisk : 20 ms
Asterisk -> A : 30 ms

C -> Asterisk : 20 ms
Asterisk -> C : 20 ms

In a Gtalk to SIP call (second configuration), P2P is not disabled, and packetization is :
B -> Asterisk : 30 ms
Asterisk -> B : 20 ms

C -> Asterisk : 20 ms
Asterisk -> C : 30 ms (packets discarded)

Looks like chan_gtalk ignores the allow=ulaw:30 attribute value. We might need to clear this up.

By: dea (dea) 2007-02-26 17:08:54.000-0600

Can you get a debug/verbose console log of a call setup
between the GTalk client and the SIP gateway?

A copy of the invite/offer from the GTalk client might also
be handy.

By: phsultan (phsultan) 2007-03-05 14:56:15.000-0600

Just to inform : I won't be able to take care of this issue for the upcoming couple of weeks, cause I'll be on holidays :)

By: phsultan (phsultan) 2007-03-29 05:42:11

Got it working : chan_gtalk ignores configured packetization, see http://bugs.digium.com/view.php?id=9416

By: Serge Vecher (serge-v) 2007-04-04 09:00:16

alright, since 9416 has been merged in, what needs to be done here?

By: dea (dea) 2007-04-04 18:54:20

9416 will(should) fix the  gtalk instance of this issue, but the
(pardon the pun) core issue remains.

We should not P2P bridge endpoints unless their streams are 100%

Bridging through the core allows us to setup smoothers to handle
framing differences, and most RTP-based endpoints will handle
asymetric framing so native bridging is also OK.

P2P bridging either needs to be extended to incorporate smoothers,
or refuse/hand off the streams to the core (assuming native
bridging is not viable)

I have a hairy suspession that recent reports of speex flakiness
on 1.4.X is related to this issue, but I have no speex capable
endpoints to test.

Feedback from a core developer on rtp-nop2p-on-framing-difference-6
would work towards fixing the root cause.

Oh, and if my tone in early posts offended anyone (reading it now, I
guess I might have), I apologize.

By: phsultan (phsultan) 2007-04-06 10:15:50

I agree with that. The last patch (rtp-no-p2p-on-framing-difference-6.diff) prevents Asterisk from starting a P2P bridge when smoothers are requested by configuration (eg. ulaw:20 vs ulaw:30).

I personnally did not feel offended by your notes, and found it great to work with you on another solution I did not think about :)

By: Joshua C. Colp (jcolp) 2007-06-21 10:26:02

Fixed in 1.4 as of revision 70727 and trunk as of revision 70729. Thanks!