概述

freeswitch是一款简单好用的VOIP开源软交换平台。

fs中有非常多的接口和通道变量,使用方式多变。

官方文档有时候也仅仅是介绍了最基本的使用方法和格式。

环境

centos:CentOS  release 7.0 (Final)或以上版本

freeswitch:v1.6

GCC:4.8.5

execute_on_xxxx

fs提供了一系列的execute_on_xxxx通道变量,供使用者设置,常见的如下。

execute_on_answer

execute_on_pre_answer

execute_on_media

execute_on_ring

execute_on_tone_detect

execute_on_originate

execute_on_post_originate

execute_on_pre_originate

execute_on_pre_bridge

execute_on_post_bridge

每一个通道变量对应呼叫流程中的状态,符合呼叫状态即会调用。

比如execute_on_media,当收到183或200之后,有媒体通道建立成功,则调用对应的APP。

用法,execute_on_media特别适合做录音的启动点,可以把早期媒体和正常通话都录下来。

<action application="export" data="execute_on_media=app + params"/>

但是某些场景下,我们需要在一个状态时调用多个APP,比如当有媒体进入的时候,我们希望同时开启录音和音频检测。

<action application="export" data="execute_on_media=record_session ${record_file}.wav"/>

<action application="export" data="execute_on_media=spandsp_start_dtmf"/>

这样的配置在实际业务流程中,由于execute_on_media是通道变量,后一个会覆盖前一个,最后只会执行一个“spandsp_start_dtmf”的APP。

源码

查看switch_channel.c的源码,execute_on的函数如下,参数2“variable_prefix”为“execute_on_media”。

SWITCH_DECLARE(switch_status_t) switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)

{

switch_event_header_t *hp;

switch_event_t *event, *cevent;

int x = 0;

switch_core_get_variables(&event);

switch_channel_get_variables(channel, &cevent);

switch_event_merge(event, cevent);

for (hp = event->headers; hp; hp = hp->next) {

char *var = hp->name;

char *val = hp->value;

if (!strncasecmp(var, variable_prefix, strlen(variable_prefix))) {

if (hp->idx) {

int i;

for (i = 0; i < hp->idx; i++) {

x++;

do_execute_on(channel, hp->array[i]);

}

} else {

x++;

do_execute_on(channel, val);

}

}

}

switch_event_destroy(&event);

switch_event_destroy(&cevent);

return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;

}

可以看出,execute_on的处理流程中,会把event的全部headers遍历一遍,对于每个header,对headername和variable_prefix进行比较。

匹配则检查header的idx,idx不为0的时候,对header下的array字段轮询调用do_execute_on。

这里有两种配置方案可以实现我们需要的多次execute_on_media。

第一种,比较明显,利用header的idx,对execute_on_media设置多个值。

<action application="export" data="execute_on_media[0]=log::execute_on_media[0]"/>

<action application="export" data="execute_on_media[1]=log execute_on_media[1]"/>

第二种,隐藏方案,strncasecmp只比较固定长度。

<action application="export" data="execute_on_media-1=log::execute_on_media[0]"/>

<action application="export" data="execute_on_media-2345=log execute_on_media[1]"/>

测试方案

测试方案使用第一种配置方案,dialplan如下。

<action application="export" data="execute_on_media[0]=log::execute_on_media[0]"/>

<action application="export" data="execute_on_media[1]=log execute_on_media[1]"/>

测试结果

发起呼叫,dialplan的流程日志如下。

2023-11-22 17:54:46.345184 [NOTICE] sofia_media.c:92 Pre-Answer sofia/external/10011@10.55.55.138!

EXECUTE sofia/external/10011@10.55.55.138 log(execute_on_media[1])

2023-11-22 17:54:46.345184 [DEBUG] mod_dptools.c:1742 execute_on_media[1]

...

2023-11-22 17:54:46.345184 [DEBUG] sofia.c:7084 Channel sofia/external/10011@10.55.55.138 entering state [early][183]

2023-11-22 17:54:46.345184 [DEBUG] switch_ivr.c:623 sofia/external/10011@10.55.55.138 Command Execute log(execute_on_media[0])

EXECUTE sofia/external/10011@10.55.55.138 log(execute_on_media[0])

2023-11-22 17:54:46.345184 [DEBUG] mod_dptools.c:1742 execute_on_media[0]

总结

execute_on大部分源码在switch_channel.c中。

思考为什么测试结果中,先执行log1,再执行log0。

空空如常

求真得真

