Asterisk:因“ast_yyerror”而挂断电话

Asterisk:因“ast_yyerror”而挂断电话

我遇到了一个间歇性问题,星号会向呼叫者播放问候语,然后挂断电话而不是让我们的电话响铃。

我无法用我这里的任何电话重现这个问题,许多呼叫者都能顺利接通。不过有些呼叫者遇到了这个问题,我找不到任何规律。

我找到的一些信息表明,这是由于评估拨号方案表达式时出现错误而导致的。我认为是这一行:

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")

有两种方法可以避免这种情况:

  1. 在使用变量之前,务必为其提供合理的默认值(正如 Pablo 建议的那样)。
  2. 在任何$[]表达式中,用双引号将变量和文字括起来。这将导致未定义的变量被视为空字符串,但仍可用于比较目的。

就我个人而言,我会尝试两者兼顾。例如:

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 值

相关内容