我遇到了一个间歇性问题,星号会向呼叫者播放问候语,然后挂断电话而不是让我们的电话响铃。
我无法用我这里的任何电话重现这个问题,许多呼叫者都能顺利接通。不过有些呼叫者遇到了这个问题,我找不到任何规律。
我找到的一些信息表明,这是由于评估拨号方案表达式时出现错误而导致的。我认为是这一行:
exten => START,n,GotoIf($[${FORCE_CLOSED}=TRUE]?CLOSED,1)
但我不确定它到底出了什么问题。
我在控制台上看到以下错误:
[4 月 4 日 16:29:49] 警告 [27038]:ast_expr2.fl:459 ast_yyerror:ast_yyerror():语法错误:语法错误,意外的“=”,预期为 $end;输入:=TRUE^
周围的控制台输出:
-- 在新堆栈中执行 [START@AGInbound:1] Answer("IAX2/AtlantaTeliax-10086", "") -- 在新堆栈中执行 [START@AGInbound:2] BackGround("IAX2/AtlantaTeliax-10086", 0000_AG_THANK_YOU_FOR_CALLING_AG") -- 播放“0000_AG_THANK_YOU_FOR_CALLING_AG.slin”(语言“en”) [4 月 4 日 16:29:49] 警告 [27038]:ast_expr2.fl:459 ast_yyerror:ast_yyerror():语法错误:语法错误,意外的“=”,预期为 $end;输入: =真 ^ [4 月 4 日 16:29:49] 警告 [27038]:ast_expr2.fl:463 ast_yyerror:如果您有任何疑问,请参阅星号源中的 doc/tex/channelvariables.tex。 -- 在新堆栈中执行 [START@AGInbound:3] GotoIf("IAX2/AtlantaTeliax-10086", "?CLOSED,1") -- 在新堆栈中执行 [START@AGInbound:4] GotoIfTime("IAX2/AtlantaTeliax-10086", "9:30-17:0|mon-fri|*|*?OPEN,1") -- 在新堆栈中执行 [START@AGInbound:5] GotoIfTime("IAX2/AtlantaTeliax-10086", "10:0-18:30|sat|*|*?OPEN,1") -- 在新堆栈中执行 [START@AGInbound:6] GotoIfTime("IAX2/AtlantaTeliax-10086", "12:0-17:0|sun|*|*?OPEN,1")
拨号计划中的相关内容:
扩展 => 开始,1,答案() exten => START,n,背景(0000_AG_THANK_YOU_FOR_CALLING_AG) ;看看我们是否营业 ;若无人应答则强制关闭 exten => START,n,GotoIf($[${FORCE_CLOSED}=TRUE]?CLOSED,1) exten => START,n,GotoIfTime(${AG_WEEKDAY_OPEN_HOUR}:${AG_WEEKDAY_OPEN_MIN}-${AG$ exten => START,n,GotoIfTime(${AG_SATURDAY_OPEN_HOUR}:${AG_SATURDAY_OPEN_MIN}-${$ exten => START,n,GotoIfTime(${AG_SUNDAY_OPEN_HOUR}:${AG_SUNDAY_OPEN_MIN}-${AG_S$ ; ...而我们不是。但也许时间已被覆盖? exten => START,n,GotoIf($[${OVERRIDE_TIME_OF_DAY}=TRUE]?OPEN,1) ;无覆盖...我们肯定关闭了。 exten => 开始,n,转到(关闭,1)
知道这个表达有什么问题吗?我们最近从 1.4 升级到了 1.6。
答案1
在 Asterisk$[]
表达式中,未定义的变量不会返回隐式空字符串或零。它们在表达式求值之前扩展为“无”,因此在变量扩展(为无)后,表达式解析器将看不到它。这会导致 Pablo Alsina 已经指出的错误:
GotoIf("IAX2/AtlantaTeliax-10086", "?CLOSED,1")
有两种方法可以避免这种情况:
- 在使用变量之前,务必为其提供合理的默认值(正如 Pablo 建议的那样)。
- 在任何
$[]
表达式中,用双引号将变量和文字括起来。这将导致未定义的变量被视为空字符串,但仍可用于比较目的。
就我个人而言,我会尝试两者兼顾。例如:
exten => START,n,Set(FORCE_CLOSED=FALSE)
exten => START,n,GotoIf($["${FORCE_CLOSED}"="TRUE"]?CLOSED,1)
注意周围的双引号${FORCE_CLOSED}
和比较值。即使变量未定义,表达式也会有""
(空字符串)来比较"TRUE"
。
实际上,您可以使用任何您喜欢的字符,因为它只会被添加到变量扩展中。它只会为您提供一个文字值,即使变量未定义,该文字值也一定会存在。我喜欢引号,因为它使代码与其他编程语言相似。您也可以同样轻松地使用类似 的内容$[x${FORCE_CLOSED}=xTRUE]
,这在 Bourne shell 脚本中很常见。最终结果是一样的。
答案2
以下是我可以告诉你的。
yyerror 是 yacc 生成的解析器错误。
错误抱怨 =。因此,看来,在那一行上, = 是语法不支持的构造。
祝你在 serverfault.com 上好运,这个问题将会在这里解决......
答案3
谁定义了${FORCE_CLOSED}?
据我所见,该变量有时似乎没有初始值,然后解析器在评估时引发错误
GotoIf("IAX2/AtlantaTeliax-10086", "?CLOSED,1")
检查引发错误的调用是否具有合理的 FORCE_CLOSED 值