Asterisk服务器Billsec统计异常求助:从振铃而非接通计时
解决方案
我来帮你搞定这个Billsec计时错误的问题——这是Asterisk里很常见的CDR逻辑问题,根源在于默认情况下CDR是从**通道创建(振铃阶段)**就开始计时了,而我们需要让它在通话实际接通后才启动计时。下面是具体的修复步骤:
1. 修改Dial命令,添加接通触发逻辑
找到你自定义上下文(或者from-internal上下文)里的Dial命令,添加G选项来触发通话接通后的CDR重置操作。比如:
exten => XXXXXXXXXX,n,Dial(SIP/your-sip-trunk/${EXTEN},30,G(call-answered^s^1))
这里的G(call-answered^s^1)表示:当被叫方接通电话时,自动跳转到call-answered上下文的s分机执行第1步操作。
2. 创建通话接通后的CDR重置上下文
在你的extensions.conf配置文件里添加以下上下文,用来重置CDR的开始时间:
[call-answered] exten => s,1,NoOp(Call answered, resetting CDR start time) exten => s,n,Set(CDR(start)=${EPOCH}) exten => s,n,Set(CDR(answer)=${EPOCH}) exten => s,n,Return()
这段代码的作用是:当通话接通时,把CDR的start和answer时间都设置为当前时间戳(${EPOCH}),这样Billsec就会从接通时刻开始计算,而不是振铃阶段。
3. 验证CDR基础配置
检查cdr.conf文件的核心设置,确保:
enable=yes(CDR功能已启用)- 没有自定义的CDR模块(比如
cdr_adaptive_odbc)干扰默认计时逻辑,如果使用了第三方CDR模块,需要确认其配置正确。
4. 确保SIP中继正确识别通话状态
检查sip.conf里的SIP中继配置,确保Asterisk能正确识别SIP 200 OK作为通话接通的信号:
- 确认中继的
context设置正确,指向你的通话处理上下文 - 如果需要,可以添加
insecure=port,invite(根据中继提供商要求调整),避免因为SIP信令问题导致通话状态识别错误
测试验证
修改配置后,重新加载Asterisk配置(asterisk -rx "core reload"),然后发起一通测试呼叫,通话结束后查看数据库里的CDR记录:
- 检查
start和answer字段的时间差,修改后两者应该几乎一致(误差在1秒内) Billsec字段的值应该等于通话实际接通的时长,不再包含振铃时间
内容的提问来源于stack exchange,提问作者Antonio Aponte
相关产品推荐
相关产品推荐

