Determine if extension is in queue call

Hello everybody,

is there a way of a clean, non-hacky check if extension is in any queue call using diaplan vars / functions? Maybe by using some of the existing Freepbx’s agis or DB entries?

(i am trying to flag an outbound call while doing sip attended transfer of a queue call to external party-- but can’t differentiate it from normal, standalone calls. To my understanding, an outbound call while doing attended transfer begins just as any other regular, stand-alone outbound call and I can’t distinguish between them. One way would be to check if this same extension that is making an outbound call is already in queue call).

We are using asterisk 18.21, device and user mode and Freepbx 15.

Big thanks in advance.

Best regards,

I got a brilliant idea (i know :man_facepalming:) that challenge could be solved by use of shared variable where endopoint would share a variable with itself, not with full channel name, but with prefix only.


Endpoint SIP/XXXX answers a queue call on channel SIP/XXXX-YYYYYYYY and has a variable FROMQ=true. Based on that, in Dial U subroutine, it creates a shared variable SHARED(FROMQ, SIP/XXXX)=true.

so… when the same endpoint puts existing incoming queue call on hold and tries to do an attended transfer, I wait for that new, fresh, parallel call from same endpoint in Dial B subroutine, channel SIP/XXXX-ZZZZZZZZ, where I check for presence of SHARED(FROMQ, SIP/XXXX)=true. If it’s present, then do __FROMQ=true for that new channel so the var will be inhertied to the new channel.

Real life:

It doesn’t work in 90% of cases and I don’t understand why (bear with me, I am just a padawan). My first thought was that shared variable gets destroyed before used on outbound call (part of attended transfer), but first call is still there (on hold), which is also seen in call log.

Maybe I am using the shared function with prefixes wrong? Or misunderstand how it’s supposed to work?

Dialplan part of Dial U subroutine:

exten => s,n,ExecIf($[“${CHANNEL:0:3}” = “SIP” & “${FROMQ}” = “true”]?Set(SHARED(ECHOFROMQ,${CUT(CHANNEL,-,1)})=true))

Call log part of Dial U subroutine:

-- Executing [s@UDIAL:9] ExecIf("SIP/1002-00000144", "1?Set(SHARED(ECHOFROMQ,SIP/1002)=true)") in new stack
-- Executing [s@UDIAL:10] NoOp("SIP/1002-00000144", "SHAREDECHOFROMQ is true") in new stack

Dialplan part of dial B subroutine:

exten => s,n,NoOp(CUT CHANNEL is ${CUT(CHANNEL,-,1)})
exten => s,n,DumpChan()
exten => s,n,ExecIf($[“${CHANNEL:0:3}” = “SIP” & “${SHARED(ECHOFROMQ,${CUT(CHANNEL,-,1)})}” = “true”]?Set(__FROMQ=true))

Call log part of Dial B subroutine:

– Executing [s@BDIAL:1] NoOp(“SIP/1002-00000145”, “BDIAL”) in new stack
– Executing [s@BDIAL:2] NoOp(“SIP/1002-00000145”, “CHANNEL is SIP/1002-00000145”) in new stack
– Executing [s@BDIAL:3] NoOp(“SIP/1002-00000145”, “MASTER CHANNEL is SIP/1002-00000145”) in new stack
– Executing [s@BDIAL:4] NoOp(“SIP/1002-00000145”, "FROMQ is ") in new stack
– Executing [s@BDIAL:5] NoOp(“SIP/1002-00000145”, “CUT CHANNEL is SIP/1002”) in new stack
– Executing [s@BDIAL:6] NoOp(“SIP/1002-00000145”, "SHAREDFROMQ is ") in new stack
– Executing [s@BDIAL:7] DumpChan(“SIP/1002-00000145”, “”) in new stack
– Executing [s@BDIAL:8] ExecIf(“SIP/1002-00000145”, “0?Set(__FROMQ=true)”) in new stack

Can anyone shed some light on that?

(I hope I used endpoint and extension expressions right this time. :wink: )

Big thanks in advance.

Do the prebuilt hints/subscriptions in FreePBX show this? Reports>Asterisk Info>Subscriptions

Thanks for your idea and continued help.

I’ve checked that one and it shows that extension (for example 305@ext-local) is busy when in the call, but not more than that.

In current form it doesn’t really help because I know that extension is in the call (and checking the state during the process of attended transfer always show in use), but don’t know if it is in a queue call.

It might be be possible to configure it.

I was thinking of AstDB and adding a custom header to SIP (idea of TheMark), but SHARED variables look very attractive solution, except they don’t work. :slight_smile:

1 Like

What about adding something like:

exten => 1234,1,Answer()
same => n,Set(FROM=${CUT(PJSIP_HEADER(read,From),@,1)})
same => n,Set(EXT=${CUT(FROM,:,2)})
same => n,NoOp(ext: ${EXT})

You could set a variable to QUEUE or EXTENSION with the LINKEDID or some other variable for you to reference later in your dialplan.

Idea is good, but to my possibly wrong understanding, when doing attended transfer:

  1. the new, parallel call that agent makes to check if target party C is free and ok to take the call is a fresh, standalone call and this header mod wouldn’t help as it wouldn’t be there when this new call starts
  2. when SIP attended transfer is made, the header mod might kick in, but to my knowledge there is no way to interact with dialplan at point in time when SIP attended transfer is made
  3. it’s too late to interact with channel at hangup as there is no guarantee that other channel where I’d like to write data to will not be destroyed before the one I am running dialplan on

I like the idea of shared variables, but they don’t work for me in prefix mode for some reason… so I settled on AstDB. It works in lab, but will need to stand the test of time in production.

1 Like

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.