Summary:ASTERISK-27259: chan_pjsip: Outgoing leg does not use all configured codecs, but subset based on caller
Reporter:laszlovl (lvl)Labels:pjsip
Date Opened:2017-09-06 17:09:06Date Closed:2017-09-28 12:26:27
Versions:15.0.0-rc1 Frequency of
Environment:Ubuntu 16.04 LTSAttachments:( 0) asterisk_transcoding.txt
( 1) notranscode_forcemediaoffer.txt
( 2) notranscode_regular.txt
( 3) pjsip_wizard.conf
( 4) sip.conf
Description:Asterisk is refusing to perform transcoding between two PJSIP channels that don't share a common codec capability. Reproducing is simple:

- Create two PJSIP endpoints with a limited set of allowed codecs, for example "g722,alaw"
- Launch a SIP phone using the first endpoint's credentials with only the g722 codec enabled
- Launch a SIP phone using the second endpoint's credentials with only the alaw codec enabled
- Create a simple dialplan so endpoint1 can dial PJSIP/endpoint2

Expected: Asterisk will use g722 on the 1st channel, use alaw on the 2nd channel, and transcode between them

Observed: Asterisk will try to force endpoint2 to use g722 even though its SDP doesn't contain it. The call will fail. Whichever codec is used on the incoming channel, will be forced onto the outgoing channel as well.

The following things don't make a difference:

- Setting asymmetric_rtp_codec to yes or no
- Setting preferred_codec_only to yes or no
- Answer()'ing the incoming call before the outgoing Dial()
- Limiting the "allow" list of codecs for endpoint1 to only "g722" and for endpoint2 to only "alaw"

The only thing that made a difference is using the PJSIP_MEDIA_OFFER function in a pre-dial handler. Setting PJSIP_MEDIA_OFFER(audio)=g722,alaw,ulaw will make Asterisk offer all these 3 codecs in the outgoing call's SDP. However, immediately after the call is answered by endpoint2, Asterisk sends a re-invite to endpoint1 offering only endpoint2's codecs, causing endpoint1 to drop the call.

Exactly the same setup (same dialplan, same Asterisk version, same phone configuration) works fine using chan_sip! Attached are the configuration files used and the logfile for the two scenarios.
Comments:By: Asterisk Team (asteriskteam) 2017-09-06 17:09:06.968-0500

Thanks for creating a report! The issue has entered the triage process. That means the issue will wait in this status until a Bug Marshal has an opportunity to review the issue. Once the issue has been reviewed you will receive comments regarding the next steps towards resolution.

