You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Asterisk GotoIf未按预期跳转:SIP头转移号拨号计划配置故障

排查Asterisk跨Context跳转静默失败的问题

我来帮你拆解这个拨号计划的跳转问题,结合你说的现象——日志显示GOTO执行了但没到目标、看不到“missing diversion”日志、同Context内用标签跳转正常,大概率是跨Context跳转的语法细节或者变量匹配逻辑出了问题,咱们一步步来:

1. 先检查Goto的语法是否完整

Asterisk的跨Context跳转必须指定三个参数:Goto(context, exten, priority),很多人容易漏写后两个参数,导致跳转失效。比如你要跳到diversion-handler这个Context的起始位置,必须写成:

Goto(diversion-handler, s, 1)

而不是只写Goto(diversion-handler)——这种写法在旧版本里可能会被忽略,或者默认用当前的exten和priority,但如果目标Context没有匹配的exten,就会静默失败。

2. 确认Diversion头的判断逻辑是否正确

你说看不到“missing diversion”的日志,说明你的GotoIf条件判断可能根本没走到else分支,要么是变量获取错了,要么是语法格式不对:

  • 首先,获取SIP头的正确写法是${SIP_HEADER(Diversion)},注意大小写(Asterisk变量名不区分大小写,但SIP头的键名是区分的,比如Diversion和diversion是两个不同的头)
  • 条件判断的语法要严格遵循Asterisk的规则,判断是否存在Diversion头的正确写法是:
    GotoIf($["${SIP_HEADER(Diversion)}" != ""]?diversion-handler,s,1)
    
    这里的$[]不能少,引号和空格也不能省——少了任何一个,条件都会判定错误,导致逻辑走偏。
  • 如果Diversion头是带格式的(比如Diversion: <sip:1234@example.com>),你要提取号码的话,得用正则:
    exten => s,n,Set(DIVERSION_NUM=${REGEX("sip:(.*?)@" ${SIP_HEADER(Diversion)},1)})
    exten => s,n,GotoIf($["${DIVERSION_NUM}" != ""]?diversion-handler,s,1)
    

3. 开启详细日志跟踪跳转流程

光看GOTO执行的日志不够,你需要打开更细的日志来定位问题:

  • 启动Asterisk控制台后,执行core set verbose 5,能看到每一步的优先级执行、变量赋值
  • 执行sip set debug on,可以看到收到的SIP请求里是否真的包含Diversion头,以及Asterisk是否正确解析了这个头
  • 这样你就能确认:Diversion头是否被正确读取、GotoIf的条件判定结果是什么、跳转后是否真的进入了目标Context的优先级1

4. 验证目标Context的匹配规则

如果跳转日志显示已经进入目标Context,但没有后续动作,可能是目标Context的exten不匹配:

  • 比如你跳转到diversion-handler,s,1,但目标Context里没有exten => s,1,...的配置,只有_X.,1,...这种匹配号码的规则,那Asterisk找不到匹配的exten,就会直接挂断,不会有任何提示
  • 确保目标Context的起始exten和你跳转时指定的一致(比如都是s,或者都是来电的号码)

示例正确配置

给你一个参考的配置写法,你可以对比调整:

[from-external]
exten => s,1,NoOp(Incoming call from ${CALLERID(num)})
; 检查Diversion头是否存在,存在则跳转
exten => s,n,GotoIf($["${SIP_HEADER(Diversion)}" != ""]?diversion-handler,s,1)
; 走到这里说明没有Diversion头,打印日志并执行原有逻辑
exten => s,n,NoOp(Missing diversion header for call from ${CALLERID(num)})
exten => s,n,Dial(SIP/100,20)
exten => s,n,Hangup()

[diversion-handler]
exten => s,1,NoOp(Handling diverted call, Diversion header: ${SIP_HEADER(Diversion)})
; 这里写转移号码对应的处理逻辑
exten => s,n,Dial(SIP/200,20)
exten => s,n,Hangup()

最后排查点

如果以上都没问题,检查你的Asterisk版本——部分旧版本的GotoIf语法和变量处理有差异,比如不需要$[]包裹条件,你可以尝试去掉$[]再测试:

GotoIf(${SIP_HEADER(Diversion)}?diversion-handler,s,1)

内容的提问来源于stack exchange,提问作者eran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:16:06