Orphaned parked call returns to PRI channel in stead of extension

In my setup, I have connected a PRI PBX to Asterisk. The PBX-extensions are identified by their DID numbers, and share (pool) the 30 channels in the E1 PRI connection. So there is no fixed relation between the channelnumber and the extensionumber.

The PBX is connected to span 2 consisting of channel 32-46,48-62

The PBX-extension in this case is 915, defined as a custom extension.

When I park a call to the PBX-extension, and it times out, it returns to the channelnumber in stead of the extensionnumber.

Since there is no fixed relation between the channel and the extension, the PBX does not know how to route it, and it ends up at the switchboard.

It can be even worse, when at the moment of the call-back the original channel is in use, which might be by an different extension.

A part of the log file

The most significant lines are
17:00:20] VERBOSE[463] logger.c: == Parked IAX2/MYTRUNK on 71@parkedcalls. Will timeout back to extension [from-did-direct] 915, 1 in 45 seconds

And

17:01:05] VERBOSE[28432] logger.c: – Added extension ‘Zap/32’ priority 1 to park-dial
17:01:05] VERBOSE[28432] logger.c: == Timeout for IAX2/MYTRUNK parked on 71. Returning to park-dial,Zap/32,1

The log file

17:00:03] VERBOSE[463] logger.c: – Zap/32-1 answered IAX2/MYTRUNK
17:00:13] VERBOSE[463] logger.c: – Started music on hold, class ‘default’, on IAX2/MYTRUNK
17:00:13] VERBOSE[463] logger.c: – <Zap/32-1> Playing ‘pbx-transfer’ (language ‘en’)
17:00:20] VERBOSE[463] logger.c: – Stopped music on hold on IAX2/MYTRUNK
17:00:20] VERBOSE[463] logger.c: – Started music on hold, class ‘default’, on IAX2/MYTRUNK
17:00:20] VERBOSE[463] logger.c: == Parked IAX2/MYTRUNK on 71@parkedcalls. Will timeout back to extension [from-did-direct] 915, 1 in 45 seconds
17:00:20] VERBOSE[463] logger.c: – <Zap/32-1> Playing ‘digits/7’ (language ‘en’)
17:00:21] VERBOSE[463] logger.c: – <Zap/32-1> Playing ‘digits/1’ (language ‘en’)
17:00:22] VERBOSE[463] logger.c: – Added extension ‘71’ priority 1 to parkedcalls
17:00:22] DEBUG[463] chan_zap.c: Set option AUDIO MODE, value: ON(1) on Zap/32-1
17:00:22] DEBUG[463] chan_zap.c: Not yet hungup… Calling hangup once with icause, and clearing call
17:00:22] DEBUG[463] chan_zap.c: Set option AUDIO MODE, value: OFF(0) on Zap/32-1
17:00:22] VERBOSE[463] logger.c: – Hungup 'Zap/32-1’
17:00:22] VERBOSE[463] logger.c: == Spawn extension (macro-dial, s, 7) exited KEEPALIVE in macro ‘dial’ on 'IAX2/MYTRUNK’
17:00:22] VERBOSE[463] logger.c: == Spawn extension (macro-exten-vm, s, 9) exited KEEPALIVE in macro ‘exten-vm’ on 'IAX2/MYTRUNK’
17:00:22] VERBOSE[463] logger.c: == Spawn extension (from-did-direct, 915, 1) exited KEEPALIVE on 'IAX2/MYTRUNK’
17:01:05] VERBOSE[28432] logger.c: – Stopped music on hold on IAX2/MYTRUNK
17:01:05] VERBOSE[28432] logger.c: – Added extension ‘Zap/32’ priority 1 to park-dial
17:01:05] VERBOSE[28432] logger.c: == Timeout for IAX2/MYTRUNK parked on 71. Returning to park-dial,Zap/32,1
17:01:05] VERBOSE[472] logger.c: – Executing [Zap/32@park-dial:1] Dial(“IAX2/MYTRUNK”, “Zap/32||t”) in new stack
17:01:05] VERBOSE[472] logger.c: – Requested transfer capability: 0x00 - SPEECH
17:01:05] VERBOSE[472] logger.c: – Called 32
17:01:05] DEBUG[28451] chan_zap.c: Queuing frame from PRI_EVENT_PROCEEDING on channel 0/1 span 2

Is there some way I can get Asterisk to dial back by extension in stead of by channel in case of an orphaned parked call, apart from ‘hacking’ the source, which is currently a bit out of my league?

Had a similar problem last week. Found it to be the way the parked call was transferred to the Parking Lot. If I transferred using Attended Option,(*2 Here) the parked call would behave as you describe.

