Summary:ASTERISK-12380: Re-Invite occurs eventhough the codecs are incompatible.
Reporter:Ramon Peek-Fares (ramonpeek)Labels:
Date Opened:2008-07-15 06:27:26Date Closed:2008-09-09 11:10:01
Versions:Frequency of
Environment:Attachments:( 0) 13076.patch
( 1) cli_trace.txt
Description:Re-invite occurs eventhough the codecs are incompatible.
See these steps to reproduce;

Device A accepts/offers codecs g711 & g729a (AudioCodes Mediant 1000)
Peer A in Asterisk only supports codec g711a
Peer B in Asterisk only supports codec g729a
Device B accepts/offers codec g729a (Snom Phone)

A call from device A is routed through Asterisk to device B.
Device B answers and then Asterisk sends a re-invite without a codec!!?
But why, The codecs don't even match!
Asterisk then prints-out the CLI-Error:
"ERROR[31381]: chan_sip.c:12326 handle_response_invite: Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled."

If canreinvite is set to no the problem obviously does not occur.
And if peer a is set to allow G711a AND G729a the problem also does not occur.

Comments:By: Ramon Peek-Fares (ramonpeek) 2008-07-15 06:33:10

See attached trace with Debug 5, verbose 3 and SIP Debug on.

IP address: is AudioCodes Mediant 1000  (originator)
IP address: is Asterisk PBX
IP address: is Snom 320 Phone running 7.1.33 firmwware.

By: Ramon Peek-Fares (ramonpeek) 2008-07-15 06:38:55

Maybe this issue is related to?:

By: Sam Deller (samdell3) 2008-09-07 23:11:10

Ive seen this error before. It usually happens when you try setting SIP_CODEC before Dial(). The error message is generated becasue the CPE sends back a 488 to asterisk after the re-invite (that should never have happened anyway).

Are you using SIP_CODEC?  If so, see bug 13243 to fix it.

If you are not using SIP_CODEC then there must be something else really broken with v1.4.21

By: Theo Belder (tbelder) 2008-09-08 09:53:01

My collegue ramonpeek is on holiday. But we are not using SIP_CODEC. ramonpeek has already spoken with Olle, and he has also confirmed that this is not correct behavior.

By: Mark Michelson (mmichelson) 2008-09-09 04:05:34

A quick look through the code suggests what you have probably guessed to be the case. Asterisk appears to be basing the codecs offered in the re-invite on what was offered in the SDP of the initial INVITE received.

This actually makes sense to some degree. If both peers are capable of communicating using the same codec and no Asterisk media features are needed for the call, then Asterisk should send REINVITES to get the endpoints to communicate directly using their mutually available codecs.

The problem appears to be that once Asterisk has surmised that both peers are capable of sending G.729, it doesn't follow through properly with the SDP's offered in the REINVITES. The first REINVITE is sent to Device B with G.729 offered in the SDP. The second is sent to Device A with ... no codecs. None. This is why Device A responds with a 488. The T.38 error message is Asterisk's attempt to figure out why it got a 488 on a reinvite and is inaccurate in this scenario.

In my opinion, while it does make sense to determine native bridge capabilities based on what the peer is capable of, it does not make sense to do this if we're only going to offer codecs configured in sip.conf in the REINVITEs. I also, however, am curious why the sip.conf entry for peer A would not match the codecs that device A is capable of using. I suppose there are sane reasons why you're doing this though.

I see two potential fixes for this. One is to change the logic used when sending the REINVITEs so that we offer the negotiated jointly capable codec to both peers (in this case G.729). The problem with this approach is that it could possibly violate the codec options placed in sip.conf. In your case, we would end up sending an SDP offering G.729 to a peer which is defined to only allow alaw. The other possible change is to use the codecs we are capable of using when communicating with the peer when determining if a native bridge is possible. This has the advantage of using only the codecs specified in sip.conf, but in your case for instance, we would lose the native bridge that we know is possible and add a transcoding burden to Asterisk for this call.

By: Theo Belder (tbelder) 2008-09-09 04:34:21

