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://www.mzph.cn/pingmian/7881.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python实验三 实现UDP协议、TCP协议进行服务器端与客户端的交互

实验三 实验题目 1、请利用生成器构造一下求阶乘的函数Factorial()&#xff0c;定义一个函数m()&#xff0c;在m()中调用生成器Factorial()生成小于100的阶乘序列存入集合s中&#xff0c;输出s。 【代码】 def factorial():n1f1while 1:​ f * n​ yield (f)​ n1…

XORM 框架的使用

1、xorm 1.1、xorm 简介 xorm 是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作非常简便。 特性 支持 struct 和数据库表之间的灵活映射&#xff0c;并支持自动同步事务支持同时支持原始SQL语句和ORM操作的混合执行使用连写来简化调用支持使用ID, In, Where, Limit,…

Python批量计算多张遥感影像的NDVI

本文介绍基于Python中的gdal模块&#xff0c;批量基于大量多波段遥感影像文件&#xff0c;计算其每1景图像各自的NDVI数值&#xff0c;并将多景结果依次保存为栅格文件的方法。 如下图所示&#xff0c;现在有大量.tif格式的遥感影像文件&#xff0c;其中均含有红光波段与近红外…

通过氧气退火增强β-Ga₂O₃二极管.中国科技大学和河北半导体研究所的研究人员在这一特定领域取得了最新重大进展

上图所示&#xff1a;&#xff08;a&#xff09;增加台面有助于提高β-Ga2O3肖特基势垒二极管的阻断电压&#xff08;b&#xff09;。 氧气退火和自对准台面终端使β-Ga2O3二极管进一步走向商业化。 虽然β-Ga2O3电力电子技术已经取得了长足的进步&#xff0c;但仍然存在挑战&…

QT creator qt6.0 使用msvc2019 64bit编译报错

qt creator qt6.0报错&#xff1a; D:\Qt6\6.3.0\msvc2019_64\include\QtCore\qglobal.h:123: error: C1189: #error: "Qt requires a C17 compiler, and a suitable value for __cplusplus. On MSVC, you must pass the /Zc:__cplusplus option to the compiler."…

VTK —— 三、简单操作 - 示例3 - 将点投影到平面上(附完整源码)

代码效果 本代码编译运行均在如下链接文章生成的库执行成功&#xff0c;若无VTK库则请先参考如下链接编译vtk源码&#xff1a; VTK —— 一、Windows10下编译VTK源码&#xff0c;并用Vs2017代码测试&#xff08;附编译流程、附编译好的库、vtk测试源码&#xff09; 教程描述 本…

什么是视频号小店?为什么这么多人都在做?一文带你轻松入门!

大家好&#xff0c;我是电商花花。 现在电商的快速发展&#xff0c;电商行业在各大电商平台上不断发展&#xff0c;而视频号小店也被更多人看到和入驻&#xff0c;让更多创业者对视频号小店产生兴趣。 知道的人都觉得视频号小店是一个不可多得的创业项目&#xff0c;因为这里…

下一代Nginx? OpenNjet 的入门实践

何为 OpenNjet &#xff1f; OpenNJet 应用引擎是基于 NGINX 的面向互联网和云原生应用提供的运行时组态服务程序&#xff0c;作为底层引擎&#xff0c;OpenNJet 实现了NGINX 云原生功能增强、安全加固和代码重构&#xff0c;利用动态加载机制可以实现不同的产品形态&#xff0…

休斯《公共管理导论》第5版/考研真题解析/章节题库

第一部分 考研真题精选 一、概念题二、简答题三、论述题四、案例分析题第二部分 章节题库 第1章 一个变革的时代第2章 政府的角色第3章 传统的公共行政模式第4章 公共管理第5章 公共政策第6章 治 理第7章 问 责第8章 利害关系人和外部环境第9章 管制、外包和公共企…

【机器学习与实现】线性回归示例——波士顿房价分析

