This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
devel:config-engines [2016/04/12 16:13] miconda [Exporting Functions To KEMI] |
devel:config-engines [2016/04/19 15:41] miconda [Python Config KEMI Engine] |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== Configuration File Engines ====== | ====== Configuration File Engines ====== | ||
- | Kamailio implements from scratch the interpreter for its configuration file (kamailio.cfg). | + | Kamailio implements from scratch the interpreter for its configuration file scripting language(used inside |
- | Starting with v5.0.0, the routing blocks can be written in some of its embedded | + | Starting with v5.0.0, the routing blocks can be written in some other (well known) scripting |
- | * Lua, implemented by app_lua module, as " | + | * Lua - implemented by app_lua module, as "lua" config engine |
+ | * Python - implemented by app_python module, as " | ||
Setting a configuration engine can be done with the global setting: | Setting a configuration engine can be done with the global setting: | ||
Line 25: | Line 26: | ||
</ | </ | ||
- | The aim is that the runtime active part of kamailio.cfg (the routing blocks) to be implemented in an embedded scripting language. | + | 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. | + | Among benefits of using different scripting languages: |
+ | |||
+ | * ability to benefit from what a well established language already provides: | ||
+ | * more people are expected to be familiar with | ||
+ | * an extended set of data types, expressions and statements already available | ||
+ | * a large set of extensions and libraries already available | ||
+ | * reload the SIP routing logic without restarting Kamailio | ||
+ | |||
+ | Internally, the support for implementing routing logic in an embedded language is codenamed **KEMI** - Kamailio EMbedded Interface. | ||
===== Exporting Functions To KEMI ===== | ===== Exporting Functions To KEMI ===== | ||
Line 91: | Line 100: | ||
* 1 param - can be int of str* | * 1 param - can be int of str* | ||
* 2 params - any combination of int or str* | * 2 params - any combination of int or str* | ||
- | * 3 params - (to be added soon) any combination of int or str* | + | * 3 params - any combination of int or str* |
* 4 params - all have to be str* (other combinations to be added as needed) | * 4 params - all have to be str* (other combinations to be added as needed) | ||
* 5 params - all have to be str* (other combinations to be added as needed) | * 5 params - all have to be str* (other combinations to be added as needed) | ||
Line 105: | Line 114: | ||
* **ksr_request_route()** - is executed by Kamailio core every time a SIP request is received. If this function is not defined, then Kamailio will write error messages. This is equivalent of request_route {} from kamailio.cfg. | * **ksr_request_route()** - is executed by Kamailio core every time a SIP request is received. If this function is not defined, then Kamailio will write error messages. This is equivalent of request_route {} from kamailio.cfg. | ||
* **ksr_reply_route()** - is executed by Kamailio core every time a SIP Response (reply) is received. If this function is not defined, then Kamailio will not write error messages. This is equivalent of reply_route {} from kamailio.cfg. | * **ksr_reply_route()** - is executed by Kamailio core every time a SIP Response (reply) is received. If this function is not defined, then Kamailio will not write error messages. This is equivalent of reply_route {} from kamailio.cfg. | ||
- | * TBD: the options for branch_route, | + | |
+ | * branch route callback - the name of the Lua function to be executed instead of a branch route has to be provided as parameter to KSR.tm.t_on_branch(...) | ||
+ | * onreply route callback - the name of the Lua function to be executed instead of an onreply route has to be provided as parameter to KSR.tm.t_on_reply(...) | ||
+ | * failure route callback - the name of the Lua function to be executed instead of a failure route has to be provided as parameter to KSR.tm.t_on_failure(...) | ||
+ | * branch failure route callback - the name of the Lua function to be executed instead of an event route for branch failure has to be provided as parameter to KSR.tm.t_on_branch_failure(...) | ||
+ | | ||
The following objects are available inside the Lua script: | The following objects are available inside the Lua script: | ||
Line 111: | Line 125: | ||
* **sr** - provided by the old way of exporting functions to Lua (https:// | * **sr** - provided by the old way of exporting functions to Lua (https:// | ||
* **KSR** - provided via KEMI interface (not many functions exported at this moment, but expected to take over all **sr** module). The functions exported to KEMI are accessible as KSR.submodule.function(...). If submodule name is empty (reserved for core functions), then they are available as KSR.function(...). | * **KSR** - provided via KEMI interface (not many functions exported at this moment, but expected to take over all **sr** module). The functions exported to KEMI are accessible as KSR.submodule.function(...). If submodule name is empty (reserved for core functions), then they are available as KSR.function(...). | ||
- | |||
==== Lua Embedded Config Example ==== | ==== Lua Embedded Config Example ==== | ||
Line 177: | Line 190: | ||
<code lua> | <code lua> | ||
+ | -- Kamailio - equivalent of routing blocks in Lua | ||
+ | -- KSR - the new dynamic object exporting Kamailio functions | ||
+ | -- sr - the old static object exporting Kamailio functions | ||
+ | -- | ||
-- SIP request routing | -- SIP request routing | ||
+ | -- equivalent of request_route{} | ||
function ksr_request_route() | function ksr_request_route() | ||
KSR.info(" | KSR.info(" | ||
if sr.maxfwd.process_maxfwd(10) < 0 then | if sr.maxfwd.process_maxfwd(10) < 0 then | ||
- | sr.sl.send_reply(483, | + | KSR.sl.send_reply(483, |
return; | return; | ||
end | end | ||
- | KSR.sl.sreply(200, | + | -- KSR.sl.sreply(200, |
+ | |||
+ | sr.pv.sets(" | ||
+ | KSR.tm.t_on_branch(" | ||
+ | KSR.tm.t_on_reply(" | ||
+ | KSR.tm.t_on_failure(" | ||
+ | |||
+ | if KSR.tm.t_relay() < 0 then | ||
+ | KSR.sl.send_reply(500, | ||
+ | end | ||
end | end | ||
-- SIP response routing | -- SIP response routing | ||
+ | -- equivalent of reply_route{} | ||
function ksr_reply_route() | function ksr_reply_route() | ||
KSR.info(" | KSR.info(" | ||
end | end | ||
+ | |||
+ | -- branch route callback | ||
+ | -- equivalent of a branch_route{} | ||
+ | function ksr_branch_route_one() | ||
+ | KSR.info(" | ||
+ | end | ||
+ | |||
+ | -- onreply route callback | ||
+ | -- equivalent of an onreply_route{} | ||
+ | function ksr_onreply_route_one() | ||
+ | KSR.info(" | ||
+ | end | ||
+ | |||
+ | -- failure route callback | ||
+ | -- equivalent of a failure_route{} | ||
+ | function ksr_failure_route_one() | ||
+ | KSR.info(" | ||
+ | end | ||
+ | |||
+ | </ | ||
+ | |||
+ | ===== Python Config KEMI Engine ===== | ||
+ | |||
+ | The **app_python** module must be loaded and the Python script with routing logic must be set to its **script_name** parameter. | ||
+ | |||
+ | The **kemi** engine is built reusing the exiting **app_python** way of executing C code from Kamailio. In the Python script you have to declare the global **mod_init()** method where to instantiate an object of a class that implements the other callback methods (functions) to be executed by Kamailio. | ||
+ | |||
+ | Inside the new class, the following methods are relevant: | ||
+ | |||
+ | * **ksr_request_route(self, | ||
+ | * **ksr_reply_route(self, | ||
+ | * **ksr_onsend_route(self, | ||
+ | * branch route callback - the name of the Python function to be executed instead of a branch route has to be provided as parameter to KSR.tm.t_on_branch(...) | ||
+ | * onreply route callback - the name of the Python function to be executed instead of an onreply route has to be provided as parameter to KSR.tm.t_on_reply(...) | ||
+ | * failure route callback - the name of the Python function to be executed instead of a failure route has to be provided as parameter to KSR.tm.t_on_failure(...) | ||
+ | * branch failure route callback - the name of the Python function to be executed instead of an event route for branch failure has to be provided as parameter to KSR.tm.t_on_branch_failure(...) | ||
+ | * TBD: the options for specific event_route blocks. Meanwhile, should work using hybrid configuration with request_route/ | ||
+ | |||
+ | The following objects are available inside the Python script: | ||
+ | |||
+ | * **Router** - provided by the old way of exporting functions to Python (https:// | ||
+ | * **KSR** - provided via KEMI interface (not many functions exported at this moment, but expected to take over all **Python** module). The functions exported to KEMI are accessible as KSR.submodule.function(...). If submodule name is empty (reserved for core functions), then they are available as KSR.function(...). | ||
+ | |||
+ | |||
+ | ==== Python Embedded Config Example ==== | ||
+ | |||
+ | The kamailio.cfg with the global/core and modules settings: | ||
+ | |||
+ | <code c> | ||
+ | #!KAMAILIO | ||
+ | # | ||
+ | # Kamailio (OpenSER) SIP Server v5.0 | ||
+ | # - web: http:// | ||
+ | # | ||
+ | ####### Global Parameters ######### | ||
+ | |||
+ | debug=4 | ||
+ | log_stderror=yes | ||
+ | fork=yes | ||
+ | children=2 | ||
+ | |||
+ | memdbg=5 | ||
+ | memlog=5 | ||
+ | |||
+ | auto_aliases=no | ||
+ | |||
+ | listen=udp: | ||
+ | |||
+ | mpath=" | ||
+ | |||
+ | loadmodule " | ||
+ | loadmodule " | ||
+ | loadmodule " | ||
+ | loadmodule " | ||
+ | loadmodule " | ||
+ | loadmodule " | ||
+ | loadmodule " | ||
+ | loadmodule " | ||
+ | loadmodule " | ||
+ | loadmodule " | ||
+ | loadmodule " | ||
+ | loadmodule " | ||
+ | loadmodule " | ||
+ | |||
+ | # ----------------- setting module-specific parameters --------------- | ||
+ | |||
+ | # ----- mi_fifo params ----- | ||
+ | modparam(" | ||
+ | |||
+ | |||
+ | # ----- tm params ----- | ||
+ | # auto-discard branches from previous serial forking leg | ||
+ | modparam(" | ||
+ | # default retransmission timeout: 30sec | ||
+ | modparam(" | ||
+ | # default invite retransmission timeout after 1xx: 120sec | ||
+ | modparam(" | ||
+ | |||
+ | # ----- debugger params ----- | ||
+ | modparam(" | ||
+ | |||
+ | ####### Routing Logic ######## | ||
+ | |||
+ | modparam(" | ||
+ | |||
+ | cfgengine " | ||
+ | </ | ||
+ | |||
+ | The **/ | ||
+ | |||
+ | <code python> | ||
+ | import sys | ||
+ | import Router.Logger as Logger | ||
+ | import KSR as KSR | ||
+ | |||
+ | def dumpObj(obj): | ||
+ | for attr in dir(obj): | ||
+ | # KSR.info(" | ||
+ | Logger.LM_INFO(" | ||
+ | |||
+ | def mod_init(): | ||
+ | KSR.info(" | ||
+ | # dumpObj(KSR); | ||
+ | return kamailio(); | ||
+ | |||
+ | class kamailio: | ||
+ | def __init__(self): | ||
+ | KSR.info(' | ||
+ | |||
+ | def child_init(self, | ||
+ | KSR.info(' | ||
+ | return 0 | ||
+ | |||
+ | def ksr_request_route(self, | ||
+ | KSR.info(" | ||
+ | msg.rewrite_ruri(" | ||
+ | KSR.tm.t_on_branch(" | ||
+ | KSR.tm.t_on_reply(" | ||
+ | KSR.tm.t_on_failure(" | ||
+ | KSR.sl.send_reply(100, | ||
+ | if KSR.tm.t_relay() < 0 : | ||
+ | KSR.sl.send_reply(500, | ||
+ | return 1; | ||
+ | |||
+ | def ksr_reply_route(self, | ||
+ | KSR.info(" | ||
+ | return 1; | ||
+ | |||
+ | def ksr_branch_route_one(self, | ||
+ | KSR.info(" | ||
+ | return 1; | ||
+ | |||
+ | def ksr_onreply_route_one(self, | ||
+ | KSR.info(" | ||
+ | return 1; | ||
+ | |||
+ | def ksr_failure_route_one(self, | ||
+ | KSR.info(" | ||
+ | return 1; | ||
</ | </ | ||