[Home]

Summary:ASTERISK-24267: Queue variables associated with setinterfacevar, setqueueentryvar, setqueuevar are not passed to local channel
Reporter:Mitch Claborn (mclaborn)Labels:
Date Opened:2014-08-25 10:33:16Date Closed:2014-12-24 15:28:59.000-0600
Priority:MajorRegression?Yes
Status:Closed/CompleteComponents:Applications/app_queue Channels/chan_local
Versions:SVN 12.5.0 Frequency of
Occurrence
Constant
Related
Issues:
Environment:Ubuntu 12.04 64 bit Asterisk 12.5 compiled from sourceAttachments:( 0) v11.log
( 1) v12.log
Description:Various queue related variables are not being passed to the local channel when invoked from an AMI action.  This worked fine in 11.1.  I've tried the local channel with and without the /n flag.

None of the following variables are present:
QUEUESRVLEVELPERF
QUEUESRVLEVEL
QUEUEABANDONED
QUEUECOMPLETED
QUEUETALKTIME
QUEUEHOLDTIME
QUEUECALLS
QUEUESTRATEGY
QUEUEMAX
QUEUENAME
QEORIGINALPOS
QEHOLDTIME
MEMBERREALTIME
MEMBERDYNAMIC
MEMBERPENALTY
MEMBERLASTCALL
MEMBERCALLS
MEMBERNAME
MEMBERINTERFACE

queue definition:
{noformat}
[StandardQueue](!)
musicclass=default
strategy=leastrecent
joinempty=no
leavewhenempty=yes
ringinuse=no
announce-frequency = 30
min-announce-frequency = 15
announce-holdtime = yes|no|once
announce-position = limit
announce-position-limit = 5
announce-round-seconds = 10
setinterfacevar = yes
setqueueentryvar = yes
setqueuevar = yes
wrapuptime=2
timeout = 16
autopause=yes  
;autopausedelay=30
autopausebusy=yes
autopauseunavail=yes
reportholdtime=no

[sales](StandardQueue)
{noformat}

dial plan:
{noformat}
[callmenow]
exten => s,1,NoOp(callmenow: Queue without answer)
 same =>n,Queue(sales,Rtc)
 
[dial-to-customer]
exten => s,1,NoOp(dial-to-customer channel=${CHANNEL(name)})
same =>n,DumpChan()
{noformat}

AMI action
{noformat}
Action: Originate
Channel: Local/s@callmenow/n
Context: dial-to-customer
Exten: s
Priority: 1
Async: true
Variable: MMCALLMENOWID=107
Timeout: 999999
Callerid: Call Me Now <778>
{noformat}



Comments:By: Rusty Newton (rnewton) 2014-09-16 20:16:21.684-0500

I just tested 11 svn 423210 vs 12 svn 423172. The behavior appears identical.

Note I had to make some changes to your configuration to attempt reproduction.

In queues.conf:

{noformat}
joinempty=yes
leavewhenempty=no
{noformat}

and the dialplan needed an answer:

{noformat}
[callmenow]
exten => s,1,NoOp(callmenow: Queue without answer)
 same => n,Answer()
 same => n,Queue(sales,Rtc)
{noformat}

Can you provide an Asterisk log with debug showing the behavior in 11 and 12 when you reproduce it?


By: Mitch Claborn (mclaborn) 2014-09-17 11:52:51.317-0500

Adding the Answer() changes the whole process. With the Answer() in there, the dial to customer is attempted right away, rather than waiting for the queue member to answer, defeating the whole purpose.  

Log files coming shortly without the Answer().

By: Mitch Claborn (mclaborn) 2014-09-17 11:54:24.640-0500

V12 Log file - variables are missing.

By: Mitch Claborn (mclaborn) 2014-09-17 12:13:27.159-0500

V11 log.  The queue variables are present.

By: Mitch Claborn (mclaborn) 2014-09-17 12:27:05.468-0500

I realize that I sent a truncated version of the dialplan earlier.  A more complete version is below.  The DumpChan() application doesn't show the queue variables in either version (which is strange, because I thought I saw it there before, but I must be mistaken.)

It is the use of the MEMBERINTERFACE and MEMBERNAME variables that is causing me grief.

I've attached the v11 and v12 logs.

In v11 I see
{noformat}
DEBUG[2588][C-00000000] pbx.c: Result of 'MEMBERINTERFACE' is 'SIP/mlcm800'
{noformat}

but v12 shows
{noformat}
DEBUG[9676][C-0000000a] pbx.c: Result of 'MEMBERINTERFACE' is NULL
{noformat}

Updated dial plan
{noformat}
[callmenow]
exten => s,1,NoOp(callmenow: Queue without answer)
 same =>n,Queue(sales,Rtc)
 
