[Home]

Summary:ASTERISK-28766: PJSIP blind transfer not completed after using Proceeding()
Reporter:laszlovl (lvl)Labels:
Date Opened:2020-03-03 10:55:35.000-0600Date Closed:2020-03-05 11:03:53.000-0600
Priority:MajorRegression?
Status:Closed/CompleteComponents:Channels/chan_pjsip
Versions:16.8.0 Frequency of
Occurrence
Related
Issues:
Environment:Attachments:( 0) sip.txt
Description:If you perform a blind transfer (REFER), transfer the call to an extension that uses {{Proceeding()}} then remains in the dialplan and does **not** dial out, the transferer will not be notified of the transfer success.

To clarify. A transfer to the following extensions will finish properly:

{code}
s,1,Proceeding()
s,2,Dial(PJSIP/bla)
{code}

{code}
s,1,Playback(bla)
{code}

While the following extension will fail:

{code}
s,1,Proceeding()
s,2,Playback(bla)
{code}

Why is this? Transfer status is handled by refer_progress_framehook in https://github.com/asterisk/asterisk/blob/master/res/res_pjsip_refer.c#L218

Apparently, if the target extension executes a {{Dial()}}, this generates a control frame of the AST_CONTROL_ANSWER type which will trigger {{refer_progress_notify}} with a status 200. This will signal to the transferer that the transfer is accepted and their phone can disconnect.

However, if the call remains in the dialplan no such control frame is generated, even if you explicitly {{Answer()}}. In this case, the transfer status is normally detected by the passing of a AST_FRAME_VOICE. But that code only triggers if {{progress->subclass}} is null, e.g. once any control frame has been detected, a subsequent voice frame can no longer trigger transfer completion.

This code was introduced in https://github.com/asterisk/asterisk/commit/77002bc377f19ea11e60732c486b6ef371688773 and subtly changed in https://github.com/asterisk/asterisk/commit/344cdab3a71d8f8b3517e7efe6864165142b14ca. My best guess is that the intention was to prevent duplicate progress messages from being generated when a voice frame was detected after a control frame had already triggered the appropriate notify.

But this premise is false, as the passing of e.g. a AST_CONTROL_PROCEEDING frame (triggering a 100) should not prevent a AST_FRAME_VOICE frame from later triggering a 200.
Comments:By: Asterisk Team (asteriskteam) 2020-03-03 10:55:36.859-0600

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].

Please note that once your issue enters an open state it has been accepted. As Asterisk is an open source project there is no guarantee or timeframe on when your issue will be looked into. If you need expedient resolution you will need to find and pay a suitable developer. Asking for an update on your issue will not yield any progress on it and will not result in a response. All updates are posted to the issue when they occur.

By: Kevin Harwell (kharwell) 2020-03-03 12:47:27.070-0600

Could you post your exact dialplan, and how you initiated the transfer for the scenario? I can't duplicate the problem when I transfer to a regular extension (not "s").

The end solution might be the same, but I'm curious as to the causing scenario.

Thanks!

By: laszlovl (lvl) 2020-03-03 13:38:07.025-0600

It's hard for me to post the exact dialplan I used to reproduce, because the whole dialplan is basically a wrapper around dialplan elements stored in a database. Would a SIP trace perhaps help equally?

By: Kevin Harwell (kharwell) 2020-03-03 13:59:53.925-0600

Yes a SIP trace would be good to have.

By: laszlovl (lvl) 2020-03-03 15:08:03.147-0600

Attaching a SIP trace.

Apart from a lot of goto/set spam, the target dialplan pretty much just executes a {{Proceeding()}}, {{Answer()}}, then {{Playback()}}.

By: Kevin Harwell (kharwell) 2020-03-03 16:03:39.374-0600

