通话记录(CDR)
支持把FreeSWITCH的通话记录写入mysql,sqlserver,oracle等数据库,也可以写入redis的list,或者PUBLISH到redis的channel,方便业务程序实时获取通话记录。
使用说明
如果一个通话是A呼叫B,那么就有2个通话记录,一个叫aleg,一个叫bleg。
如果自动外呼或者呼入IVR这样没转接给其他电话或者分机的,就只有一个通话记录。
uuid 这个通话的callid,整个系统唯一的。
destination_number 一般是拨打的号码(自动外呼的的通话如果接通了,就变成了自动外呼配置的目的地(路由条件)
caller_id_number 主叫号码 (来电显示的号码)
callee_id_number 被叫号码(DID号),业务系统建议使用dial_number这个cti定义的变量,因为很多sip终端注册的contact地址可能不是实际的分机号,导致这个不是真实的被叫号码。
怎么把一个通话的2个UUID关联起来
主叫的originator为空,被叫的originator 是主叫的UUID。
webrtc(jssip、sip.js、siml5)问题
大部分例子都没设置 正确的contact_uri,会导致 呼叫 webrtc js sip分机 callee_id_number 和 destination_number 变成一个随机字符串,解决这个问题的方法是设置正确的 contact_uri 为 sip:分机号@sip服务器地址,或者使用cti自定义变量,避免使用者2个变量,防止客户端恶意篡改。
计费
可以通过通话时间业务自行计算费用,也可以吧费率设置到通道变量,cti模块就会计算出通话的费用。
费率通道变量
费率格式 单价/计费单位, 比如每分钟计费 1角钱 就是 0.1/60
。6秒1分钱 0.01/6
。比如ASR一次一分钱 0.01/1
。
tel_cost_rate 电话成本费率
tel_sell_rate 电话销售费率
asr_bill_type 语音识别计费方式
- per 按次计费
- time 按时间计费
asr_cost_rate 语音识别成本费率
asr_sell_rate 语音识别销售费率
计费结果变量
可以根据业务情况把需要的通道变量,加入cti.json的cdr.fields 中,同时数据库的CDR表添加对应字段,把计费金额存储到数据库。
tel_cost_money 电话成本金额
tel_sell_money 电话销售金额
asr_cost_money 语音识别成本金额
asr_sell_money 语音识别销售金额
常见计费用法介绍
比如对网关线路(呼出线路) 设置成本费率, 对分机设置销售费率。如果启用了质检,可以对主叫和被叫都设置语音识别费率。
多租户模式 不同租户使用同一个线路设置不同的费率
通道变量 cti_line_name 默认是线路名
通道变量 organization 可以设置为租户信息
假设 cti_line_name 是 trunk, organization是ddt, 那么cdr模块会组合成一个动态线路名 trunk.ddt
然后redis创建一个hash 名字为 cti_line_bill@域名, 添加一个field trunk.ddt
value 是json格式的费率信息比如 {"tel_cost_rate":"0.1","tel_sell_rate":"0.2"}
。
cti_line_bill更新通知格式为{"type":"config_change","table":"cti_line_bill","key":"trunk.ddt"}
来电去电号码归属地区号到CDR
cti.json 配置文件 cdr配置项目里面添加一个配置phoneattribution=true,然后cdr表添加一个areacode字段 varchar(4)。并且确保导入了号码归属地文件到redis。
{ |
cdr.phoneattribution配置为true的时候,cti模块会根据cti_dial_number计算区号,并且存储到cti_areacode这个通道变量。呼入的拨号方案要把主叫号码存储到cti_dial_number,呼出的时候要把被叫存储到cti_dial_number。
分机互打
主叫方
- account 分机号
- direction inbound (分机呼叫fs,所以是呼入)
- originator 空
- bridge_uuid 最后通话的对方的UUID
- call_source dialplan(拨号方案里面设置的)
- source_name 主叫分机号(拨号方案里面设置的)
- dial_number 被叫分机号(拨号方案里面设置的)
被叫方
- account 分机号
- direction outbound (fs呼叫分机,所以是呼出)
- originator 主叫方uuid
- bridge_uuid 最后通话的对方的UUID,因为一个通话可能给转移和多个人对话,所以和originator可能不是一个UUID
- call_source dialplan(拨号方案里面设置的)
- source_name 主叫分机号(拨号方案里面设置的)
- dial_number 被叫分机号(拨号方案里面设置的)
分机呼出
被叫方
- account 如果外呼使用的实际线路是网关,就是网关名,如果不是网关对接的是通线路组外呼的,就是线路名。
- 其他参数和分机互打的被叫方一样。
自动外呼
注意:自动外呼的通话记录主叫被叫记录接通和未接通是不一样的。下面描述这些差异。 - destination_number 未接通的通话是被叫号码,接通的通话是外呼任务配置的路由条件。
- caller_id_number 未接通的通话是主叫号码,接通的通话是被叫号码(就是自动外呼拨打的号码)
- callee_id_number 未接通的通话是被叫号码,接通的通话是主叫号码(就是自动外呼设置的主叫号码),如果转接给了分机或者其他手机,这个值就变成了转接的被叫号码。
- call_source queuedialer
- source_name 外呼队列名字
- dial_number 被叫号码
- cti_line_group_name 外呼使用的线路组
排队呼叫分机
- call_source acd
- source_name 排队名字
- source_number 原始主叫号码
- dial_number 分机线路名字
- cti_line_group_name 分机所属线路组
配置说明,在cti.json中添加cdr配置,cdr.json文件路径在cdr.conf.xml中配置,默认时fs的conf目录。
"cdr": {
/*details:生产环境的时候设置为flase,details信息很长*/
"details": false,
"enable_msec":false,//时间字段是否带毫秒
/*fields需要记录到cdr表的自定义变量,number:开始的表示使用数字格式。如果变量名和数据库字段名字不一样,可以”字段名:变量名”这样。*/
"fields": [ "rtp_last_audio_codec_string", "number:billsec", "number:duration", "record_filename", "call_source", "source_name", "dial_number:cti_dial_number", "originator", "bridge_uuid" ],
/*如果需要把cdr信息推送到到redis的list或者channels,list配置redis list的名字,channels配置redis cahnnels的名字*/
"redis": {
"channel": "cdr",
"list": ""
},
/*如果需要把cdr记录到数据库,需要配置table, 机器人交互记录,也使用这个配置*/
"database": {
/*dbtype 数据库类型 比如mysql ,sqlserver*/
"dbtype": "mysql",
/*mysql例子:127.0.0.1,3306@dbname sqlserevr例子:tcp:127.0.0.1,1433@dbname*/
"connectionstring": "localhost,3306@cti",
"username": "root",
"password": "123456",
/*cdr表名*/
"table": "cdr",
/*是否启用CDR实时模式,实时模式创建通道的时候插入记录,通话状态变化更新记录,非实时模式通话挂断才记录到CDR*/
"real": false,
"recover":true, //启动时,把最近的异常记录(created_time为最近10分钟,hungup_time为NULL)设置为hungup_time=NOW(), billsec=NOW()-answered_time, duration=NOW()-created_time, hangup_cause='CRASH'
"autocommit": false
},
/*cdr记录写入到数据库推送通知[推送内容为表名和UUID],:disable去了,才使用这个配置*/
"notify:disable": {
"redis": {
"channel": "cdr", //推送到redis的channel
"list": "cdr" //记录到redis的list
},
"http": {
"url": "http://127.0.0.1/notify" //推送到url接口
}
},
/*notify通知是附加的变量*/
"notify_fields": [
"number:billsec",
"tel_sell_money:tel_sell_money"
],
"log":
"log": true //是否输出cdr调试日志
},
- details 是否记录所有的CDR信息。JSON格式。
- fields 要记录那些通道变量,number:开始的表示使用数字格式。可以自定义需要记录的通道变量,数据库中也要添加同名字段,如果变量名和数据库字段名字不一样,可以”字段名:变量名”这样,也可以组合2个通道变量记录到一个字段”字段名:${通道变量1}${通道变量2}”。
- redis 配置CDR记录到redis的信息,如果不需要记录到redis,就不要配置这个。
database 数据库配置
dbtype 数据库类型 比如mysql ,sqlserver
connectionstring 连接串。mysql例子:127..0.0.1,3306@dbname sqlserevr例子:tcp:127.0.0.1,1433@dbname
username 用户名
password
table 表名
real 是否启用CDR实时模式,实时模式创建通道的时候插入记录,通话状态变化更新记录,非实时模式通话挂断才记录到CDR
- notify 写入数据库通知
- redis 通知到redis的list或者channel
{"table":"cdr","uuid":"ac8b888c-c36e-479a-947a-1113fe6de64a","cuase":"storage"}
- http 通过http get 通知到web服务器
http://127.0.0.1/notify?table=cdr&uuid=8c956b55-2b1a-49d8-9971-3e86d5f58397&cause=storage
- cuase
- storage:写入数据库成功
- dump:多次写入数据库失败存储到日志文件。
- notify_fields 可以在这个配置里面定义更多变量 。
- redis 通知到redis的list或者channel
自定义字段记录到CDR
例子记录外呼队列的自定义变量到CDR
- 外呼队列添加自定义变量
- mysql添加一个 queue_name的字段
- cdr.json的 “fields”: [ “rtp_last_audio_codec_string”,”number:billsec”, “number:duration”,”record_filename” ,”queue_name”] 添加queue_name这个自定义变量名。
- 线路也可以同样的方式添加自定义变量到CDR。
sip.js传递参数到CDR
sip.js UA的invite方法的附加参数 extraHeaders参数,接收一个Array(String),我们需要传递到后台的参数需要放到此参数中.
格式是固定的,必须以X-为前缀,示例:X-MY-ID: id
sip.js部分代码session = ua.invite(number, {
sessionDescriptionHandlerOptions: {
constraints: {
audio: true,
video: false
}
},
extraHeaders: [ 'X-MY-ID: ID', 'X-MY-VAR: var' ]
});数据库CDR表添加一个varchar的myid字段
- cti.json里面cdr的配置”fields”: [ “rtp_last_audio_codec_string”,”number:billsec”, “number:duration”,”record_filename” ,”myid:sip_h_X-MY-ID”]
CTI模块自带的变量,可以根据需求配置到json的 cdr.fields,写入数据库。
- cti_line_group_name 外呼使用的线路组名
- cti_line_name 外呼使用的线路名
- call_source 呼叫来源类型 比如 acd(排队呼叫坐席),queuedialer(队列外呼),scheduledialer(定时呼叫) ,extencallout(分机呼出),exten2exten(分机互打),callin2exten(呼入转分机)
- source_name 呼叫来源的名字 队列外呼就是队列名字,排队转接的就是排队名字
- source_number acd呼叫坐席时,被叫坐席端(bleg)记录来源号码
- cti_dial_number 呼出是被叫号码,呼入是来电号码。(需要拨号方案设置好)
- record_filename 通话录音地址
- acd_bridge_line 进入排队后,主叫(aleg)最后接通的坐席线路名
- acd_bridge_time 进入排队后,主叫(aleg)最后接通的坐席的时间戳
- cti_asr_call_time 本次通话调用ASR的时间
- cti_asr_call_count 本次通话调用ASR的次数
- cti_progress_time 收到sip信令180的时间,如果没180就是183的时间。
- cti_progress_media_time 收到sip信令183的时间
- cti_bridged_time 桥接时间
- cti_transferred_time 转接时间
时间字段记录到毫秒
cdr的配置enable_msec 设置为true,cti_progress_time,cti_progress_media_time,cti_bridged_time,cti_transferred_time,created_time,hungup_time,answered_time 就是带毫秒的(2000-01-01 00:00:00.000)这样的格式。
freeswitch常用变量
- originator 发起方的UUID
- bridge_uuid 最后桥接的UUID
- billsec 接通时间单位秒
- duration 呼叫总时间单位秒
- rtp_last_audio_codec_string 声音编码
- billmsec 接通时间单位毫秒
- mduration 呼叫总时间单位毫秒
默认字段
- uuid 通话的UUID
- channel 通道
- account 记录规则为如果是分机通话account为分机号,如果是通过网关呼叫account为网关名字,如果是通过线路组呼叫account为线路名字,以上都不是直接获取通道号中的号码。
- direction 方向 inbound outbound
- destination_number 拨打的号码(自动外呼接接通后是接通后执行的目的地)
- caller_id_number 主叫 (自动外呼接通后是自动外呼的被叫号码)
- callee_id_number 被叫(呼入未转接的呼叫为空,自动外呼接通后为自动外呼的主叫号码)
- sip_term_status 终止sip代码(主动挂断为空)
- sip_hangup_disposition 挂断说明 recv_bye:对方发起挂断 send_bye:本地发起挂断 recv_refuse:对方拒接 send_refuse:本地取消呼叫 send_cancel:也是本地取消呼叫,一般是呼叫超时。recv_xxx:收到对方发起的呼叫终止,send_xxx:fs主动终止呼叫。
- network_addr 对方网络地址
- created_time 发起呼叫时间
- answered_time 接通时间(这个时间不为空,就是接通了,判断电话是否接通为这个为准)
- hungup_time 挂断时间
- hangup_cause 挂断原因,见下表,含义参考:https://freeswitch.org/confluence/display/FREESWITCH/Hangup+Cause+Code+Table
常见的几个
RECOVERY_ON_TIMER_EXPIRE 呼叫超时,一般网络不通
NO_USER_RESPONSE 一般是SIP480
USER_BUSY 线路忙
UNALLOCATED_NUMBER 未分配的号码,比如(VOS)路由配置错误
CALL_REJECTED 呼叫拒绝,路由配置错误或者设备配置错误
USER_NOT_REGISTERED 没有注册
CRASH FreeSWItCH奔溃,启动时cti模块会恢复话单(需要先配置cti.json的gui.channel.hash),挂机原因会设置为CRASH
全部说明:
NONE
UNALLOCATED_NUMBER
NO_ROUTE_TRANSIT_NET
NO_ROUTE_DESTINATION
CHANNEL_UNACCEPTABLE
CALL_AWARDED_DELIVERED
NORMAL_CLEARING
USER_BUSY
NO_USER_RESPONSE
NO_ANSWER
SUBSCRIBER_ABSENT
CALL_REJECTED
NUMBER_CHANGED
REDIRECTION_TO_NEW_DESTINATION
EXCHANGE_ROUTING_ERROR
DESTINATION_OUT_OF_ORDER
INVALID_NUMBER_FORMAT
FACILITY_REJECTED
RESPONSE_TO_STATUS_ENQUIRY
NORMAL_UNSPECIFIED
NORMAL_CIRCUIT_CONGESTION
NETWORK_OUT_OF_ORDER
NORMAL_TEMPORARY_FAILURE
SWITCH_CONGESTION
ACCESS_INFO_DISCARDED
REQUESTED_CHAN_UNAVAIL
PRE_EMPTED
FACILITY_NOT_SUBSCRIBED
OUTGOING_CALL_BARRED
INCOMING_CALL_BARRED
BEARERCAPABILITY_NOTAUTH
BEARERCAPABILITY_NOTAVAIL
SERVICE_UNAVAILABLE
BEARERCAPABILITY_NOTIMPL
CHAN_NOT_IMPLEMENTED
FACILITY_NOT_IMPLEMENTED
SERVICE_NOT_IMPLEMENTED
INVALID_CALL_REFERENCE
INCOMPATIBLE_DESTINATION
INVALID_MSG_UNSPECIFIED
MANDATORY_IE_MISSING
MESSAGE_TYPE_NONEXIST
WRONG_MESSAGE
IE_NONEXIST
INVALID_IE_CONTENTS
WRONG_CALL_STATE
RECOVERY_ON_TIMER_EXPIRE
MANDATORY_IE_LENGTH_ERROR
PROTOCOL_ERROR
INTERWORKING
SUCCESS
ORIGINATOR_CANCEL
CRASH
SYSTEM_SHUTDOWN
LOSE_RACE
MANAGER_REQUEST
BLIND_TRANSFER
ATTENDED_TRANSFER
ALLOTTED_TIMEOUT
USER_CHALLENGE
MEDIA_TIMEOUT
PICKED_OFF"
USER_NOT_REGISTERED
PROGRESS_TIMEOUT
INVALID_GATEWAY
GATEWAY_DOWN
INVALID_URL
INVALID_PROFILE
NO_PICKUP
SRTP_READ_ERROR
BOWOUT
BUSY_EVERYWHERE
DECLINE
DOES_NOT_EXIST_ANYWHERE
NOT_ACCEPTABLE
UNWANTED
建表SQL例子
CREATE TABLE cdr (
uuid VARCHAR(50) ,
channel VARCHAR(100) ,
account VARCHAR(50) ,
direction VARCHAR(50) ,
destination_number VARCHAR(50),
caller_id_number VARCHAR(50) ,
callee_id_number VARCHAR(50) ,
direction VARCHAR(50) ,
sip_term_status VARCHAR(50) ,
hangup_cause VARCHAR(100) ,
sip_hangup_disposition VARCHAR(50) ,
network_addr VARCHAR(50) ,
created_time DATETIME ,
answered_time DATETIME ,
hungup_time DATETIME ,
billsec INT ,
duration INT ,
rtp_last_audio_codec_string VARCHAR(50) ,
record_filename VARCHAR(256) ,
details TEXT
)
实时通道信息记录到redis
cti.json"gui": {
/*通道信息推送到redis*/
"channel": {
"hash": "channels",
"channel": "",
"list": ""
}
}
所有通话信息会写入哈希表channels,挂断的通话会自动删除
key:通道UUID
value:通道信息{
"Event-Name": "CHANNEL_ANSWER",
"Core-UUID": "4ec66b95-7b32-4f64-9c9a-853bde810e5e",
"FreeSWITCH-Hostname": "ai",
"FreeSWITCH-Switchname": "ai",
"FreeSWITCH-IPv4": "192.168.31.57",
"FreeSWITCH-IPv6": "::1",
"Event-Date-Local": "2022-04-07 23:27:14",
"Event-Date-GMT": "Thu, 07 Apr 2022 15:27:14 GMT",
"Event-Date-Timestamp": "1649345234133196",
"Event-Calling-File": "switch_channel.c",
"Event-Calling-Function": "switch_channel_perform_mark_answered",
"Event-Calling-Line-Number": "3884",
"Event-Sequence": "751",
"Channel-State": "CS_EXECUTE",
"Channel-Call-State": "EARLY",
"Channel-State-Number": "4",
"Channel-Name": "sofia/internal/121@192.168.31.57",
"Unique-ID": "276ad4f8-21cc-42cd-b4e1-2718186ea4ba",
"Call-Direction": "inbound",
"Presence-Call-Direction": "inbound",
"Channel-HIT-Dialplan": "true",
"Channel-Call-UUID": "276ad4f8-21cc-42cd-b4e1-2718186ea4ba",
"Answer-State": "answered",
"Channel-Read-Codec-Name": "PCMU",
"Channel-Read-Codec-Rate": "8000",
"Channel-Read-Codec-Bit-Rate": "64000",
"Channel-Write-Codec-Name": "PCMU",
"Channel-Write-Codec-Rate": "8000",
"Channel-Write-Codec-Bit-Rate": "64000",
"Caller-Direction": "inbound",
"Caller-Logical-Direction": "inbound",
"Caller-Username": "121",
"Caller-Dialplan": "XML",
"Caller-Caller-ID-Name": "121",
"Caller-Caller-ID-Number": "121",
"Caller-Orig-Caller-ID-Name": "121",
"Caller-Orig-Caller-ID-Number": "121",
"Caller-Network-Addr": "192.168.31.57",
"Caller-ANI": "121",
"Caller-Destination-Number": "5555",
"Caller-Unique-ID": "276ad4f8-21cc-42cd-b4e1-2718186ea4ba",
"Caller-Source": "mod_sofia",
"Caller-Context": "default",
"Caller-Channel-Name": "sofia/internal/121@192.168.31.57",
"Caller-Profile-Index": "1",
"Caller-Profile-Created-Time": "1649345232522813",
"Caller-Channel-Created-Time": "1649345232522813",
"Caller-Channel-Answered-Time": "1649345234133196",
"Caller-Channel-Progress-Time": "0",
"Caller-Channel-Progress-Media-Time": "1649345232782872",
"Caller-Channel-Hangup-Time": "0",
"Caller-Channel-Transfer-Time": "0",
"Caller-Channel-Resurrect-Time": "0",
"Caller-Channel-Bridged-Time": "0",
"Caller-Channel-Last-Hold": "0",
"Caller-Channel-Hold-Accum": "0",
"Caller-Screen-Bit": "true",
"Caller-Privacy-Hide-Name": "false",
"Caller-Privacy-Hide-Number": "false",
"variable_direction": "inbound",
"variable_uuid": "276ad4f8-21cc-42cd-b4e1-2718186ea4ba",
"variable_session_id": "1",
"variable_sip_from_user": "121",
"variable_sip_from_uri": "121@192.168.31.57",
"variable_sip_from_host": "192.168.31.57",
"variable_video_media_flow": "disabled",
"variable_text_media_flow": "disabled",
"variable_channel_name": "sofia/internal/121@192.168.31.57",
"variable_sip_call_id": "a80ee1bbce7a4ae7a4cac09cc47ad948",
"variable_sip_local_network_addr": "112.49.100.46",
"variable_sip_network_ip": "192.168.31.57",
"variable_sip_network_port": "55458",
"variable_sip_invite_stamp": "1649345232463302",
"variable_acl_token": "121@192.168.31.57",
"variable_sip_received_ip": "192.168.31.57",
"variable_sip_received_port": "55458",
"variable_sip_via_protocol": "udp",
"variable_sip_authorized": "true",
"variable_sip_acl_authed_by": "domains",
"variable_sip_acl_token": "121@192.168.31.57",
"variable_sip-force-contact": "NDLB-connectile-dysfunction-2.0",
"variable_effective_caller_id_name": "121",
"variable_sip-allow-multiple-registrations": "false",
"variable_sip-force-expires": "20",
"variable_force_ping": "false",
"variable_user_name": "121",
"variable_domain_name": "192.168.31.57",
"variable_sip_from_user_stripped": "121",
"variable_sip_from_tag": "5268bb483d5a4d139ed5f7f068510c8b",
"variable_sofia_profile_name": "internal",
"variable_sofia_profile_url": "sip:mod_sofia@192.168.31.57:39468",
"variable_recovery_profile_name": "internal",
"variable_sip_full_via": "SIP/2.0/UDP 192.168.31.57:55458;rport=55458;branch=z9hG4bKPj6e4b4ec52e304b928834efd7174bfe18",
"variable_sip_full_from": "sip:121@192.168.31.57;tag=5268bb483d5a4d139ed5f7f068510c8b",
"variable_sip_full_to": "sip:5555@192.168.31.57",
"variable_sip_allow": "PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS",
"variable_sip_req_user": "5555",
"variable_sip_req_port": "39468",
"variable_sip_req_uri": "5555@192.168.31.57:39468",
"variable_sip_req_host": "192.168.31.57",
"variable_sip_to_user": "5555",
"variable_sip_to_uri": "5555@192.168.31.57",
"variable_sip_to_host": "192.168.31.57",
"variable_sip_contact_params": "ob",
"variable_sip_contact_user": "121",
"variable_sip_contact_port": "55458",
"variable_sip_contact_uri": "121@192.168.31.57:55458",
"variable_sip_contact_host": "192.168.31.57",
"variable_sip_via_host": "192.168.31.57",
"variable_sip_via_port": "55458",
"variable_sip_via_rport": "55458",
"variable_max_forwards": "70",
"variable_switch_r_sdp": "v=0\r\no=- 3858362832 3858362832 IN IP4 192.168.31.57\r\ns=pjmedia\r\nb=AS:84\r\nt=0 0\r\na=X-nat:0\r\nm=audio 4018 RTP/AVP 0 8 120\r\nc=IN IP4 192.168.31.57\r\nb=TIAS:64000\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:120 telephone-event/8000\r\na=fmtp:120 0-16\r\na=rtcp:4019 IN IP4 192.168.31.57\r\na=ssrc:1327126755 cname:77bc1a0344685f79\r\n",
"variable_ep_codec_string": "CORE_PCM_MODULE.PCMU@8000h@20i@64000b,CORE_PCM_MODULE.PCMA@8000h@20i@64000b",
"variable_call_uuid": "276ad4f8-21cc-42cd-b4e1-2718186ea4ba",
"variable_rtp_use_codec_string": "PCMU,PCMA",
"variable_remote_video_media_flow": "inactive",
"variable_remote_text_media_flow": "inactive",
"variable_remote_audio_media_flow": "sendrecv",
"variable_audio_media_flow": "sendrecv",
"variable_rtp_remote_audio_rtcp_port": "4019",
"variable_rtp_audio_recv_pt": "0",
"variable_rtp_use_codec_name": "PCMU",
"variable_rtp_use_codec_rate": "8000",
"variable_rtp_use_codec_ptime": "20",
"variable_rtp_use_codec_channels": "1",
"variable_rtp_last_audio_codec_string": "PCMU@8000h@20i@1c",
"variable_read_codec": "PCMU",
"variable_original_read_codec": "PCMU",
"variable_read_rate": "8000",
"variable_original_read_rate": "8000",
"variable_write_codec": "PCMU",
"variable_write_rate": "8000",
"variable_dtmf_type": "rfc2833",
"variable_local_media_ip": "192.168.31.57",
"variable_local_media_port": "25140",
"variable_advertised_media_ip": "192.168.31.57",
"variable_rtp_use_timer_name": "soft",
"variable_rtp_use_pt": "0",
"variable_rtp_use_ssrc": "2465115496",
"variable_rtp_2833_send_payload": "120",
"variable_rtp_2833_recv_payload": "120",
"variable_remote_media_ip": "192.168.31.57",
"variable_remote_media_port": "4018",
"variable_endpoint_disposition": "EARLY MEDIA",
"variable_RECORD_READ_ONLY": "false",
"variable_RECORD_WRITE_ONLY": "false",
"variable_RECORD_BRIDGE_REQ": "false",
"variable_RECORD_STEREO": "false",
"variable_record_filename": "C:/src/utility/freeswitch/x64/Debug/recordings/2022-04-07/121_5555_23-27-13_276ad4f8-21cc-42cd-b4e1-2718186ea4ba.wav",
"variable_export_vars": "record_filename",
"variable_execute_on_answer_record": "record_session C:/src/utility/freeswitch/x64/Debug/recordings/2022-04-07/121_5555_23-27-13_276ad4f8-21cc-42cd-b4e1-2718186ea4ba.wav",
"variable_current_application": "answer",
"variable_rtp_local_sdp_str": "v=0\r\no=ddt 1649320092 1649320094 IN IP4 192.168.31.57\r\ns=ddt\r\nc=IN IP4 192.168.31.57\r\nt=0 0\r\nm=audio 25140 RTP/AVP 0 120\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:120 telephone-event/8000\r\na=fmtp:120 0-15\r\na=ptime:20\r\na=sendrecv\r\na=rtcp:25141 IN IP4 192.168.31.57\r\n",
"variable_sip_nat_detected": "true"
}