文章目录
- 一、Freeswitch-mod开发
- 1.1 介绍
- 1.2 实战
- 1.2.1 新建一个mymod.c或者mymod.cpp
- 1.2.2 新建一个Makefile
- 1.2.3 编译
- 二、Freeswitch-mod-自定义Dialplan模块
- 2.1 介绍
- 2.2 实战
- 2.2.1 改造mymod.c(代码是完整的,自己做区别看一下)
- 2.2.2 编译
- 2.2.3 测试
- 三、Freeswitch-mod-自定义app模块
- 3.1 介绍
- 3.2 实战
- 3.2.1 改造mymod.c(代码是完整的,自己做区别看一下)
- 3.2.2 编译
- 3.2.3 测试
- 四、Freeswitch-mod-自定义api模块
- 4.1 介绍
- 4.2 实战
- 4.2.1 改造mymod.c(代码是完整的,自己做区别看一下)
- 4.2.2 编译
- 4.2.3 测试
- 致敬读者
一、Freeswitch-mod开发
1.1 介绍
通过上述自定义模块的代码示例,可以看到自定义模块最少要实现2个标准接口:
模块加载
SWITCH_MODULE_LOAD_FUNCTION(mod_mymod_load)
模块卸载
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mymod_shutdown)
和一个申明
//模块定义名称,分别是模块加载函数、模块卸载函数
SWITCH_MODULE_DEFINITION(mod_mymod, mod_mymod_load, mod_mymod_shutdown, NULL);
1.2 实战
1.2.1 新建一个mymod.c或者mymod.cpp
#include <switch.h>
SWITCH_MODULE_LOAD_FUNCTION(mod_mymod_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mymod_shutdown);
SWITCH_MODULE_DEFINITION(mymod, mod_mymod_load, mod_mymod_shutdown, NULL);
SWITCH_MODULE_LOAD_FUNCTION(mod_mymod_load)
{
// init module interface
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mymod_shutdown) { return SWITCH_STATUS_SUCCESS; }
1.2.2 新建一个Makefile
BASE=/usr/local/src/freeswitch-1.10.5
include $(BASE)/build/modmake.rules
1.2.3 编译
这里注意一下编译的文件夹和自定义mod的xxx.c名称保持一致
make
make install
这就定义好了
二、Freeswitch-mod-自定义Dialplan模块
2.1 介绍
注意红色字体就好了
2.2 实战
2.2.1 改造mymod.c(代码是完整的,自己做区别看一下)
#include <switch.h>
SWITCH_MODULE_LOAD_FUNCTION(mod_mymod_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mymod_shutdown);
SWITCH_MODULE_DEFINITION(mymod, mod_mymod_load, mod_mymod_shutdown, NULL);
// 定义一个名为 my_dialplan_hunt的标准拨号计划处理函数
SWITCH_STANDARD_DIALPLAN(my_dialplan_hunt)
{
switch_caller_extension_t *extension = NULL; // 声明一个呼叫方扩展结构体指针,用于存储呼叫路由信息
switch_channel_t *channel = switch_core_session_get_channel(session); // 获取当前呼叫的通道信息
if (!caller_profile) { // 如果呼叫者配置信息为空
caller_profile = switch_channel_get_caller_profile(channel); // 获取呼叫者的配置信息
}
// 记录日志,显示呼叫处理过程中的相关信息
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO,
"Processing %s <%s> -> %s in context %s\n",
caller_profile->caller_id_name, caller_profile->caller_id_number,
caller_profile->destination_number, caller_profile->context);
// 创建一个名为 "my_dialplan" 的呼叫方扩展,并将其添加到当前会话的呼叫方扩展列表中
extension = switch_caller_extension_new(session, "my_dialplan", "my_dialplan");
if (!extension) // 如果创建呼叫方扩展失败
abort(); // 终止程序
// 向呼叫方扩展添加一个应用程序,用于在日志中记录信息
switch_caller_extension_add_application(session, extension, "log", "INFO Hey, I'm in the ,my_dialplan");
return extension; // 返回创建的呼叫方扩展结构体指针
}
SWITCH_MODULE_LOAD_FUNCTION(mod_mymod_load)
{
// 拨号计划接口指针
switch_dialplan_interface_t *dp_interface;
// init module interface 初始化接口
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
//表示向名为 dp_interface 的拨号计划接口中添加一个名称为 "my_dialplan" 的自定义拨号计划,
//并指定了处理匹配的函数为 my_dialplan_hunt。
SWITCH_ADD_DIALPLAN(dp_interface,"my_dialplan",my_dialplan_hunt);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mymod_shutdown) { return SWITCH_STATUS_SUCCESS; }
2.2.2 编译
这里注意一下编译的文件夹和自定义mod的xxx.c名称保持一致
make
make install
2.2.3 测试
originate user/1002 9999 my_dialplan
三、Freeswitch-mod-自定义app模块
3.1 介绍
注意红色字体就好了
3.2 实战
3.2.1 改造mymod.c(代码是完整的,自己做区别看一下)
#include <switch.h>
SWITCH_MODULE_LOAD_FUNCTION(mod_mymod_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mymod_shutdown);
SWITCH_MODULE_DEFINITION(mymod, mod_mymod_load, mod_mymod_shutdown, NULL);
SWITCH_STANDARD_APP(myapp_function)
{
const char *name;
if (zstr(data)){
name="No Name";
}else{
name =data;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),SWITCH_LOG_INFO,"I'm a book, My name is %s \n", name);
}
SWITCH_MODULE_LOAD_FUNCTION(mod_mymod_load)
{
// app接口指针
switch_application_interface_t *app_interface;
// init module interface 初始化接口
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
//将该App向核心注册,并增加一个回调函数 book_function:
//app_interface:应用程序接口的名称,用于标识这个应用程序。
//"myapp":应用程序的命令名称,即在 FreeSWITCH 的命令行界面或配置文件中使用的名称,用于调用这个应用程序。
//"myapp example":应用程序的描述,用于在帮助文档或其他地方显示给用户,描述这个应用程序的作用。
//"myapp example":应用程序的语法描述,用于指导用户在命令行中如何正确地使用这个应用程序。
//myapp_function:应用程序的函数指针,指向实际的处理函数,当用户调用这个应用程序时,会执行该函数进行相应的处理。
//"[name]":应用程序的配置参数,这是一个应用程序参数的格式,它是一个字符串,用于指定应用程序所需参数的格式。在这个例子中,这个参数为 "[name]"。
//SAF_SUPPORT_NOMEDIA: 这是应用程序的标志(flag),用于指定应用程序的特性。在这个例子中,这个标志表示该应用程序支持无媒体处理(No-Media Processing)。
//这意味着这个应用程序可以在没有任何媒体(如音频、视频)流的情况下执行其功能。如果是SAF_NONE:应用程序的标志,表示这个应用程序没有特殊的标志,
SWITCH_ADD_APP(app_interface,"myapp","myapp example","myapp example",myapp_function,"[name]",SAF_SUPPORT_NOMEDIA);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mymod_shutdown) { return SWITCH_STATUS_SUCCESS; }
3.2.2 编译
这里注意一下编译的文件夹和自定义mod的xxx.c名称保持一致
make
make install
3.2.3 测试
添加
F6刷新配置
四、Freeswitch-mod-自定义api模块
4.1 介绍
注意红色字体就好了
4.2 实战
4.2.1 改造mymod.c(代码是完整的,自己做区别看一下)
#include <switch.h>
SWITCH_MODULE_LOAD_FUNCTION(mod_mymod_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mymod_shutdown);
SWITCH_MODULE_DEFINITION(mymod, mod_mymod_load, mod_mymod_shutdown, NULL);
SWITCH_STANDARD_API(my_api_function)
{
const char *name;
if(zstr(cmd)){
name="No Name";
} else {
name = cmd;
}
stream->write_function(stream,"I'm a developer, My name is:%s \n",name);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_mymod_load)
{
// api接口指针
switch_api_interface_t *api_interface;
// init module interface 初始化接口
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
//SWITCH_ADD_API: 这是一个宏,用于向 FreeSWITCH 中注册一个新的 API 接口。它的语法通常是 SWITCH_ADD_API(名称, 描述, 函数名称, 参数)
SWITCH_ADD_API(api_interface,"myapi","myapi example",my_api_function,"[name]");
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mymod_shutdown) { return SWITCH_STATUS_SUCCESS; }
4.2.2 编译
这里注意一下编译的文件夹和自定义mod的xxx.c名称保持一致
make
make install
4.2.3 测试
方法一:编写拨号
方法二:直接测
致敬读者
偶然的机会我接触到FreeSWITCH并进行学习和整理笔记。如有您有需要,请联系我18956043585(微信同号),我们一起学习进步。文章内容如有疑问点,我必定洗耳恭听并虚心接受,请您多多指教。感谢你的时间阅读。