[Home]

Summary:ASTERISK-26423: res_pjsip_sdp_rtp: Asymmetric RTP codec can cause audio loss and wonkiness
Reporter:Andreas Wetzel (rakanishu)Labels:
Date Opened:2016-09-29 05:40:15Date Closed:2016-10-27 16:51:55
Priority:MajorRegression?
Status:Closed/CompleteComponents:Resources/res_pjsip_sdp_rtp
Versions:13.11.2 Frequency of
Occurrence
Constant
Related
Issues:
is related toASTERISK-26317 res_pjsip_session: Add ability to use preferred codec only
is related toASTERISK-26143 res_rtp_asterisk: One way audio when transcoding
is related toASTERISK-26553 pjsip: Cannot hear transcoded sound files in a g722 call
Environment:FreeBSD 10.3-RELEASE-p8 i386 Gigaset S850A GO IP phoneAttachments:( 0) ASTERISK-26423.diff
Description:This is an interoperability issue between asterisk/pjsip and a Gigaset S850A GO IP telephone due to way codecs are negotiated between both devices.

When a call is placed from the S850A GO the initial INVITE message contains the list of configured codecs in the preferred order, i.e. g722, pcma, pcmu. When asterisk responds with OK, it also presents the configured codec list and preferred order, lets assume it's also g722, pcma, pcmu. What the S850A GO now seems to be doing is to pick the first codec from asterisk's list which it also supports. If asterisk now sends RTP data to the S850A GO, that is encoded in a format different than the one it has picked, the phone sends reINVITEs whose sdp only contains the single codec it has chosen. Asterisk confirms that it would respect this and sends OK with also only the single codec, but continues to send RTP data encoded in a different format, leading to an endless loop of reINVITEs and OK messages, with only one way audio. This occurs for example when calling an extension that does only support pcma and pcmu, in which case asterisk will send alaw encoded RTP to the S850A GO, as it was in it's list of supported codecs.

I understand that this issue is in part caused by the firmware of the S850A GO phone. Similar issues seem to exist with a number of other manufacturers like Grandstream, Yealink and Snom. Nevertheless I feel that asterisk/pjsip is not behaving correctly in this regard either. If asterisk acknowledges the use of a single codec as was requested by the device in the reINVITE message, then it should obey that and not continue sending differently encoded RTP to the device.
Comments:By: Asterisk Team (asteriskteam) 2016-09-29 05:40:15.738-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: Joshua C. Colp (jcolp) 2016-10-04 12:14:58.666-0500

Can you also provide the SIP logs showing this behavior as well as configuration?

By: JoshE (n8ideas) 2016-10-04 13:37:48.884-0500

We've certainly seen this issue as well.  This gets to a philosophical issue of standards compliance vs practical implementation.  From our reading of the spec, it's pretty clear that the Asterisk 13 behavior on PJSIP (though different from Asterisk 11) is correct:

