mod_conference ESL控制三(程序)
第一篇描述了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控制三(程序)的更多相关文章
- mod_conference ESL控制二(事件)
根据上篇所述功能需求,esl需要处理以下几类事件: ESL_EVENT_CHANNEL_* #channel相关事件,用户判断参会者是否应答.计费 DTMF事件 #识别参会者按键,根据按键进行操作( ...
- mod_conference ESL控制一(原理)
本文介绍通过freeswitch mod_conference 的配置和APP,以及如何通过这些事件实现会议控制. 需求 ESL内联,发起会议.加人.踢人.静音.恢复静音.申请发言.结束会议等基础功能 ...
- PIC12F629帮我用C语言写个程序,控制三个LED亮灭
http://power.baidu.com/question/240873584599025684.html?entry=browse_difficult PIC12F629帮我用C语言写个程序,控 ...
- 使用C#模拟键盘输入、鼠标移动和点击、设置光标位置及控制应用程序的显示
1.模拟键盘输入(SendKeys) 功能:将一个或多个按键消息发送到活动窗口,就如同在键盘上进行输入一样. 语法:SendKeys.Send(string keys);SendKeys.SendWa ...
- 控制 Android 程序使用的内存
如何控制应用程序使用的内存? 1. 记得关闭启动的服务 当服务中的任务完成后,要记得停止该服务.可以考虑使用 IntentService,因为 IntentService 在完成任务后会自动停止. 2 ...
- c#控制WPF程序自动登录(Automation方式实现)
说明:winForm窗体,可以通过win32接口dll的findWindow之类的函数来实现查找winform窗口,mfc窗口等. 但是wpf却是不实用这些,可以靠automation方式来进行操作. ...
- Linux及安全实践三——程序破解
Linux及安全实践三--程序破解 一.基本知识 常用指令机器码 指令 作用 机器码 nop 无作用(no operation) 90 call 调用子程序,子程序以ret结尾 e8 ret 返回程序 ...
- vscode 显示"没有活动的源代码控制提供程序“处理
不知为何我的 VS Code 在 1.25 版本开始就一直 ”没有活动的源代码控制提供程序“,找了好几天都没找到,今天终于找到怎么处理了, 切换到插件中找到下图对应的 Git (可以直接再上面搜索框输 ...
- VSCode Git 没有活动的源代码控制提供程序
主要原因:我以前安装的Git只允许在Git-Bash中运行,需要重新安装Git,选择允许三方软件的那个选项,然后安装Git插件,修改git.path即可. 以下是解决过程中的尝试,记录如下,实际上只需 ...
随机推荐
- [c/c++] programming之路(25)、字符串(六)——memset,Unicode及宽字符,strset
一.memset #include<stdio.h> #include<stdlib.h> #include<memory.h> void *mymemset(vo ...
- 分析hello1项目里面的web.xml
在example目录下的web\jsf\hello1\target\hello1\WEB-INF路径里可以找到hello1的web.xml <?xml version="1.0&quo ...
- (转载)Unity3D开发之编辑器统一修改Text字体
最近遇到一个需求,就是我们在做完一个场景后,美工感觉字体不好看,效果不是很好,想要换一种字体.UGUI的界面已经搭完,如果要一个一个Text寻找,工作量将是巨大.而且作为程序人员是不会容忍自己做这些机 ...
- JavaScript形而上的单例模式
什么是单例模式? 单例模式是指,类多次实例化返回的对象是同一个. 反例 var tt = function(name){ this.name = name; }; var t1 = new tt('t ...
- Java问题解决:The project cannot be built until build path errors are resolved
参考:http://blog.csdn.net/marty_zhu/article/details/2566299 1,看看project -- Build Automatically有没有勾上?如果 ...
- Openstack官网文档简介
OpenStack documentation相关文档见 docs.openstack.org. 主要包含这些方面的文档: Installation Guides Deployment Guides ...
- 数据结构与算法之PHP排序算法(堆排序)
一.堆的定义 堆通常是一个可以被看做一棵树的数组对象,其任一非叶节点满足以下性质: 1)堆中某个节点的值总是不大于或不小于其父节点的值: 每个节点的值都大于或等于其左右子节点的值,称为大顶堆.即:ar ...
- golang并发(1)介绍
概述 简而言之,所谓并发编程是指在一台处理器上“同时”处理多个任务. 随着硬件的发展,并发程序变得越来越重要.Web服务器会一次处理成千上万的请求.平板电脑和手机app在渲染用户画面同时还会后台执行各 ...
- MySQL 排名、分组后组内排名、取各组的前几名 及排名后更新插入数据表中
一.排名 /*普通排名:从1开始,顺序往下排*/ AS rank ) r ORDER BY score; /*并列排名:相同的值是相同的排名*/ SELECT cs.* , CASE WHEN @p= ...
- tensorboard中show不出来数据
tensorboard中show不出来数据,可通过在命令中加入training解决,如下: tensorboard --logdir==training:model_dir