IF dialplan behaviour (macro-user-callerid)

I have a single freepbx system running asterisk 18.6 (Freepbx 15.0.17.59) that is malforming the CALLERID(number) for some reason and it makes no sense to me at the moment.

The offending line is

exten => s,n,Set(CALLERID(number)=${IF($["${CHANCONTEXT}" = "webcallback"]?${CHANEXTEN}:${CALLERID(number)})})

Which to me checks if CHANCONTEXT is webcallback, which it isn’t and should set the CALLERID(number) to CALLERID(number) but instead it seems to set the CALLERID(number) to CHANEXTEN:CALLERID(number) so e.g.

-- Executing [s@macro-user-callerid:6] Set("IAX2/77.240.61.186:4569-379", "CALLERID(number)=4569-379:07890009999") in new stack

Commenting the line solves the issue, and what I’ve done is created an override for macro-user-callerid to get everything working, but I’d like to know what the issue is and why its doing it?

Here’s the debug

[2021-10-22 11:45:15] e[1;32mDEBUGe[0m[18134][C-000000de]: e[1;37mpbx_variables.ce[0m:e[1;37m377e[0m e[1;37mast_str_retrieve_variablee[0m: Result of 'CHANCONTEXT' is ''
[2021-10-22 11:45:15] e[1;32mDEBUGe[0m[18134][C-000000de]: e[1;37mpbx_variables.ce[0m:e[1;37m823e[0m e[1;37mpbx_substitute_variables_helper_fulle[0m: Expression result is '0'
[2021-10-22 11:45:15] e[1;32mDEBUGe[0m[18134][C-000000de]: e[1;37mpbx_variables.ce[0m:e[1;37m377e[0m e[1;37mast_str_retrieve_variablee[0m: Result of 'CHANEXTEN' is '77.240.61.176:4569-16245'
[2021-10-22 11:45:15] e[1;32mDEBUGe[0m[18134][C-000000de]: e[1;37mpbx_variables.ce[0m:e[1;37m759e[0m e[1;37mpbx_substitute_variables_helper_fulle[0m: Function CALLERID(number) result is '07890009999'
[2021-10-22 11:45:15] e[1;32mDEBUGe[0m[18134][C-000000de]: e[1;37mpbx_variables.ce[0m:e[1;37m759e[0m e[1;37mpbx_substitute_variables_helper_fulle[0m: Function IF(0?77.240.61.176:4569-16245:07890009999) result is '4569-16245:07890009999'
e[0K[2021-10-22 11:45:15] e[1;32mDEBUGe[0m[18134][C-000000de]: e[1;37mpbx.ce[0m:e[1;37m2938e[0m e[1;37mpbx_extension_helpere[0m: Launching 'Set'
e[1;30m    -- e[0mExecuting [s@macro-user-callerid:6] e[1;36mSete[0m("e[1;35mIAX2/77.240.61.176:4569-16245e[0m", "e[1;35mCALLERID(number)=4569-16245:07890009999e[0m") in new stack

This isn’t urgent, but is bugging me somewhat. I really need to get more familiar with dialplans because this is probably something very simple that I’m missing.

Thank you
Rich

I suggest you change the subject to be about the IF function as this forum doesn’t deal with FreePBX dialplans, but there does seem to be evidence of misbehaviour in the IF function.

Nothing stands out as wrong with the syntax of the line.

I don’t see anything off with the dialplan either. As a work around I assume this achieves the same result?


exten => s,n,Set(CALLERID(number)=${IF($["${CHANCONTEXT}" = "webcallback"]?${CHANEXTEN})})
exten => s,n,Set(CALLERID(number)=${IF($["${CHANCONTEXT}" != "webcallback"]?${CALLERID(number)})})

Does anything change if you remove the spaces from the condition in the square brackets?

exten => s,n,Set(CALLERID(number)=${IF($["${CHANCONTEXT}" != "webcallback"]?${CALLERID(number)})})

The revision with not equals works as desired.

Removing whitespace from the original comparison makes no difference, still results in…
-- Executing [s@macro-user-callerid:6] Set("IAX2/77.240.61.174:4569-16369", "CALLERID(number)=4569-16369:07890009999") in new stack

Two considerations that shouldn’t have any bearing, this is asterisk 18.6.0 and this is an incoming iAX2 call. Regardless, the CALLERID(number) is set correctly up to this point. In the debug provided originally I cannot see any special characters or corruption that could break the IF but I’m not a dialplan expert by any means. The only thing that stands out to me is that the variable has a colon in it, thus the IF evaluates as:

0?77.240.61.176:4569-16245:07890009999

So that’s 0 as in not, which is either “77.240.61.176:4569-16245” or “07890009999”. Is the IF parsing the colon within ${CHANEXTEN} and seeing that as the separator between true and false?

I have already tried switching back to Asterisk 16 which made no change.

I think the person who suggested that was actually thinking of ExecIF(.....?Set()), rather than the IF function. As ExecIF is more commonly used, it should be less likely to misbehave, and you should be able to use : successfully.

That’s important information that you failed to provide! I even tried looking for something like that. The dialplan interpreter is really a macro processor, basically substituting things beginning with $, so the IF function sees 0?..:… or 1?..:…, with no variables or variable markers. If the input variables contain :s those :s are as syntactically significant to IF (or ExecIF, or GotoIF) as the ones that appear in the source code.

That’s expected behaviour. I’d have to look at the source code to see if those functions are applications provide any means to escape the :, but I suspect you will have to protect the whole string, e.g. by URI encoding. (Incidentally, if these are going to get used for caller IDs, URI encoding is going to need to happen anyway, and I don’t know if Asterisk does that for you or expects something that is directly usable in a SIP URI user field.)

Thanks for the confirmation. From what I can see, asterisk assigns the channel when the IAX2 call first hits the switch and the freepbx dialplan just goes with it. If you’re aware of anywhere to change the format of the channel name outside of the dialplan please point me in the right direction?

[2021-10-23 17:04:34] DEBUG[29293][C-00000007]: stasis.c:613 stasis_topic_create_with_detail: Topic 'channel:1635005074.11': 0x7f83e8004530 created
[2021-10-23 17:04:34] DEBUG[29293][C-00000007]: channel.c:951 __ast_channel_alloc_ap: Channel 0x7f83e8002210 'IAX2/77.240.61.184:4569-2563' allocated

I could strip the : from the variable (cut probably) further up the dialplan, or, override macro-user-callerid (as I am now) to remove the offending IF. Neither are great and will no doubt cause me pain in the future as freepbx updates and something breaks.

Very few people use IAX, and I’m not familiar with its channel names. However, I don’t understand why you should want to set the caller ID to be the channel name. Normally caller IDs are expected to have the form of telephone numbers.

Channel names can change during a call. They are generally set on the first contact with the peer in the call, but, if the protocol allows transfers, they can change to reflect the new party.

E.g. for SIP, if the originate sends a REFER, Asterisk will start a new A leg, which might not even by SIP, and will change the name to reflect that new leg. In some cases, there may be a period in which the channel name is that of Local channel, which changes into the final channel name. Typically in this case, there will be a local channel, which will generate the channel towards the new A leg, but then be optimised into that new A leg, taking on its channel name.

In the case of this sort of transfer, the UNIQUEID is actually more stable, and is an equally valid way of naming the channel.

Very few people use IAX, and I’m not familiar with its channel names. However, I don’t understand why you should want to set the caller ID to be the channel name. Normally caller IDs are expected to have the form of telephone numbers.

Just for clarity because this is starting to be a long post, I want CALLERID(number) to be a number, it is a number until it reaches the IF (step 6) in macro-user-callerid which is part of freepbx and is called from the inbound call context. For whatever reason IAX2 channel ID has : in it, and Freepbx just passes that on through and this breaks the macro and malforms my callerid. FWIW this works great on SIP because SIP doesn’t include a : in its channel name but for various reasons IAX2 is the chosen protocol for this inbound route.

From the abundance of knowledge you’ve provided here I don’t think I’m going to be able to fix this within the freepbx model and having an override for this macro, whilst not perfect, does the job for now. Hopefully the guys who work on Freepbx will fix this in their build at some point and everything will be ok.

Did you report this to their issue tracker? They can’t fix what they don’t know isn’t working.

My suspicion is that the only way this will get fixed is by clearer documentation. Asterisk isn’t doing anything wrong, it is just that there are subtleties in how it works. The OP is doing something very strange by trying to use an Asterisk channel name as a caller ID.

The way that this is presented in IAX2 Channel Name incoming - General Help - FreePBX Community Forums is that this is FreePBX standard code. I had assumed that it was user provided custom code.

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