为了实现动态组合拨号方案避免重复配置,把拨号方案拆分成了2个部分,一个是cti_dialplan_extensio@domain,保存单个拨号方案配置,一个是cti_dialplan_context@domain把多个拨号方案组合一个路由表。拨号方案和路由配置修改后会实时生效。
拨号方案的原理就是对通道变量执行正则表达式匹配,如果匹配上了,就执行对应的动作(APP)。fs的很多特性是通过设置通道变量来实现的。这里介绍一下常用的通道变量,更详细的说明参考 https://freeswitch.org/confluence/display/FREESWITCH/Channel+Variables 和 https://freeswitch.org/confluence/display/FREESWITCH/Variables+Master+List
下面几个时设置系统特性常用的通道变量
fs的通道变量非常多,怎么查看通话的通道变量呢,有2个方法 方法1 执行fs控制台命令 uuid_dump 通话UUID,方法2 拨号方案里面执行fs的动作info 也可以输出通道变量,info输出的通道变量有些名字和uuid_dump的不一样,文末复制了一个fs官方文档里面的对应关系。
通过API cti_http_get url [connect_timeout] [response_timeout] [varname] 可以在拨号方案任意位置调用http接口,可以把通道变量作为 http接口的参数,传递给接口。
eval ${cti_http_get(http://ip?arg=${通道变量})}set myval=${cti_http_get(http://ip?arg=${通道变量})}{"header":{"value1":"1","value2":"2"},"body":""}拨号方案的condition(条件),也可以调用http接口,根据返回的结果和正则表达式进行匹配。具体可以看下图的例子。注意返回的数据前后不要有空格换行等不可见字符,会导致和正则表达式匹配不上。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vMaJvNes-1661834141133)(dialplan/image-20220830104137369.png)]
cti_hash_get hash field [varname] ,cti模块定义了cti_hash_get这个同名的API和APP,用来读取redis的hash表.
hash 表的key
field hash表的 field
varname 读取到的value存放的变量
cti_hash_set hash field value cti模块定义了cti_hash_set这个同名的API和APP,用来设置redis的hash表
APP就是一个动作,拨号方案里面可以直接添加动作,拨号方案调用API就和使用变量一样${API名字(参数)},多个参数用空格隔开,可以用set 这个APP把API的返回结果写入变量。也可以嵌套使用比如${cti_extension_exists(${cti_hash_get(callhistory@${cti_domain} ${cti_mid_string(${caller_id_number} -11)})})},如果不需要把返回结果写入变量,只是想执行这个API,可以用eval ,这个什么也不做的APP去调用API。
APP cti_curl http://ip/app?number=${destination_number} cti_curl 这个APP会调用http,执行接口返回的动作。
返回例子说明,数组格式,支持多个动作。
[{"application":"log","data":"INFO 3text"}]
录音的例子
{
"condition": [
{
"field": "${record_filename}",
"description": "测试是否已经启动录音",
"expression": ".+",
"anti-action": [
{
"application": "export",
"data": "RECORD_READ_ONLY=false",
"description": "是否只录音对方"
},
{
"application": "export",
"data": "RECORD_WRITE_ONLY=false",
"description": "是否只录音本方"
},
{
"application": "export",
"data": "RECORD_BRIDGE_REQ=false",
"description": "是否应答后开始录音"
},
{
"application": "export",
"data": "RECORD_STEREO=false",
"description": "是否双道录音"
},
{
"application": "export",
"data": "record_filename=$${recordings_dir}/${strftime(%Y-%m-%d)}/${caller_id_number}.${destination_number}.${strftime(%H-%M-%S)}.${uuid}.wav",
"description": "录音录音文件名"
},
{
"application": "record_session",
"data": "${record_filename}",
"description": "开始录音"
}
]
}
],
"continue": true
}
外呼的例子
{
"condition": [
{
"field": "destination_number",
"expression": "^00\\d*$",
"description": "静止呼叫国际长途",
"action": [
{
"application": "hangup",
"description": "00开始的号码挂断"
}
],
"break": "on-true"
},
{
"field": "destination_number",
"expression": "^\\d+$",
"description": "允许全数字号码呼出",
"action": [
{
"application": "bridge",
"description": "通过default网关呼出",
"data": "sofia/gateway/default/${destination_number}"
}
]
}
]
}
这里就不做解释了,具体参考FreeSWITCH的拨号方案写法。
支持嵌套等XML拨号方案的所有功能。
[
"call extension",
"call trunk",
"testabc"
]
CTI模块根据顺序把cti_dialplan_extensio@domain里面的内容组合成一个拨号方案的XML文件。
variable_xxxx)Some variables, as shown from the info app, may have variable_ in front of their names. For example, if you pass a header variable called type from the proxy server, it will get displayed as variable_sip_h_type in FreeSWITCH™. To access that variable, you should strip off the variable_, and just do ${sip_h_type}. Other variables shown in the info app are prepended with channel, which should be stripped as well. The example below show a list of info app variables and the corresponding channel variable names:
| Info variable name | channel variable name | Description |
|---|---|---|
| Channel-State | state | Current state of the channel |
| Channel-State-Number | state_number | Integer |
| Channel-Name | channel_name | Channel name |
| Unique-ID | uuid | uuid of this channel’s call leg |
| Call-Direction | direction | Inbound or Outbound |
| Answer-State | state | - |
| Channel-Read-Codec-Name | read_codec | the read codec variable mean the source codec |
| Channel-Read-Codec-Rate | read_rate | the source rate |
| Channel-Write-Codec-Name | write_codec | the destination codec same to write_codec if not transcoded |
| Channel-Write-Codec-Rate | write_rate | destination rate same to read rate if not transcoded |
| Caller-Username | username | . |
| Caller-Dialplan | dialplan | user dialplan like xml, lua, enum, lcr |
| Caller-Caller-ID-Name | caller_id_name | . |
| Caller-Caller-ID-Number | caller_id_number | . |
| Caller-ANI | ani | ANI of caller, frequently the same as caller ID number |
| Caller-ANI-II | aniii | ANI II Digits (OLI - Originating Line Information), if available. Refer to: http://www.nanpa.com/number_resource_info/ani_ii_digits.html |
| Caller-Network-Addr | network_addr | IP address of calling party |
| Caller-Destination-Number | destination_number | Destination (dialed) number |
| Caller-Unique-ID | uuid | This channel’s uuid |
| Caller-Source | source | Source module, i.e. mod_sofia, mod_openzap, etc. |
| Caller-Context | context | Dialplan context |
| Caller-RDNIS | rdnis | Redirected DNIS info. See mod_dptools: transfer application |
| Caller-Channel-Name | channel_name | . |
| Caller-Profile-Index | profile_index | . |
| Caller-Channel-Created-Time | created_time | GMT microseconds timestamp when the channel was created |
| Caller-Channel-Answered-Time | answered_time | GMT microseconds timestamp when the channel was answered |
| Caller-Channel-Hangup-Time | hangup_time | GMT microseconds timestamp when the channel was hung up |
| Caller-Channel-Transfer-Time | transfer_time | GMT microseconds timestamp when the channel was transfered |
| Caller-Screen-Bit | screen_bit | . |
| Caller-Privacy-Hide-Name | privacy_hide_name | . |
| Caller-Privacy-Hide-Number | privacy_hide_number | This variable tells you if the inbound call is asking for CLIR[Calling Line ID presentation Restriction] (either with anonymous method or Privacy:id method) |
| initial_callee_id_name | Sets the callee id name during the 183. This allows the phone to see a name of who they are calling prior to the phone being answered. An example of setting this to the caller id name of the number being dialled: | |
| variable_sip_received_ip | sip_received_ip | . |
| variable_sip_received_port | sip_received_port | . |
| variable_sip_authorized | sip_authorized | . |
| variable_sip_mailbox | sip_mailbox | . |
| variable_sip_auth_username | sip_auth_username | . |
| variable_sip_auth_realm | sip_auth_realm | . |
| variable_mailbox | mailbox | . |
| variable_user_name | user_name | . |
| variable_domain_name | domain_name | . |
| variable_record_stereo | record_stereo | . |
| variable_accountcode | accountcode | Accountcode for the call. This is an arbitrary value. It can be defined in the user variables in the directory, or it can be set/modified from dialplan. The accountcode may be used to force a specific CDR CSV template for the call; if the value of the accountcode variable matches the name of a template then that template will be used. This is valuable for having a specific template be used on a per-call basis. See mod_cdr_csv. |
| variable_user_context | user_context | . |
| variable_effective_caller_id_name | effective_caller_id_name | . |
| variable_effective_caller_id_number | effective_caller_id_number | . |
| variable_caller_domain | caller_domain | . |
| variable_sip_from_user | sip_from_user | . |
| variable_sip_from_uri | sip_from_uri | . |
| variable_sip_from_host | sip_from_host | . |
| variable_sip_from_user_stripped | sip_from_user_stripped | . |
| variable_sip_from_tag | sip_from_tag | . |
| variable_sofia_profile_name | sofia_profile_name | . |
| variable_sofia_profile_domain_name | sofia_profile_domain_name | . |
| variable_sip_full_route | sip_full_route | The complete contents of the Route: header. |
| variable_sip_full_via | sip_full_via | The complete contents of the Via: header. |
| variable_sip_full_from | sip_full_from | The complete contents of the From: header. |
| variable_sip_full_to | sip_full_to | The complete contents of the To: header. |
| variable_sip_req_params | sip_req_params | . |
| variable_sip_req_user | sip_req_user | . |
| variable_sip_req_uri | sip_req_uri | . |
| variable_sip_req_host | sip_req_host | . |
| variable_sip_to_params | sip_to_params | . |
| variable_sip_to_tag | sip_to_tag | . |
| variable_sip_to_user | sip_to_user | . |
| variable_sip_to_uri | sip_to_uri | . |
| variable_sip_to_host | sip_to_host | . |
| variable_sip_contact_params | sip_contact_params | . |
| variable_sip_contact_user | sip_contact_user | . |
| variable_sip_contact_port | sip_contact_port | . |
| variable_sip_contact_uri | sip_contact_uri | . |
| variable_sip_contact_host | sip_contact_host | . |
| variable_sip_invite_domain | sip_invite_domain | . |
| variable_channel_name | channel_name | . |
| variable_sip_call_id | sip_call_id | SIP header Call-ID |
| variable_sip_user_agent | sip_user_agent | . |
| variable_sip_via_host | sip_via_host | . |
| variable_sip_via_port | sip_via_port | . |
| variable_sip_via_rport | sip_via_rport | . |
| variable_presence_id | presence_id | . |
| variable_sip_h_P-Key-Flags | sip_h_p-key-flags | This will contain the optional P-Key-Flags header(s) that may be received from calling endpoint. |
| variable_switch_r_sdp | switch_r_sdp | The whole SDP received from calling endpoint. |
| variable_remote_media_ip | remote_media_ip | . |
| variable_remote_media_port | remote_media_port | . |
| variable_write_codec | write_codec | . |
| variable_write_rate | write_rate | . |
| variable_endpoint_disposition | endpoint_disposition | . |
| variable_dialed_ext | dialed_ext | . |
| variable_transfer_ringback | transfer_ringback | . |
| variable_call_timeout | call_timeout | . |
| variable_hangup_after_bridge | hangup_after_bridge | . |
| variable_continue_on_fail | continue_on_fail | . |
| variable_dialed_user | dialed_user | . |
| variable_dialed_domain | dialed_domain | . |
| variable_sip_redirect_contact_user_0 | sip_redirect_contact_user_0 | . |
| variable_sip_redirect_contact_host_0 | sip_redirect_contact_host_0 | . |
| variable_sip_h_Referred-By | sip_h_referred-by | . |
| variable_sip_refer_to | sip_refer_to | The full SIP URI received from a SIP Refer-To: response |
| variable_max_forwards | max_forwards | . |
| variable_originate_disposition | originate_disposition | . |
| variable_read_codec | read_codec | . |
| variable_read_rate | read_rate | . |
| variable_open | open | . |
| variable_use_profile | use_profile | . |
| variable_current_application | current_application | . |
| variable_ep_codec_string | ep_codec_string | This variable is only available if late negotiation is enabled on the profile. It’s a readable string containing all the codecs proposed by the calling endpoint. This can be easily parsed in the dialplan. |
| variable_rtp_disable_hold | rtp_disable_hold | This variable when set will disable the hold feature of the phone. |
| variable_sip_acl_authed_by | sip_acl_authed_by | This variable holds what ACL rule allowed the call. |
| variable_curl_response_data | curl_response_data | This variable stores the output from the last curl made. |
| variable_drop_dtmf | drop_dtmf | Set on a channel to drop DTMF events on the way out. |
| variable_drop_dtmf_masking_file | drop_dtmf_masking_file | If drop_dtmf is true play specified file for every tone received. |
| variable_drop_dtmf_masking_digits | drop_dtmf_masking_digits | If drop_dtmf is true play specified tone for every tone received. |
| sip_codec_negotiation | sip_codec_negotiation | sip_codec_negotiation is basically a channel variable equivalent of inbound-codec-negotiation. sip_codec_negotiation accepts “scrooge” & “greedy” as values. This means you can change codec negotiation on a per call basis. |
| Caller-Callee-ID-Name | - | - |
| Caller-Callee-ID-Number | - | - |
| Caller-Channel-Progress-Media-Time | - | - |
| Caller-Channel-Progress-Time | - | - |
| Caller-Direction | - | - |
| Caller-Profile-Created-Time | profile_created | GMT microseconds timestamp when the caller profile was created |
| Caller-Transfer-Source | - | - |
| Channel-Call-State | - | Current state of the call |
| Channel-Call-UUID | - | - |
| Channel-HIT-Dialplan | - | - |
| Channel-Read-Codec-Bit-Rate | - | - |
| Channel-Write-Codec-Bit-Rate | - | - |
| Core-UUID | - | - |
| Event-Calling-File | - | - |
| Event-Calling-Function | - | - |
| Event-Calling-Line-Number | - | - |
| Event-Date-GMT | - | - |
| Event-Date-Local | - | - |
| Event-Date-Timestamp | - | - |
| Event-Name | - | - |
| Event-Sequence | - | - |
| FreeSWITCH-Hostname | - | - |
| FreeSWITCH-IPv4 | - | - |
| FreeSWITCH-IPv6 | - | - |
| FreeSWITCH-Switchname | - | - |
| Hunt-ANI | - | - |
| Hunt-Callee-ID-Name | - | - |
| Hunt-Callee-ID-Number | - | - |
| Hunt-Caller-ID-Name | - | - |
| Hunt-Caller-ID-Number | - | - |
| Hunt-Channel-Answered-Time | - | - |
| Hunt-Channel-Created-Time | - | - |
| Hunt-Channel-Hangup-Time | - | - |
| Hunt-Channel-Name | - | - |
| Hunt-Channel-Progress-Media-Time | - | - |
| Hunt-Channel-Progress-Time | - | - |
| Hunt-Channel-Transfer-Time | - | - |
| Hunt-Context | - | - |
| Hunt-Destination-Number | - | - |
| Hunt-Dialplan | - | - |
| Hunt-Direction | - | - |
| Hunt-Network-Addr | - | - |
| Hunt-Privacy-Hide-Name | - | - |
| Hunt-Privacy-Hide-Number | - | - |
| Hunt-Profile-Created-Time | profile_created | - |
| Hunt-Profile-Index | - | - |
| Hunt-RDNIS | - | - |
| Hunt-Screen-Bit | - | - |
| Hunt-Source | - | - |
| Hunt-Transfer-Source | - | - |
| Hunt-Unique-ID | - | - |
| Hunt-Username | - | - |
| Presence-Call-Direction | - | - |
| variable_DIALSTATUS | - | - |
| variable_absolute_codec_string | - | - |
| variable_advertised_media_ip | - | - |
| variable_answersec | ||
| variable_answermsec | ||
| variable_answerusec | ||
| variable_billsec | ||
| variable_billmsec | ||
| variable_billusec | ||
| variable_bridge_channel | - | - |
| variable_bridge_hangup_cause | - | - |
| variable_bridge_uuid | - | - |
| variable_call_uuid | - | - |
| variable_current_application_response | - | - |
| variable_direction | - | - |
| variable_duration | ||
| variable_mduration | ||
| variable_uduration | ||
| variable_inherit_codec | - | - |
| variable_is_outbound | - | - |
| variable_last_bridge_to | - | - |
| variable_last_sent_callee_id_name | - | - |
| variable_last_sent_callee_id_number | - | - |
| variable_local_media_ip | - | - |
| variable_local_media_port | - | - |
| variable_number_alias | - | - |
| variable_originate_early_media | - | - |
| variable_originating_leg_uuid | - | - |
| variable_originator | - | - |
| variable_originator_codec | - | - |
| variable_outbound_caller_id_number | - | - |
| variable_progresssec | ||
| variable_progressmsec | ||
| variable_progressusec | ||
| variable_progress_mediasec | ||
| variable_progress_mediamsec | ||
| variable_progress_mediausec | ||
| variable_recovery_profile_name | - | - |
| variable_rtp_audio_in_mos | Mean Opinion Score; read-only, available in CS_REPORTING state, published by CHANNEL_DESTROY event | |
| variable_rtp_use_ssrc | - | - |
| variable_session_id | - | - |
| variable_sip_2833_recv_payload | - | - |
| variable_sip_2833_send_payload | - | - |
| variable_sip_P-Asserted-Identity | - | - |
| variable_sip_Privacy | - | - |
| variable_sip_audio_recv_pt | - | - |
| variable_sip_cid_type | - | - |
| variable_sip_cseq | - | - |
| variable_sip_destination_url | - | - |
| variable_sip_from_display | sip_from_display | ‘User’ element of SIP From: line |
| variable_sip_from_port | - | - |
| variable_sip_gateway | - | - |
| variable_sip_gateway_name | - | - |
| variable_sip_h_P-Charging-Vector | - | - |
| variable_sip_local_network_addr | - | - |
| variable_sip_local_sdp_str | - | - |
| variable_sip_network_ip | - | - |
| variable_sip_network_port | - | - |
| variable_sip_number_alias | - | - |
| variable_sip_outgoing_contact_uri | - | - |
| variable_sip_ph_P-Charging-Vector | - | - |
| variable_sip_profile_name | - | - |
| variable_sip_recover_contact | - | - |
| variable_sip_recover_via | - | - |
| variable_sip_reply_host | - | - |
| variable_sip_reply_port | - | - |
| variable_sip_req_port | - | - |
| variable_sip_to_port | - | - |
| variable_sip_use_codec_name | - | - |
| variable_sip_use_codec_ptime | - | - |
| variable_sip_use_codec_rate | - | - |
| variable_sip_use_pt | - | - |
| variable_sip_via_protocol | - | - |
| variable_switch_m_sdp | - | - |
| variable_transfer_history | - | - |
| variable_transfer_source | - | - |
| variable_uuid | - | - |
| variable_waitsec | ||
| variable_waitmsec | ||
| variable_waitusec |