编写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
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值