Kamailio RPC和OpenSIPS MI

2023-02-28 12:29:47 浏览数 (2)

今天笔者来给大家讲一下KamailioRPC和OpenSIPSMI的一些小区别。

以查找注册用户的信息为例,Kamailio的命令如下:

代码语言:javascript复制
kamcmd ul.lookup location 1001@192.168.100.173
代码语言:javascript复制
{
        AoR: 1001
        Contacts: {
                Contact: {
                        Address: sip:1001@192.168.1.122:9999;transport=udp
                        Expires: 2949
                        Q: -1
                        Call-ID: 61A34281A03EAD774B7CE87E3D1C009B@192.168.100.173
                        CSeq: 2
                        User-Agent: Kapanga Softphone Desktop Windows 1.00/2180b 1654855613_88A4C2D0E069_0A002700000D_508492987BAA_508492987BAB_528492987BAA
                        Received: sip:192.168.1.122:9999
                        Path: [not set]
                        State: CS_SYNC
                        Flags: 0
                        CFlags: 64
                        Socket: udp:192.168.100.173:5060
                        Methods: 16383
                        Ruid: uloc-6350e6b4-70a-1
                        Instance: [not set]
                        Reg-Id: 0
                        Server-Id: 0
                        Tcpconn-Id: -1
                        Keepalive: 0
                        Last-Keepalive: 1666246840
                        KA-Roundtrip: 0
                        Last-Modified: 1666246840
                }
        }
}

而OpenSIPS的命令是:

代码语言:javascript复制
opensips-cli -x mi ul_show_contact location 1001@192.168.100.173
代码语言:javascript复制
DEBUG: Loaded module 'mi'
DEBUG: sent command ':opensips_fifo_reply_22563:{"jsonrpc": "2.0", "id": "21695", "method": "which", "params": []}'
DEBUG: reply file '/tmp/opensips_fifo_reply_22563'
DEBUG: running in non-interactive mode mi ul_show_contact ['location', '1001@192.168.100.173']
DEBUG: running command 'ul_show_contact' '['location', '1001@192.168.100.173']'
DEBUG: positional parameters are used
DEBUG: 0. ['location', '1001@192.168.100.173']
DEBUG: running command 'ul_show_contact' '['location', '1001@192.168.100.173']'
DEBUG: sent command ':opensips_fifo_reply_30177:{"jsonrpc": "2.0", "id": "16856", "method": "ul_show_contact", "params": ["location", "1001@192.168.100.173"]}'
DEBUG: reply file '/tmp/opensips_fifo_reply_30177'
{
    "AOR": "1001",
    "Contacts": [
        {
            "Contact": "sip:1001@192.168.1.122:9999;transport=udp",
            "ContactID": "3784999887725085067",
            "Expires": 2963,
            "Q": "",
            "Callid": "7922F7BEA5AB8F92EE0AA287B27AB56F@192.168.100.173",
            "Cseq": 2,
            "User-agent": "Kapanga Softphone Desktop Windows 1.00/2180b 1654855613_88A4C2D0E069_0A002700000D_508492987BAA_508492987BAB_528492987BAA",
            "Received": "sip:192.168.1.122:9999",
            "State": "CS_SYNC",
            "Flags": 0,
            "Cflags": "NAT",
            "Socket": "udp:192.168.100.173:5060",
            "Methods": 16383
        }
    ]
}

无论传递的参数还是返回的结果,二者都非常相似。

其中Cflags保存的是分支标志,上面的例子Kamailio的分支标志是64,一般在Kamailio.cfg的开头几行能找到这样的定义:

代码语言:javascript复制
#!define FLB_NATB 6

这是处理用户注册的路由脚本:

代码语言:javascript复制
route[REGISTRAR] {
  if (!is_method("REGISTER")) return;

  if(isflagset(FLT_NATS)) {
    setbflag(FLB_NATB);  /* 如果运行到这里,ul.lookup看到的Cflags就是64, 1左移6,正好是64*/
  }
  if (!save("location")) {
    sl_reply_error();
  }
  exit;
}

OpenSIPS的分支标志是字符串,处理用户注册的路由脚本一般是:

代码语言:javascript复制
  if (nat_uac_test(23)) {
    if (is_method("REGISTER")) {
      fix_nated_register();
      setbflag("NAT");  /* 如果运行到这里,ul_show_contact看到的Cflags就是NAT */
    } else {
      fix_nated_contact();
      setflag("NAT");
    }
  }

对于Kamailio,Ruid是主键,而对于OpenSIPS,contact_id是主键。

Kamailio的usrloc模块可以配置KeepAlive参数,服务器周期性探测客户端是否在线,这样Contact里面多了几个跟KeepAlive有关的参数。OpenSIPS的usrloc模块暂时没有这个功能。

上面给的都是外部程序调用,但其实在路由脚本里面调用Kamailio的RPC或者OpenSIPS的MI,都是很方便的。下面给出例子:

kamailio.cfg:

代码语言:javascript复制
  $var(aor) = $tU   "@"   $td;
  $var(req) = '{"jsonrpc":"2.0","method":"ul.lookup","params":["location", "$var(aor)"],"id":1}';
  jsonrpc_exec("$var(req)");
  xlog("code = $jsonrpl(code)n");
  xlog("body = $jsonrpl(body)n");

opensips.cfg:

代码语言:javascript复制
  /* 需要loadmodule "mi_script.so" */
  /* 需要loadmodule "json.so",解析结果 */
  $var(aor) = $tU   "@"   $td;
  $avp(params) = $var(aor);
  $avp(params) = "location";
  mi("ul_show_contact", $var(data), $avp(params));
  xlog("data = $var(data)n");

需要注意的是,avp变量是以堆栈形式保存数据的,因此aor要放前面,接着是location,传到usrloc模块进行处理的时候参数正好反过来,location在前,aor在后。

以上代码在Kamailio5.5.5和OpenSIP3.2.8下测试通过。

0 人点赞