开始
我们需要给home_location模块增加一个参数,配置当地的号码区号
首先,我们删除maxfwd.c文件中开头的很多注释,我们先把注意力集中在代码上。
删除了30多行注释,代码还剩160多行。
首先我们一个变量,用来保存本地的区号。这个变量是个str类型。
str local_zone_code = {"",0};
str
关于str类型,可以参考opensips/str.h头文件。
struct __str {
char* s; /**< string as char array */
int len; /**< string length, not including null-termination */
};
typedef struct __str str;
实际上,str是个指向__str结构体,可以看出这个结构体有指向字符串的char*类型的指针,以及一个代表字符串长度的len属性。这样做的好处是可以高效的获取字符串的长度,很多有名的开源项目都有类似的结构体。
opensips几乎所有的字符串都是用的str类型
param_export_t
param_export_t这个结构体是用来通过脚本里面的modparam向模块传递参数的。这个数组最后一向是{0,0,0}
这最后一项其实是个标志,标志着数组的结束。
static param_export_t params[]={
{"max_limit", INT_PARAM, &max_limit},
{"local_zone_code", STR_PARAM, &local_zone_code.s},
{0,0,0}
};
在sr_module_deps.h和sr_module.h中有下面的代码
typedef struct param_export_ param_export_t;
param_export_t实际上是指向param_export_这个结构体。
这个结构体有三个参数
- name 表示参数的名称
- modparam_t 表示参数的类型。参数类型有以下几种
- STR_PARAM 字符串类型
- INT_PARAM 整数类型
- USE_FUNC_PARAM 函数类型
- PARAM_TYPE_MASK 这个用到的时候再说
- param_pointer 是一个指针,用到的时候再具体说明
struct param_export_ {
char* name; /*!< null terminated param. name */
modparam_t type; /*!< param. type */
void* param_pointer; /*!< pointer to the param. memory location */
};
#define STR_PARAM (1U<<0) /* String parameter type */
#define INT_PARAM (1U<<1) /* Integer parameter type */
#define USE_FUNC_PARAM (1U<<(8*sizeof(int)-1))
#define PARAM_TYPE_MASK(_x) ((_x)&(~USE_FUNC_PARAM))
typedef unsigned int modparam_t;
回过头来,看看local_zone_code这个参数的配置,是不是就非常明确了呀
{"local_zone_code", STR_PARAM, &local_zone_code.s},
接着,你可能会问,加入我们配置好了这个参数,如何再运行的时候将local_zone_code这个变量的值打印出来呢?
再module_exports这个结构体里面,最后的几个参数实际上是一个函数。
这些函数再模块的生命周期内会调用。比如那个mod_init, 就是模块初始化的时候就会调用这个函数。
那么,我们就在模块初始化的时候打印local_zone_code的值好了。
下面的代码,我们其实只插入了一行, LM_INFO, 用来打印。其他就保持原样好了。
mod_init函数的返回值是有特殊含义的,如果返回是0,表示成功。如果返回的是负数, 例如E_CFG, 这时候opensips就会认为你的脚本写的有问题,就不会继续启动opensips。
static int mod_init(void)
{
LM_INFO("initializing...\n");
LM_INFO("Initializing local_zone_code: %s\n", local_zone_code.s);
if ( max_limit<1 || max_limit>MAXFWD_UPPER_LIMIT ) {
LM_ERR("invalid max limit (%d) [1,%d]\n",
max_limit,MAXFWD_UPPER_LIMIT);
return E_CFG;
}
return 0;
}
再error.h中,可以看到opensips定义了很多的错误码。
编译模块
源码的c文件我们修改好了,下面就是编译它,不知道会不会报错呢?😂
➜ home_location git:(home_location) ✗ ./dev.sh build
/root/code/gitee/opensips
make[1]: Entering directory '/root/code/gitee/opensips/modules/home_location'
Compiling maxfwd.c
Linking home_location.so
make[1]: Leaving directory '/root/code/gitee/opensips/modules/home_location'
似乎没啥问题
编辑dev.cfg 增加local_zone_code参数
loadmodule "/root/code/gitee/opensips/modules/home_location/home_location.so"
+ modparam("home_location", "local_zone_code", "010")
./dev.sh start
看看log.txt, local_zone_code已经被打印出来,并且他的值是我们在cfg脚本里配置的010。
~ Apr 21 13:47:40 [1048372] INFO:home_location:mod_init: initializing...
~ Apr 21 13:47:40 [1048372] INFO:home_location:mod_init: Initializing local_zone_code: 010
ok, 第三章结束。