介绍kamailio的dialog模块

2023-11-06 09:44
文章标签 模块 介绍 dialog kamailio

本文主要是介绍介绍kamailio的dialog模块,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

# 介绍kamailio的dialog模块

`kamailio`的`dialog`模块一般有四个作用:

- 读写对话变量
- 跟`uac`模块配合,完成`uac trunk auth`功能
- 统计`early_dialogs`和`active_dialogs`等
- 利用`dialog profile`实现分类统计功能或者实现呼叫限制功能

`dialog`模块的参数可以配置如下:

```
modparam("dialog", "db_url", DBURL)
modparam("dialog", "enable_stats", 1) # 使能统计功能
modparam("dialog", "db_mode", 1)
modparam("dialog", "dlg_flag", DLG_FLAG) # 范围是0:31
modparam("dialog", "dlg_match_mode", 1)
modparam("dialog", "default_timeout", 43200 ) # 12小时,设置dialog超时时间
modparam("dialog", "track_cseq_updates", 1)
modparam("dialog", "profiles_no_value", "total; emergency")
modparam("dialog", "profiles_with_value", "user; type; account")
```

下面这段路由脚本创建对话:

```
route[INVITE] {
    if (is_method("INVITE") && !has_totag()) {
        setflag(DLG_FLAG); # 创建对话,跟dlg_flag参数的值对应起来
        # dlg_manage(); # 调用这个函数也可以创建对话
    }
    return;
}
```

目前对话变量仅支持字符串类型,下面这段代码可以证明这点:

```
$dlg_var(test_i) = 1;
if (!pv_isset("$dlg_var(test_i)")) {
    xerr("route run here, file=$cfg(file) line=$cfg(line)\n");
}

$dlg_var(test_s) = '1';
if (pv_isset("$dlg_var(test_s)")) {
    xinfo("route run here, file=$cfg(file) line=$cfg(line)\n");
}
```

我们知道`avp`变量仅在事务期间有效,如果想在整个对话期间都有效那就需要用到对话变量了

对话变量常见的使用场景可能是写自己的话单,这里给出路由脚本:

```
route[INVITE] {
    if (is_method("INVITE") && !has_totag()) {
        dlg_manage();
        $dlg_var(SetupTime) = $TS;
    }
    return;
}

event_route[dialog:start] {
    $dlg_var(AnswerTime) = $TS;
}

event_route[dialog:end] {
    $dlg_var(EndTime) = $TS;
    $dlg_var(BillSec) = (str)($dlg_var(EndTime) - $dlg_var(AnswerTime));  # 转成字符串类型
    xinfo("+++$dlg_var(BillSec)\n");

    $var(x) = $_s({"Event":"Call_End", "CallID":"$dlg(callid)", "From":"$dlg(from_uri)", "To":"$dlg(to_uri), ");
    $var(x) = $var(x) + $_s("SetupTime":$dlg_var(SetupTime), "AnswerTime":$dlg_var(AnswerTime), "EndTime":$dlg_var(EndTime), "BillSec":$dlg_var(BillSec)});

    xinfo("$var(x)\n");
    # http post
}
```

接下来讨论`uac trunk auth`,流程如下:

```
1. A -> INVITE -> kamailio                     B
2. A              kamailio ->    INVITE     -> B CSeq
3. A              kamailio <-    401(7)     <- B
4. A              kamailio -> INVITE (auth) -> B CSeq+1
5. A              kamailio <-      200      <- B
6. A  <- 200 <-   kamailio
```

把`dialog`模块的`track_cseq_updates`参数配置为1,第四步`CSeq`就会自动加一

模块配置和路由脚本示意如下:

```
#!define UAC_CONTACT_ADDRESS "192.168.1.100:5060"

modparam("uac", "reg_db_url", DBURL)
modparam("uac", "reg_timer_interval", 3)
modparam("uac", "reg_retry_interval", 28)
modparam("uac", "reg_gc_interval", 30)
modparam("uac", "reg_contact_addr", UAC_CONTACT_ADDRESS)
modparam("uac", "auth_realm_avp", "$avp(arealm)")
modparam("uac", "auth_username_avp", "$avp(auser)")
modparam("uac", "auth_password_avp", "$avp(apasswd)")
modparam("uac", "reg_keep_callid", 1)

route[GW] {
    $du = "sip:192.168.1.101:5060";
    t_on_failure("TRUNKAUTH");
    t_relay();
    exit;
}

failure_route[TRUNKAUTH] {
    if (t_is_canceled()) {
        exit;
    }

    if(t_check_status("401|407")) {
        $avp(auser) = "test"; # 实际使用时需从数据库取出用户名和密码
        $avp(apasswd) = "test"; # 同上
        if (uac_auth()) {
            t_relay();
        }
        exit;
    }
}
```

接下来我们讨论`dialog`自带的统计功能

`enable_stats`参数配置为1就可以使能了

这里有二个`shell`命令,都可以查到`dialog`模块的统计:

```shell
kamcmd stats.get_statistics all | grep dialog
```

```shell
kamcmd dlg.stats_active
```

最后我们讨论`dialog profile`方面的问题

比如,`dialog`这样配置模块参数:

```
modparam("dialog", "profiles_no_value", "total; emergency")
modparam("dialog", "profiles_with_value", "user; type; account")
```

那么我们这样写路由:

```
route[INVITE] {
    if (is_method("INVITE") && !has_totag()) {
        dlg_manage();
        set_dlg_profile("total");
    }

    route(LOCATION);
    return;
}
```

