Kamailio學習【二】--自定義模塊


寫在前面的話:裏面的截圖除非特殊說明,都是來自sr_module.h

參考:https://blog.csdn.net/ttomqq/article/details/38821411

一、關於版本

定義每一個模塊都要說明這個模塊的結構,以便於讓kamailio能解釋它,包括模塊導出函數的結構cmd_export_和模塊整體的結構module_exports。在sr_module.h中有兩種版本的模塊結構,一個是SER,一個是kam,是這樣定義的:

 

 

這裏的cmd_export_t和module_exports即可代表ser的也可以代表kam的。在自己定義模塊時候直接由結構的內容體現是哪種版本(個數)。

 

模塊導出函數結構:

 

 

模塊結構:

 


有默認使用哪種版本的定義,猜想應該是從這裏默認定義的:

 

默認版本是SER的,但是沒找到用另一個版本kam所代表的數值,在json_mod.c中就是用的kam版本的(下圖)


但是裏面的版本聲明 MODULE_VERSION仍然是SER的意思,這裏面應該有一些定義是沒注意到的,也就是什麼時候可以用kam版本,這個我沒找到,希望有大神能幫我解惑

二、結構具體含義

1對於模塊導出函數結構:

 

第一個參數是該module導出到opensips腳本中的函數名

第二個參數是對應的具體執行函數。cmd_function的函數定義爲

 

從第二個參數起都是字符串。具體使用多少個參數由結構體第三個參數決定

對於cmd_function,返回值小於0表示函數執行出錯,返回值等於0會使該次腳本執行結束;返回值大於0表示函數執行正常

第四個參數fixup function,主要用於將腳本傳入的參數轉換成int、正則表達式等其他種類的參數。常用的類型轉換定義在mod_fix.h中,一般直接調用

第五個參數用於描述該導出函數可以在哪段路由中被執行。可選的值定義在route.h中:

 

kam版本比ser的多了一個free_fixup_function參數,用於釋放fixup function執行時申請的內存

 

2、對於模塊結構:

 

char* name: 模塊的名字

ser_cmd_export_t* cmds:前面定義的模塊導出函數,這裏如果一個模塊裏多於兩個導出函數的情況下就要定義ser_cmd_export_t類型的結構體數組cmds[],每一個元素都是一個ser_cmd_export_t類型的結構體,各對應一個導出函數。

rpc_export_t* rpc_methods:遠程程序調用的導出函數(rpc.h中定義的)。

 

param_export_t* params:參數導出,很多參數的時候也是定義一個param_export_t類型的數組,每個數組元素都是對這個參數的說明,例如acc_mod.c中的184行(部分):

 

init_function init_f: 模塊初始化化函數,只在啓動的時候被執行一次

response_function response_f: 用於回覆,有yesnonull也行,不知道做什麼的。

destroy_function destroy_f: 模塊銷燬時被調用

onbreak_function onbreak_f;:不知道做什麼的,onbreak_function120行:

typedef void (*onbreak_function)(struct sip_msg*);是指向sip_msg結構體的一個指針。

child_init_function init_child_f: 模塊在每個子進程中的初始化函數。因kamailio的架構是多進程的,像數據庫連接這些必須在每個子進程內自己創建一份

 

unsigned int dlflags: 一般都把值設爲DEFAULT_DLFLAG,後面的stat_nn_pv_還沒看是做什麼的。

proc_export_t* procs: 定義模塊自己的獨立運行進程

三、編寫一個簡單的模塊

1、寫模塊主體代碼test.c文件

在目錄/usr/local/src/kamailio-5.1/kamailio/src/modules(也就是下載kamailio源碼的位置那)建立一個名爲test的文件夾,編寫模塊主體代碼test.c文件。

cd /usr/local/src/kamailio-5.1/kamailio/src/modules

sudo mkdir test

cd test

sudo vi test.c   /*根據自己常用的編輯器來即可*/

test.c文件如下:

/*

*時間:2018年3月29日16點24分

*作者:cxy

*模塊名:test

*導出函數名:my_test

*功能:在初始化的時候在日誌輸出“cxy-initializing...”,在每一個request(invite,subscribe,

*register,cancel等等)到來時候輸出“Receive message 123456”,爲了看是否模塊添加成功

*輸入:123456(或者其他)

*輸出:Receive message 123456(或者其他)

*/

#include "../../core/sr_module.h"

MODULE_VERSION
 
static int mod_init(void);

static int my_test(struct sip_msg* _msg, char *param);

/* Exported functions */

static cmd_export_t cmds[]={

{"my_test", (cmd_function)my_test, 1, 0, ANY_ROUTE},       /*在任何路由塊都能用*/

{0, 0, 0, 0, 0}

};

/* Module interface */

struct ser_module_exports exports = {

"test",	       /**< null terminated module name */

 cmds,         /**< null terminated array of the exported

                                              commands */

 0,              /**< null terminated array of exported rpc methods */

 0,              /**< null terminated array of the exported  module parameters */
 
 mod_init,      /**< Initialization function */

 0,              /**< function used for responses, returns yes or no; can be null */

 0,              /**< function called when the module should be "destroyed", e.g: on ser exit;

                                                                	can be null */
 
 0,

 0,              /**< function called by all processes after the fork */

};

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("cxy-initializing...\n");

return 0;

}

2、編寫Makefile文件

如果這個module不需要連接其他額外的庫,只要把NAME後面生成庫的名字改成test.so。如下所示:

#

#test makefile

#

#WARNING: do not run this directly. it should be run by the master Makefile

include ../../Makefile.defs

auto_gen=

NAME=test.so

LIBS=

DEFS+=-DSER_MOD_INTERFACE

include ../../Makefile.modules

3、編譯

編譯這個模塊,除非在src目錄下的主Makefileexclude_modules中加入了這個模塊的名字,就不編譯這個模塊。

cd /usr/local/src/kamailio-5.1/kamailio

sudo make all

sudo make install

(按理說不用再次安裝吧?但是如果不再安裝的話我發現生成的庫文件test.so不能被導入/usr/local/lib64/kamailio/modules中,還是說是應該要安裝一遍的?)

  由於一開始我是仿照https://blog.csdn.net/ttomqq/article/details/38821411裏面的test模塊,修改了一些版本的差異,一開始我是按照kamailio版本寫的模塊但總是提示警告,提示我有多餘的元素。經過比較,不管是cmd模塊導出函數聲明還是module模塊導出聲明,SER版本的的確是比kam版本的元素個數要少(SER版本cmd5個元素,module9個;kam版本cmd6個,module12個)。默認版本是SER,因此下面的警告根源在版本這裏,改成了SER版本就行了。

 

4、載入新模塊

不載入的話kamailio不會自己添加這個功能的,在kamailio.cfg文件中相應位置加入以下語句:

loadmodule "test.so"

把新編寫的模塊加入路由之中,在路由邏輯的request邏輯下插入:

my_test("123456");

5、驗證模塊是否添加成功

打開kamailio,註冊用戶並登陸,見https://blog.csdn.net/qq_36069590/article/details/79106771,可以看到路由被執行到時,日誌有輸出:

 

 

PS:這裏有什麼說錯的麻煩能告訴我一下,謝謝!作爲一個kamailio初學者,我感覺要學的東西太多了,這可能是和我專業不是計算機相關的有關吧。知識是一點點積累的,需要什麼就去學什麼就好了,涉及到基礎的東西就去系統的看看教材或視頻。今天花了一下午把昨天學到的東西記錄在這裏,在這裏就順便給自己打打氣,加油cxy。

           任重而道遠,與君共勉。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章