Freeswitch-mod开发

文章目录

  • 一、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(微信同号),我们一起学习进步。文章内容如有疑问点,我必定洗耳恭听并虚心接受,请您多多指教。感谢你的时间阅读。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3015364.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

淘宝数据分析——Python爬虫模式♥

大数据时代&#xff0c; 数据收集不仅是科学研究的基石&#xff0c; 更是企业决策的关键。 然而&#xff0c;如何高效地收集数据 成了摆在我们面前的一项重要任务。 本文将为你揭示&#xff0c; 一系列实时数据采集方法&#xff0c; 助你在信息洪流中&#xff0c; 找到…

突然断电,瀚高数据库启动失败

服务器临时断电后&#xff0c;数据库启动不起来 ps -ef|grep postgres 进到数据库的data目录下看下ls 看下 查看临时文件&#xff1a; ls -la /tmp 把这两个5866的文件改个名字张老师 加个bak就行 改完了pg_ctl start起一下

AUTOSAR中EcuM、ComM和CanNm的关联

ComM的内外部唤醒 ComM可以通过NM保持网络的唤醒&#xff0c;同时也可以通过SM激活通信&#xff0c;总之就像一个通信的总管。 下面通过两种唤醒源来解释ComM的状态机。 1、内部唤醒 ① 当ComM上电初始化时会首先进入NO COMMUNICATION状态&#xff0c;在该状态下ComM会持续循…

口感与风味的完善结合:精酿啤酒的多样风格

啤酒的世界是丰富多彩的&#xff0c;不同的啤酒有着各自与众不同的口感和风味。而Fendi club啤酒&#xff0c;作为精酿啤酒的代表&#xff0c;以其多样化的风格和卓着的口感&#xff0c;吸引了无数啤酒爱好者的目光。 Fendi club啤酒的多样风格&#xff0c;首先体现在其原料的选…

吴恩达深度学习笔记:深度学习的 实践层面 (Practical aspects of Deep Learning)1.13-1.14

目录 第二门课: 改善深层神经网络&#xff1a;超参数调试、正 则 化 以 及 优 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)第一周&#xff1a;深度学习的 实践层面 (Practical aspects of Deep Learning)1.13 梯度检验&#…

element-plus el-cascader 懒加载实现-省市区街道选择及回显

大概思路&#xff1a; 准备一个接口可以通过父Id,查询到下一级省市区街道的信息&#xff1b;如下方的getRegionListOne确定后端的数据结构&#xff0c;需要在created里边处理数据回显逻辑el-cascader接收的数据格式是[‘’,‘’,‘’];后端的数据格式多为[{provinceId: ‘’, …

Postman轻松签名,让SHA256withRSA保驾护航!

前言 在接口测试中&#xff0c;我们经常需要对请求进行签名&#xff0c;以保证数据的安全性。而SHA256withRSA是一种较为常见的签名算法&#xff0c;它可以使用私钥对数据进行签名&#xff0c;使用公钥进行验签。 但是&#xff0c;实现该算法签名可能会涉及到一些繁琐的操作&…

利用生成式AI重新构想ITSM的未来

对注入 AI 的生成式 ITSM 的需求&#xff0c;在 2023 年 Gartner AI 炒作周期中&#xff0c;生成式 AI 达到预期值达到顶峰后&#xff0c;三分之二的企业已经将生成式 AI 集成到其流程中。 你问为什么这种追求&#xff1f;在预定义算法的驱动下&#xff0c;IT 服务交付和管理中…

如何把一个PDF文档每两页合并为一页?跟我学,5秒搞定!

想要将两张PDF的内容合并到一张A4纸上显示。 这需要用到PDF编辑软件&#xff0c;在迅捷PDF编辑器中的“打印”功能里进行设置。 下面给大家演示一下具体怎么操作&#xff1a; 01.打开迅捷PDF编辑器&#xff0c;导入PDF文件&#xff0c;找到左上角【打印】功能。 02.在弹出…

服务器2080ti驱动的卸载与安装

服务器2080ti驱动的卸载与安装 前言1、下载驱动2、驱动卸载与安装2.1 卸载原来驱动2.2 安装新驱动 3、查看安装情况 前言 安装transformers库&#xff0c;运行bert模型时出错&#xff0c;显示torch版本太低&#xff0c;要2.0以上的&#xff0c;所以更新显卡驱动&#xff0c;重…

