第一篇描述了mod_conference控制原理,第二篇描述了conference相关事件,接下来对esl内联程序做简要说明。

由于event-socket采用TCP协议,因此需要一个线程与freeswitch保持长连接,轮询相关事件并上报应用层;另外一个线程接受应用层命令,并控制freeswitch。这两个线程需要共享一个重要参数esl连接"esl_handle_t *pHanndle";当然线程二也可以连接到fs,与线程一使用不同的esl_handle_t,不订阅事件即可。本人采用两个线程共享一个esl链接方式。

备注:以下代码未测试,仅作参考

线程一:


esl_handle_t handle = {{0}};
esl_status_t status;
while((status=esl_connect(&handle, "127.0.0.1", 8021, NULL, "ClueCon")) != ESL_SUCCESS)
{
        printf("esl_connect error:%s:%d\n",handle.err,status);
        sleep(5);
}
esl_events(&handle, ESL_EVENT_TYPE_PLAIN, "CHANNEL_CREATE CHANNEL_ANSWER CHANNEL_HANGUP_COMPLETE DTMF CUSTOM conference::maintenance");
esl_filter(&handle,"action","conference-create");
esl_filter(&handle,"action","conference-destroy");
esl_filter(&handle,"action","add-member");
esl_filter(&handle,"action","del-member");
esl_filter(&handle,"action","mute-member");
esl_filter(&handle,"action","unmute-member");
//esl_filter(&handle,"action","kick-member");
//esl_filter(&handle,"action","floor-change");
esl_filter(&handle,"Event-Name","DTMF");
esl_filter(&handle,"Event-Name","CHANNEL_CREATE");
esl_filter(&handle,"Event-Name","CHANNEL_ANSWER");
esl_filter(&handle,"Event-Name","CHANNEL_HANGUP_COMPLETE"); while((status = esl_recv_timed(&handle,1000)) != ESL_FAIL)
{
        if(status != ESL_SUCCESS)
        {
                usleep(100);
                continue;
        }
        const char *type = esl_event_get_header(handle.last_event, "content-type");
        if(type==NULL || strcasecmp(type, "text/event-plain")!=0)
        {
                continue;
        }         if(handle.last_event->body!=NULL)
        {
                proc_event(handle.last_event->body);
        }
}
printf("diconnected:%d\n",status);//此处可作断线重连操作
esl_disconnect(&handle);

上述代码连接到fs event-socket,订阅事件、过滤事件、接收事件并处理。proc_event函数对订阅的事件进行解码、识别、处理。

线程二:业务线程,自行实现,以下说明如何向fs发命令。


char cmd[128]={0x00};
uuid_t uuid;char str[36];
uuid_generate(uuid);
uuid_unparse(uuid, str);
snprintf(cmd,256,"bgapi originate "
                "{origination_uuid=%s,bridge_early_media=false,ignore_early_media=true,effective_caller_id_number=%s,dtmf_type=%s,execute_on_answer=start_dtmf}"
                "sofia/gateway/%s/%s %s XML default"
                ,str,pFsm->ecp_phone,gw_dtmf_type,gw_name,phone,pFsm->confname);
//save_uuid_taskid(str,pFsm->taskid); if(pFsm->fsnode->node_handle != NULL)
esl_send(pFsm->fsnode->node_handle,cmd);

当然,首先得取到esl连接的句柄handle,向fs发消息需要该handle,其次必须得校验该handle,防止esl断线了还调用esl_send进行发送导致出错。也可进一步对esl_send返回值校验,这里忽略了。

具体使用可以参考esl源代码获取相关API。

2015/2/14补充:

为了便于会场控制、计费,最终实现时取消了CHANNEL_HANGUP_COMPLETE事件的订阅,改为订阅CHANNEL_HANGUP事件。mod_conference对CHANNELS内事件作了“订阅”,当收到CHANNEL_HANGUP事件时会在会场中踢出对应的参会者,进而产生MEMBER-DEL事件,CHANNEL_HANGUP_COMPLETE在最后产生。即收到的事件顺序为:CHANNEL_CREATE->CHANNEL_ANSWER->MEMBER_ADD->CHANNEL_HANGUP->MEMBER-DEL->CHANNEL_HANGUP_COMPLETE,开发时注意这一点“收到事件的先后顺序”即可。