A good first step is for you to review the [Asterisk Issue Guidelines|https://wiki.asterisk.org/wiki/display/AST/Asterisk+Issue+Guidelines] if you haven't already. The guidelines detail what is expected from an Asterisk issue report.

Then, if you are submitting a patch, please review the [Patch Contribution Process|https://wiki.asterisk.org/wiki/display/AST/Patch+Contribution+Process].

By: laszlovl (lvl) 2017-09-13 08:52:12.541-0500

I've checked and this bug doesn't exist in 14.6 + chan_pjsip. So I assume the problem was introduced in one of these commits: https://github.com/asterisk/asterisk/commit/aed6c219a3b21d212cea28425e0144eb52a3db70, https://github.com/asterisk/asterisk/commit/e5e887be53ceb0b3ae4c0aa5a5cd055bd524fbde or https://github.com/asterisk/asterisk/commit/d3e951edf5517b9f508a7e1b474176ec2be9e18f.

Since it's a regression, can I assume this will be fixed before the final release of Asterisk 15?

By: Joshua C. Colp (jcolp) 2017-09-13 09:26:30.592-0500

Yes, it's been marked as such and is in queue. It will be fixed before final release.

By: Friendly Automation (friendly-automation) 2017-09-28 12:26:28.085-0500

Change 6573 merged by Joshua Colp:
res_pjsip_session: outgoing call did not offer all configured codecs


By: Friendly Automation (friendly-automation) 2017-09-28 12:26:44.454-0500

Change 6572 merged by Joshua Colp:
res_pjsip_session: outgoing call did not offer all configured codecs


By: Friendly Automation (friendly-automation) 2017-09-28 12:35:05.260-0500

Change 6569 merged by Jenkins2:
res_pjsip_session: outgoing call did not offer all configured codecs


By: laszlovl (lvl) 2017-10-02 04:33:35.030-0500

Unfortunately the patch does not appear to solve the problem.

The INVITE for the outgoing leg now correctly contains all codecs configured for that endpoint (oddly regardless of the asymmetric_rtp_codec & preferred_codec_only setting), and the call is established succesfully. However, immediately after the call is answered, Asterisk sends a re-INVITE to the caller endpoint containing only the callee's offered codecs, causing the call to drop. This is the same behavior as initially reported when using PJSIP_MEDIA_OFFER to force codecs, shown in the notranscode_forcemediaoffer.txt trace.

<--- Transmitting SIP response (1247 bytes) to UDP:1:8065 --->
SIP/2.0 200 OK
a=rtpmap:9 G722/8000

   -- Channel PJSIP/proxy-1-00000008 joined 'simple_bridge' basic-bridge <b13a02a2-1e89-4706-8799-703f00ddc0d5>
   -- Channel PJSIP/proxy-1-00000007 joined 'simple_bridge' basic-bridge <b13a02a2-1e89-4706-8799-703f00ddc0d5>

<--- Transmitting SIP request (1180 bytes) to UDP:1:8065 --->
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000

<--- Received SIP response (543 bytes) from UDP:1:8065 --->
SIP/2.0 500 Server Internal Error

By: Asterisk Team (asteriskteam) 2017-10-02 04:33:36.085-0500

This issue has been reopened as a result of your commenting on it as the reporter. It will be triaged once again as applicable.

By: Joshua C. Colp (jcolp) 2017-10-02 07:38:33.885-0500

Did you try the 15 or 15.0 branch, or merely the patch itself? There have been numerous other changes to that behavior.

By: laszlovl (lvl) 2017-10-02 07:41:53.699-0500

I tested with the latest version of the 15.0 branch. (https://github.com/asterisk/asterisk/archive/15.0.0.tar.gz)

By: laszlovl (lvl) 2017-10-11 07:16:35.898-0500

I see the final version of Asterisk 15 has been released, but this bug is still present. To be completely sure, I re-tested the scenario with the official 15.0 release (http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-15.0.0.tar.gz). Attached is the full logfile. The result is the same regardless of the "asymmetric_rtp_codec = yes" option. Most specifically:

Received INVITE from 5061:
a=rtpmap:9 G722/8000

Transmitting INVITE to 15060:
a=rtpmap:9 G722/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000

Received OK from 15060:
a=rtpmap:8 PCMA/8000

Transmitting OK to 5061:
a=rtpmap:9 G722/8000

native_rtp_bridge_compatible_check: Bridge 'c98af1ad-af82-42e5-b931-2f6868d13614': Channel codec0 = (alaw) is not codec1 = (g722), cannot native bridge in RTP.
find_best_technology: Chose bridge technology simple_bridge

   -- Channel PJSIP/laptop-00000003 joined 'simple_bridge' basic-bridge <3d5407c7-f048-4331-ba7e-8fbbed229167>
   -- Channel PJSIP/desktop-00000002 joined 'simple_bridge' basic-bridge <3d5407c7-f048-4331-ba7e-8fbbed229167>

// So far so good. The problem starts below - 5061 doesn't support PCMA so it can't handle the re-INVITE

res_pjsip_session.c:1628 ast_sip_session_refresh: Sending session refresh SDP via re-INVITE to desktop

Transmitting INVITE to 5061:
a=rtpmap:8 PCMA/8000

Received from 5061:
SIP/2.0 500 Server Internal Error

By: Joshua C. Colp (jcolp) 2017-10-11 07:32:53.875-0500

[~lvl] What exactly happens as a result of that? Does media not flow? Does the other endpoint break in some fashion? It's fine to attempt to reinvite in that case, and now we don't terminate the call if that fails.

By: laszlovl (lvl) 2017-10-11 07:58:57.634-0500

The client I'm testing with (Jitsi) shows a "Offer contained no valid media descriptions" error message, then terminates the call. Admittedly that's quite drastic, and I haven't tested this scenario with other clients yet.

By: Joshua C. Colp (jcolp) 2017-10-11 08:06:48.595-0500

Okay, that's not what it should be doing. It should be rejecting the re-invite and the call should remain up. Based on the configuration and the RFC what we're doing itself is fine, it's just the interaction with that specific endpoint and their behavior that is the problem. That helps narrow this issue more and understand what is going on.

By: laszlovl (lvl) 2017-10-11 08:17:51.667-0500

I agree the RFC is pretty clear here, looks like I assumed too quickly that this was Asterisk's fault as well. Thanks for the feedback, I'll check this out on a variety of clients.

By: laszlovl (lvl) 2017-10-13 15:57:52.760-0500

Preliminary testing on my end shows that most endpoints handle this behavior gracefully, but not all of them. Apart from Jitsi I observed a Snom phone replying to the re-INVITE with an empty set of payloads, which means the call doesn't terminate but proceeds without flowing audio. The strategy in https://gerrit.asterisk.org/#/c/6759/ looks like a great improvement for broad compatibility, thank you!

By: Asterisk Team (asteriskteam) 2017-10-13 15:57:52.959-0500

This issue has been reopened as a result of your commenting on it as the reporter. It will be triaged once again as applicable.

By: Friendly Automation (friendly-automation) 2017-10-17 08:38:07.646-0500

Change 6759 merged by Jenkins2:
bridge_simple: Improve renegotiation success rate.


By: Friendly Automation (friendly-automation) 2017-10-17 08:50:02.518-0500

Change 6760 merged by Jenkins2:
bridge_simple: Improve renegotiation success rate.