概述

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. Yunfly 一款高效、性能优异的 node.js web 框架

    介绍 Yunfly 一款高性能 Node.js WEB 框架, 使用 Typescript 构建我们的应用. 使用 Koa2 做为 HTTP 底层框架, 使用 routing-controllers ...

  2. Kitex微服务开发实践(ETCD服务注册)

    服务注册通常用于分布式系统或微服务架构中,是一种用于管理和发现这些分布式服务的机制.它的目标是让服务能够动态地找到其他服务,并能够与其进行通信,而无需显式地配置其位置信息 本文简单讲述使用etcd进行 ...

  3. Linux下apt与dpkg的详解

    apt是一个包管理工具,用于管理Debian和Ubuntu等基于Debian的Linux发行版中的软件包.它是"Advanced Packaging Tool"的缩写,允许用户在系 ...

  4. 利用选项卡提高Visual Studio 2022开发效率

    设计器作为软件开发的必要工具,其效率的提高显得尤为重要.Visual Studio 2022作为一款功能强大的设计器,通过选项卡提高了工作效率,让开发者在使用过程中更加便捷. 在Visual Stud ...

  5. vue3探索——组件通信之事件总线

    Vue2.x使用EventBus进行组件通信,而Vue3.x推荐使用mitt.js. 比起Vue实例上的EventBus,mitt.js好在哪里呢?首先它足够小,仅有200bytes,其次支持全部事件 ...

  6. redhat7查找已接网线但是还未配置IP的网卡接口

    方法一:nmcli 输出中参数WIRED-PROPERTIES.CARRIER为on即为接网线网卡 #nmcli device show |grep -i -E "device|carrie ...

  7. web应用及微信小程序版本更新检测方案实践

    背景: 随着项目体量越来越大,用户群体越来越多,用户的声音也越来越明显:关于应用发版之后用户无感知,导致用户用的是仍然还是老版本功能,除非用户手动刷新,否则体验不到最新的功能:这样的体验非常不好,于是 ...

  8. 文心一言 VS 讯飞星火 VS chatgpt (96)-- 算法导论9.3 1题

    一.用go语言,在算法 SELECT 中,输人元素被分为每组 5 个元素.如果它们被分为每组 7个元素,该算法仍然会是线性时间吗?证明:如果分成每组 3 个元素,SELECT 的运行时间不是线性的. ...

  9. Solution -「GXOI / GZOI 2019」AND OR Sum

    Description Link. 给定一个 \(N \times N\) 的矩阵,她希望求出: 该矩阵的所有子矩阵的 \(\texttt{AND}\) 值之和(所有子矩阵 \(\texttt{AND ...

  10. 2023-09-23:用go语言,假设每一次获得随机数的时候,这个数字大于100的概率是P。 尝试N次,其中大于100的次数在A次~B次之间的概率是多少? 0 < P < 1, P是double类型,

    2023-09-23:用go语言,假设每一次获得随机数的时候,这个数字大于100的概率是P. 尝试N次,其中大于100的次数在A次~B次之间的概率是多少? 0 < P < 1, P是dou ...