Asterisk 13.X 使用 PJSIP 代替傳統的 chan_sip

Asterisk 由第一天開始所提供的 SIP Stack 由 2001 年開始已經運行了十多個年頭了。SIP 由最初還未普及的十多年前到現在打下了所有對手橫掃整個通訊行業,由規範,技術甚至用家使用上也有很大的轉變。chan_sip 是Asterisk 一直由開始沿用至今的默認 SIP Stack。他有簡單,稳定,易於管理的優點,同時他也是跟足 IETF RFC 3261 的要求打造,所以兼容性極高。但因為用戶的需求不斷增加,和各種週邊設備的快速更新,chan_sip 也開始應付不到現在的需求。所以, Asterisk 由 versioN 12 開始引入 PJSIP (http://www.pjsip.org)作另外一種 SIP Stack (chan_pjsip, 或 res_pjsip) 的選擇。

要使到 Asterisk 支援 chan_pjsip 需要較煩覆的安裝程序,具體內容我是參考這個網站:

http://www.siplab.cn/ast/Asterisk-Admin-Guide/Installing-pjproject_25919783.html

Asterisk 12 包含两个 SIP 协议栈: 一个是,用户一直使用的,原来的chan_sip,此协议栈已经支持了以前的asterisk版本,新协议栈是基于 pjproject. 更多关于在Asterisk 12 中选择新协议栈的背景知识,请参阅新的SIP 通道驱动页面。

因为当前的 SIP pjproject 不能支持共享 object 支持包,我们进行了一些必要的修改以便支持 Asterisk 12。当前pjproject 可以从官方网站下载 www.pjsip.org 将not不能直接支持Asterisk 12.

Icon

不像Asterisk 11, 这个版本使用了嵌入到 pjproject来在RTP 引擎中支持ICE, STUN 和TURN 包,Asterisk 12将使用动态链接来配合pjproject.

Icon

如果你安装了早期的pjproject版本, 你必须删除这个版本,重新安装和asterisk-12 兼容的版本。参考 卸载 pjproject 更多信息。

Icon

现在Asterisk 开发团队正在和Teluu(此人是pjproject 项目维护者) 一起工作来进一步提升版本的兼容性,将来就不需要特别的版本来支持Asterisk 12 以后的版本。

Asterisk 12 兼容的 pjproject 版本在此链接获得 github, 可能根据你的Linux发布版本不同打包成了不同的包。Wiki 页面提供了具体的安装Asterisk 12 步骤.

源代码搭建和安装 pjproject

下载 pjproject

  1. 如果木安装git, 请在你的机器上安装。
    Icon

    下载和安装 git 超出了我们的讨论范围,如果是Debian/Ubuntu 系统, 安装方式也非常简单:

    apt-get install git

    如果是 RedHat/CentOS 系统:

    yum install git
  2. 此这里检查和Asterisk 12兼容的pjproject github repo:
    # git clone https://github.com/asterisk/pjproject pjproject

     

搭建和安装 pjproject

  1. 修改 pjproject 源代码安装路径:
    # cd pjproject
  2. 在 pjproject 代码路径下执行配置脚本:
    # ./configure --prefix=/usr --enable-shared --disable-sound --disable-resample --disable-video --disable-opencore-amr CFLAGS=-fPIC

    pjproject 调用了多个第三方的支持包,这些支持包可能和你目前的系统有兼容性问题。因此我们强烈建议安装pjproject 时最好基于你目前的系统版本进行安装。编辑工程时,支持了多个选项,允许用户关闭一些第三方的支持包。以下列表罗列出来几个典型的安装选项。

    Library Configure option Notes
    libspeex shared objects --with-external-speex Make sure that the library development headers are accessible from pjproject. The CFLAGS and LDFLAGS environment variables may be used to set the include/lib paths.
    libsrtp shared objects --with-external-srtp Make sure that the library development headers are accessible from pjproject. The CFLAGS and LDFLAGS environment variables may be used to set the include/lib paths.
    GSM codec --with-external-gsm Make sure that the library development headers are accessible from pjproject. The CFLAGS and LDFLAGS environment variables may be used to set the include/lib paths.
    Disable sound --disable-sound Let Asterisk perform sound manipulations.
    Disable resampling --disable-resample Let Asterisk perform resample operations.
    Disable video --disable-video Disable video support in pjproject’s media libraries. This is not used by Asterisk.
    Disable AMR –disable-opencore-amr Disable AMR codec support. This is not used by Asterisk

    These are some of the more common options used to disable third party libraries in pjproject. However, other options may be needed depending on your system – see configure --help for a full list of configure options you can pass to pjproject.

    Icon

    You must specify --enable-shared in order to build the shared objects for Asterisk. --prefix should be set to the base path of the lib directory where the shared objects will be installed.

    Icon

    If running on a 64-bit Red Hat distribution (e.g. Fedora, CentOS), then you will also need to add --libdir=/usr/lib64

  3. 编译 pjproject:
    # make dep
    # make
    
  4. 安装 pjproject

    # make install
  5. 更新共享包的链接.
    # ldconfig
  6. 检查确认 pjproject已经成功安装到目的地路径:
    # ldconfig -p | grep pj
    	libpjsua.so (libc6,x86-64) => /usr/lib/libpjsua.so
    	libpjsip.so (libc6,x86-64) => /usr/lib/libpjsip.so
    	libpjsip-ua.so (libc6,x86-64) => /usr/lib/libpjsip-ua.so
    	libpjsip-simple.so (libc6,x86-64) => /usr/lib/libpjsip-simple.so
    	libpjnath.so (libc6,x86-64) => /usr/lib/libpjnath.so
    	libpjmedia.so (libc6,x86-64) => /usr/lib/libpjmedia.so
    	libpjmedia-videodev.so (libc6,x86-64) => /usr/lib/libpjmedia-videodev.so
    	libpjmedia-codec.so (libc6,x86-64) => /usr/lib/libpjmedia-codec.so
    	libpjmedia-audiodev.so (libc6,x86-64) => /usr/lib/libpjmedia-audiodev.so
    	libpjlib-util.so (libc6,x86-64) => /usr/lib/libpjlib-util.so
    	libpj.so (libc6,x86-64) => /usr/lib/libpj.so
  7. 最后,检查是否asterisk 对 pjproject 包支持,在asterisk 源代码路径下,执行:
    # ./configure
    # make menuselect
  8. 找到 Resource Modules 分类,检查 res_pjsip 模块是否开启,确认已经开启:

 

相关问题

问题

安装 pjproject以后,asterisk 不能找到相关的支持包,包括 不能在Asterisk menuselect 中 选择res_pjsip 模块

解决办法

首先检查 Asterisk’s config.log 日志文件,可能会显示以下报错信息:

configure:23029: checking for PJPROJECT
configure:23036: $PKG_CONFIG --exists --print-errors "libpjproject"
Package libpjproject was not found in the pkg-config search path.
Perhaps you should add the directory containing `libpjproject.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libpjproject' found
  1. 确认系统已经安装 pkg-config.
  2. pjproject 将在 /usr/lib/pkgconfig 安装支持包。一些发布版本,例如 Fedora, 可能安装在 /usr/lib64,使用/usr/lib/pkgconfig 更新系统的 PKG_CONFIG_PATH 环境变量,然后重新运行asterisk configure 脚本。

问题

当创建 pjproject, 可能 errors about opencore_amr ,例如:

output/pjmedia-codec-x86_64-unknown-linux-gnu/opencore_amr.o:(.rodata+0x60): multiple definition of `pjmedia_codec_amrnb_framelenbits'
output/pjmedia-codec-x86_64-unknown-linux-gnu/opencore_amr.o:(.rodata+0x60): first defined here
output/pjmedia-codec-x86_64-unknown-linux-gnu/opencore_amr.o:(.rodata+0x80): multiple definition of `pjmedia_codec_amrnb_framelen'
output/pjmedia-codec-x86_64-unknown-linux-gnu/opencore_amr.o:(.rodata+0x80): first defined here
output/pjmedia-codec-x86_64-unknown-linux-gnu/opencore_amr.o:(.rodata+0x20): multiple definition of `pjmedia_codec_amrwb_framelenbits'
output/pjmedia-codec-x86_64-unknown-linux-gnu/opencore_amr.o:(.rodata+0x20): first defined here
output/pjmedia-codec-x86_64-unknown-linux-gnu/opencore_amr.o:(.rodata+0x40): multiple definition of `pjmedia_codec_amrwb_framelen'
output/pjmedia-codec-x86_64-unknown-linux-gnu/opencore_amr.o:(.rodata+0x40): first defined here
...

解决办法

你已经安装了 AMR codec,运行 configure 时加参数 --disable-opencore-amr 。

问题

单创建 pjproject, 链接器 正在指向一个视频的函数,例如:

/home/mjordan/projects/pjproject/pjmedia/lib/libpjmedia-videodev.so: undefined reference to `pjmedia_format_init_video'
/home/mjordan/projects/pjproject/pjmedia/lib/libpjmedia.so: undefined reference to `pjmedia_video_format_mgr_instance'
/home/mjordan/projects/pjproject/pjmedia/lib/libpjmedia-videodev.so: undefined reference to `pjmedia_format_get_video_format_detail'
/home/mjordan/projects/pjproject/pjmedia/lib/libpjmedia-videodev.so: undefined reference to `pjmedia_get_video_format_info'
解决办法

运行 configure 加一个或者两个参数 --disable-video or --disable-v4l2

问题

创建 pjproject以后, ldconfig -p 通过对dump 不能显示.

解决办法

运行 ldconfig 重新配置动态链接器的 run-time 绑定

 

如何删除以前的 pjproject 版本

典型环境下,其他的 pjproject 版本安装为静态的包。这些支持包如果不和 Asterisk 兼容,会拒绝Asterisk 12 的执行。因此,任何静态的包都必须首先删除,以便兼容性需要安装的版本。

pjproject 提供了 uninstall ,可以删除所有以前安装的版本,可以通过以下命令来执行删除,在源代码路径下执行:

# make uninstall

如果你的系统没有 “uninstall” 命令,可能你需要获得最新的pjproject,下载链接 https://github.com/asterisk/pjproject

另外一种方法是执行以下删除命令,也可以删除已安装的静态包:

# rm -f /usr/lib/libpj*.a /usr/lib/libmilenage*.a /usr/lib/pkgconfig/libpjproject.pc

========================================================================================

*Bug fixes*
 In the process of writing this new feature, two bugs were fixed in the PJSIP
 stack:
 (1) The existing .transfer channel callback had the limitation that it could
     only transfer channels to a SIP URI, i.e., you had to pass
     'PJSIP/sip:foo@my_provider.com' to the dialplan application. While this is
     still supported, it is somewhat unintuitive - particularly in a world full
     of endpoints. As such, we now also support specifying the PJSIP endpoint to
     transfer to.
 (2) res_pjsip_multihomed was, unfortunately, trying to 'help' a 302 redirect by
     updating its Contact header. Alas, that resulted in the forwarding
     destination set by the dialplan application/ARI resource/whatever being
     rewritten with very incorrect information. Hence, we now don't bother
     updating an outgoing response if it is a 302. Since this took a looong time
     to find, some additional debug statements have been added to those modules
     that update the Contact headers.
 
 Review: <a href="https://reviewboard.asterisk.org/r/4316/">https://reviewboard.asterisk.org/r/4316/</a>

Leave a Reply