Browsed by
Category: miniSipServer服务器

基于windows以及Ubuntu的专业SIP服务器软件

Request-URI 的附加参数

Request-URI 的附加参数

SIP 网络默认采用 SIP URI 传递信息,例如 From、To等消息头,格式如下:

sip:+8613901088888@ims.bj.chinamobile.com

传统的电信网络一般都是采用 E.164 格式的电话号码,这种格式与 SIP URI 有很大差别,因此 ETSI(3GPP)定义了一种新的 URI,即 TEL URI,格式如下:

tel:+8613901088888

因此在连接电信运营商的 IMS 网络时,通常可能有两种 URI 格式: SIP URI 以及 TEL URI。miniSIPServer 可以支持这两种格式,能够自动处理入呼叫的 TEL URI 格式,但是 miniSIPServer 自己在发出呼叫时,总是采用 SIP URI 格式。

这里有一点问题。幸运的是 IMS 网络考虑非常仔细,例如中国移动可以接受 TEL URI 以及带有特殊参数“user=phone“ 的 SIP URI,格式如下:

sip:+8613901088888@ims.bj.chinamobile.com;user=phone

如果我们配置”外线”连接中国移动的网络,事情就很顺利,因为 miniSIPServer 在外线的呼叫中会自动给 Request-URI 添加“user=phone”。但是在某些市场(区域),中国移动要求采用 SIP 中继的连接方式,这就会导致问题。 miniSIPServer 在中继呼叫中不会对 Request-URI 添加上述参数,因为这种场景我们认为是“服务器 对 服务器”的模式。

为了解决这个问题,我们在 SIP 中继的“出呼叫”配置中增加了“Request-URI 附加参数”项,请参考下图:

Request-URI 附加参数配置
Request-URI 附加参数配置

临时响应的可靠性

临时响应的可靠性

众所周知,RFC3262 协议定义了 SIP 临时响应消息的可靠性。这是个非常古早的特性,miniSIPServer(无论是本地版本,还是云端版本)在很久以前就已经支持这个特性。在与传统电信运营商的 IMS 网络对接时,往往必须要支持可靠的临时响应消息,如果设备不具备此能力,运营商通常会直接拒绝所有的呼叫。

RFC3262 定义了“100rel”参数来指示临时响应消息的可靠性,因此我们在此将其称为“100rel”能力。通常情况下,主叫在发起呼叫时应明确指示出自己是否支持“100rel”能力,被叫也同样需要明确要求采用“100rel”能力,因此呼叫双方才能建立临时响应消息的可靠性。

启动100rel能力的基本呼叫流程

在 RFC3262 标准中,我们可以明确以下细节:

…… the initial request contained a Supported or Require header field listing 100rel, and that there is a provisional response to be sent reliably. ……

UAS core … MUST contain a Require header field containing the option tag 100rel, and MUST include an RSeq header field.

上图描述了可靠临时响应消息的基本流程。UAC 在收到可靠的临时响应 18x 消息时,应当向 UAS 方发送 PRACK 消息,告诉 UAS 自己已经收到了 18x 消息。

这不是一个很复杂的流程,我们一直都认为如此。然而几天前一位云通信用户向我们反映,他无法呼叫外部电话。我们跟踪了他的呼叫,得到以下图描述的呼叫流程:

在 100rel 流程中收到 405 错误消息

难以置信…… 这家 VoIP 运营商升级系统后,在 183 消息中要求采用“100rel”能力确保临时响应的可靠性,然而在 miniSIPServer 发送 PRACK 消息进行确认时,它居然返回“405 method not allowed”。这种情况下当然会导致所有的外呼呼叫都失败了。

这是为什么?!如果不能接受、或者不支持 PRACK 消息,它为什么在临时响应消息(也就是183消息)中明确要求“100rel”呢?

要解决这个问题本来也相当简单。只要在临时响应消息中移除“100rel”、即不要求可靠性保证即可,那样 miniSIPServer 就不会发出 PRACK 消息。但是不幸的是,这家运营商的团队居然不知道该怎么做。

