Summary:ASTERISK-21410: Park() application never returns in some cases
Reporter:Red (redwolf890)Labels:
Date Opened:2013-04-11 08:51:12Date Closed:2013-04-12 08:41:37
Versions: Frequency of
Environment:CentOS 5.5 2.6.18-308.13.1.e15 x86_64Attachments:
Description:In my setup, I manually manage call parking and unparking.  This requires bookkeeping to be done in the priorities that immediately _follow_ the actual call to the Park() application.  However, under no circumstances are those priorities ever executed.

If the parking spot times out, Park correctly routes to the timeout context.  However, if a timeout is neither reached nor is the call unparked the Park NEVER returns.  An example of this is A calls B, B parks A, A hangs up before timeout.

The following dialplan code is an example:
;   This context manages parking of calls and
;   access to the parking lot.
 include => parkedcalls  ;none of the features.conf stuff seems to work so this isn't really necessary
 exten => _700, 1, NoOp(=-=-=- ${EXTEN}@${CONTEXT} -=-=-=)
 ;Check out a free parking spot and associate it
 ; with a given account, then park it:
 exten => _700, n, Set(PARKINGEXTEN=${VOIP_GetAvailableParkingSpot()})
 exten => _700, n, Set(VOIP_DeleteAvailableParkingSpot(${PARKINGEXTEN})=)
 exten => _700, n, Set(VOIP_AddParkedCall(${PARKINGEXTEN},${HASH(account,id)})=)
 ; Here is where the problem is:
 exten => _700, n, Park(45000,call-park-timeout,${PARKINGEXTEN},1,,)
 exten => _700, n, NoOp(Nothing after the above park ever gets run.)
 exten => _700, n, NoOp(Either the timeout context is routed to)
 exten => _700, n, NoOp(or Park() flakes out and never returns.  Bug?!)
 exten => _700, n, Hangup()
Comments:By: Jonathan Rose (jrose) 2013-04-11 12:58:36.426-0500

This doesn't show that Park isn't returning. This only demonstrates that the call that was parked isn't proceeding in the dial plan, and this is expected behavior. If you hangup while an application is running, then on returning from the application when the your call will get sent to to h extension if it exists. It doesn't go on to the next priority. That's standard behavior for most things. From there you can perform your various NoOp messages (or maybe something less trivial, I don't know, whatever floats your boat). If you want a little more control than that, you should consider looking into a new feature for Asterisk 11 called hangup handlers which you can read more about here: https://wiki.asterisk.org/wiki/display/AST/Hangup+Handlers

Generally speaking, you should look at Park as a terminal extension. Under normal circumstances, the parkee will either stay in the parking space until it times out and then does the usual comeback stuff (which will always involve going to a different extension) or else the parkedcall application will be used to retrieve it and from there you basically (not quite, just basically. The internals of this are weird in current implementations of parking) have a Dial from the retriever to the parkee (ex-parkee at this point, but you get the idea). If I'm not mistaken about how it works, the parkee will no longer actually be in the PBX at this point and the retriever will essentially own the call, even if the original dial that resulted in the park in the first place belonged to the parkee.

By: Richard Mudgett (rmudgett) 2013-04-11 13:10:43.905-0500

Since the parked call hung up you should expect to see the h exten being executed if you have one.  You will not see extension priorities after Park being executed when this happens.  The behavior you are describing is as expected and *not a bug*.

Trying to manually manage the parking slots is not going to work very well because of the many exception conditions possible.  All you really need to do for parking is to configure it in features.conf and include the parkedcalls context in your dialplan.  Many channel driver configuration files also have a parkinglot option to specify a default parking lot to use for incoming calls.

Look at the features.conf.sample file for parking configuration options documentation.

By: Red (redwolf890) 2013-04-11 13:22:41.401-0500

It is mentioned to handle the h extensions, but I seem to recall that during dev for Park() h was captured within the application because exposing it causes crash/stability issues.  So I cannot handle h in the case the the parkee hangs up.  And yes, something less trivial is happening than those NoOps after park, I just didn't want to expose it.

Also there are a couple issues with just using features.conf to setup parking.  First is that with the below configs under [general], call parking never worked in my setup (a separate problem altogether).  Secondly, supposing I could somehow configure parking this way, there is nothing to prevent cross-account unparking (company A user parks a call in 701, company B user accidentally unparks it).  And yes I understand I can _manually_ specify different lots, but that would require carving up extensions 701-799 between my ever growing list of accounts.

; Setting these values has no impact, and in no way
; enables parking in my setup.  If it did it would
; still not cover cross-account unparking security
; issues.
parkext => 700
parkpos => 701-799
context => parkedcalls
comebacktoorigin => yes
; Also it was unclear where to place the
; "include => parkedcalls" in my dialplan

By: Richard Mudgett (rmudgett) 2013-04-11 13:50:04.369-0500

The [general] section sets up the default parking lot.  If you create multiple parking lots you can specify which tennant can go into which parking lot and which tennant can pickup parked calls.  Most parking options can be set per parking lot to isolate the parkinglots between tennants:

parkext = 700
parkpos = 701-799
context = pl_a
comebacktoorigin = yes

parkext = 700
parkpos = 701-799
context = pl_b
comebacktoorigin = yes

parkext = 700
parkpos = 701-799
context = pl_c
comebacktoorigin = yes

; Tennant A cannot access parkinglot_b and parkinglot_c because it does not include those parking contexts.
include => pl_a

include => pl_b

include => pl_c

By: Red (redwolf890) 2013-04-11 14:28:50.079-0500

I have two issues that prevent me from doing it this way.  The first is that using the default setup (indicated above) call parking never actually worked to begin with.  Secondly, I have 200 tenants with new ones coming on every day.  In my extensions.conf I can't dedicate a context (and associated include => pl_n) to a single customer because everything is done in generic terms (because there are so many accounts).  It would be nearly impossible to keep adding in new parking lots statically all the time.

So two questions: why does my default setup in features.conf (above) not work at all?  and   how does dynamic parking lot creation work (in 1.8)?


By: Richard Mudgett (rmudgett) 2013-04-11 19:21:58.728-0500

This is turning into a support issue which is not what the issue tracker is for.  The asterisk-users list or IRC is better for this discussion.

It is hard to say why the default parking setup is not working for you when you have not described how it is not working.

Dynamic parking lots are created on the fly.  If they are enabled, you request to park a call into a named parking lot.  If that parking lot does not already exist it is created using the channel variables described in the Park application documentation.
PARKINGDYNCONTEXT is equivalent to features.conf context
PARKINGDYNEXTEN is equivalent to features.conf parkext
PARKINGDYNPOS is equivalent to features.conf parkpos