🏠 博客主页:小小马车夫的主页
🍅 所属专栏:FreeSwitch开发实践
🥝 专栏介绍:主要介绍博主在实际项目中使用FreeSwitch开发外呼类项目的一些经验心得,主要涉及FreeSwitch的基本安装编译、基本配置、ESL、WSS、录音、自定义模块、media bug、语音播放、MRCP及对接AI机器人等内容。内容在持续更新中,如果感兴趣可以对专栏进行订阅~🎈🎈想对未来的自己说的话🎈🎈🥑 🥑 间歇性的努力和蒙混过日子,都是对之前努力的清零🥑 🥑
前言
在FreeSwitch
的架构中,存在为数重多的模块或接口,在FreeSwitch中称为app
和api
,如果常用的接听模块answer
、挂断模块hangup
、睡眠模块sleep
、回音模块echo
等,数量非常之多,这些app和api共同组成了FreeSwitch的核心。然而,FreeSwitch还提供了自定义模块的功能,开发者可以按照标准接口自己实现一个app,然后在通话中使用,极大地拓展FreeSwitch的能力,也方便在实际业务中实现特定的功能。
> 在介绍`FreeSwitch`自定义模块之前,先看一个完整的`自定义模块`示例,然后针对代码示例对自定义模块进行介绍:
#include <switch.h>
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_myapp_shutdown);
SWITCH_MODULE_LOAD_FUNCTION(mod_myapp_load);
//模块定义,分别是模块加载、模块卸载
SWITCH_MODULE_DEFINITION(mod_myapp, mod_myapp_load, mod_myapp_shutdown, NULL);
SWITCH_STANDARD_APP(myapp_function);
//模块加载
SWITCH_MODULE_LOAD_FUNCTION(mod_myapp_load)
{
switch_application_interface_t *app_interface;
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "myapp mod loaded.\n");
SWITCH_ADD_APP(app_interface, "myapp", "myapp", "myapp", myapp_function, "", SAF_NONE);
return SWITCH_STATUS_SUCCESS;
}
//模块卸载
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_myapp_shutdown)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "myapp shutdown\n");
return SWITCH_STATUS_SUCCESS;
}
//myapp 执行函数
SWITCH_STANDARD_APP(myapp_function)
{
switch_status_t status;
if (session == NULL)
return;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "myapp function start\n");
return;
}
一、自定义模块的加载和卸载
通过上述自定义模块的代码示例,可以看到自定义模块最少要实现3个标准接口:
- 模块加载
SWITCH_MODULE_LOAD_FUNCTION(mod_myapp_load)
- 模块卸载
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_myapp_shutdown)
其中宏定义如下:
所以模块加载和卸载的完整定义如下:
模块加载
switch_status_t mod_myapp_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool)
模块卸载
switch_status_t mod_myapp_unload(void)
二、自定义模块"app"的创建
这里是关键,真正的可使用的app是这个接口实现的:
switch_application_interface_t *app_interface;
SWITCH_ADD_APP(app_interface, "myapp", "myapp", "myapp", myapp_function, "", SAF_NONE);
和模块的创建和卸载一样,app接口也是一个宏定义:
参数说明:
参数 | 解释 |
---|---|
app_int | app接口句柄 |
int_name` | app名称 |
short_descript | app短描述 |
long_descript | app长描述 |
funcptr | app回调函数 |
syntax_string | app格式字符串 |
app_flags | app标志 |
app回调函数
SWITCH_STANDARD_APP(myapp_function)
{
switch_status_t status;
if (session == NULL)
return;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "myapp function start\n");
return;
}
和上面一样先看下宏定义:
#define SWITCH_STANDARD_APP(name) static void name (switch_core_session_t *session, const char *data)
参数说明:
app_int | app接口句柄 |
---|---|
session | 会话session |
data | app参数,每个app都可以传递参数 |
app回调函数可以实现业务特定功能,如:
- 启动业务线程
- 添加media bug,获取通话语音流
- 实现业务循环,比如启动ASR/TSS
三、在拨号计划中加入自定义模块app
将如下代码加入到 FreeSwitch目录conf/dialplan/default.xml
<extension name="myapp-diaplan">
<condition field="destination_number" expression="^123$">
<action application="answer"/>
<action application="myapp"/>
<action application="echo" data=""/>
<action application="hangup" data=""/>
</condition>
</extension>
说明:
destination_number
拨号计划表达式字符串,即拨打“123”号码,就可以进行condition拨号配置answer
接听
-myapp
这就是前面我们创建的自定义模块里面的app
-echo
回音app,由于myapp不是阻塞函数,所以要用echo程序以阻塞通话,达到通话不中断目的
-hangup
挂断
四、通话测试
启动FreeSwitch,使用Yate注册1000号码,先看下自定义模块myapp
加载输出:
拨号命令:
originate user/1000 123
123
是前面拨号计划配置表达字符串
输出:
最后
以上就是今天的内容,详细介绍了FreeSwitch自定义模块的创建和使用。如果觉得有些帮助或觉得文章还不错,请关注一下博主,你的关注是我持续写作的动力。另外,如果有什么问题,可以在评论区留言,或者私信博主,博主看到后会第一时间回复。