已多年没测试Asterisk,这次还是使用Asterisk13.29.0版本为基础部署然后测试呼叫,但是发现其写入Mysql的CDR【通话详单不正确】,感觉到其写入的开始时间,通话时间,与结束时间都是一致,然决定分析一下些版本的cdr_mysql是否会有问题。
先预安装好asterisk,我的sip、extension、cdr配置如下:
sip.conf配置:
[general]
;externip=XXX.XXX.XXX.XXX
;localnet=192.168.0.0/255.255.0.0
bindport=5060 ; UDP Port to bind to (SIP standard port is 5060)
bindaddr=0.0.0.0
srvlookup=no
allowguest=no
context=default
dtmfmode=rfc2833
rtptimeout=60
rtpholdtimeout=300
relaxdtmf=yes
directmedia=off
match_auth_username=yes
useragent=PJPBX
disallow=all ; First disallow all codecs
allow=all ; Allow codecs in order of preference
language=cn
callcounter=yes
register_retry_403=yes
global_disallowagent=xlite
;exten
[8001]
type=friend
host=dynamic
username=8001
secret=123456
nat=comedia
directmedia=off
qualify=yes
dtmfmode=rfc2833
context=from-exten
callgroup=1
pickupgroup=1
call-limit=2
[8002]
type=friend
host=dynamic
username=8002
secret=123456
nat=comedia
directmedia=off
qualify=yes
dtmfmode=rfc2833
context=from-exten
callgroup=1
pickupgroup=1
call-limit=2
;Trunk
[TrunkGW]
type=friend
port=4060
host=192.168.1.36
nat=comedia
directmedia=off
insecure=port,invite
qualify=yes
dtmfmode=rfc2833
disallow=all
allow=all
context=inbound
call-limit=92
extension.conf配置:
[default]
exten => _X., 1, NoOp(Caller from ${CALLERID(all)} to ${EXTEN})
exten => _X., n, Hangup
[from-exten]
exten => _XXXX, 1, NoOp(Caller from ${CALLERID(all)} to ${EXTEN})
exten => _XXXX, n, Ringing
exten => _XXXX, n, Dial(SIP/${EXTEN},60,tT)
exten => _XXXX, n, Hangup
exten => _XXXXXXX., 1, NoOp(Caller from ${CALLERID(all)} to ${EXTEN})
exten => _XXXXXXX., n, Dial(SIP/TrunkGW/${EXTEN},60,tT)
exten => _XXXXXXX., n, Hangup
[inbound]
exten => _XXXX., 1, NoOp(Caller from ${CALLERID(all)} to ${EXTEN})
exten => _XXXX., n, Ringing
exten => _XXXX., n, Dial(SIP/${EXTEN:-4},60,tT)
exten => _XXXX., n, Hangup
cdr.conf配置
[general]
enable=yes
unanswered = yes
[csv]
usegmtime=no ; log date/time in GMT. Default is “no”
loguniqueid=yes ; log uniqueid. Default is “no”
loguserfield=yes ; log user field. Default is “no”
accountlogs=yes ; create separate log file for each account code. Default is “yes”
;newcdrcolumns=yes ; Enable logging of post-1.8 CDR columns (peeraccount, linkedid, sequence).
; Default is “no”.
cdr_mysql.conf配置
[global]
hostname=127.0.0.1
dbname=ast
table=cdr
password=123456
user=root
port=3306
sock=/tmp/mysql.sock
[columns]
;static “” =>
;alias =>
alias start => calldate
alias end => enddate
alias answer => answerdate
mysql的配置:
CREATE TABLE cdr
(id
int(11) unsigned NOT NULL AUTO_INCREMENT,calldate
datetime DEFAULT ‘1979-01-01 00:00:00’,answerdate
datetime DEFAULT ‘1979-01-01 00:00:00’,enddate
datetime NOT NULL DEFAULT ‘1979-01-01 00:00:00’,clid
varchar(80) DEFAULT NULL,src
varchar(80) DEFAULT NULL,dst
varchar(80) DEFAULT NULL,dcontext
varchar(80) DEFAULT NULL,channel
varchar(80) DEFAULT NULL,dstchannel
varchar(80) DEFAULT NULL,lastapp
varchar(80) DEFAULT NULL,lastdata
varchar(80) DEFAULT NULL,duration
int(11) DEFAULT ‘0’,billsec
int(11) DEFAULT ‘0’,disposition
varchar(45) DEFAULT NULL,amaflags
int(11) DEFAULT ‘0’,accountcode
varchar(20) DEFAULT NULL,uniqueid
varchar(255) DEFAULT NULL,userfield
varchar(255) DEFAULT NULL,ast
varchar(255) DEFAULT NULL,
PRIMARY KEY (id
),
KEY calldate
(calldate
),
KEY src
(src
),
KEY dst
(dst
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
场景说明:

通过分机互呼,或呼叫到落地,但是通话记录里的开始时间,接通时间与结束时间都会存在问题,如下的呼叫图信息:
没修正前的debug记录
以下图为接通的记录,电话接通了8秒,开始时间、接通时间,与结束时间,都是 2023-04-12 10:18:51

以下图为没接通的记录,电话响铃了10秒,开始时间、接通时间,与结束时间,都是 2023-04-12 10:26:58

经以上的分析,认定为cdr_mysql.c有bug,以下为原段信息:
vim addons/cdr_mysql.c

标红的这一段,说明只要存在start/answer/end字段,都对其重置为开始时间,显然这个逻辑不正确,需要修正。
因answer字段,当在电话没接通时,此值为空的,所以我们只需要对answer字段进行处理即可以,修正如下:

完成以上修正后,make && make install,然后重新测试
没接通的呼叫记录,时间正确了,answerdata字段因是空,所以为初始值:

接通的记录,各个时间都正确了:

到此,mysql cdr完成修正,再进入github看了一下asterisk的源码,这问题影响了asterisk 13,14,15,16,17,18,19的版本,asterisk20版本后取消了cdr_mysql模块。