先理解SIP Profile的几个概念
- 一个Profile就是一个UA;一个UA就是一个“IP地址: 端口”;
- fs的/sip_profiles目录下主要有三个东西(不考虑ipv6):external.xml、internal.xml、 /external目录。其中external.xml和internal.xml就是两个Profile;而/external里的xml文件是我们自定义的外部网关,这些外部网关都会被fs装入external.xml中;
- internal.xml默认运行在5060端口,external.xml默认运行在5080端口。注意不要因为它们的名称而把它们理解为内部和外部。 60端口和80端口的区别就是前者会对sip消息鉴权而后者不需要(各自xml中的auth-calls标签定义)。
2. 本地用户互拨流程
本地user/1000拨打本地user/1001:
- 因为user/1000注册在5060端口,所以向fs的5060端口发送INVITE请求;
- INVITE请求到达internal这个Profile所配置的UA(internal.xml);
- 此UA会对此INVITE请求进行鉴权(因为auth-calls=ture);
- 先检查ACL(acl.conf.xml),然后进行Digest鉴权(directory/default/1000.xml中的用户名和密码);
- 若鉴权通过则开始寻找路由,在1000.xml中的user_context标签即是路由;
- 这里以user_context的值是default为例,则进入diaplan/default.xml中寻找路由;
- diaplan/default.xml会找到1001这个用户,并执行bridge user/1001;
- bridge user/1001这个呼叫字符串会再次查找directory用户目录并找到directory/default/1001.xml;
- 因为1001是被叫,所以fs会进一步找到它实际注册位置,内部用户的实际注册位置在conf/directory/default.xml中dial-string标签配置。在这个标签中可以看到调用了sofia_contact这个API,这个API会查找数据库并找到user/1001的contact地址并返回真正的呼叫字符串。
3. 本地用户拨打外部号码流程:
本地user/1000拨打外部号码40012345:
- 因为user/1000注册在5060端口,所以向fs的5060端口发送INVITE请求;
- INVITE请求到达internal这个Profile所配置的UA(internal.xml);
- 此UA会对此INVITE请求进行鉴权(因为auth-calls=ture);
- 先检查ACL(acl.conf.xml),然后进行Digest鉴权(directory/default/1000.xml中的用户名和密码);
- 若鉴权通过后会找到该用户的配置文件(即1000.xml),在1000.xml中的user_context标签中配置了路由,所以fs会根据此配置进行路由查找:以默认配置为例:<param name="user_context" value="default">,此时进入diaplan/default.xml中寻找路由;
- 对于外部号码,default.xml中一般会将请求送到外部网关,例如:bridge sofia/gateway/gw1/40012345这样;
- 其中gw1是我们配置的一个网关。本文开头解释过,网关最终都会被装入external.xml,而external这个Profile运行在5080端口。因此,该INVITE请求最终会通过本机的5080端口发往gw1网关(在gw1对应的xml中配好了目的地的ip和端口)。
4. 本地用户接听外部来电流程:
外部送来的sip消息可能送到5080端口,也可能送到5060端口。
如果送到5080端口:
- 外部的INVITE请求到达fs的5080端口,即external这个Profile,external不会对来话进行鉴权,直接进行路由;
- 在external.xml的context标签中配置了路由,以默认配置为例:<param name="context" value="public">,那么就会去diaplan/public.xml中查找路由,路由中设定了接下来的操作,是转到一个本地用户,还是继续bridge到其他地方;
- 如果是路由将请求转向一个本地用户(例如user/1000),那么将会找到这个用户的配置文件1000.xml,并根据1000.xml中user_context标签的配置继续进行路由(参考上面内部用户互拨流程);
如果送到5060端口:
- 外部的INVITE请求到达fs的5060端口,即internal这个Profile,internal会对来话进行鉴权;
- 先ACL鉴权,再Digest鉴权。如果INVITE请求发送者的ip在autoload_configs/acl.conf.xml中配置过,则ACL鉴权通过,直接根据external.xml中context标签的配置进行路由;如果未通过ACL鉴权则进行Digest鉴权,如果通过Digest鉴权的认证就会找到一个内部用户(例如user/1000),进而根据其用户目录(即1000.xml)中user_context标签的配置进行路由。
浏览器坐席
5. 坐席外呼用户
- 页面点呼叫,请求到达cm,cm知道了操作请求+操作对端信息
- cm构造呼叫命令:originate agent &lua(manual_call_start.lua);用esl发给fs
- fs执行呼叫命令串。先呼通坐席,再bridge 用户端。
6. 用户呼入
- 浏览器坐席登录,在km-reg鉴权,注册ip信息同步到cm
- 呼叫从gateway、km到fs的ivr业务,cti查找空闲坐席(IP),构造originate呼叫命令,通过esl发给fs
- fs呼叫坐席,fs收到180,通过esl通知cti,cti通知浏览器页面弹窗振铃
- 浏览器接听,fs收到200ok,通过esl通知cti,浏览器已接听
顶顶通空号检测--整体流程解析
呼叫设定通道变量{ execute_on_media=start_da2} -- 183 -- 通过回调调用da2,结果返回fs –fs将结果通过esl_event发到cm(后端) -- cm完成入库、得助前端渲染(前端)