mod_conference ESL控制三(程序)的更多相关文章

  1. mod_conference ESL控制二(事件)

    根据上篇所述功能需求,esl需要处理以下几类事件: ESL_EVENT_CHANNEL_*  #channel相关事件,用户判断参会者是否应答.计费 DTMF事件 #识别参会者按键,根据按键进行操作( ...

  2. mod_conference ESL控制一(原理)

    本文介绍通过freeswitch mod_conference 的配置和APP,以及如何通过这些事件实现会议控制. 需求 ESL内联,发起会议.加人.踢人.静音.恢复静音.申请发言.结束会议等基础功能 ...

  3. PIC12F629帮我用C语言写个程序,控制三个LED亮灭

    http://power.baidu.com/question/240873584599025684.html?entry=browse_difficult PIC12F629帮我用C语言写个程序,控 ...

  4. 使用C#模拟键盘输入、鼠标移动和点击、设置光标位置及控制应用程序的显示

    1.模拟键盘输入(SendKeys) 功能:将一个或多个按键消息发送到活动窗口,就如同在键盘上进行输入一样. 语法:SendKeys.Send(string keys);SendKeys.SendWa ...

  5. 控制 Android 程序使用的内存

    如何控制应用程序使用的内存? 1. 记得关闭启动的服务 当服务中的任务完成后,要记得停止该服务.可以考虑使用 IntentService,因为 IntentService 在完成任务后会自动停止. 2 ...

  6. c#控制WPF程序自动登录(Automation方式实现)

    说明:winForm窗体,可以通过win32接口dll的findWindow之类的函数来实现查找winform窗口,mfc窗口等. 但是wpf却是不实用这些,可以靠automation方式来进行操作. ...

  7. Linux及安全实践三——程序破解

    Linux及安全实践三--程序破解 一.基本知识 常用指令机器码 指令 作用 机器码 nop 无作用(no operation) 90 call 调用子程序,子程序以ret结尾 e8 ret 返回程序 ...

  8. vscode 显示"没有活动的源代码控制提供程序“处理

    不知为何我的 VS Code 在 1.25 版本开始就一直 ”没有活动的源代码控制提供程序“,找了好几天都没找到,今天终于找到怎么处理了, 切换到插件中找到下图对应的 Git (可以直接再上面搜索框输 ...

  9. VSCode Git 没有活动的源代码控制提供程序

    主要原因:我以前安装的Git只允许在Git-Bash中运行,需要重新安装Git,选择允许三方软件的那个选项,然后安装Git插件,修改git.path即可. 以下是解决过程中的尝试,记录如下,实际上只需 ...

随机推荐

  1. Android一个工程引用另一个工程的方法

    一个工程包含另一个工程.相当于一个jar包的引用.但又不是jar包反而像个package 现在已经有了一个Android工程A.我们想扩展A的功能,但是不想在A的基础上做开发,于是新建了另外一个And ...

  2. (转载)UnityShader学习笔记(七) 让贴图纹理动起来(河流瀑布特效、精灵序列帧实现)

    大家好,我是Zander.这一章我们将使用纹理贴图实现动画.混合和真实特效来达到理想的效果. 纹理贴图可以使我们的着色器快速的实现逼真的效果,但是如果添加的纹理贴图过多,会非常影响游戏性能,特别是在移 ...

  3. Linux——命令

    1.pod2text    # 功能输出处理对象(脚本)中的的=head1 ...=head1 ......=cut框架中的信息 2.date           # 输出时间  eg: Sat Ju ...

  4. 导出html table 数据到Excel

    其实只需要复制  粘贴.... <script type="text/javascript" src="http://code.jquery.com/jquery- ...

  5. 【BZOJ】 4813: [Cqoi2017]小Q的棋盘

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4813 暴力转移就好,考虑以某一个点为根的子树分为是否走回来两种情况 ${f_{i,j}}$ ...

  6. MVC _Ajax的使用【七】

    一.本篇主要写的是在MVC项目中一种ajax的使用方法 1.  首先在控制器中创建两个方法,showCreate()和AddUserInfo() using System; using System. ...

  7. IDEA复制某个类的包名路径

    在对应的类中右键: 然后看图:

  8. R apply() 函数和 tapply() 函数

    apply(a,b,c) a是矩阵 b是行或列的代表,1是行,2是列 c是执行函数,如求和-sum,求平均-mean,求-range tapply(a,b,c) a是一个一维数据,           ...

  9. h5设计图尺寸

    640 标准的话 设计图: 640*1136 body,html 背景图的话需要640*1008的 这样才能整屏刚刚好 750 标准的话 设计图: 750*1334 body,html背景图的话,75 ...

  10. 《SQL 基础教程》第二章:查询基础

    这一章的结构如下: SELECT 语句基础 算术运算符和比较运算符 逻辑运算符 SELECT 语句可用于查询数据,并且可以设定条件来查询具有特定值的记录.条件的设定就需要算数运算符.比较运算符和逻辑运 ...