RFC 3264 (https://www.ietf.org/rfc/rfc3264.txt), on Page 5:

  The list of media formats for each media stream conveys two pieces of
  information, namely the set of formats (codecs and any parameters
  associated with the codec, in the case of RTP) that the offerer is
  capable of sending and/or receiving (depending on the direction
  attributes), and, in the case of RTP, the RTP payload type numbers
  used to identify those formats.  *If multiple formats are listed, it
  means that the offerer is capable of making use of any of those
  formats during the session.  In other words, the answerer MAY change
  formats in the middle of the session, making use of any of the
  formats listed, without sending a new offer.*

That said, Snom, Grandstream and several others make an incorrect simplifying assumption that sending codec = receiving codec and expecting the device to make a new offer if that should need to be changed.

Over the course of several months, we were able to work with Yealink to resolve this issue on all of their currently supported phones, though the older phones remain non-compliant.  You can find the firmware that resolves these issues in their forums.

Just throwing in my $.02 here: we'd certainly like to possibly have a knob to deal with this behavior for non-compliant endpoints, given the difficulty of getting all manufacturers to update software.

By: Andreas Wetzel (rakanishu) 2016-10-06 03:48:25.394-0500

This is what a short call from the S850A GO to an ekiga softphone that has been deliberately configured to allow for alaw and ulaw only looks like. This setup exhibits the same problem as when placing an outbound call from the S850A GO through my ITSP. All endpoints are set to allow for g722, alaw and ulaw and have direct_media disabled, so that audio has to pass through asterisk. You can see that from the moment the call is picked up, the S850A GO is continously sending reinvites to asterisk:
{noformat}
No.   Timestamp  (Dir) Address                  SIP Message
===== ========== ============================== ===================================
00000 1475913733 * <== 10.6.6.64:5060           INVITE sip:301@rakanishu.de;user=phone SIP/2.0
00001 1475913733 * ==> 10.6.6.64:5060           SIP/2.0 401 Unauthorized
00002 1475913733 * <== 10.6.6.64:5060           ACK sip:301@rakanishu.de;user=phone SIP/2.0
00003 1475913733 * <== 10.6.6.64:5060           INVITE sip:301@rakanishu.de;user=phone SIP/2.0
00004 1475913733 * ==> 10.6.6.64:5060           SIP/2.0 100 Trying
00005 1475913733 * ==> 10.6.8.6:5060            INVITE sip:ekiga@10.6.8.6 SIP/2.0
00006 1475913733 * <== 10.6.8.6:5060            SIP/2.0 100 Trying
00007 1475913733 * <== 10.6.8.6:5060            SIP/2.0 180 Ringing
00008 1475913733 * ==> 10.6.6.64:5060           SIP/2.0 180 Ringing
00009 1475913736 * <== 10.6.8.6:5060            SIP/2.0 200 OK
00010 1475913736 * ==> 10.6.8.6:5060            ACK sip:ekiga@10.6.8.6 SIP/2.0
00011 1475913736 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00012 1475913737 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00013 1475913737 * <== 10.6.6.64:5060           INVITE sip:10.6.6.1:5060 SIP/2.0
00014 1475913737 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00015 1475913737 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00016 1475913737 * <== 10.6.6.64:5060           INVITE sip:10.6.6.1:5060 SIP/2.0
00017 1475913737 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00018 1475913737 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00019 1475913737 * <== 10.6.6.64:5060           INVITE sip:10.6.6.1:5060 SIP/2.0
00020 1475913737 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00021 1475913737 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00022 1475913737 * <== 10.6.6.64:5060           INVITE sip:10.6.6.1:5060 SIP/2.0
00023 1475913737 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00024 1475913737 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00025 1475913737 * <== 10.6.6.64:5060           INVITE sip:10.6.6.1:5060 SIP/2.0
00026 1475913737 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00027 1475913737 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00028 1475913738 * <== 10.6.6.64:5060           INVITE sip:10.6.6.1:5060 SIP/2.0
00029 1475913738 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00030 1475913738 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00031 1475913738 * <== 10.6.6.64:5060           INVITE sip:10.6.6.1:5060 SIP/2.0
00032 1475913738 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00033 1475913738 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00034 1475913738 * <== 10.6.6.64:5060           INVITE sip:10.6.6.1:5060 SIP/2.0
00035 1475913738 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00036 1475913738 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00037 1475913738 * <== 10.6.6.64:5060           INVITE sip:10.6.6.1:5060 SIP/2.0
00038 1475913738 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00039 1475913738 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00040 1475913738 * <== 10.6.6.64:5060           INVITE sip:10.6.6.1:5060 SIP/2.0
00041 1475913738 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00042 1475913738 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00043 1475913738 * <== 10.6.6.64:5060           INVITE sip:10.6.6.1:5060 SIP/2.0
00044 1475913738 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00045 1475913739 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00046 1475913739 * <== 10.6.6.64:5060           INVITE sip:10.6.6.1:5060 SIP/2.0
00047 1475913739 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00048 1475913739 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00049 1475913739 * <== 10.6.6.64:5060           BYE sip:10.6.6.1:5060 SIP/2.0
00050 1475913739 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00051 1475913739 * ==> 10.6.8.6:5060            BYE sip:ekiga@10.6.8.6 SIP/2.0
00052 1475913739 * <== 10.6.8.6:5060            SIP/2.0 200 OK
{noformat}
The initial INVITE from the S850A GO to asterisk looks like this:
{noformat}
<--- History Entry 3 Received from 10.6.6.64:5060 at 1475913733 --->
INVITE sip:301@rakanishu.de;user=phone SIP/2.0
Via: SIP/2.0/UDP 10.6.6.64:5060;rport=5060;received=10.6.6.64;branch=z9hG4bKade1c634dd173d62f8c3eb3780f35d36
From: <sip:S850A-1@rakanishu.de>;tag=1659051246
To: <sip:301@rakanishu.de;user=phone>
Call-ID: 4125927375@10_6_6_64
CSeq: 3 INVITE
Contact: <sip:S850A-1@10.6.6.64:5060>
Authorization: Digest username="S850A-1", realm="rakanishu.de", nonce="1475913733/5c5efdb918c389e6c7a84fe1459d7a97", uri="sip:301@rakanishu.de;user=phone", response="878fb5463208e432f9b8bc9bb987f640", algorithm=md5, cnonce="c6a6c96e27e5e5ccccfb17212c3e986", opaque="6205d84a6dbb5632", qop=auth, nc=00000001
Max-Forwards: 70
User-Agent: S850A GO/42.238.00.000.000
Supported: replaces
Allow-Events: message-summary, refer, ua-profile, talk, check-sync
Allow: INVITE, ACK, CANCEL, BYE, OPTIONS, INFO, SUBSCRIBE, NOTIFY, REFER, UPDATE
Content-Type: application/sdp
Content-Length: 240
Content-Type: application/sdp
Content-Length:   240

v=0
o=S850A-1 5012 4 IN IP4 10.6.6.64
s=Mapping
c=IN IP4 10.6.6.64
t=0 0
m=audio 5012 RTP/AVP 9 8 0 101
a=rtpmap:9 G722/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
{noformat}
And asterisk's reply:
{noformat}
<--- History Entry 11 Sent to 10.6.6.64:5060 at 1475913736 --->
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.6.6.64:5060;rport=5060;received=10.6.6.64;branch=z9hG4bKade1c634dd173d62f8c3eb3780f35d36
Call-ID: 4125927375@10_6_6_64
From: <sip:S850A-1@rakanishu.de>;tag=1659051246
To: <sip:301@rakanishu.de;user=phone>;tag=8c881966-ea65-40ea-8225-25247f769f23
CSeq: 3 INVITE
Server: ACME
Allow: OPTIONS, SUBSCRIBE, NOTIFY, PUBLISH, INVITE, ACK, BYE, CANCEL, UPDATE, PRACK, REGISTER, MESSAGE, REFER
Contact: <sip:10.6.6.1:5060>
Supported: 100rel, timer, replaces, norefersub
Content-Type: application/sdp
Content-Length:   261

v=0
o=- 5012 6 IN IP4 78.51.220.96
s=ACME
c=IN IP4 10.6.6.1
t=0 0
m=audio 5006 RTP/AVP 9 8 0 101
a=rtpmap:9 G722/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=maxptime:150
a=sendrecv
{noformat}
From the information in the sdp of the initial INVITE, asterisk seems to assume that it's ok to send alaw encoded RTP to the S850A GO, and as the audio coming in from the ekiga client is alaw encoded it tries to avoid transcoding and just wants to pass the data along as is. But when the S850A GO receives RTP encoded in a format different than the one it has chosen internally, it sends reINVITEs, asking for exclusive use of the chosen codec, which asterisk confirms in the OK reply. Yet asterisk/pjsip continues to send alaw encoded RTP to the S850A GO, leading to an endless loop of reINVITEs and only one way audio:
{noformat}
<--- History Entry 13 Received from 10.6.6.64:5060 at 1475913737 --->
INVITE sip:10.6.6.1:5060 SIP/2.0
Via: SIP/2.0/UDP 10.6.6.64:5060;rport=5060;received=10.6.6.64;branch=z9hG4bK370b7b836bef75f99801f70229a94f07
From: <sip:S850A-1@rakanishu.de>;tag=1659051246
To: <sip:301@rakanishu.de;user=phone>;tag=8c881966-ea65-40ea-8225-25247f769f23
Call-ID: 4125927375@10_6_6_64
CSeq: 4 INVITE
Contact: <sip:S850A-1@10.6.6.64:5060>
Authorization: Digest username="S850A-1", realm="rakanishu.de", nonce="1475913733/5c5efdb918c389e6c7a84fe1459d7a97", uri="sip:10.6.6.1:5060", response="7c1d4f6de1e80f2d3a7f07638f770794", algorithm=md5, cnonce="fd549e07868b0abc7f442e56782bc509", opaque="6205d84a6dbb5632", qop=auth, nc=00000002
Max-Forwards: 70
User-Agent: S850A GO/42.238.00.000.000
Supported: replaces
Allow: INVITE, ACK, CANCEL, BYE, OPTIONS, INFO, SUBSCRIBE, NOTIFY, REFER, UPDATE
Content-Type: application/sdp
Content-Length: 192
Content-Type: application/sdp
Content-Length:   192

v=0
o=S850A-1 5012 5 IN IP4 10.6.6.64
s=Mapping
c=IN IP4 10.6.6.64
t=0 0
m=audio 5012 RTP/AVP 9 101
a=rtpmap:9 G722/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20

<--- History Entry 14 Sent to 10.6.6.64:5060 at 1475913737 --->
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.6.6.64:5060;rport=5060;received=10.6.6.64;branch=z9hG4bK370b7b836bef75f99801f70229a94f07
Call-ID: 4125927375@10_6_6_64
From: <sip:S850A-1@rakanishu.de>;tag=1659051246
To: <sip:301@rakanishu.de;user=phone>;tag=8c881966-ea65-40ea-8225-25247f769f23
CSeq: 4 INVITE
Contact: <sip:10.6.6.1:5060>
Allow: OPTIONS, SUBSCRIBE, NOTIFY, PUBLISH, INVITE, ACK, BYE, CANCEL, UPDATE, PRACK, REGISTER, MESSAGE, REFER
Supported: 100rel, timer, replaces, norefersub
Server: ACME
Content-Type: application/sdp
Content-Length:   213

v=0
o=- 5012 7 IN IP4 78.51.220.96
s=ACME
c=IN IP4 10.6.6.1
t=0 0
m=audio 5006 RTP/AVP 9 101
a=rtpmap:9 G722/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=maxptime:150
a=sendrecv

<--- History Entry 15 Received from 10.6.6.64:5060 at 1475913737 --->
ACK sip:10.6.6.1:5060 SIP/2.0
Via: SIP/2.0/UDP 10.6.6.64:5060;rport=5060;received=10.6.6.64;branch=z9hG4bKa1f03562b7d4df1ecde9e8251f06d528
From: <sip:S850A-1@rakanishu.de>;tag=1659051246
To: <sip:301@rakanishu.de;user=phone>;tag=8c881966-ea65-40ea-8225-25247f769f23
Call-ID: 4125927375@10_6_6_64
CSeq: 4 ACK
Contact: <sip:S850A-1@10.6.6.64:5060>
Authorization: Digest username="S850A-1", realm="rakanishu.de", nonce="1475913733/5c5efdb918c389e6c7a84fe1459d7a97", uri="sip:10.6.6.1:5060", response="7c1d4f6de1e80f2d3a7f07638f770794", algorithm=md5, cnonce="fd549e07868b0abc7f442e56782bc509", opaque="6205d84a6dbb5632", qop=auth, nc=00000002
Max-Forwards: 70
User-Agent: S850A GO/42.238.00.000.000
Content-Length: 0
Content-Length:  0
{noformat}
Excerpt from the RTP log shows that asterisk is indeed receiving g722 encoded RTP (type=09) from the S850A GO, but is sending alaw encoded RTP (type=08) to the S850A GO:
{noformat}
[2016-10-08 10:02:18.919] VERBOSE[100951][C-00000004] res_rtp_asterisk.c: Got  RTP packet from    10.6.6.64:5012 (type 09, seq 000176, ts 17428160, len 000160)
[2016-10-08 10:02:18.923] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:18.939] VERBOSE[100951][C-00000004] res_rtp_asterisk.c: Got  RTP packet from    10.6.6.64:5012 (type 09, seq 000177, ts 17428320, len 000160)
[2016-10-08 10:02:18.943] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:18.963] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:18.983] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.003] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.023] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.039] VERBOSE[100951][C-00000004] res_rtp_asterisk.c: Got  RTP packet from    10.6.6.64:5012 (type 09, seq 000178, ts 17428480, len 000160)
[2016-10-08 10:02:19.042] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.059] VERBOSE[100951][C-00000004] res_rtp_asterisk.c: Got  RTP packet from    10.6.6.64:5012 (type 09, seq 000179, ts 17428640, len 000160)
[2016-10-08 10:02:19.063] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.079] VERBOSE[100951][C-00000004] res_rtp_asterisk.c: Got  RTP packet from    10.6.6.64:5012 (type 09, seq 000180, ts 17428800, len 000160)
[2016-10-08 10:02:19.083] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.099] VERBOSE[100951][C-00000004] res_rtp_asterisk.c: Got  RTP packet from    10.6.6.64:5012 (type 09, seq 000181, ts 17428960, len 000160)
[2016-10-08 10:02:19.103] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.119] VERBOSE[100951][C-00000004] res_rtp_asterisk.c: Got  RTP packet from    10.6.6.64:5012 (type 09, seq 000182, ts 17429120, len 000160)
[2016-10-08 10:02:19.123] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.143] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.163] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.183] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.203] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.223] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.226] VERBOSE[100951][C-00000004] res_rtp_asterisk.c: Got  RTP packet from    10.6.6.64:5012 (type 09, seq 000183, ts 17429280, len 000160)
[2016-10-08 10:02:19.243] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.246] VERBOSE[100951][C-00000004] res_rtp_asterisk.c: Got  RTP packet from    10.6.6.64:5012 (type 09, seq 000184, ts 17429440, len 000160)
[2016-10-08 10:02:19.264] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.291] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
[2016-10-08 10:02:19.303] VERBOSE[100954][C-00000004] res_rtp_asterisk.c: Sent RTP P2P packet to 10.6.6.64:5012 (type 08, len 000160)
{noformat}
And the pjsip.conf file with personal information anonymized:
{noformat}
;===================================================================
; PJSIP Configuration
;===================================================================

