This is an old revision of the document!
Kamailio implements from scratch the interpreter for its configuration file (kamailio.cfg).
Starting with v5.0.0, the routing blocks can be written in some of its embedded languages interpreter. Known to work:
Setting a configuration engine can be done with the global setting:
cfgengine = "name"
If the name is “native” or “default”, then is own language interpreter will be used (this is same behaviour as when cfgengine is not set at all).
This setting must be after loading the module that implements the engine. For example:
... loadmodule "app_lua.so" ... cfgengine = "lua" ...
The aim is that the runtime active part of kamailio.cfg (the routing blocks) to be implemented in an embedded scripting language.
Internally, the support for implementing routing logic in an embedded language is codenamed kemi - Kamailio EMbedded Interface.
The current implementation relies on the ability of Lua to allow hash tables with custom index. This is like an object that can have methods defined on the fly. Kamailio registers an empty object with a custom index function implemented in Kamailio code, whenever a member of that object is accessed, the index function is executed and Kamailio will resolve it to one of its functions, corresponding by name.
Each existing component of Kamailio (e.g., module), can export new functions to KEMI in the following way:
The structure sr_kemi_t is declared in Kamailio core, the file kemi.h:
#define SR_KEMI_PARAMS_MAX 6 typedef struct sr_kemi { str mname; /* sub-module name */ str fname; /* function name */ int rtype; /* return type (supported SR_KEMIP_INT/BOOL) */ void *func; /* pointer to the C function to be executed */ int ptypes[SR_KEMI_PARAMS_MAX]; /* array with the type of parameters */ } sr_kemi_t;
Next C code snippet shows how sl module exports two functions:
static sr_kemi_t sl_kemi_exports[] = { { str_init("sl"), str_init("sreply"), SR_KEMIP_INT, sl_send_reply_str, { SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, { str_init("sl"), str_init("freply"), SR_KEMIP_INT, send_reply, { SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } }; int mod_register(char *path, int *dlflags, void *p1, void *p2) { sr_kemi_modules_add(sl_kemi_exports); return 0; }
Note that the exported array is ended by a sentinel of 0/NULL values for all fields.
Exported functions must take first parameter as 'sip_msg_t*' type (which is the structure with the SIP message being processed), then followed by up to 6 int or str* parameters. When SR_KEMIP_NONE is given in the array with the types of parameters, it means there is no parameter from there on (some compilers may rise warning, so it is recommended to fill all 6 items in array).
The functions exported by Kamailio core are listed inside the array _sr_kemi_core from the file kemi.c.
Not all combinations of extra (after sip_msg_t*) parameters types are supported right now - currently the are:
The app_lua module must be loaded and the Lua script with routing logic must be set to its load parameter.
Inside the Lua script, following functions are relevant:
The following objects are available inside the Lua script:
The kamailio.cfg with global/core and module settings:
#!KAMAILIO debug=3 log_stderror=yes fork=yes children=2 memdbg=5 memlog=5 auto_aliases=no listen=udp:127.0.0.1:5060 mpath="modules" loadmodule "mi_fifo.so" loadmodule "kex.so" loadmodule "tm.so" loadmodule "tmx.so" loadmodule "sl.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "textops.so" loadmodule "xlog.so" loadmodule "ctl.so" loadmodule "mi_rpc.so" loadmodule "debugger.so" loadmodule "app_lua.so" # ----------------- setting module-specific parameters --------------- # ----- mi_fifo params ----- modparam("mi_fifo", "fifo_name", "/var/run/kamailio/kamailio_fifo") # ----- tm params ----- # auto-discard branches from previous serial forking leg modparam("tm", "failure_reply_mode", 3) # default retransmission timeout: 30sec modparam("tm", "fr_timer", 30000) # default invite retransmission timeout after 1xx: 120sec modparam("tm", "fr_inv_timer", 120000) # ----- debugger params ----- modparam("debugger", "cfgtrace", 1) ####### Routing Logic ######## modparam("app_lua", "load", "/etc/kamailio/kamailio.lua") modparam("app_lua", "register", "maxfwd") modparam("app_lua", "register", "sl") cfgengine "lua"
The /etc/kamailio/kamailio.lua with the routing logic for runtime:
-- SIP request routing function ksr_request_route() KSR.info("===== request - from kamailio lua script\n"); if sr.maxfwd.process_maxfwd(10) < 0 then sr.sl.send_reply(483, "Too Many Hops"); return; end KSR.sl.sreply(200, "OK Lua"); end -- SIP response routing function ksr_reply_route() KSR.info("===== response - from kamailio lua script\n"); end