Why NOTICE for LEN?

with CALLERID(num) = 912726172

exten => 213031450,n,GotoIf($[LEN(${CALLERID(num)}) = 9]?inside)

NOTICE: ast_expr2.y:761 in compose_func_args: argbuf allocated 10 bytes;
NOTICE: ast_expr2.y:780 in compose_func_args: argbuf uses 9 bytes;

Need ${} around the LEN

${LEN()}

Because it is a function! However, it does look as though it would make more sense for this to be debug, as it looks like it was there to make sure the malloc amount wasn’t being calculated too short.

A possibly neater way of doing this, and likely a faster one, would be:

exten => 213031450/_XXXXXXXXX,n,Goto(inside)
exten => 213031450,s,Noop

Looking at Expr2 Built-in Functions - Asterisk Project - Asterisk Project Wiki it is a bit more subtle than this. LEN is not a function recognized by the expression language, but this statement still applies:

All other dialplan functions are available by simply calling them (read-only). In other words, you don’t need to surround function calls in $[…] expressions with ${…}. Don’t jump to conclusions, though! - you still need to wrap variable names in curly braces!

I think there is a subtle difference in when the function is evaluated. If you use ${…}, it will be macro expanded before any of the expression is parsed, but I think that if you use it bare, it will get expanded at its proper place in the expression, as it is parsed.

I haven’t looked in detail, but I think that you will only get notices when it is evaluated by the expression parser. Actually I’m pretty sure, as the C function that generates the NOTICEs is called compose_func_args, but there will be no evidence that there was a function there, if it has already been macro expanded.

exten => 213031450/_XXXXXXXXX,n,Goto(inside)

Yes this is good idea, anyway the spot was on why NOTICE on LEN().

In fact and yes,
after ${LEN()} no more notice.

But still confusing in boolean expression like AND
(expr) & (expr | expr | expr)

GotoIf($[exprA] & $[exprB1 | exprB2 | exprB3 ]?Y:)

If this returns 1 on exprA and 0 on (exprB1 | exprB2 | exprB3)
so 1 & 0, shouldn´t give 0 ?

The & here is a literal & not an logical AND operator, as it is not in any expression.

So how do I do this
(expr) & (expr | expr | expr) in GotoIf?

The same as for anything that requires a truth value. You need to evaluate to a single value which is either 0 or 1, which means to a single top level expression. Set the logging to verbose level 3 or more and you will see the result of evaluating the expression. At the moment you will be getting one of “0 & 0”, “0 & 1”, “1 & 0”, or “1 & 1”. I’m not sure how values that are not 0 or 1 or handled, but it might be something like if it is empty or begins with 0, it is false, otherwise true. In any case, that is academic, as you don’t want that case to actually be handled.