The problem appears to be Asterisk failing to send back the 200 OK sipfrag in the NOTIFY. Instead it's getting the following:
{noformat}
<--- Transmitting SIP request (857 bytes) to UDP:1.6.1.6:8065 --->
NOTIFY sip:phone_186347_0@1.6.1.6:38474;ob;alias=1.6.1.6~38474~1 SIP/2.0
Via: SIP/2.0/UDP 1.6.1.6:8066;rport;branch=z9hG4bKPj4c8e78b3-3757-467e-9a1b-7a8449795ba8
From: "Aa unit" <sip:201@1.6.1.6>;tag=7327871d-6ecb-4b84-9cb7-31fef1706837
To: <sip:phone_186347_0@acme01.exampledev.com>;tag=b6b470f4-4e5c-4cd9-93bf-8fd422953978
Contact: <sip:asterisk@1.6.1.6:8066>
Call-ID: b429f61a-94b6-4d47-8c15-719dbf745a13
CSeq: 32547 NOTIFY
Route: <sip:1.6.1.6:8065;lr;ftag=7327871d-6ecb-4b84-9cb7-31fef1706837;did=4a4.bfd>
Route: <sip:1.6.1.6:8060;lr>
Event: refer
Subscription-State: terminated;reason=noresource
Allow-Events: presence, dialog, message-summary, refer
Max-Forwards: 70
User-Agent: Acme PBX
Content-Type: message/sipfrag;version=2.0
Content-Length:    33

SIP/2.0 503 Service Unavailable
{noformat}
I am getting this too in my testing with Proceeding.

By: laszlovl (lvl) 2020-03-03 16:07:22.624-0600

Indeed, and this causes most (all?) phones to keep the line open on the transferer's side, even though the transfer has in reality long been completed.

The patch I submitted will make Asterisk send out the 200 OK sipfrag even when you've used {{Proceeding()}}.

By: Kevin Harwell (kharwell) 2020-03-03 16:08:11.372-0600

I tested your change by adding the line you added to my code as well:
{noformat}
progress->subclass = AST_CONTROL_ANSWER;
{noformat}
And I still had the problem. For me at least it's not entering that section of code. The frametype is a voice frame at this point, but the subclass is set to PROGRESS still whereas the code is checking for a subclass of '0'.

I wonder if the that second check needs to be there or one could check for a PROGRESS subclass too? For instance just removing the subclass check fixed it for me:
{noformat}
if (f->frametype == AST_FRAME_VOICE) {
....
{noformat}
But I haven't thought much through all the implications of doing that so might not be the most correct solution either.

By: laszlovl (lvl) 2020-03-03 16:11:32.798-0600

Did you apply the entire patch or only the {{progress->subclass = AST_CONTROL_ANSWER;}} line? The key element is removing the three {{progress->subclass = f->subclass.integer;}} lines. I'm running an Asterisk with the entire patch applied and can no longer reproduce the problem, and can see that the 200 OK sipfrag is now sent.

By: Kevin Harwell (kharwell) 2020-03-03 16:28:10.588-0600

oh yeah ha! that was it. I just added the one line, and didn't apply the whole patch. In the review for some reason my brain saw the added comments, but skipped over the deleted parts.

I see why your patch fixes it now. Okay makes much more sense.

By: laszlovl (lvl) 2020-03-03 16:29:21.669-0600

Yeah I get that, the diff's representation is certainly a bit misleading here. Good to hear :)

By: Friendly Automation (friendly-automation) 2020-03-05 11:03:54.443-0600

Change 13881 merged by Kevin Harwell:
res_pjsip_refer: ensure refer progress is still sent after Proceeding()

[https://gerrit.asterisk.org/c/asterisk/+/13881|https://gerrit.asterisk.org/c/asterisk/+/13881]

By: Friendly Automation (friendly-automation) 2020-03-05 11:04:16.347-0600

Change 13852 merged by Kevin Harwell:
res_pjsip_refer: ensure refer progress is still sent after Proceeding()

[https://gerrit.asterisk.org/c/asterisk/+/13852|https://gerrit.asterisk.org/c/asterisk/+/13852]

By: Friendly Automation (friendly-automation) 2020-03-05 11:04:33.023-0600

Change 13876 merged by Kevin Harwell:
res_pjsip_refer: ensure refer progress is still sent after Proceeding()

[https://gerrit.asterisk.org/c/asterisk/+/13876|https://gerrit.asterisk.org/c/asterisk/+/13876]

By: Friendly Automation (friendly-automation) 2020-03-05 11:04:47.860-0600

Change 13877 merged by Kevin Harwell:
res_pjsip_refer: ensure refer progress is still sent after Proceeding()

[https://gerrit.asterisk.org/c/asterisk/+/13877|https://gerrit.asterisk.org/c/asterisk/+/13877]

By: Joshua C. Colp (jcolp) 2020-04-14 05:12:26.739-0500

A user has reported an issue with NOTIFY messages going out[1] that may have been caused by this change. It is not yet confirmed, but another issue may be getting opened if it is.

[1] https://community.asterisk.org/t/sip-xfers-via-reinvite-refer-and-order-of-notifys/83572