Allow Caller to Exit Park

Hello Everyone,

I don’t have much experience with Asterisk, if anyone can help, i’ll appreciate it!

Parking lot with a timeout destination to a Queue.

What we are trying to accomplish:
Allow the caller to press a digit or digits while being parked that will send the caller to the timeout destination.

Can anyone provide some tips how to accomplish this?

Many thanks.

You may want to skip parking the caller and instead place them directly in the queue, queues support having a dialplan context associated with them to handle dialing extensions while waiting for an agent.

Thought of that already.
But park manager won’t work with this. Plus, I want anyone to be able to retrieve the call and all other park features.

Is there anyway to include in the park config that it should listen for DTMF, and once received it should go to the timeout destination?

I don’t believe that is possible to do with the Park application.

Understood. As mentioned, I’m no expert, so here I am with another question…

Is there a possibility to send the call to a custom dialplan before going to park which will set the call to listen the entire time for DTMF?

You could park a local channel, in which case any features that can accessed from Dial could be used.

Hi David, I know this is quite old, but we never found a proper solution to that and I want to revisit this.

Can you please elaborate on that?

During an active call I see both channels SIP/DEV1 and SIP/DEV2

testpbx*CLI> core show channels
Channel              Location             State   Application(Data)
SIP/101-00000082   (None)               Up      AppDial((Outgoing Line))
SIP/107-00000081     s@macro-dial-one:55  Up      Dial(SIP/101,,HhTtrb(func-ap

Where would I get the local channel?

Further testing, I see that non of the Dynamic Features are working while the caller is parked.

Maybe I am missing something?

Depends on which channel you are parking.

Looking at the example above, 107.

The initial extension called by 107 dials a local channel, with the /n option, and with features enabled. The local channel invokes the Queue application. When the call gets parked, it is the ;2 side of the local channel that gets parked, so the feature code can still act on the real incoming channel, which is bridged to the ;1 side, and not, itself, parked.

Thanks, I’ll look into it.

In the meantime, does anyone know if this intentionally by design to now allow these to be dialed while parked?

Dynamic features only work while in Dial() and bridging to someone else. It’s just the way the implementation works.

1 Like

Understood, Thanks.

When you say bridging to someone else, you indicated that in a holding bridge it won’t work as well. Is that correct?

That is correct. They don’t apply there.

Thanks. I’ll see what I can come up with.

I’m trying a bit of a different approach.

Per the documentation:

d - Allow the calling user to dial a 1 digit extension while waiting for a call to be answered. Exit to that extension if it exists in the current context, or the context defined in the EXITCONTEXT variable, if it exists.

So I’m trying the below

exten => 613,1,Noop(Test 613)
exten => 613,n,Answer()
exten => 613,n,Set(__EXITCONTEXT=s@my-exit-context)
exten => 613,n,Dial(local/s@play-moh-test,,d)

exten => s,1,Noop()
exten => s,n,DumpChan()
exten => s,n,MusicOnHold(default)

But it does not send the call to the exit context.

 == Using SIP RTP TOS bits 184
  == Using SIP RTP CoS mark 5
       > 0x7f46b3a6d100 -- Strict RTP learning after remote address set to: my.remote.ip:12050
    -- Executing [613@from-internal:1] NoOp("SIP/64066-000000e4", "Test 613") in new stack
    -- Executing [613@from-internal:2] Answer("SIP/64066-000000e4", "") in new stack
       > 0x7f46b3a6d100 -- Strict RTP switching to RTP target address my.remote.ip:12050 as source
    -- Executing [613@from-internal:3] Set("SIP/64066-000000e4", "__EXITCONTEXT=s@my-exit-context") in new stack
    -- Executing [613@from-internal:4] Dial("SIP/64066-000000e4", "local/s@play-moh-test,,d") in new stack
    -- Called local/s@play-moh-test
    -- Executing [s@play-moh-test:1] NoOp("Local/s@play-moh-test-00000026;2", "") in new stack
    -- Executing [s@play-moh-test:2] DumpChan("Local/s@play-moh-test-00000026;2", "") in new stack

Dumping Info For Channel: Local/s@play-moh-test-00000026;2:
Name=               Local/s@play-moh-test-00000026;2
Type=               Local
UniqueID=           1605701175.309
LinkedID=           1605701175.307
CallerIDNum=        64066
CallerIDName=       Desk1
ConnectedLineIDNum= 613
DNIDDigits=         (N/A)
RDNIS=              (N/A)
Language=           en
State=              Ring (4)
Rings=              0
NativeFormat=       (ulaw)
WriteFormat=        ulaw
ReadFormat=         ulaw
RawWriteFormat=     ulaw
RawReadFormat=      ulaw
WriteTranscode=     No
ReadTranscode=      No
1stFileDescriptor=  -1
Framesin=           0
Framesout=          0
TimetoHangup=       0
ElapsedTime=        0h0m0s
BridgeID=           (Not bridged)
Context=            play-moh-test
Extension=          s
Priority=           2
Application=        DumpChan
Data=               (Empty)
Blocking_in=        (Not Blocking)

    -- Executing [s@play-moh-test:3] MusicOnHold("Local/s@play-moh-test-00000026;2", "default") in new stack
    -- Started music on hold, class 'default', on channel 'Local/s@play-moh-test-00000026;2'
       > 0x7f46b3a6d100 -- Strict RTP learning complete - Locking on source address my.remote.ip:12050
[2020-11-18 07:06:25] DTMF[79716][C-000000d5]: channel.c:3987 __ast_read: DTMF begin '1' received on SIP/64066-000000e4
[2020-11-18 07:06:25] DTMF[79716][C-000000d5]: channel.c:3998 __ast_read: DTMF begin passthrough '1' on SIP/64066-000000e4
[2020-11-18 07:06:25] DTMF[79717][C-000000d5]: channel.c:3987 __ast_read: DTMF begin '1' received on Local/s@play-moh-test-00000026;2
[2020-11-18 07:06:25] DTMF[79717][C-000000d5]: channel.c:3998 __ast_read: DTMF begin passthrough '1' on Local/s@play-moh-test-00000026;2
[2020-11-18 07:06:25] DTMF[79716][C-000000d5]: channel.c:3873 __ast_read: DTMF end '1' received on SIP/64066-000000e4, duration 100 ms
[2020-11-18 07:06:25] DTMF[79716][C-000000d5]: channel.c:3924 __ast_read: DTMF end accepted with begin '1' on SIP/64066-000000e4
[2020-11-18 07:06:25] DTMF[79716][C-000000d5]: channel.c:3962 __ast_read: DTMF end passthrough '1' on SIP/64066-000000e4
[2020-11-18 07:06:25] DTMF[79717][C-000000d5]: channel.c:3873 __ast_read: DTMF end '1' received on Local/s@play-moh-test-00000026;2, duration 100 ms
[2020-11-18 07:06:25] DTMF[79717][C-000000d5]: channel.c:3924 __ast_read: DTMF end accepted with begin '1' on Local/s@play-moh-test-00000026;2
[2020-11-18 07:06:25] DTMF[79717][C-000000d5]: channel.c:3962 __ast_read: DTMF end passthrough '1' on Local/s@play-moh-test-00000026;2

What am I missing?


This is an extension, not a context. Also s is not a valid DTMF digit, so they couldn’t dial the s extension in that context even if you only provided the context.

1 Like

Got it.

I changed it to

exten => 613,n,Set(__EXITCONTEXT=my-exit-context)

And now, when I pressed 1 it went to extension 1 in my-exit-context

I will continue working with this and report back

Hey everyone,

Following the approach of using the Dial application along with the d option. I can say that what I wanted to accomplish is almost considered… accomplished…

I must admit that I am surprised that this is working, although not 100% as I wanted, but as far as I tested, nothing breaks or got broken.

I also want to point out, that it seems like literally everything is doable with Asterisk, maybe you have to combine a couple of applications/functions and at the end using a “hacky” method, but it’s working :slight_smile:

So, here’s the dialplan: (using FreePBX)
We have 4 “parking” extensions with hints. 8501, 8502, 8503 & 8504

exten => _850[1-4],hint,Custom:CPark${EXTEN:-1}
exten => _850[1-4],1,Noop(Entering Custom Park Context. DEBUG: hint- ${DEVICE_STATE(Custom:CPark${EXTEN:-1})})
exten => _850[1-4],n,GotoIf($["${DEVICE_STATE(Custom:CPark${EXTEN:-1})}" = "INUSE"]?cpark-pickup,${EXTEN},1)
exten => _850[1-4],n,Playback(pbx-invalidpark)
exten => _850[1-4],n,Hangup()

exten => _850[1-4],1,Noop(Checking if we can transfer the call or if there is an existing call parked already. DEBUG: The hint is ${DEVICE_STATE(Custom:CPark1)})
exten => _850[1-4],n,Set(_CPark_Parker=${PICKUPMARK})
exten => _850[1-4],n,Set(_CPark=CPark${EXTEN:-1})
exten => _850[1-4],n,GotoIf($["${DEVICE_STATE(Custom:${CPark})}" = "NOT_INUSE"]?proceed)
exten => _850[1-4],n,Noop(Seems like there's a call there. We will now return the call to the Parker. the parker is ${CPark_Parker})
exten => _850[1-4],n,Goto(from-internal,${CPark_Parker},1)
exten => _850[1-4],n(proceed),Goto(cpark-park-calls,${EXTEN},1)

exten => _850[1-4],1,Noop(Parking call....)
exten => _850[1-4],n,Set(__EXITCONTEXT=cpark-exit-context)
exten => _850[1-4],n,Set(DEVICE_STATE(Custom:${CPark})=INUSE)
exten => _850[1-4],n,Answer()
exten => _850[1-4],n,Dial(local/${EXTEN}@play-park-moh,300,d)
exten => _850[1-4],n,Noop(Park timed out. Returning call to parker. The parker is: ${CPark_Parker})
exten => _850[1-4],n,Set(DEVICE_STATE(Custom:${CPark})=NOT_INUSE)
exten => _850[1-4],n,Goto(from-internal,${CPark_Parker},1)
exten => h,1,Noop(Entering the Hangup exten)
exten => h,n,GotoIf($["${DIALSTATUS}" = "ANSWER"]?skip)
exten => h,n,Noop(Caller left park, hanging up the call and resetting the BLF state)
exten => h,n,Set(DEVICE_STATE(Custom:${CPark})=NOT_INUSE)
exten => h,n(skip),Hangup()

exten => _850[1-4],1,Noop(Starting the park MOH...)
exten => _850[1-4],n,MusicOnHold(CParkMOH)

exten => _850[1-4],1,Noop(Entering context to pickup-retrieve a parked call...)
exten => _850[1-4],n,Set(DEVICE_STATE(Custom:CPark${EXTEN:-1})=NOT_INUSE)
exten => _850[1-4],n,Pickup(${EXTEN}@play-park-moh)
exten => _850[1-4],n,Hangup()

exten => 1,1,Noop(In exit context)
exten => 1,n,Set(DEVICE_STATE(Custom:${CPark})=NOT_INUSE)
exten => 1,n,Goto(from-internal,${CPark_Parker},1)
exten => 1,n,Hangup()

Sooo… As mentioned, this works. However, there are some improvements I want to implement.

  1. When retrieving a call, I want to play a beep on both legs of the call.
  2. Now, if the the parkee hangs up while parked, it calls the h extension in cpark-park-calls which is good. The problem is that it also calls the h extension after he call was retrieved from park and completed. Is there a way to avoid that?
  3. Can anyone tell if I might run into any other issues?

Thank you very much

EDIT: Forgot to include the exit context