文章目录

  • 一、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 介绍

Freeswitch-mod开发_Freeswitch


通过上述自定义模块的代码示例,可以看到自定义模块最少要实现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

Freeswitch-mod开发_API_02

1.2.3 编译

这里注意一下编译的文件夹和自定义mod的xxx.c名称保持一致

make
make install

Freeswitch-mod开发_API_03


Freeswitch-mod开发_应用程序_04


这就定义好了

二、Freeswitch-mod-自定义Dialplan模块

2.1 介绍

注意红色字体就好了

Freeswitch-mod开发_自定义_05

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

Freeswitch-mod开发_应用程序_06

2.2.3 测试

originate user/1002 9999 my_dialplan

Freeswitch-mod开发_Freeswitch_07


Freeswitch-mod开发_API_08

三、Freeswitch-mod-自定义app模块

3.1 介绍

注意红色字体就好了

Freeswitch-mod开发_API_09

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

Freeswitch-mod开发_自定义_10

3.2.3 测试

Freeswitch-mod开发_自定义_11


添加

Freeswitch-mod开发_自定义_12

F6刷新配置

Freeswitch-mod开发_mod_13

Freeswitch-mod开发_API_14

四、Freeswitch-mod-自定义api模块

4.1 介绍

注意红色字体就好了

Freeswitch-mod开发_API_15

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

Freeswitch-mod开发_API_16

4.2.3 测试

方法一:编写拨号

Freeswitch-mod开发_自定义_17


Freeswitch-mod开发_API_18


方法二:直接测

Freeswitch-mod开发_自定义_19

致敬读者

  偶然的机会我接触到FreeSWITCH并进行学习和整理笔记。文章内容如有疑问点,我必定洗耳恭听并虚心接受,请您多多指教。感谢你的时间阅读。