黑马点评项目总结

登录 基于session登录 短信验证码登录 配置登录拦截器 向 Spring MVC 框架中添加拦截器&#xff0c;LoginInterceptor 是一个自定义的拦截器&#xff0c;用于拦截用户的登录请求。 excludePathPatterns这一句是设置拦截器需要放行的请求路径列表。 "/user/code", …

Java | Leetcode Java题解之第67题二进制求和

题目&#xff1a; 题解&#xff1a; class Solution {public String addBinary(String a, String b) {StringBuffer ans new StringBuffer();int n Math.max(a.length(), b.length()), carry 0;for (int i 0; i < n; i) {carry i < a.length() ? (a.charAt(a.leng…

基于云制造的智能工厂简单介绍

基于云制造的智能工厂是利用云制造服务平台&#xff0c;以制造资源层、现场控制层、车间执行层、企业管理层、平台应用层、企业协同的业务需求和集成协作为牵引&#xff0c;综合基于云制造服务平台的应用模式&#xff0c;同时考虑智能工厂整体安全&#xff0c;构建基于云制造的…

Gradio之blocks灵活搭建页面

这里写目录标题 搭建一个UI界面搭建上半部分的框架比例调节以及其他效果搭建下半部分左边部分搭建下半部分右边部分拓展-CSS的应用 使用标签搭建第二个页面示例 补充AccordionGroup() 搭建一个UI界面 搭建上半部分的框架 如下图&#xff0c;我们想要基本还原下图右边的UI界面…

【优选算法】——Leetcode——202—— 快乐数

目录 1.题目 2. 题⽬分析: 3.简单证明&#xff1a; 4. 解法&#xff08;快慢指针&#xff09;&#xff1a; 算法思路&#xff1a; 补充知识&#xff1a;如何求⼀个数n每个位置上的数字的平⽅和。 总结概括 5.代码实现 1.C语言 2.C 1.题目 202. 快乐数 编写一个算法来…

论文复现和点评《基于随机森林模型的个人信用风险评估研究》

作者Toby&#xff0c;来源公众号&#xff1a;Python风控模型&#xff0c;论文复现和点评《基于随机森林模型的个人信用风险评估研究》 最近Toby老师看到一篇论文热度比较高&#xff0c;下载量有665次&#xff0c;论文标题是《基于随机森林模型的 个人信用风险评估研究》 论文篇…

陪诊系统|陪诊小程序成品|陪诊系统功能

随着人们对健康的日益关注以及医疗技术的不断进步&#xff0c;陪诊小程序应运而生&#xff0c;通过提供陪同就医、医疗服务和健康管理等功能为患者和家庭成员提供了更多的便利和选择。本文将分析陪诊小程序的关键功能&#xff0c;以便更好地理解其在医疗领域的作用。 在陪诊小程…

练习项目后端代码解析注解篇(annotation)

前言 本来想从接口处入手的&#xff0c;但是一下看到接口里几十个方法&#xff0c;眼睛有点抗拒&#xff0c;想想还是先看作者写的自定义注解吧。 项目里有三个自定义注解&#xff1a; 分别是AccessLimit注解、OperationLogger注解、VisitLogger注解 AccessLimit注解 这是一…

Summer ‘24来啦!15个最热门的功能抢先看!

Salesforce Summer 24即将发布&#xff01;本篇文章我们将深入了解Summer 24最热门的声明性功能。 01 自动化Lightning应用程序 新的自动化Lightning应用程序中包含所有与自动化相关的内容。访问该应用程序的用户可以在主应用程序中看到Flow、错误信息和其他基于社区的链接。…

自动驾驶主流芯片及平台架构(一)

零部件成本下降、中低端车竞争加剧&#xff0c;推动ADAS渗透率在中国市场快速提升&#xff0c;自主品牌ADAS装配量大幅提升 零部件成本下降、中低端车竞争加剧&#xff0c;推动ADAS渗透率在中国市场快速提升&#xff0c;自主品牌ADAS装配量大幅提升。5年前在一些高端车型上才有…