我们的客户就被耽搁在这了,他的业务被迫停滞下来。另一方面,我个人猜测这家(以及某些)运营商采用了开源的服务器,例如 Asterisk、FreeSwitch 等,来构建自己的解决方案,但是他们也许没有足够的专家来理解自己究竟构建了什么。

因此我们更新了 miniSIPServer,在外线的配置中增加一个选项用于关闭“100rel”能力,如下图所示:

关闭临时响应消息的可靠性

一旦勾选了这项, miniSIPServer 向外线发出 INVITE 消息时,将不会再携带“100rel”参数。如果您对接了类似荒谬的运营商,请试试这个选项。

ptime=20, 30, 40

ptime=20, 30, 40

在 SIP 会话中, 我们常常在 SDP 中设置 ptime 参数,用于指示呼叫的双方协商 RTP 数据包的大小。如果呼叫中的一方对 RTP 数据包的大小有不同的看法, 它可以在呼叫中设置自己期望的 ptime 参数。但是世界是如此的多样而复杂,有一些 SIP 设备根本就不关心 ptime 参数,并且它们也根本不会告诉呼叫的另一方自己期望的 ptime 参数,往往就是直接开始发送 RTP 包。这种做法就极可能导致问题。

比如,“呼叫记录”业务要求 miniSIPServer 混合从呼叫双方收到的语音流。为了让工作轻松、简单,miniSIPServer 会设置 ptime 参数为20,也就是要求呼叫的双方每20毫秒发送一个 RTP 数据包,因此 miniSIPServer 每20毫秒从双方获得数据包并进行混音、保存在本地文件中。让人毫不意外的是,有些 SIP 设备每30毫秒发送一个包、有些设备每40毫秒发送一个包。当 miniSIPServer 拿到这些大小不一的包进行混音时,时间不一致、大小不一致,有些数据就不得不丢弃。这就导致最后混音的本地语音文件语音质量欠佳。

当然,理想的解决方案是各家设备都尊重 ptime 参数,但是我们对此毫不指望。

因此不得不升级 miniSIPServer 至 V40(build 20220922)来解决这个问题。新版本试图缓存从呼叫双方获得的 RTP 数据包,然后尽力平滑语音的混音过程。另外,我们不得不指出,这显然增加了服务器的 工作负荷。

再见,Windows XP/2003

再见,Windows XP/2003

最近我们更新了 miniSIPServer 以适应 4K 分辨率显示屏的显示效果,但是我们发现,如果想获得非常完美的效果,必须同时升级我们现有的开发工具链。

然而新的工具链不再支持 Windows XP/2003 操作系统。这些操作系统非常棒,勤恳、可靠、任劳任怨,我们一直非常喜爱、信任这些老旧的系统。现在是时候道别了,我们将继续前行。

如果您是在 Windows 系统上部署 miniSIPServer,最新版本(V40)及后续版本将不再支持 Windows XP/2003 系统,最低要求为 Windows 7 (或以上)版本。我们也同步重新构建了 Debian / Ubuntu 系统上的版本,以适应高分辨率的显示需求。

请享受新版本吧。如果有任何问题、或者建议,欢迎您和我们联系。谢谢!

适配 4K 屏幕

适配 4K 屏幕

最近有客户向我们报告了一个问题:miniSIPPhone 在 4K 屏幕中界面异常。如下图所示:

miniSIPPhone 界面异常
miniSIPPhone 异常界面

在构建图形界面(包括 miniSIPPhone 以及 miniSIPServer)时,我们采用绝对位置、长度来安排界面中的各个组件,因此如果屏幕具备很高的分辨率时(例如 4K 屏幕),绝对坐标值就显得非常小、甚至过于紧凑。

为了解决这个问题,我们将图形界面中的布局、组件全部换成相对坐标、相对尺寸。当然,同时修改、升级了 miniSIPPhone(V8.4) 以及 miniSIPServer(V39 build 20220823)。

另一方面,我们同时也修改了 miniSIPServer 对话框的尺寸、风格、以及布局,因此 miniSIPServer 的图形界面整体上更统一、更整齐,使用感受也会更舒服一些。