现在做一个呼叫测试,6001呼叫6002

```shell
$kamcmd dlg.profile_get_size total
1
```

结果是1

下面这个命令得到的输出更加详细:

```shell
$kamcmd dlg.profile_list total
{
    h_entry: 3702
    h_id: 5131
    ref: 2
    call-id: ef6fcea66f0f40938cc3060226340f39
    from_uri: sip:6002@192.168.100.200
    to_uri: sip:6001@192.168.100.200
    state: 4
    start_ts: 1691650230
    init_ts: 1691650229
    end_ts: 0
    duration: 35
    timeout: 1691693429
    lifetime: 43200
    dflags: 1536
    sflags: 0
    iflags: 0
    caller: {
        tag: fa86e515d20348c6b217ae3bd4efcefc
        contact: sip:6002@192.168.100.172:61224;ob
        cseq: 32127
        route_set:
        socket: udp:192.168.100.200:5060
    }
    callee: {
        tag: 8CC433477696B38087EC8FFAB0858E00
        contact: sip:6001@192.168.100.121:5060;transport=udp
        cseq: 0
        route_set:
        socket: udp:192.168.100.200:5060
    }
    profiles: {
        total
    }
    variables: {
    }
}
```

请注意,`variables`无值

下面是进一步的说明:

- set_dlg_profile("total");  # 没问题,因为profiles_no_value里面已定义total
- set_dlg_profile("emergency"); # 没问题,因为profiles_no_value里面已定义emergency
- set_dlg_profile("total", "$fu");  # 不行,因为profiles_with_value没有定义total
- set_dlg_profile("user", "$fu");  # 没问题,因为profiles_with_value已定义user

分类统计方面我们可以给一个例子:

```
modparam("dialog", "profiles_no_value", "total; local; domestic; international")

route[INVITE] {
    if (is_method("INVITE") && !has_totag()) {
        dlg_manage();
        set_dlg_profile("total"); # 总的呼叫数加一
        if ($tU =~ "^00") {
            set_dlg_profile("international"); # 国际长途呼叫数加一
        } else if ($tU =~ "^0") {
            set_dlg_profile("domestic"); # 国内长途呼叫数加一
        } else {
            set_dlg_profile("local"); # 本地呼叫数加一
        }
    }

    route(LOCATION);
    return;
}
```

至于如何实现呼叫限制功能,网上能查到的资料非常丰富,这里就不再赘述了。
 

这篇关于介绍kamailio的dialog模块的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/355860

相关文章

python logging模块详解及其日志定时清理方式

《pythonlogging模块详解及其日志定时清理方式》:本文主要介绍pythonlogging模块详解及其日志定时清理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录python logging模块及日志定时清理1.创建logger对象2.logging.basicCo

Qt spdlog日志模块的使用详解

《Qtspdlog日志模块的使用详解》在Qt应用程序开发中,良好的日志系统至关重要,本文将介绍如何使用spdlog1.5.0创建满足以下要求的日志系统,感兴趣的朋友一起看看吧... 目录版本摘要例子logmanager.cpp文件main.cpp文件版本spdlog版本:1.5.0采用1.5.0版本主要

Pytest多环境切换的常见方法介绍

《Pytest多环境切换的常见方法介绍》Pytest作为自动化测试的主力框架,如何实现本地、测试、预发、生产环境的灵活切换,本文总结了通过pytest框架实现自由环境切换的几种方法,大家可以根据需要进... 目录1.pytest-base-url2.hooks函数3.yml和fixture结论你是否也遇到过

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

Python使用date模块进行日期处理的终极指南

《Python使用date模块进行日期处理的终极指南》在处理与时间相关的数据时,Python的date模块是开发者最趁手的工具之一,本文将用通俗的语言,结合真实案例,带您掌握date模块的六大核心功能... 目录引言一、date模块的核心功能1.1 日期表示1.2 日期计算1.3 日期比较二、六大常用方法详

MySQL中慢SQL优化的不同方式介绍

《MySQL中慢SQL优化的不同方式介绍》慢SQL的优化,主要从两个方面考虑,SQL语句本身的优化,以及数据库设计的优化,下面小编就来给大家介绍一下有哪些方式可以优化慢SQL吧... 目录避免不必要的列分页优化索引优化JOIN 的优化排序优化UNION 优化慢 SQL 的优化,主要从两个方面考虑,SQL 语

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

Python实现html转png的完美方案介绍

《Python实现html转png的完美方案介绍》这篇文章主要为大家详细介绍了如何使用Python实现html转png功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 1.增强稳定性与错误处理建议使用三层异常捕获结构:try: with sync_playwright(

Java使用多线程处理未知任务数的方案介绍

《Java使用多线程处理未知任务数的方案介绍》这篇文章主要为大家详细介绍了Java如何使用多线程实现处理未知任务数,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 知道任务个数,你可以定义好线程数规则,生成线程数去跑代码说明:1.虚拟线程池:使用 Executors.newVir

python中time模块的常用方法及应用详解

《python中time模块的常用方法及应用详解》在Python开发中,时间处理是绕不开的刚需场景,从性能计时到定时任务,从日志记录到数据同步,时间模块始终是开发者最得力的工具之一,本文将通过真实案例... 目录一、时间基石:time.time()典型场景:程序性能分析进阶技巧:结合上下文管理器实现自动计时