概述Overview
FreeSWITCH的目录下 $FS_ROOT/conf/directory/
包含账户信息 (即XML文件) ,用于用户(即SIP电话分机)注册到freeswitch.
注意: 这里的语法跟在 Dialplan 内的不一样
用户设置 User settings
<include> <!--定义用户 包含在<user></user>内--> <user id="1000" cidr="12.34.56.78/32,20.0.0.0/8"> <!--ID 为SIP注册用户名. CIDR可选-- 如果指定的话,这些IP地址与该用户自动认证--> <params><!--参数集--> <param name="password" value="correcthorsebatterystaple"/> <!--SIP 密码--> <param name="vm-password" value="8761"/> <!--虚拟密码 用于语音信箱--> </params> <variables><!--这些变量是在信道访问--> <variable name="accountcode" value="1000"/> <!--在你的拨号方案内使用,授权和限制。此外,cdr_csv可以在各自的CDR文件内使用--> <variable name="user_context" value="default"/> <!--魔术变量: 指定context--> <variable name="effective_caller_id_name" value="Extension 1000"/><!--魔术变量: 用户出局主叫ID--> <variable name="effective_caller_id_number" value="1000"/><!--魔术变量: 用户出局主叫名或者主叫号码--> </variables> </user> </include> 复制代码
基本用户 Basic User
基本配置是相当简单的,你只需要添加用户名和密码。
如:添加文件 $FS_ROOT/conf/directory/mike_x2239.xml
<domain name="$${sip_profile}"> <user id="mike"> <params> <param name="password" value="micke"/> </params> </user> </domain> 复制代码
domain标签告诉FS该用户所属的domain. 注意所有用户都应该在同一个域domain中标签, 除非你正在使用多域名multiple domains. 用户名在SIP地址@的左部分 (如上面定义的用户”mike” 在 “mike@sub.mydomain.com”). $${sip_profile} 将domain替换为在freeswitch.xml中定义的.
加密 a1-hash
明文密码可以替换为 “a1-hash”加密密码. a1-hash 是通过MD5函数对”username用户名:domain域:password密码”(不含引号)加密生成的 MD5 digest function . Linux下, 加密可以通过以下方式生成: openssl dgst -md5 < filename
, 或者 echo -n "username:domain:password" | openssl dgst -md5
.
<domain name="$${sip_profile}"> <user id="mike"> <params> <param name="a1-hash" value="c6440e5de50b403206989679159de89a"/> </params> </user> </domain> 复制代码
反向认证 reverse authentication
有些端点需要验证某些类型的请求 (如. SIP NOTIFY同步). 你可以设置这些认证数据
<domain name="$${sip_profile}"> <user id="jim"> <params> <param name="reverse-auth-user" value="jim" /> <!--反向认证用户--> <param name="reverse-auth-pass" value="foo123" /> <!--反向认证密码--> </params> </user> </domain> 复制代码
电子名片 VCards
你可以添加电子名片VCards支持,需要添加mod_dingaling支持. 添加如下格式的信息
<domain name="$${sip_profile}"> <user id="peter"> <params> <param name="password" value="thepassword"/> </params> <!-- This is only for mod_dingaling so it can deliver vcards in component mode--> <vcard xmlns='vcard-temp'> <FN>Peter Saint-Andre</FN> <N> <FAMILY>Saint-Andre</FAMILY> <GIVEN>Peter</GIVEN> <MIDDLE/> </N> <NICKNAME>stpeter</NICKNAME> <URL>http://www.jabber.org/people/stpeter.php</URL> <BDAY>1966-08-06</BDAY> <ORG> <ORGNAME>Jabber Software Foundation</ORGNAME> <ORGUNIT>Jabber Software Foundation</ORGUNIT> </ORG> <TITLE>Executive Director</TITLE> <ROLE>Patron Saint</ROLE> <TEL><WORK/><VOICE/><NUMBER>303-308-3282</NUMBER></TEL> <TEL><WORK/><FAX/><NUMBER/></TEL> <TEL><WORK/><MSG/><NUMBER/></TEL> <ADR> <WORK/> <EXTADD>Suite 600</EXTADD> <STREET>1899 Wynkoop Street</STREET> <LOCALITY>Denver</LOCALITY> <REGION>CO</REGION> <PCODE>80202</PCODE> <CTRY>USA</CTRY> </ADR> <TEL><HOME/><VOICE/><NUMBER>303-555-1212</NUMBER></TEL> <TEL><HOME/><FAX/><NUMBER/></TEL> <TEL><HOME/><MSG/><NUMBER/></TEL> <ADR> <HOME/> <EXTADD/> <STREET/> <LOCALITY>Denver</LOCALITY> <REGION>CO</REGION> <PCODE>80209</PCODE> <CTRY>USA</CTRY> </ADR> <EMAIL><INTERNET/><PREF/><USERID>stpeter@jabber.org</USERID></EMAIL> <JABBERID>stpeter@jabber.org</JABBERID> <DESC> More information about me is located on my personal website: http://www.saint-andre.com/ </DESC> </vcard> </user> </domain> 复制代码
组Groups
组是用户逻辑合集,FS可以使用并行,串行的方式桥接呼叫.根据group_call application 参数的不同 . 使用组是可选的– 如果你想使用,你可以直接将用户信息放在domain节点内.
这是特别有用,如果你使用mod_xml_curl的向用户提供目录FreeSWITCH的和逻辑结构,希望一些用户分组。 This is specially useful if you use mod_xml_curl to provide the user directory to FreeSWITCH and want to group some users in a logical structure. 以下组”200″ 将4个用户设置为一个组. It’s interesting to notice the “dial-string” param, which is used to bridge the calls to those users. Users 1000 and 1001 will use the default “dial-string” while user 2014 uses a loopback channel so FreeSWITCH can actually query the dialplan to figure out how to reach that user (this also works for external numbers through OpenZAP and gateways):
type=”pointer” is a pointer so you can have the same user in multiple groups. It basically means to keep searching for the user in the directory.
<document type="freeswitch/xml"> <section name="directory"> <domain name="sip.example.com"> <users> <user id="1000"> <params> <param name="dial-string" value="{presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}"/> </params> <variables> <variable name="user_context" value="default"/> </variables> </user> <user id="1001"> <params> <param name="dial-string" value="{presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}"/> </params> <variables> <variable name="user_context" value="default"/> </variables> </user> </users> <groups> <group name="200"> <users> <user id="2014"> <params> <param name="dial-string" value="loopback/2014/default/XML"/> </params> <variables> <variable name="user_context" value="default"/> </variables> </user> <user id="1000" type="pointer"/> <user id="1001" type="pointer"/> </users> </group> </groups> </domain> </section> </document> 复制代码
The dialplan for the above group can be defined like this:
<extension name="Group 200"> <condition field="destination_number" expression="200"> <action application="set" data="hangup_after_bridge=true"/> <action application="set" data="continue_on_fail=true"/> <action application="set" data="originate_continue_on_timeout=true"/> <action application="set" data="call_timeout=15"/> <action application="bridge" data="${group_call(200@${domain_name}+F)}"/> <action application="transfer" data="200 XML default"/> <action application="hangup"/> </condition> </extension> 复制代码
The extension 200 will ring all the users defined in the user directory for group 200 in a serial fashion (specified by the +F argument, if you want to ring all the users at once use the +A argument) for 15 seconds, then it will transfer the call to the same group again so the call will ring the group infinitely.
To explain the variables set prior to the bridge:
The hangup_after_bridge is set to true for this effect: if the bridge is successfully answered and the B-leg later hangs up, the A-leg will also be hung up.
The continue_on_fail is set to true for this: if the bridge fails, dialplan execution will continue and the transfer will be executed.
The originate_continue_on_timeout is set to true for this: if the bridge’s dial string specifies several destinations separated by the “|” (this is for failover), the bridge will time out on an unanswered destination and will attempt the next specified destination. Without originate_continue_on_timeout set to true, the bridge will time out on the first destination it tries and the bridge itself will fail. (In the example above, the bridge string is generated by group_call with the +F option; this specifies a dial string with all the group’s destinations separated by “|”. So originate_continue_on_timeout needs to be set to true for serial calling behavior.)
The call_timeout is set so that the bridge attempt to a destination that goes unanswered will time out. NOTE: If the destination sends early media, the bridge will be answered (pre-answered) and will NOT time out! To time out a bridge attempt to a destination sending early media, set ignore_early_media to true.
The dialplan for user 2014, which in this example happens to be terminated through a gateway defined via mod_lcr, can be defined like this:
<extension name="Extension 2014"> <condition field="destination_number" expression="2014"> <action application="lcr" data="2014"/> <action application="set" data="dialed_ext=${lcr_auto_route}"/> <action application="export" data="dialed_ext=${lcr_auto_route}"/> <action application="set" data="hangup_after_bridge=true"/> <action application="set" data="call_timeout=120"/> <action application="bridge" data="${lcr_auto_route}"/> <action application="hangup"/> </condition> </extension> 复制代码
Alphanumeric to numeric user mapping
Say you want a user’s id to be alphanumeric (like an email username), such as johnsmith@pbx.example.com. These users have alphanumeric usernames in their sip phone config, but you want to map them from their sip username to a numeric extension, and vice versa.
As of version 1.0.4, FreeSWITCH makes this trivial to accomplish. A user’s ID can be any alphanumeric string, and this can be simply tied to an extension number using the ‘number-alias’ property. This property creates an aliased directory entry that points to the alphanumeric user entry.
NOTE: When using this attribute, you must be careful not to create a directory collision by having another user whose ID is the same as another user’s alias
Here is an example from the user directory:
<user id="johnsmith" number-alias="1001"> <!-- Insert the usual user configuration variables and params here, including user password, voicemail password, caller ID info, etc --> <variables> <variable name="mailbox" value="1001"/> <variable name="effective_caller_id_name" value="1001"/> <variable name="effective_caller_id_number" value="1001"/> <variable name="voicemail_alternate_greet_id" value="1001"/> </variables> </user> 复制代码
So when a user dials extension number 1001, your dialplan can use the ‘user_data’ function to look up the ID attribute associated with that number alias. In the default dialplan, the ‘Local Extension’ section can be made to work with a small change to the ‘bridge’ line:
<action application="bridge" data="user/${user_data(${destination_number}@${domain_name} attr id)}"/> 复制代码
NOTE: Using this user_data function in combination with mod_xml_curl will generate an additional request each time the user_data function is called. Note that it is already called once in the Local Extension section to determine the callgroup. Beware of performance implications of this with high-volume systems.
More Complex Examples
Each can also have it’s own variables and gateways with their own [semi-]complex configurations.
User-Specific Gateways
<user id="user1"> <params> <param name="password" value="1"/> </params> <variables> <variable name="register-gateway" value="user1out"/> </variables> <gateways> <gateway name="user1out"> <param name="username" value="4347382173"/> <param name="password" value="1"/> <param name="proxy" value="sip.example.com"/> <param name="register" value="false"/> </gateway> </gateways> </user> 复制代码
The variable can be set to the name of a specific gateway, a comma delimited list of multiple gateways, or “all”. Setting it to one or more gateways will register the named gateway(s) when the registers with FreeSWITCH.(whether they’re in the ’s or some other ’s or anywhere). Setting the variable to “all” will register all of the particular ’s gateways.
Group call with answer confirmation
The following example makes the user reachable at multiple phone numbers in SIP and PSTN networks. A call to a mobile phone may usually be answered with a message that a mobile user is unreachable, or end up in a voicemail. In order to avoid such situations, group_confirm_key is used to request the user to press “1” for call confirmation.
Loopback endpoint duplicates all channel variables, so if group_confirm_key is set globally, the confirmation key would be asked twice. So it needs to be applied with [] to limit to one leg only. The loopback endpoint is used to route the call to a PSTN number, assuming that users in the default context are allowed to dial international numbers and they are routed to an appropriate gateway.
<!-- dialplan/default.xml --> <extension name="global" continue="true"> <condition> <action application="set" data="group_confirm_file=phrase:press_one_to_answer"/> <action application="set" data="group_confirm_read_timeout=1000"/> </condition> </extension> <extension name="dvop_groupcall"> <condition field="destination_number" expression="^(71[1-9]0)$"> <action application="answer"/> <action application="set" data="ringback=$${hold_music}"/> <action application="set" data="call_timeout=60"/> <action application="set" data="hangup_after_bridge=true"/> <action application="bridge" data="${group_call(hunt_$1@${domain_name}+A)}"/> </condition> </extension> <!-- directory/default.xml --> <users> <user id="7012"> <params> <param name="a1-hash" value="538db5a1dcf95cd9df62bf2ff0466c4b"/> </params> <variables> <variable name="user_context" value="default"/> </variables> </user> <user id="7017"> <params> <param name="dial-string" value="[group_confirm_key=1]loopback/00491637743380/default"/> </params> </user> </users> <groups> <group name="hunt_7190"> <users> <user id="7012" type="pointer"/> <user id="7017" type="pointer"/> </users> </group> </groups> 复制代码
Domains & Users Parameters
and tags are valid inside , and tags.
Parameters and variables set on the domain will apply to all users in the domain, and parameters and variables set in a group will apply to all users in the group.
Priority will be given to identical parameters and variables in the following order: users, groups, domain.
Password
<param name="password" value="123456"/> 复制代码
Do Not Allow Empty Passwords
If you do not include the above ‘password’ parameter, anybody can register as the user without using a password. It is always wise to include this parameter in the directory section in case a user does not set their password.
<param name="allow-empty-password" value="false"/> 复制代码
Dial String
The dial string MUST be defined and will control the behavior of the call when a user is dialed. The dial-string parameter is used by the user/ endpoint.
Default value goes as follows:
<param name="dial-string" value="${sofia_contact(${dialed_user}@${dialed_domain})}"/> 复制代码
Channel variables useful for the dial-string
- transfer_fallback_extension
- presence_id
<param name="dial-string" value="{transfer_fallback_extension=${dialed_user}}${sofia_contact(${dialed_user}@${dialed_domain})}"/> 复制代码
Include Pickup Endpoints
<param name="dial-string" value="${sofia_contact(${dialed_user}@${dialed_domain})},pickup/${dialed_user}@${dialed_domain}"/> 复制代码
Advanced dial-string
- Sets presence and creates pickup endpoint
<param name="dial-string" value="{sip_invite_domain=${dialed_domain},presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})},pickup/${dialed_user}@${dialed_domain}"/> 复制代码
Variables
Any variables defined in the domain or user will be defined as channel variables when there is a call to user or when there is an inbound calls from that user.
Forcing a particular user to a particular extension
In a PABX environment, an authenticated user can specify that they are at an arbitrary extension. This behavior can be restricted in two ways.
To force a user to use a specified extension, add
<variable name="sip-force-user" value="<extension>"/> 复制代码
to that user’s directory entry.
Alternatively, to check that users authenticate with the same username as that in their contact field for an entire profile, add
<variable name="inbound-reg-force-matching-username" value="true"/> 复制代码
to that profile’s definition.
Additionally look at [1] – easy way of registration user with different SIP ID (Contact header) and username (Authorization header).
Force Registrations to Expire
To help prevent stale registrations you are able to override the client specified registration expiry. You do this in the clients directory profile, by simply adding the variable
<variable name="sip-force-expires" value="180"/>