freeswitch设置多个execute_on_media的更多相关文章

  1. freeswitch设置支持视频语音编码

    1.修改FreeSWITCH安装路径下/conf/var.xml文件中,增加: <X-PRE-PROCESS cmd=="set" data="proxy_medi ...

  2. FreeSWITCH技巧:notify与message-waiting

    FreeSWITCH技巧:notify与message-waiting @(Freeswitch经验点滴) 现象描述 在客户端登陆抓包时,发现了FreeSWITCH发来的包: NOTIFY sip:9 ...

  3. 线程池c3p0和dbcp2的配置初始化实例

    一.c3p0 public class ConnectionManager { public static ComboPooledDataSource dataSource; static { try ...

  4. Linux命令总结大全,包含所有linux命令

    使用说明:此文档包含所有的Linux命令,只有你想不到的没有你看不到的,此文档共计10万余字,有8400多行,预计阅读时间差不多需要3个小时左右,所以要给大家说一说如何阅读此文档 为了方便大家阅读,我 ...

  5. FreeSWITCH黑名单功能设置

    功能描述:对呼叫的号码进行过滤 步骤: 1.编译mod_blacklist 模块:进入源目录/usr/local/src/freeswitch  --> make mod_blacklist-i ...

  6. 使用FreeSWITCH做电话自动回访设置

    一.背景介绍: 目前公司在处理客户回访方面,需要人工进行电话回访,尤其是逢年过节的时候,电话问候更能体现服务的品质: 在某些公司,电话销售员需要给大批量的陌生用户打电话,如果能过滤掉不关心的用户,销售 ...

  7. FreeSWITCH 客户端fs_cli连接设置(acl)

    FreeSWITCH 默认配置只能 在本机连接, 要从 外面连接, 就要配置: acl.conf.xml::network-lists/list event_socket.conf.xml::appl ...

  8. freeswitch控制台日志级别设置以及存储

    1.在管理控制台上设置 console loglevel (0~7)越往上级别越大 2.打开sip详细日志 sofia profile internal siptrace on 3.关闭sip详细日志 ...

  9. freeswitch模块之event_socket

    这是我之前整理的关于freeswitch mod_event_socket的相关内容,这里记录下,也方便我以后查阅. mod_event_socket以socket的形式,对外提供控制FS一种途径, ...

  10. freeswitch呼叫流程分析

    今天翻文档时发现之前整理的关于freeswitch呼叫相关的内容,写成博文分享出来也方便我以后查阅. 整体结构图 FreeswitchCore 模块加载过程 freeswitch主程序初始化时会从mo ...

随机推荐

  1. Hugging News #0731: 新课程重磅发布、用户交流群邀请你加入、真实图像编辑方法 LEDTIS 来啦!

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  2. .NET周刊【8月第1期 2023-08-06】

    国内文章 NativeBuferring,一种零分配的数据类型(上篇) https://www.cnblogs.com/artech/p/17586781.html 之前一个项目涉及到针对海量(千万级 ...

  3. VS2015项目.net-framework-4.5.2升级或新建项目无法选择framework 4.6.2(解决办法)

    VS2015里面没有.NET Framework 4.6.2 VS2015默认安装的目标框架最高是.NET Framework 4.6.1,但是我的项目里面某些NuGet软件包更新需要依赖.NET F ...

  4. Oracle数据库字符集概述及修改方式

    1.字符集概述 Oracle语言环境的描述包括三部分:language.territory.characterset(语言.地域.字符集) language:主要指定服务器消息的语言,提示信息显示中文 ...

  5. 领域驱动设计(DDD):三层架构到DDD架构演化

    三层架构的问题 在前文中,我从基础代码的角度探讨了如何运用领域驱动设计(DDD)来实现高内聚低耦合的代码.本篇文章将从项目架构的角度,继续探讨三层架构与DDD之间的演化过程,以及DDD如何优化架构的问 ...

  6. ThreadLocal:线程中的全局变量

    最近接了一个新需求,业务场景上需要在原有基础上新增2个字段,接口新增参数意味着很多类和方法的逻辑都需要改变,需要先判断是否属于该业务场景,再做对应的逻辑.原本的打算是在入口处新增变量,在操作数据的时候 ...

  7. KRPANO资源分析工具下载720YUN全景图

    提示:目前分析工具中的全景图下载功能将被极速全景图下载大师替代,相比分析工具,极速全景图下载大师支持更多的网站(包括各类KRPano全景网站,和百度街景) 详细可以查看如下的链接: 极速全景图下载大师 ...

  8. Ds100p -「数据结构百题」51~60

    纪念 数据结构一百题50题了呢,该过半周年啦~~~~ LYC和WGY半年的努力让这个几乎玩笑一般的系列到了现在. 今后也请多多关照啦. 祝愿dp100p早日过半 51.CF1000F One Occu ...

  9. Go 语言开发环境搭建

    Go 语言开发环境搭建 目录 Go 语言开发环境搭建 一. GO 环境安装 1.1 下载 1.2 Go 版本的选择 1.3 安装 1.3.1 Windows安装 1.3.2 Linux下安装 1.3. ...

  10. python---简单最大类间方差法(OTSU)算法

    from matplotlib import pyplot as plt # cv2.imread()用于读取图片文件 # imread函数有两个参数,第一个参数是图片路径,第二个参数表示读取图片的形 ...