;
; Global options that apply to all SIP communications.
;

[global]
type = global
user_agent = ACME
default_from_user = acme
default_realm = rakanishu.de
disable_multi_domain = yes

;
; Transport definitions.
;

[transport-udp]
type = transport
protocol = udp
bind = 0.0.0.0
tos = cs4

;
; Templates for use in other configuration sections.
;

[ep-common](!)
type = endpoint
transport = transport-udp
sdp_session = ACME
tos_audio = cs5
disallow = all
allow = g722,alaw,ulaw
user_eq_phone = yes
allow_subscribe = no

[ep-internal](!,ep-common)
context = local-in
device_state_busy_at = 2
direct_media = no

[ep-o2](!,ep-common)
context = o2-in
direct_media = no
from_domain = sip.my.itsp
trust_id_inbound = yes
allow_transfer = no

[auth-userpass](!)
type = auth
auth_type = userpass

[aor-dynamic](!)
type = aor
max_contacts = 1

[reg-o2](!)
type = registration
transport = transport-udp
server_uri = sip:sip.my.itsp
retry_interval = 60
line = yes

;
; Phone configuration
;

; Gigaset S850A-GO

[S850A-1](ep-internal)
aors = S850A-1
auth = auth-S850A-1
deny = 0.0.0.0/0
permit = 10.6.6.64