在 Ubuntu 22.04 系统上运行 miniSIPServer

在 Ubuntu 22.04 系统上运行 miniSIPServer

Ubuntu 发布了最新的 LTS (长期支持)版本,即 22.04 (Jammy Jellyfish)。毫无疑问这是个非常重要的商用版本,因此我们有必要详细测试 miniSIPServer 在该系统上的运行状况。

非常幸运,miniSIPServer 可以直接安装、运行,无需任何改动!目前的测试结果表明,运行非常完美! 请参考下图的运行状况。

miniSIPServer 运行在 Ubuntu 22.04 系统
miniSIPServer 运行在 Ubuntu 22.04 系统

如果您打算部署一个新的 VoIP 网络,完全可以选择在 Ubuntu 22.04 版本上运行 miniSIPServer。

call tag 以及 cause

call tag 以及 cause

有时候客户希望知道一些历史呼叫的细节,例如哪一方释放的呼叫、为什么会释放呼叫等。由于这些细节都不是实时呼叫的细节,我们无法用 miniSIPServer 内部的跟踪工具进行跟踪,因此我们更新了 CDR 功能,以便回溯信息、了解呼叫的更深一点的细节。

在 CDR 的 FCI(Furnish Call/Charge Information, “提供呼叫/计费信息”)字段中,我们增加了参数“callTag=”以及”cause=”。请参考下图 CDR 记录的细节:

FCI 字段细节
FCI 字段细节

“callTag=” 参数用于保存当前呼叫的在 miniSIPServer 内部的释放位置,根据这个参数,我们可以知道呼叫在哪里被释放了、以及谁释放了这个呼叫。例如,呼叫有可能是收到了主叫侧的 BYE 消息从而导致释放的,诸如此类。这个参数的具体数值是 miniSIPServer 系统内部值,目前不会向客户们公开具体值的含义。

“cause=” 参数用于保存呼叫释放时的原因值。如果 miniSIPServer 收到了被叫侧的 4xx 或者 5xx 消息、同时该消息中包含 Reason 头域、并且在该域中携带了 cause 参数,则 miniSIPServer 会使用该原因值释放呼叫。其他情况下, miniSIPServer 根据内部的呼叫情况使用自己的 cause 值释放呼叫。当然,无论哪种情况, cause 值都会保存在 CDR 记录的 FCI 字段中。

“回呼”业务更新

“回呼”业务更新

miniSIPServer 默认打开 UDP 端口 5080 接受来自应用服务器的 call-back 请求并发起两路呼叫,如果 miniSIPServer 是部署在公网,有可能收到外部很多不相关的 UDP 数据包。我们可以通过配置“应用服务器地址”进行 IP 地址鉴权,但是不幸的是,这个地址默认是空,miniSIPServer会接受外部数据包并进行后续操作, 这带来隐性危险。

因此我们更新了“回呼”业务,进行适度的保护,同时也稍微修改了业务的处理逻辑。请先参考以下新的配置界面:

回呼业务配置

(1) “应用服务器地址”的默认值修改为本地循环地址“127.0.0.1”,这样外部的数据包将无法通过地址鉴权而被直接抛弃。当然,我们还是可以将它配置为空,允许所有的地址向 miniSIPServer 发送 call-back 请求,但我们强烈建议不要这么配置。

(2) “本地监听端口”可以配置为0,一旦配置为0, miniSIPServer 将关闭“回呼”业务,因此就绝对不会接受外部的任何数据包。如果您的环境没有部署“回呼”业务,我们强烈建议将这一项配置为0。

(3)取消“外线模式”。部分客户经常问道这个配置项是什么意思,也经常被它搞糊涂。其实当初设置这个配置项,主要是让 miniSIPServer 自动在外呼号码前添加“出群呼叫前缀”(默认也就是“9”)。实际上,这个项确实特别不灵活,比如客户可能在“回呼”业务中可能同时呼叫本地分机和外部用户,这个配置就容易导致号码错误。因此我们取消了这一项的配置,如果希望呼叫外部用户,可以在 REQUEST 消息中明确添加出群呼叫前缀。也就是说, 应用服务器自己决定号码格式、自己需要清楚号码分析结果(也就是路由结果)。