Thanks for the explanation and thinking of this problem.
Indeed there are two fixes possible for this problem:
- Send a REINVITE with the possibility of violating the codec options
- Transcode the call (send no REINVITE) or reject the call when no transcoding is possible (when no g729 license is activated).

In my opinion Asterisk shouldn't send a REINVITE in this scenario. In that case Asterisk should be "smart" enough to transcode this call (or reject the call when no transcoding is possible).

Also Asterisk should never send a REINVITE without a codec.

By: Mark Michelson (mmichelson) 2008-09-09 07:47:40

I have uploaded 13076.patch for testing. Please see if this fixes the problem reported. Thanks!

By: Mark Michelson (mmichelson) 2008-09-09 07:51:30

Oh, and just to be clear, the patch implements the change you suggested. When determining if we can attempt a native bridge, we only consider codecs that both ends of a call leg can use. In your case, you should no longer see REINVITEs coming from Asterisk.

By: Theo Belder (tbelder) 2008-09-09 08:59:25


Tested your patch in 2 ways.
Test 1:
- Peer A offers alaw/g729, Peer B offers g729
- Peer A is configured in sip.conf to allow only alaw
- Peer B is configured in sip.conf to allow only g729

In this case Asterisk doesn't send a REINVITE, but transcodes the call, which is correct.

Test 2:
- Peer A offers alaw/g729, Peer B offers g729
- Peer A is configured in sip.conf to allow g729 and alaw
- Peer B is configured in sip.conf to allow only g729

In this case Asterisk sends a REINVITE and offers in both invites to peer A and B g729 as codec, which is also correct.

So the patch is working for us. But I have no overview to determine the effects of this patch. Asterisk now gets the codecs from what is allowed instead of which codecs are offered by the peer. Am i correct?

By: Theo Belder (tbelder) 2008-09-09 09:18:23

I've made another test:
Test 3:
- Peer A offers alaw/g729, Peer B offers g729
- Peer A is configured in sip.conf to allow only alaw
- Peer B is configured in sip.conf to allow only g729
- G729 module isn't loaded (transcoding not possible)

In this case Asterisk doesn't transcode the call and rejects the call (603 Declined), which is correct.

By: Mark Michelson (mmichelson) 2008-09-09 10:05:34

Great! Thanks for the tests. I'm glad everything is working as expected. To answer your question of "Am I correct?" You are mostly correct and may in fact be fully correct. Here's the explanation for you just in case.

Asterisk maintains three "capabilities" variables per call  leg:
* ourcapabilities - What is defined in sip.conf for the peer
* peercapabilities - What was offered in the SDP by the peer
* jointcapabilities - A bitwise AND of the above two variables

The old (and broken) version was using peercapabilities of both call legs to determine if they shared common codecs. Then, when the time came to send a REINVITE, it may be that because the jointcapabilities of a call leg does not include the codec that was determined to be used for the native bridge, Asterisk would end up sending a REINVITE with no codec at all. This, as you put it, should never happen.

The way used in the patch is to use the jointcapabilites of both call legs to determine if they share common codecs. This way, we already know that Asterisk has the capability of communicating using the negotiated codec from the native bridge code.

By: Digium Subversion (svnbot) 2008-09-09 11:09:59

Repository: asterisk
Revision: 142079

U   branches/1.4/channels/chan_sip.c

r142079 | mmichelson | 2008-09-09 11:09:58 -0500 (Tue, 09 Sep 2008) | 21 lines

When determining if codecs used by SIP peers allow
the media to be natively bridged, use the jointcapability
instead of the peercapability.

It seems that the intent of using the peercapability was to
expand the choice of codecs for the call to increase the
chances of being able to native bridge the channels. The
problem is that if a codec were settled on for the native
bridge and that wasn't a codec that was configured to be used
by Asterisk for that peer, then Asterisk would send a
REINVITE with no codecs in the SDP which is a bug no matter
how you slice it.

(closes issue ASTERISK-12380)
Reported by: ramonpeek
     13076.patch uploaded by putnopvut (license 60)
Tested by: tbelder