[S850A-1](aor-dynamic)

[auth-S850A-1](auth-userpass)
username = S850A-1
password = topsecret

; Ekiga

[ekiga](ep-internal)
aors = ekiga
auth = auth-ekiga
deny = 0.0.0.0/0
permit = 10.6.8.6

[ekiga](aor-dynamic)

[auth-ekiga](auth-userpass)
username = ekiga
password = topsecret

;
; Provider configuration
;

; Outbound authentication

[auth-o2-17](auth-userpass)
username = MY-DID-1
password = topsecret1

[auth-o2-18](auth-userpass)
username = MY-DID-2
password = topsecret2

[auth-o2-19](auth-userpass)
username = MY-DID-3
password = topsecret3

[auth-o2-20](auth-userpass)
username = MY-DID-4
password = topsecret4

; ITSP AOR

[aor-o2]
type = aor
contact = sip:sip.my.itsp

; ITSP endpoints

[ep-o2-17](ep-o2)
outbound_auth = auth-o2-17
aors = aor-o2
from_user = MY-DID-1

[ep-o2-18](ep-o2)
outbound_auth = auth-o2-18
aors = aor-o2
from_user = MY-DID-2

[ep-o2-19](ep-o2)
outbound_auth = auth-o2-19
aors = aor-o2
from_user = MY-DID-3
t38_udptl = yes
t38_udptl_ec = fec