请参考“回呼”业务文档了解更多的细节。

Linux 系统启动时自动运行 miniSIPServer

Linux 系统启动时自动运行 miniSIPServer

在以前的 Debian 系统,我们可以更新 rc.local 文件让系统启动时自动运行 miniSIPServer。不过目前的各版本 Debian 已经迁移到 systemd 方式进行管理,因此需要改用其他方式来实现。

首先能采用的方式是保留 rc.local,此时我们需要指示 systemd 激活“rc-local.service”,默认情况下这个 service 是没有激活的,采用以下命令激活即可:

sudo systemctl enable rc-local

这种方式不是一个理想的方式,只能算权宜之计。因为要启动 miniSIPServer, 我们可能不得不更改 rc-local.service,这有可能影响到其他通过同样方式启动的应用程序。

更合理、更好的方式当然是定义独立的 minisipserver.service,由 systemd 单独管理。实际上,这样也是相当简单。我们以树莓派(Raspberry Pi)系统为例,指示 Pi 在系统启动时以 “pi”用户身份启动 miniSIPServer 命令行程序。

我们在目录“/lib/systemd/system”下创建“minisipserver.service”文件,内容如下:

[Unit]
Description=miniSIPServer
After=network.target mariadb.service
Requires=network.target mariadb.service

[Service]
Type=simple
User=pi
KillMode=process
ExecStart=/opt/sipserver/minisipserver-cli

[Install]
WantedBy=multi-user.target

然后使用以下命令激活:

sudo systemctl enable minisipserver

一旦激活了“minisipserver.service”,系统启动或者重启时,将自动运行 miniSIPServer 命令行程序。

上述文件有两个重要的节段:[Unit] 和[Service],我们再进一步解释其中的内容。

Unit

(请点击此处了解 systemd 关于 Unit 节段的详细信息。)

我们关心“After=”和“Requires=”两个参数。

因为 miniSIPServer 是网络应用程序,因此必然要求网络要首先准备好,网络没准备好之前不应该启动 miniSIPServer。

在我们的环境中,miniSIPServer 同时也连接了 mariadb/mysql 数据库,因此也要求在启动之前必须准备好数据库系统。如果您的 miniSIPServer 并没有连接数据库,可以从上述两个参数中删除“mariadb.service”的内容。

Service

(请点击此处了解 systemd 关于 Service 节段的详细信息。)

我们关心“User=”和“ExecStart=”两个参数。

“User=” 指示 systemd 以哪位用户的身份(包括权限)去运行当前业务、启动指定的程序。树莓派系统默认的用户是“pi”,因此我们将其也设置为“pi”即可,在您自己的 Linux 系统,您可以指定为自己实际的相关用户。

miniSIPServer 默认安装在“/opt/sipserver”目录下,命令行程序为“minisipserver-cli”,因此设置“ExecStart=”参数指示 systemd 在启动时找到、并运行该程序。

新的呼叫记录文件格式

新的呼叫记录文件格式

以前的 miniSIPServer 版本将呼叫记录(Call Detail Record,简称CDR)保存为二进制文件,存放在“应用数据/cdr”目录下。如果您希望查询、检查以前的呼叫记录,只能使用自带的 miniCDR 工具打开这些文件。如果希望能做更多的分析和查询,就不得不用 miniCDR 将这些文件转换成 CSV 格式的文件。

现在 miniSIPServer 的新版本(即 V39 或者后续更新的版本)将 CDR 记录直接保存为 CSV 文件。当然,所有的 CSV 文件仍然保存在“应用数据/cdr”目录下。既然 .csv 文件其实都是文本文件,因此您可以使用任何文本工具,例如 Windows 平台下的“记事本”或者 Linux 平台下的 Gedit 等,打开这些 .csv 文件。如果您有微软公司的 Excel 软件,也可以直接打开这些文件并进行分析、查询等。

与此同时,miniCDR 也相应进行了升级。从兼容性考虑, miniCDR 可以同时处理以前的 .cdr 文件和如今的 .csv 文件。