If I used Blind transfer code (## in our system) the call will return to the parking extension.

Just make sure you’re transferring to the parking lot as an unattended transfer.

Bill

Having just enabled the standard parking module, I tested it by phoning the DID of my ZAP extension from my cell phone, pick up my ZAP extension, blind transfered the call to the parking extension, listened to the number of the parking lot, hang up the ZAP extension, and then waited for the parking time to time out. When it did, I heard the call ring on the switchboard (which receioves all unspecified calls) in stead of my own extension, and on the asterisk CLI I saw that the ZAP channel (ZAP/32) was called in stead of the extension (915)

Then I disconnected from my cell phone, examined the log file, and posted this message.

Thanks for your reaction, but it looks our system behaved differently.

In the log of that ticket you also see the channel (SIP/120) instead of the extension (120) being returned

radpeter,
the way that the Asterisk Parking function works is tied to the ‘device’ that parked the call. For example, if the phone you park a call from is SIP/222 then Asterisk is going to dynamically generate an extension in the context “park-dial” that looks like:

exten => “SIP/222”,1,Dial(SIP/222,t) ;(*)

ithe “SIP/222” is pseudo code and really means extension SIP/222 and not extension SIP with CID 222. Thanks radpeter for clarifying this below.[/i]

And what happens internally is it jumps to:

park-dial,SIP/222,1

when it times out. So if you have custom extensions that are going through dialplan, the current implementation of the Asterisk park function is not going to work and is going to do what you encountered. It would require a modification of the Asterisk parking function to do what you are trying to do if I understand it correctly.

Afraid to step on the wrong foot, but

is this dynamically generated line correct?

If I look at http://www.voip-info.org/tiki-index.php?page=Asterisk%20config%20extensions.conf

The line

exten => SIP/222,1,Dial(SIP/222,t)

means
if the dialed extension=SIP and the callerid=222, then Dial(SIP/222,t)

aka as the ex-girlfriend logic.

If you jump to a line, is the dialpattern/extension validated or is it executed unconditionally?

Did you perhaps intend the
exten => SIP/222,1,Dial(SIP/222,t)

As an example of a bad line generated in case of a custom extension?

Similar lines are generated in case of a genuine SIP extension.

radpeter,

you are correct that my example is misleading and that the syntax if put in extensions.conf would imply extension SIP and CID 222. So I’m not even sure if you could generate the same extension in extensions.conf that it dynamically generates. So using ‘pseudo notation’ - in my example, it does in fact generate:

exten => “SIP/222”,1,Dial(SIP/222,t)

where the quotes mean that is literally the extension. If you do a “show dialplan park-dial” or in 1.4 “dialpan show park-dial” you will see what I am referring to (it is only there if the call has been parked and returned recently). The interesting thing to note is, when using the exten/cid format - the “dialplan show” will not even show the cid portion (at least on 1.2) but that is not relevant to this discussion.

So unfortunately, the behavior is still as I described and the park application is working as the authors intended in your situation.

Thank you for your reaction and explanation.

I have tried to find the source with the actual implementation but could not find it on short notice.

Looking at the implementation in app_parkandannounce.c, which also deals with parking calls, I do not totally agree but this is probably not the proper place to discuss the actual implementation.

Once again, thank you for your involvement.

res_features.c is where the parking code is located. Run some tests, I’m pretty sure what I describe is the case. (As I have done patches to the parking code to do other behavior such as force parked calls to not return to the device that parked them but instead to a configurable destination).

so my possibilities to test are limited. However, I have looked into the code in res_features.c reviison 100626 Jan 28 19:26.

I might be barking up the wrong tree, but it looks like the ‘true’ branch from the if (pu->peername[0]) on line 1681 of version 100626 is causing my problems.

If the ‘false’ branch on line 1699 was executed instead, as it was perhaps originally allways (judging by the wordin of the ast_verbose message on line 398), it would use the ‘old’ way of returning me to me to my original context, extensions and priority.

When we want to keep the True branch, it might need fixing.

In the True branch the channel identifier, which is stored in peername, is parsed and molded to a.o. the dialstring. And this while the proper dialinformation for an extension is usually present in freepbx, in devinfo_dial . While this information is probably not allways available in Asterisk, since some people don’t use freepbx, the dialstring is also available in the hints (CLI show hints)

So, it might be possible to extract the dial information from the hints list and using it as argument for the ast_add_extension2 on line 1695.

If I’m correct, hints are a fairly recent addition, so the solution doesn’t work for older versiosn which don’t support hints.

HTH

Peter

“Fools rush in where angels fear to tread” Alexander Pope

My suggestion - fire up a vmware image, attach a couple phones to it, make the changes that look like it will fix the issue, and give it a test. You won’t have your real PRI setup, but you can simply look at the dialstring that is being generated or otherwise instrument your changes with enough debug statements to the log to determine if it looks like it is doing the right thing. If it is really doing the right thing, you will see it at the CLI because it should re-run through the normal dialplan to get to the extension.

and this is used in the 24/7 production environment.

I might be able to set up a system with only SIP phones, but since chanennl and dialstring of aSIP phone are usually the same, like SIP/200, the problem doesn’t manifest itself there.

The parker needs to be a zaptel connected device.

I understand, I’m suggesting you setup a vmware with just sip phones (or softphones). You can try your modifications on that system and learn a lot. If you setup in deviceanduser mode, and create an extension with multiple devices, and get your patch working, then the timedout call will ring both devices instead of just the physical device that called it. If you can get that working, then the patch will probably accomplish what you want on the real system.