[ep-o2-20](ep-o2)
outbound_auth = auth-o2-20
aors = aor-o2
from_user = MY-DID-4

; Outbound registrations

[reg-o2-17](reg-o2)
outbound_auth = auth-o2-17
client_uri = sip:MY-DID-1@sip.my.itsp
contact_user = MY-DID-1
endpoint = ep-o2-17

[reg-o2-18](reg-o2)
outbound_auth = auth-o2-18
client_uri = sip:MY-DID-2@sip.my.itsp
contact_user = MY-DID-2
endpoint = ep-o2-18

[reg-o2-19](reg-o2)
outbound_auth = auth-o2-19
client_uri = sip:MY-DID-3@sip.my.itsp
contact_user = MY-DID-3
endpoint = ep-o2-19

[reg-o2-20](reg-o2)
outbound_auth = auth-o2-20
client_uri = sip:MY-DID-4@sip.my.itsp
contact_user = MY-DID-4
endpoint = ep-o2-20
{noformat}

By: Marcelo Bello (mbello) 2016-10-11 08:46:09.730-0500

This is a known issue with multiple brands of phones, such as:
- Yealink
- Grandstream
- Siemens Gigaset
- Cisco Linksys
- HTEK

Up until now it was always considered a bug on SIP phones, but the RE-INVITE behaviour described here also hints to a potential bug in PJSIP as well. At the very least, I believe the behavior of failing to consider the REINVITE from the SIP phone is something that should be fixed. However, I have not seen such REINVITE behavior on Yealink and GS phones, so fixing it could help the Gigaset devices, but I believe not Yealink and GS devices.

