首页 > 新闻 > 专家观点 >

《FreeSWITCH: VoIP实战》:SIP 模块 - mod_sofia

2012-08-15 14:06:51   作者:杜金房    来源:FreeSWITCH    评论:0  点击:


  SIP 模块是 FreeSWITCH 的主要模块,所以,值得拿出专门一章来讲解。

  在前几章时里,你肯定见过几次 sofia 这个词,只是或许还不知道是什么意思。是这样的,Sofia-SIP 是由诺基亚公司开发的 SIP 协议栈,它以开源的许可证 LGPL 发布,为了避免重复发明轮子,FreeSWITCH 便直接使用了它。

  在 FreeSWITCH 中,实现一些互联协议接口的模块称为 Endpoint。FreeSWITH 支持很多的 Endpoint, 如 SIP、H232等。那么实现 SIP 的模块为什么不支持叫 mod_sip呢?这是由于 FreeSWITCH 的 Endpoint 是一个抽象的概念,你可以用任何的技术来实现。实际上 mod_sofia 只是对 Sofia-SIP 库的一个粘合和封装。除 Sofia-SIP 外,还有很多开源的 SIP 协议栈,如 pjsip、osip 等。最初选型的时候,FreeSWITCH 的开发团队也对比过许多不同的 SIP 协议栈,最终选用了 Sofia-SIP。FreeSWITCH 是一个高度模块化的结构,如果你不喜欢,可以自己实现 mod_pjsip 或 mod_osip 等,它们是互不影响的。这也正是 FreeSWITCH 架构设计的精巧之处。

   Sofia-SIP 遵循 RFC3261 标准,因而 FreeSWITCH 也是。

   配置文件

  Sofia 的配置文件是 conf/autoload_configs/sofia.conf.xml,不过,你一般不用直接修改它,因为它实际上直接使用一条预处理指令装入了 conf/sip_profiles/ 目录中的 XML 文件:

    <X-PRE-PROCESS cmd="include" data="../sip_profiles/*.xml"/>

  所以,从现在起,可以认为所有的 Sofia 配置文件都在 conf/sip_profiles/ 中。

  Sofia 支持多个 profile,而一个 profile 相当于一个 SIP UA,在启动后它会监听一个 “IP地址:端口” 对。读到这里细心的读者或许会发现我们前面的一个错误。我们在讲 B2BUA 的概念时,实际上只用到了一个 profile,也就是一个 UA,但我们还是说 FreeSWITCH 启动了两个 UA(一对背靠背的 UA)来为 alice 和 bob 服务。是的,从物理上来讲,它确实只是一个 UA,但由于它同时支持多个 Session,在逻辑上就是相当于两个 UA,为了不使用读者太纠结于这种概念问题中,我在前面没有太多的分析。但到了本章,你应该非常清楚 UA 的含义了。

  FreeSWITCH 默认的配置带了三个 profile(也就是三个 UA),在这里,我们不讨论 IPv6,因此只剩下 internal 和 external 两个。 internal 和 external 的区别就是一个运行在 5060 端口上,另一个是在 5080 端口上。当然,还有其它区别,我们慢慢讲。

internal.xml

internel.xml 定义了一个 profile,在本节,我们以系统默认的配置逐行来解释:

<profile name="internal">

profile 的名字就叫 internal,这个名字本身并没有特殊的意义,也不需要与文件名相同,你可以改成任何你喜欢的名字,只是需要记住它,因为很多地方要使用这个名字。

  <aliases>
    <!--   <alias name="default"/>  -->
  </aliases>

如果你喜欢,可以为该 profile 起一个别名。注意默认是加了注释的,也就是说不起作用。再说一遍,“<!-- -->”在 XML 中的含义是注释。

  <gateways>
    <X-PRE-PROCESS cmd="include" data="internal/*.xml"/>
  </gateways>

即然 profile 是一个 UA,它就可以注册到别的 SIP 服务器上去,它要注册的 SIP 服务器就称为 Gateway。我们一般不在 internal 这个 profile 上使用 Gateway,这个留到 external 时再讲。

  <domains>
    <!--<domain name="$${domain}" parse="true"/>-->
    <domain name="all" alias="true" parse="false"/>
  </domains>

定义该 profile 所属的 domain。它可以是 IP 地址,或一个 DNS 域名。需要注意,直接在 hosts 文件中设置的 IP-域名可能不好用。

  <settings>

settings 部分设置 profile 的参数。

    <!--<param name="media-option" value="resume-media-on-hold"/> -->

   如果 FreeSWITCH 是没有媒体(no media)的,那么如果设置了该参数,当你在话机上按下 hold 键时,FreeSWITCH 将会回到有媒体的状态。

  那么什么叫有媒体无媒体呢?如下图,bob 和 alice 通过 FreeSWITCH 使用 SIP 接通了电话,他们谈话的语音(或视频)数据要通过 RTP 包传送的。RTP 可以 像 SIP 一样经过 FreeSWITCH 转发,但是,RTP 占用很大的带宽,如果 FreeSWITCH 不需要“偷听”他们谈话的话,为了节省带宽,完全可以让 RTP 直接在两者间传送,这种情况对 FreeSWITCH 来讲就是没有 media 的,在 FreeSWITCH 中也称 bypass media(绕过媒体)。

                FreeSWITCH
          SIP /            \ SIP
            /                \
        bob  ------RTP------  alice

.

    <!--<param name="media-option" value="bypass-media-after-att-xfer"/>-->

Attended Transfer 称为出席转移,它需要 media 才能完成工作。但如果在执行 att-xfer 之前没有媒体,该参数能让 att-xfer 执行时有 media,转移结束后再回到 bypass media 状态。

    <!-- <param name="user-agent-string" value="FreeSWITCH Rocks!"/> -->

不用解释,就是设置 SIP 消息中显示的 User-Agent 字段。

    <param name="debug" value="0"/>

debug 级别。

    <!-- <param name="shutdown-on-fail" value="true"/> -->

由于各种原因(如端口被占用,IP地址错误等),都可能造成 UA 在初始化时失败,该参数在失败时会停止 FreeSWITCH。

    <param name="sip-trace" value="no"/>

是否开启 SIP 消息跟踪。另外,也可以在控制台上用以下命令开启和关闭 sip-trace:

sofia profile internal siptrace on
sofia profile internal siptrace off

.

    <param name="log-auth-failures" value="true"/>

是否将认证错误写入日志。

    <param name="context" value="public"/>

context 是 dialplan 中的环境。在此指定来话要落到 dialplan 的哪个 context 环境中。需要指出,如果用户注册到该 profile 上(或是经过认证的用户,即本地用户),则用户目录(directory)中设置的 contex 优先级要比这里高。

    <param name="rfc2833-pt" value="101"/>

设置 SDP 中 RFC2833 的值。RFC2833 是传递 DTMF 的标准。

    <param name="sip-port" value="$${internal_sip_port}"/>

监听的 SIP 端口号,变量 internal_sip_port 在 vars.xml 中定义,默认是 5060。

    <param name="dialplan" value="XML"/>

设置对应默认的 dialplan。我们后面会专门讲 dialplan。

    <param name="dtmf-duration" value="2000"/>

设置 DTMF 的时长。

    <param name="inbound-codec-prefs" value="$${global_codec_prefs}"/>

支持的来话语音编码,用于语音编码协商。global_codec_prefs 是在 vars.xml中定义的。

    <param name="outbound-codec-prefs" value="$${global_codec_prefs}"/>

支持的去话语音编码。

    <param name="rtp-timer-name" value="soft"/>

相关阅读:

分享到: 收藏

专题