[dial-to-customer]
exten => s,1,NoOp(dial-to-customer channel=${CHANNEL(name)})
 same =>n,Set(ODBC_CALLMENOW_PICKED_UP(${MMCALLMENOWID})=fred)
 same =>n,Wait(1)
 same =>n,Playback(custom/callmenow-announce)
 same =>n,GoSub(sub-outbound_caller_id,start,1)
 same =>n,Set(MMCUSTOMER_NUMBER=${ODBC_CALLMENOW_GET_NUMBER(${MMCALLMENOWID})})
 same =>n,Set(__CALLMENOW_ID=${MMCALLMENOWID})
 same =>n,Set(__CALLMENOW_NUMBER=${MMCUSTOMER_NUMBER})
 same =>n,Set(__CALLMENOW_MEMBERINTERFACE=${MEMBERINTERFACE})
 same =>n,Set(__CALLMENOW_MEMBERNAME=${MEMBERNAME})
{noformat}


By: Rusty Newton (rnewton) 2014-09-23 19:16:29.069-0500

Thanks. I was attempting to understand the simplest way to reproduce the issue. I was able to reproduce. All that is needed is a few references for the local channel to execute to observe the lack of data in those variables.

{noformat}
[callmenow]
exten => s,1,NoOp(callmenow: Queue without answer)
 same =>n,Queue(sales,Rtc)

[dial-to-customer]
exten => s,1,NoOp(dial-to-customer channel=${CHANNEL(name)})
same => n,NoOp(MEMBERINTERFACE: ${MEMBERINTERFACE})
same => n,NoOp(MEMBERNAME: ${MEMBERNAME})
{noformat}

I also don't know why DumpChan doesn't show the variables in either version, though I've personally never used DumpChan before so I'm not used to it's behavior.

By: Rusty Newton (rnewton) 2014-12-24 12:05:13.566-0600

A note that - however this issue is resolved - we should fix the documentation to be very clear on when and where these variables get set. That is, the documentation for the three options:

{noformat}
;setinterfacevar=no
<snip>
;setqueueentryvar=no
<snip>
;setqueuevar=no
{noformat}

By: Kevin Harwell (kharwell) 2014-12-24 15:18:00.577-0600

This issue is not a bug and is working as expected in Asterisk 12+ and even in 11 (although in 11 it is undefined).

I'll try to explain what is happening. In this instance, when a customer originates the call it creates two local channels: ";1" and ";2". The ";2" channels goes into the queue and once the queue locates an agent, and that agent answers, then local channel ";2" and the agent channel are bridged and all queue channel variables are propagated to both (";2" and agent channel). However, neither of these channels is what is available when dialing the customer (in this case in the "dial-to-customer" context at "s" extension). Instead the available channel is local channel ";1" which does not have the queue channel variables on it.

This is the normal and expected behavior in Asterisk 12+ (with/without local channel optimization) as well as in Asterisk 11 (without local channel optimization). Things get a little more complicated when local channel optimization is enabled in Asterisk 11. The behavior should in most cases be the same. However if a "wait" is introduced that gives time for the local channels to be optimized out and the agent channel to be "masqueraded" in. This results in the agent channel (with all the queue channel variables) effectively running dialplan.

Since this is a source of undefined behavior in Asterisk 11 and simply won't occur at all in Asterisk 12+ I'd recommend moving to a new workaround that would give access to the needed channel variables and works with all version of Asterisk.

Possible workaround:

For a given queue it is possible to specify a macro that will run when the agent answers and before execution of the "dial-to-customer" context/extension. This macro has access through the agent channel to the queue variables in question. Using dialplan it is then possible to locate the local channel ";1" and set shared variables on it. These shared variables can then be accessed later in the "dial-to-customer" context/extension.  Example dialplan:
{noformat}
[macro-sales]
exten => s,1,Noop(sales queue macro)
     ; get a list of all local channels
     same => n,Set(local_channels=${CHANNELS(Local/s@callmenow.*\;1)})
     ; find the one that has a shared "uid" and that matches "MMCALLMENOWID"
     same => n,While($["${SET(chan=${POP(local_channels, )})}" != ""])
     same => n,GotoIf($[${SHARED(uid,${chan})}=${MMCALLMENOWID}]?match)
     same => n,EndWhile
     same => n,Hangup()
     ; match was found
     same => n(match),Noop()
     ; write shared variable(s) to the matching local channel
     same => n,Set(SHARED(membername,${chan})=${MEMBERNAME})
 
[callmenow]
exten => s,1,NoOp(callmenow: Queue without answer)
     same =>n,Queue(sales,Rtc,,,,,sales)
 
[dial-to-customer]
exten => s,1,Noop(dial-to-customer channel=${CHANNEL(name)})
     ; retrieve the shared variable
     same => n,Noop(SHARED: ${SHARED(membername)})
{noformat}

In order for this to be able to match the locally originated channel to the answering agent channel two extra variables need to be specified on origination.  Below is an example using the same ami originate on the issue, but with an extra variable added (also note that MMCALLMENOWID is set to be inherited):
{noformat}
Action: Originate
Channel: Local/s@callmenow
Context: dial-to-customer
Exten: s
Priority: 1
Async: true
Variable: __MMCALLMENOWID=107
Variable: SHARED(uid)=107
Timeout: 999999
Callerid: Call Me Now <778>
{noformat}