Yealink has already released a test firmware with a fix to accept Asymmetric RTP codec. Today I opened a ticket with Grandstream for the same issue, hopefully they will fix it soon.

Yealink (discussion thread with link to the firmware where the issue has been fixed):
http://forum.yealink.com/forum/showthread.php?tid=8330

Grandstream (first is the ticket, second is the report on their forums):
https://helpdesk.grandstream.com/users/show_ticket/61551
http://forums.grandstream.com/forums/index.php?topic=33128.0


By: Joshua C. Colp (jcolp) 2016-10-23 07:47:28.597-0500

I'm attaching a preliminary change which fixes a few codec problems in chan_pjsip. This ensures that if negotiated payloads change we will re-evaluate the bridge situation, it ensures that outgoing media is of the same payload of received media, and it also ensures that bridge choice selection uses the negotiated codecs.

I will be testing this out fully tomorrow but thought I would put it up now to elicit any feedback.

It can be applied by downloading the patch and applying it using "patch -p1 < ASTERISK-26423.diff"

If any issues occur with it please ensure you have a log with debug enabled (debug in logger.conf and core set debug 9 on the CLI).

By: Joshua C. Colp (jcolp) 2016-10-24 11:46:05.644-0500

My testing so far has gone well and behavior is what I'd like it to be. Can anyone with devices that were having problems try the patch and see how it performs for them? I'd like to be certain this fixes things for everyone before putting it up for review.

By: JoshE (n8ideas) 2016-10-24 21:21:18.497-0500

For our part, this patch does resolve issues here @jcolp, specifically with Grandstream, Aastra, and legacy Yealink, though I don't have a Gigaset to test the reinvite scenario Marcelo references above, which appears to be unique to that model.

I do have some concerns about going back to a world where we are forced to have sending = receiving codec.  We've seen better performance (reduced transcoding legs) out of support for different sending and receiving codecs, and it would generally be better for phone vendors to implement this properly.

Any chance to make this some sort of a knob in dialplan or elsewhere so we could control this behavior on the fly?  Just a thought...

By: Joshua C. Colp (jcolp) 2016-10-25 05:27:34.545-0500

I could potentially add it as an endpoint option and default it to off...

I wouldn't default it to on as the behavior has clearly shown itself to be problematic and for end users they may not know what is going on or that the option would help.

By: Andreas Wetzel (rakanishu) 2016-10-27 11:54:31.140-0500

I have applied the patch to Asterisk 13.12.0 and testing with the Gigaset S850A GO shows a significant improvement:
{noformat}
No.   Timestamp  (Dir) Address                  SIP Message
===== ========== ============================== ===================================
00000 1477585228 * <== 10.6.6.64:5060           INVITE sip:301@rakanishu.de;user=phone SIP/2.0
00001 1477585228 * ==> 10.6.6.64:5060           SIP/2.0 401 Unauthorized
00002 1477585228 * <== 10.6.6.64:5060           ACK sip:301@rakanishu.de;user=phone SIP/2.0
00003 1477585228 * <== 10.6.6.64:5060           INVITE sip:301@rakanishu.de;user=phone SIP/2.0
00004 1477585228 * ==> 10.6.6.64:5060           SIP/2.0 100 Trying
00005 1477585228 * ==> 10.6.8.6:5060            INVITE sip:ekiga@10.6.8.6 SIP/2.0
00006 1477585228 * <== 10.6.8.6:5060            SIP/2.0 100 Trying
00007 1477585228 * <== 10.6.8.6:5060            SIP/2.0 180 Ringing
00008 1477585228 * ==> 10.6.6.64:5060           SIP/2.0 180 Ringing
00009 1477585231 * <== 10.6.8.6:5060            SIP/2.0 200 OK
00010 1477585231 * ==> 10.6.8.6:5060            ACK sip:ekiga@10.6.8.6 SIP/2.0
00011 1477585231 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00012 1477585231 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00013 1477585231 * <== 10.6.6.64:5060           INVITE sip:10.6.6.1:5060 SIP/2.0
00014 1477585231 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00015 1477585231 * <== 10.6.6.64:5060           ACK sip:10.6.6.1:5060 SIP/2.0
00016 1477585233 * <== 10.6.6.64:5060           BYE sip:10.6.6.1:5060 SIP/2.0
00017 1477585233 * ==> 10.6.6.64:5060           SIP/2.0 200 OK
00018 1477585233 * ==> 10.6.8.6:5060            BYE sip:ekiga@10.6.8.6 SIP/2.0
00019 1477585233 * <== 10.6.8.6:5060            SIP/2.0 200 OK
{noformat}