目录 一、创建Pandas对象并查看数据的基本情况二、使用皮尔逊相关系数分析特征之间的相关性三、可视化不同特征与因变量MEDV&#xff08;房价中值&#xff09;间的相关性四、划分训练集和测试集并进行回归分析 一、创建Pandas对象并查看数据的基本情况 boston.csv数据集下载&a…

Go 语言基础之面向对象编程

1、OOP 首先&#xff0c;Go 语言并不是面向对象的语言&#xff0c;只是可以通过一些方法来模拟面向对象。 1.1、封装 Go 语言是通过结构体&#xff08;struct&#xff09;来实现封装的。 1.2、继承 继承主要由下面这三种方式实现&#xff1a; 1.2.1、嵌套匿名字段 //Add…

CoPilot 产品体验:提升 OpenNJet 的控制管理和服务提供能力

文章目录 前言系统架构介绍CoPilot 配置CoPilot 插件规范 体验 CoPilot 实例CoPilot: Broker 实例CoPilot: Ctrl 实例 开发其他语言编写的 CoPilot目标主要思路具体实现执行 go 程序代码 功能扩展总结 前言 CoPilot 是 OpenNJet 的一个重要组成部分&#xff0c;它在 Master-Wo…

246 基于matlab的交流电机动态方程

基于matlab的交流电机动态方程&#xff0c;用于交流电机动态分析。输入电机的额定功率(kW)、电机的额定转速(r/min)、转子外径(m)、铁心长(m)转子槽数、电机极对数 等参数&#xff0c;输出转速变化、力矩变化等结果。程序已调通&#xff0c;可直接运行。 246 交流电机动态 转速…

DAY 2

winget.cpp #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {this->resize(540,415);this->setFixedSize(540,415);//窗口标题this->setWindowTitle("盗版QQ");//窗口图标this->setWindowIcon(QIcon("E:\\qq\\pi…

30分钟打造属于自己的Flutter内存泄漏检测工具---FlutterLeakCanary

30分钟打造属于自己的Flutter内存泄漏检测工具 思路检测Dart 也有弱引用-----WeakReference如何执行Full GC&#xff1f;如何知道一个引用他的文件路径以及类名&#xff1f; 代码实践第一步&#xff0c;实现Full GC第二步&#xff0c;如何根据对象引用&#xff0c;获取出他的类…

HarmonyOS实战开发教程-如何开发一个2048游戏

今天为大家分享的是2048小游戏&#xff0c;先看效果图&#xff1a; 这个项目对于新手友友来说可能有一点难度&#xff0c;但是只要坚持看完一定会有收获。因为小编想分享的并不局限于ArkTs语言&#xff0c;而是编程思想。 这个游戏的基本逻辑是初始化一个4乘4的数组&#xff…

LeetCode 每日一题 Day 144-157

2385. 感染二叉树需要的总时间 给你一棵二叉树的根节点 root &#xff0c;二叉树中节点的值 互不相同 。另给你一个整数 start 。在第 0 分钟&#xff0c;感染 将会从值为 start 的节点开始爆发。 每分钟&#xff0c;如果节点满足以下全部条件&#xff0c;就会被感染&#xf…

网络基础(1)网络编程套接字TCP,守护进程化

TCP协议 下面我们来学习一下TCP套接字的使用。 也就是使用一下基本的接口。首先TCP套接字的使用和UDP套接字的使用是大同小异的&#xff0c;但是多了一些步骤。 这里回顾一下&#xff1a;UDP是不可靠的&#xff0c;无连接的协议。而TCP则是可靠的&#xff0c;面向连接的协议…

[HUBUCTF 2022 新生赛]checkin

数组反序列化弱比较 <?php $info array(username>true,password>true); echo serialize($info); ?> //?infoa:2:{s:8:"username";b:1;s:8:"password";b:1;}1.构造不能用类&#xff0c;因为$data_unserialize只是一个变量&#xff0c;不能…