Kamailio Transformations:常用的伪变量转换函数

Kamailio Transformations:常用的伪变量转换函数

伪变量转换函数大部分在 pv 模块中处理,官方文档记录的很全面,但是给的例子比较少。本文列举比较常用的转换函数。

参数列表转换

{param.value,name[, delimiter]}

根据名字从参数列表里面找到对应的项目,并返回其值 name 是参数名字,delimiter 是定界符。


$var(x) = "a=1;b=2;c=3";
$var(c) = $(var(x){param.value,c}); // "3"

// 默认定界符是分号,但也可以指定其它定界符(逗号除外)
$var(x) = "a=1&b=2&c=3";
$var(c) = $(var(x){param.value,c,&}); // "3"

// 下面的代码是错误的,定界符不能用逗号
$var(x) = "a=1,b=2,c=3";
$var(c) = $(var(x){param.value,c,,}); // 错误提示是 invalid separator in transformation: value,c,,

这个函数非常有用,比如我们可以在 FreeSWITCH 里面配置一个网关,realm 指向 Kamailio ,contact-params 指向 IMS。

<param name="realm" value="192.168.1.100"/> <!--Kamailio-->
<param name="contact-params" value="gwaddr=192.168.1.200:5060"/> <!--IMS-->

Kamailio 的 request 路由可以这样写:

route[SRC_FREESWITCH] {
  $var(params) = $(sel(contact.uri.params)); // 取 contact 的参数
  $var(gwaddr) = $(var(params){param.value,gwaddr}); // 取网关地址
  $du = "sip:" + $var(gwaddr);
  t_relay();
  exit;
}
{param.valueat,index[, delimiter]}

根据索引从参数列表里面找到对应的项目,并返回其值,index 是索引号(从 0 开始),delimiter 是定界符。

$var(x) = "a=1;b=2;c=3";
$var(b) = $(var(x){param.valueat,1}); // "2"

字符串转换

{s.int}

字符串转整数


$var(x) = "1234";
$var(i) = $(var(x){s.int}); // 1234

$var(x) = "1234.2";
$var(i) = $(var(x){s.int}); // 出错

$var(x) = "s1234";
$var(i) = $(var(x){s.int}); // 出错
{s.numeric}

删除字符串的所有非数字部分,并转成整数。

$var(x) = "(040)1234/567-89";
$var(num) = $(var(x){s.numeric}); // 040123456789
{s.ftime,format}

删除字符串里面的单引号对和双引号对。

$var(x) = "'alice'";
$var(alice) = $(var(x){s.unquote}); // "alice"

$var(x) = "'alice";
$var(alice) = $(var(x){s.unquote}); // "'alice",没有变化,因为单引号没有成对
{s.unbracket}

删除字符串里面的 () 对、 [] 对、 {} 对以及 <> 对。

$var(x) = "<sip:alice@test.sip>";
$var(uri) = $(var(x){s.unbracket}); // "sip:alice@test.sip"

用这个函数来处理 Contact 头比较方便。

URI 转换

$var(contact) = "sip:1001@192.168.1.100:5080;transport=udp;a=1;b=2";

$var(a)=$(var(contact){uri,param,a}); // "1"
$var(c)=$(var(contact){uri,param,c}); // ""
$var(a)=$(var(contact){uri.params}); // "transport=udp;a=1;b=2"
$var(a)=$(var(contact){uri.host}); // "192.168.1.100"
$var(a)=$(var(contact){uri.port}); // "5080"
$var(a)=$(var(contact){uri.user}); // "1001"
$var(a)=$(var(contact){uri.scheme}); // "sip"

多行文本转换

{line.count}

返回多行文本的行数。

{line.sw,match}

返回以 match 开头的行。

# 字符串赋值
$var(sdp) = "v=0\r\n";
$var(sdp) = $var(sdp) + "o=freeswitch 1680834355 1680834356 IN IP4 192.168.1.100\r\n";
$var(sdp) = $var(sdp) + "s=freeswitch\r\n";
$var(sdp) = $var(sdp) + "c=IN IP4 192.168.1.100\r\n";
$var(sdp) = $var(sdp) + "t=0 0\r\n";
$var(sdp) = $var(sdp) + "m=audio 2560 RTP/AVP 8 101\r\n";
$var(sdp) = $var(sdp) + "a=rtpmap:8 PCMA/8000\r\n";
$var(sdp) = $var(sdp) + "a=rtpmap:101 telephone-event/8000\r\n";
$var(sdp) = $var(sdp) + "a=fmtp:101 0-15\r\n";
$var(sdp) = $var(sdp) + "a=sendrecv\r\n";
$var(sdp) = $var(sdp) + "a=ptime:20\r\n";

$var(media) = $(var(sdp){line.sw,m=audio}); // 得到的值是 "m=audio 2560 RTP/AVP 8 101",$var(sdp) 是多行文本,line.sw 函数找到包含 m=audio 的那一行
$var(count) = $(var(sdp){line.count});  // 得到的值是 11 ,`$var(sdp)` 有 11 行

这个函数有用,比如下面的路由代码把 sdp 里面的 ptime 属性强制修改成 10 (尽管很少这么做)。

loadmodule "textops.so"
loadmodule "textopsx.so"
loadmodule "sdpops.so"

...

route[MODIFY_PTIME_10] {
  if (has_body("application/sdp")) {
    $var(body) = $sdp(body);
    $var(ptime_line) = $(var(body){line.sw,a=ptime});
    $var(new_ptime_line) = "a=ptime:10";
    replace_body($var(ptime_line), $var(new_ptime_line));
    msg_apply_changes();
    xinfo("newsdp = $sdp(body)\n");
  }
}

正则表达式替换

{re.subst,expression}

此转换类由 textops 模块导出,对伪变量执行 POSIX 正则表达式替换。

$var(s) = "9123456789";
$var(s1) = $(var(s){re.subst,/^9(.*)/\1/}); // 去掉字冠 9,得到 123456789

再举一个比较实用的例子:

$var(contact) = '"XiaoYingTao" <sip:6753997@xwitch.cn:5060>';
$var(uri) = $(var(contact){re.subst,/^.*<(sip:.*)>/\1/});  // 得到 sip:6753997@xwitch.cn:5060

还有一个例子:

$var(sdp) = "v=0\r\n";
$var(sdp) = $var(sdp) + "o=- 1704250570 3 IN IP4 192.168.1.100\r\n";
$var(sdp) = $var(sdp) + "s=-\r\n";
$var(sdp) = $var(sdp) + "c=IN IP4 192.168.1.100\r\n";
$var(sdp) = $var(sdp) + "t=0 0\r\n";
$var(sdp) = $var(sdp) + "m=audio 30608 RTP/AVPF 8\r\n";
     
$var(new_sdp) = $(var(sdp){re.subst,/AVPF/AVP/g}); # 把 sdp 里面的 AVPF 替换成 AVP

 json 转换 

此转换类由 json 模块导出。

loadmodule "json.so"

...

$var(j) = '{"a":"1", "b":2}';
$var(a) = $(var(j){json.parse,a}); // "1"
$var(b) = $(var(j){json.parse,b}); // "2" ,字符串,不是整数
$var(c) = $(var(j){json.parse,c}); // ""

作者:韩小仿
来源:FreeSWITCH中文社区
原文:https://mp.weixin.qq.com/s/8k7yA-FjW0tSZ31k4P4c5Q

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论