The endless loop of reinvites is gone and after a single reINVITE from the S850A GO, both parties are happily exchanging RTP data using type 09/G722 with functioning audio in both directions:

{noformat}
Got  RTP packet from    10.6.6.64:5018 (type 09, seq 000061, ts 51262560, len 000160)
Sent RTP P2P packet to 10.6.6.64:5018 (type 08, len 000160)
Got  RTP packet from    10.6.6.64:5018 (type 09, seq 000062, ts 51262720, len 000160)
Sent RTP P2P packet to 10.6.6.64:5018 (type 08, len 000160)
Got  RTP packet from    10.6.6.64:5018 (type 09, seq 000063, ts 51262880, len 000160)
Sent RTP P2P packet to 10.6.6.64:5018 (type 08, len 000160)
Got  RTP packet from    10.6.6.64:5018 (type 09, seq 000064, ts 51263040, len 000160)
Sent RTP packet to      10.6.6.64:5018 (type 09, seq 004928, ts 000960, len 000160)
Got  RTP packet from    10.6.6.64:5018 (type 09, seq 000065, ts 51263200, len 000160)
Sent RTP packet to      10.6.6.64:5018 (type 09, seq 004929, ts 001120, len 000160)
Sent RTP packet to      10.6.6.64:5018 (type 09, seq 004930, ts 001280, len 000160)
Sent RTP packet to      10.6.6.64:5018 (type 09, seq 004931, ts 001440, len 000160)
Sent RTP packet to      10.6.6.64:5018 (type 09, seq 004932, ts 001600, len 000160)
Sent RTP packet to      10.6.6.64:5018 (type 09, seq 004933, ts 001760, len 000160)
Got  RTP packet from    10.6.6.64:5018 (type 09, seq 000066, ts 51263360, len 000160)
Sent RTP packet to      10.6.6.64:5018 (type 09, seq 004934, ts 001920, len 000160)
Got  RTP packet from    10.6.6.64:5018 (type 09, seq 000067, ts 51263520, len 000160)
Sent RTP packet to      10.6.6.64:5018 (type 09, seq 004935, ts 002080, len 000160)
Got  RTP packet from    10.6.6.64:5018 (type 09, seq 000068, ts 51263680, len 000160)
Sent RTP packet to      10.6.6.64:5018 (type 09, seq 004936, ts 002240, len 000160)
...
{noformat}
Which can also be confirmed by looking at the individual channels:
{noformat}
core show channel PJSIP/S850A-1-00000006
-- General --
          Name: PJSIP/S850A-1-00000006
          Type: PJSIP
      UniqueID: sip.rakanishu.de-1477585770.9
      LinkedID: sip.rakanishu.de-1477585770.9
     Caller ID: S850A-1
Caller ID Name: (N/A)
Connected Line ID: 301
Connected Line ID Name: (N/A)
Eff. Connected Line ID: 301
Eff. Connected Line ID Name: (N/A)
   DNID Digits: (N/A)
      Language: en
         State: Up (6)
 NativeFormats: (g722)
   WriteFormat: slin16
    ReadFormat: slin16
WriteTranscode: Yes (slin@16000)->(g722@16000)
 ReadTranscode: Yes (g722@16000)->(slin@16000)
Time to Hangup: 0
  Elapsed Time: 0h2m20s
     Bridge ID: 96d98461-cbd4-4b9f-b6ac-861c212a5137
--   PBX   --
       Context: local-in
     Extension: 301
      Priority: 1
    Call Group: 0
  Pickup Group: 0
   Application: Dial
          Data: PJSIP/ekiga
Call Identifer: [C-00000003]
     Variables:
BRIDGEPVTCALLID=22f9ac08-7fb7-4386-bf7e-8e65817b8847
BRIDGEPEER=PJSIP/ekiga-00000007
DIALEDPEERNUMBER=ekiga
DIALEDPEERNAME=PJSIP/ekiga-00000007
DIALSTATUS=ANSWER
DIALEDTIME=
ANSWEREDTIME=
 CDR Variables:
