编写opensips自定义模块

11 篇文章 0 订阅
编写module需要用到的各种数据结构定义在sr_module.h。其中比较重要的是cmd_export_t,用于声明这 个module的导出函数

struct cmd_export_ {
char * name ;             /* null terminated command name */
cmd_function function ;   /* pointer to the corresponding function */
int param_no ;           /* number of parameters used by the function */
fixup_function fixup ;   /* pointer to the function called to "fix" the
  parameters */
free_fixup_function
free_fixup ; /* pointer to the function called to free the
  "fixed" parameters */
int flags ;               /* Function flags */
};

第一个参数是该module导出到opensips脚本中的函数名
第二个参数是对应的具体执行函数。cmd_function的函数定义为
typedef  int (*cmd_function)(struct sip_msg*, char*, char*, char*, char*, char*, char*);
从第二个参数起都是字符串。具体使用多少个参数由结构体第三个参数决定
对于cmd_function,返回值小于0表示函数执行出错,返回值等于0会使该次脚本执行结束;返回值大于0 表示函数执行正常

第四个参数fixup function,主要用于将脚本传入的参数转换成int、正则表达式等其他种类的参数。 opensips已经定义好了常用的类型转换,定义在mod_fix.h中,一般直接调用现成的即可以
第五个参数free_fixup_function,用于释放fixup function执行时申请的内存

第六个参数,用于描述该导出函数可以在哪段路由中被执行。可选的值包括
REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE等


另外一个比较重要的结构体是

struct module_exports {
char * name ;                     /*!< null terminated module name */
char * version ;                   /*!< module version */
char * compile_flags ;             /*!< compile flags used on the module */
unsigned int dlflags ;           /*!< flags for dlopen */
cmd_export_t * cmds ;             /*!< null terminated array of the exported
                                  commands */
param_export_t * params ;         /*!< null terminated array of the exported
                                  module parameters */
stat_export_t * stats ;           /*!< null terminated array of the exported
                                  module statistics */
mi_export_t * mi_cmds ;           /*!< null terminated array of the exported
                                  MI functions */
pv_export_t * items ;             /*!< null terminated array of the exported
                                  module items (pseudo-variables) */
proc_export_t * procs ;           /*!< null terminated array of the additional
                                  processes reqired by the module */
init_function init_f ;           /*!< Initialization function */
response_function response_f ;   /*!< function used for responses,
                                  returns yes or no; can be null */
destroy_function destroy_f ;     /*!< function called when the module should
                                  be "destroyed", e.g: on opensips exit */
child_init_function init_child_f ; /*!< function called by all processes
                                   after the fork */
};


char* name: 模块的名字
char *version: 一般都把值设为MODULE_VERSION
char *compile_flags: 一般都把值设为DEFAULT_DLFLAGS
接着几个参数设置模块的导出函数、导出参数、MI命令等
proc_export_t* procs: 定义模块自己的独立运行进程
init_function init_f: 模块初始化化函数,只在opensips启动的时候被执行一次
response_function response_f: 很少有模块需要用到,尚不清楚有什么用
destroy_function destroy_f: 模块销毁时被调用
child_init_function init_child_f: 模块在每个子进程中的初始化函数。因为opensips的架构是多进 程的,像数据库连接这些必须在每个子进程内自己创建一份


对编写module有个基本的认识以后,可以开始着手写一个简单的module

1、在opensips/modules目录下新建一个目录test

2、编写这个test module的Makefile。如果这个module不需要连接其他额外的库,Makefile是相当的简 单,只要把NAME后面生成库的名字改一下

include ../../ Makefile . defs
auto_gen =
NAME = test . so
LIBS =
include ../../ Makefile . modules

3、编写这个模块的主体代码test.c
  
  
#include "../../sr_module.h"
static int mod_init ( void );
/* Exported functions */
static int my_test ( struct sip_msg * _msg , char * param );
static cmd_export_t cmds [] = {
{ "my_test" , ( cmd_function ) my_test , 1 , 0 , 0 ,
REQUEST_ROUTE },
{ 0 , 0 , 0 , 0 , 0 , 0 }
};
/* Module interface */
struct module_exports exports = {
"test" ,   /* module name*/
MODULE_VERSION ,
DEFAULT_DLFLAGS , /* dlopen flags */
cmds ,       /* exported functions */
0 ,           /* module parameters */
0 ,           /* exported statistics */
0 ,           /* exported MI functions */
0 ,           /* exported pseudo-variables */
0 ,           /* extra processes */
mod_init ,   /* module initialization function */
0 ,           /* response function */
0 ,           /* destroy function */
0 ,           /* per-child init function */
};
static int my_test ( struct sip_msg * _msg , char * param )
{
LM_INFO ( "Receive message %s\n" , param );
return 1 ;
}
static int mod_init ( void )
{
LM_INFO ( "initializing...\n" );
return 0 ;
}


4、建立好这个模块的目录之后,opensips就会去编译这个模块,除非你在Makefile.conf的 exclude_modules中加入了这个模块的名字。按照正常opensips的编译步骤进行编译


5、把新编写的模块加入路由之中
loadmodule "msg_trace.so"
在路由的某个地方插入
my_test("1234");

可以看到路由被执行到时,日志有输出
Aug  2 06:20:45 simope-0A ./opensips[2346]: INFO:test:my_test: Receive message 1234


主要参考textops、cachedb_local、cfgutils等较为简单的module

另外也可以参考同源的kamailio项目,虽然结构上也有细微的变换,但是kamailio的开发文档相对比较 齐全
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然!我可以给你提供一些关于OpenSIPS(Open SIP Server)的教程。 1. 开始使用OpenSIPS - 首先,你需要安装OpenSIPS。你可以从官方网站上下载最新的稳定版本,并按照它们的安装指南进行安装。 - 一旦安装完成,你可以通过在命令行中输入“opensipsctl start”来启动OpenSIPS。 - 接下来,你可以配置OpenSIPS以满足你的需求。配置文件位于/etc/opensips/目录下。你可以编辑这些文件来定义路由规则、处理脚本和其他功能。 - 完成配置后,你可以使用“opensipsctl start”命令重新启动OpenSIPS以加载新的配置。 2. OpenSIPS 路由 - OpenSIPS的主要功能之一是路由。通过配置路由规则,你可以决定如何处理传入和传出的SIP请求。 - 在配置文件中,你可以使用“route”关键字定义路由规则。例如,你可以定义一个基本的路由规则来处理所有传入的INVITE请求: ``` route{ if (is_method("INVITE")) { # 在这里处理INVITE请求 } } ``` - 你可以在路由规则中使用OpenSIPS的函数和变量来处理请求并制定下一步的行为。 3. OpenSIPS 脚本语言 - OpenSIPS使用自己的脚本语言来处理SIP请求和响应。这个脚本语言是基于类C语法的。 - 你可以在路由规则中使用脚本语言来执行各种操作,例如:修改请求、添加头部、发送请求等。 - 你可以参考OpenSIPS官方文档中的脚本语言指南,以了解更多关于它的详细信息。 4. OpenSIPS 模块 - OpenSIPS通过模块来扩展其功能。模块提供了各种功能,例如:认证、媒体处理、数据库集成等。 - 你可以使用OpenSIPS模块管理工具来查看已安装的模块和加载/卸载模块。例如,你可以使用以下命令查看已加载的模块: ``` opensipsctl module ``` 这只是OpenSIPS的一些基础知识和指导,希望对你有所帮助!如果你对特定主题有更多问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值