[Home]

Summary:ASTERISK-02135: Slash operator to match extension based on callerid does not play well with changing callerid
Reporter:gryn (gryn)Labels:
Date Opened:2004-07-28 15:35:08Date Closed:2004-09-25 02:12:18
Priority:MinorRegression?No
Status:Closed/CompleteComponents:Core/General
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:
Description:While this may be obvious to some the following lines do not work:

exten => _X./_49[678]X,1,SetCIDNum(123456${CALLERIDNUM}|a)
exten => _X./_49[678]X,2,SetCIDName(Company|a)
exten => _X./_49[678]X,3,Goto(outgoing,${EXTEN},1)

The reason is that the first line will change the callerid number, which is what the slash operator uses to match on (and so the other two lines don't execute).

Additionally, this code also doesn't work:

exten => _X./_49[678]X,1,SetCIDNum(123456${CALLERIDNUM}|a)
exten => _X.,2,Goto(outgoing,${EXTEN},1)

(which side steps the issue that, even if this did work, you wouldn't be able to set the name, since it must be set after setting the number).

Asterisk doesn't run this code because it thinks it's run to the end of the line.  (And I agree that it should think that).

The only way to get around this problem is to do something like this:

exten => _X./_49[678]X,1,setvar(extension=${EXTEN})
exten => _X./_49[678]X,2,goto(company,1)
exten => company,1,SetCIDNum(123456${CALLERIDNUM}|a)
exten => company,2,SetCIDName(Company|a)
exten => company,3,Goto(outgoing,${extension},1)

Which is just sad.  I might as well use the regular expressions and have a bunch of gotoif's.

My proposed behaviour is to have a copy of the callerid information saved at the beginning of a call.  This copy is then used for all slash operator matching.  A goto out of an extension that matched would be able to reset this information, otherwise changes to callerid would be ignored by the slash operator.
Comments:By: Mark Spencer (markster) 2004-07-28 17:26:42

No way, not even remotely.  

Your dialplan should always do what it says it does.  There are *no* "special" applications which have different behavior from others.  It matches based on Caller*ID.  What you should be using in this case is a macro:

[macro-foo]
exten => s,1,SetCIDNum(123456${CALLERIDNUM},a)
exten => s,2,SetCIDName(Company,a)

[default]
exten => _X./_49[678]X,1,Macro(foo)

By: gryn (gryn) 2004-07-28 17:57:42

Ok, I'm fine with that opinion.  But your macro solution requires the entire extensions logic to be inside a macro.  This isn't any different from my suggestion for working around the problem.

I still feel this is a bad or at least cludgy behaviour.  This is because your only recourse for changing these variables is to jump to a controlled location.  It makes the slash operator fairly useless in the case of changing the callerid.  You are probably better off using a set gotoif()'s which is clearer than starting off in a slash extension and suddenly goto()ing a macro, different extension or context.

I agree that it is straightforward behaviour, especially if you simply view it from the inside out.  But from the outside in, it seems better to promote program flow.  And also, the propose solution does -not- clutter the inside, we are talking about a second copy of the number in the struct, a set of that number when the call initiated, and a set anytime a goto is made that doesn't just jump to a priority.

I'm happy to make a patch to show that it's not something that would destroy the code and add only minimum lines.  But I can see that you are adamantly against this, so I'm not going to unless you say you've changed your mind (or someone else agrees and requests it for their own use).  As for myself, I'm just working around it.

Lastly, sorry for reopening the bug, but I couldn't reply without doing so.  Feel free to close it back up.  Thanks for listening.  Oh and this isn't a special application.  The slash code and goto code are both located in the pbx.c file.

BTW, here is an example of just using slashes (no macros/gotos), which seems really difficult to read (but it will help illustrate your side and mine):

; map of internal extensions to outgoing cids
mapping_2000 = 4045551234
mapping_2001 = 4045555678
mapping_2002 = 4046669999

; To Dial external number, setup callerid first
exten => _X./_20XX,1,SetCIDNum(${mapping_${CALLERIDNUM}})
exten => _X./4045551234,2,SetCIDName("Bill")
exten => _X./4045555678,2,SetCIDName("Bob")
exten => _X./4046669999,2,SetCIDName("Beth")
exten => _X./4045551234,3,Dial(Zap/g1/${EXTEN})
exten => _X./4045555678,3,Dial(Zap/g1/${EXTEN})
exten => _X./4046669999,3,Dial(Zap/g1/${EXTEN})

(and here is the same, with the proposed behaviour:

; map of internal extensions to outgoing cids
mapping_2000 = 4045551234
mapping_2001 = 4045555678
mapping_2002 = 4046669999
mapping_name_2000 = Bill
mapping_name_2001 = Bob
mapping_name_2002 = Beth

; To Dial external number, setup callerid first
exten => _X./_20XX,1,SetCIDNum(${mapping_${CALLERIDNUM}})
exten => _X./_20XX,2,SetCIDName(${mapping_name_${CALLERIDNUM}})
exten => _X./_20XX,3,Dial(Zap/g1/${EXTEN})

)

By: Mark Spencer (markster) 2004-07-28 19:52:07

Yah, I'm pretty adamantly against this, because it breaks the consistency of the system.  I would have done your example even more concisely (without changing any behavior of Asterisk) as follows:

[globals]
mapping_2000 = 4045551234
mapping_2001 = 4045555678
mapping_2002 = 4046669999
mapping_name_2000 = Bill
mapping_name_2001 = Bob
mapping_name_2002 = Beth

exten => _X.,1,Noop
exten => _X./_20XX,1,SetCallerID("${mapping_name_${CALLERIDNUM}}" <${mapping_${CALLERIDNUM}}>)
exten => _X.,2,Dial(Zap/g1/${EXTEN})

And because i went to college with you, I actually tested my theory with the following code:

[globals]
num_2564286275 => 2564286000
name_2564286275 => Joe Blow

[default]
exten => 804,1,Noop
exten => 804/2564286275,1,SetCallerID("${name_${CALLERIDNUM}}" <${num_${CALLERIDNUM}}>)
exten => 804,2,Noop(${CALLERID})