level 1: calledsubaddr=
level 1: callingsubaddr=
level 1: dnid=
level 1: clid="" <S850A-1>
level 1: src=S850A-1
level 1: dst=301
level 1: dcontext=local-in
level 1: channel=PJSIP/S850A-1-00000006
level 1: dstchannel=PJSIP/ekiga-00000007
level 1: lastapp=Dial
level 1: lastdata=PJSIP/ekiga
level 1: start=1477585770.828084
level 1: answer=1477585773.047506
level 1: end=0.000000
level 1: duration=139
level 1: billsec=137
level 1: disposition=8
level 1: amaflags=3
level 1: uniqueid=sip.rakanishu.de-1477585770.9
level 1: linkedid=sip.rakanishu.de-1477585770.9
level 1: sequence=6
{noformat}
{noformat}
core show channel PJSIP/ekiga-00000007
-- General --
          Name: PJSIP/ekiga-00000007
          Type: PJSIP
      UniqueID: sip.rakanishu.de-1477585770.10
      LinkedID: sip.rakanishu.de-1477585770.9
     Caller ID: 301
Caller ID Name: (N/A)
Connected Line ID: S850A-1
Connected Line ID Name: (N/A)
Eff. Connected Line ID: S850A-1
Eff. Connected Line ID Name: (N/A)
   DNID Digits: (N/A)
      Language: en
         State: Up (6)
 NativeFormats: (alaw)
   WriteFormat: slin16
    ReadFormat: slin16
WriteTranscode: Yes (slin@16000)->(slin@8000)->(alaw@8000)
 ReadTranscode: Yes (alaw@8000)->(slin@8000)->(slin@16000)
Time to Hangup: 0
  Elapsed Time: 0h2m43s
     Bridge ID: 96d98461-cbd4-4b9f-b6ac-861c212a5137
--   PBX   --
       Context: local-in
     Extension:
      Priority: 1
    Call Group: 0
  Pickup Group: 0
   Application: AppDial
          Data: (Outgoing Line)
Call Identifer: [C-00000003]
     Variables:
BRIDGEPVTCALLID=1109113516@10_6_6_64
BRIDGEPEER=PJSIP/S850A-1-00000006
DIALEDPEERNUMBER=ekiga
 CDR Variables:
level 1: calledsubaddr=
level 1: callingsubaddr=
level 1: dnid=
level 1: clid="" <301>
level 1: src=301
level 1: dcontext=local-in
level 1: channel=PJSIP/ekiga-00000007
level 1: lastapp=AppDial
level 1: lastdata=(Outgoing Line)
level 1: start=1477585770.849915
level 1: answer=1477585773.047438
level 1: end=1477585773.054909
level 1: duration=2
level 1: billsec=0
level 1: disposition=8
level 1: amaflags=3
level 1: uniqueid=sip.rakanishu.de-1477585770.10
level 1: linkedid=sip.rakanishu.de-1477585770.9
level 1: sequence=7
{noformat}
'pjsip show channelstats' however still displays a wrong codec/no codec at all for the channels. No idea where it gets that information from:
{noformat}
BridgeId ChannelId ........ UpTime.. Codec.   Count    Lost Pct  Jitter   Count    Lost Pct  Jitter RTT....
===========================================================================================================

96d98461 S850A-1-00000006   00:00:33 ulaw     1499      86    5   0.000   1454       0    0   0.000   0.000
96d98461 ekiga-00000007     00:00:33          1456   33056  2270   0.000   1494       0    0   0.001   0.000
{noformat}

By: Friendly Automation (friendly-automation) 2016-10-27 16:51:55.694-0500

Change 4172 merged by Joshua Colp:
pjsip: Fix a few media bugs with reinvites and asymmetric payloads.

[https://gerrit.asterisk.org/4172|https://gerrit.asterisk.org/4172]

By: Friendly Automation (friendly-automation) 2016-10-27 18:09:07.669-0500

Change 4173 merged by Joshua Colp:
pjsip: Fix a few media bugs with reinvites and asymmetric payloads.

[https://gerrit.asterisk.org/4173|https://gerrit.asterisk.org/4173]

By: Friendly Automation (friendly-automation) 2016-10-27 18:36:50.560-0500

Change 4213 had a related patch set uploaded by Joshua Colp:
pjsip/attribute_passthrough/speex_h263_h264: Disable direct media.

[https://gerrit.asterisk.org/4213|https://gerrit.asterisk.org/4213]

By: Friendly Automation (friendly-automation) 2016-10-27 19:38:09.773-0500

Change 4174 merged by Joshua Colp:
pjsip: Fix a few media bugs with reinvites and asymmetric payloads.

[https://gerrit.asterisk.org/4174|https://gerrit.asterisk.org/4174]

By: Friendly Automation (friendly-automation) 2016-10-27 20:38:36.826-0500

Change 4213 merged by zuul:
pjsip/attribute_passthrough/speex_h263_h264: Disable direct media.

[https://gerrit.asterisk.org/4213|https://gerrit.asterisk.org/4213]