## Core KEMI Functions ## The exports to KEMI framework from the core of Kamailio: * several functions directly to `KSR` module (like `KSR.function(params)`), which are mostly the main functions from the core and for writing log messages (some being part of xlog module for native kamailio.cfg language) * the `KSR.pv` submodule, which are the generic functions to manage pseudo-variables, like set and get operations (some types of variables can have dedicated functions exported by various module, like `htable` to work with items in the shared memory hash table, or r-uri and xavp operations from `pv` and `kemix` modules). * the `KSR.hdr` submodule, which are the most used functions for managing SIP message headers (some of the functions in this submodules correspond to the ones in `textops` or `textopsx` modules for `kamailio.cfg`). Example of using KEMI functions exported to Lua interpreter: ```Lua KSR.dbg("a debug message from Lua script\n"); KSR.hdr.remove("Route"); ``` Exported functions from core directly to KSR module or KSR.hdr submodule are listed in the next sections. ### KSR.add_local_rport() ### `bool add_local_rport()` Set the internal flag to add rport parameter to local generated Via header. Example: ``` KSR.add_local_rport(); ``` ### KSR.add_tcp_alias() ### `add_tcp_alias(int port)` Adds a tcp port alias for the current connection (if tcp). Useful if you want to send all the trafic to port_alias through the same connection this request came from (it could help for firewall or nat traversal). When the `aliased` connection is closed (e.g. it is idle for too much time), all the port aliases are removed. ``` KSR.add_tcp_alias(5080); ``` ### KSR.add_tcp_alias_via() ### `int add_tcp_alias_via()` Adds the port from the message via as an alias to TCP connection. See `add_tcp_alias(int port)` for more details. Example: ``` KSR.add_tcp_alias_via(); ``` ### void KSR.dbg(...) ### `void KSR.dbg(str "msg")` Write a log message to DEBUG level. Example: ``` KSR.dbg("debug log message from embedded interpreter\n"); ``` ### void KSR.err(...) ### `void KSR.err(str "msg")` Write a log message to ERROR level. Example: ``` KSR.err("error log message from embedded interpreter\n"); ``` ### int KSR.get_debug(...) ### `int KSR.get_debug()` Return the debug level for config logging. Example: ``` if KSR.get_debug() < 2 then -- debug and info log messages are not printed end ``` ### KSR.force_rport() ### `bool force_rport()` Add rport parameter to the top Via of the incoming request and sent the SIP response to source port. ### void KSR.info(...) ### `void KSR.info(str "msg")` Write a log message to INFO level. Example: ``` KSR.info("info log message from embedded interpreter\n"); ``` ### KSR.is_method() ### `bool is_method(str "vmethod")` Return true if the value of the parameter matches the method type of the SIP message. ```JavaScript if(KSR.is_method("INVITE")) { ... } ``` ### KSR.is_method_in() ### `bool is_method_in(str "vmethod")` Return true if SIP method of the currently processed message is matching one of the corresponding characters given as parameter. Matching the method is done based on corresponding characters: * `I` - INVITE * `A` - ACK * `B` - BYE * `C` - CANCEL * `R` - REGISTER * `M` - MESSAGE * `O` - OPTIONS * `S` - SUBSCRIBE * `P` - PUBLISH * `N` - NOTIFY * `U` - UPDATE * `K` - KDMQ * `G` - GET * `T` - POST * `V` - PUT * `D` - DELETE Example: ```Lua if KSR.is_method_in("IABC") then -- the method is INVITE, ACK, BYE or CANCEL ... end ``` ### KSR.is_INVITE() ### `bool is_INVITE()` Return true if the method type of the SIP message is `INVITE`. ```Lua if KSR.is_INVITE() then ... end ``` ### KSR.is_ACK() ### `bool is_ACK()` Return true if the method type of the SIP message is `ACK`. ### KSR.is_BYE() ### `bool is_BYE()` Return true if the method type of the SIP message is `BYE`. ### KSR.is_CANCEL() ### `bool is_CANCEL()` Return true if the method type of the SIP message is `CANCEL`. ### KSR.is_REGISTER() ### `bool is_REGISTER()` Return true if the method type of the SIP message is `REGISTER`. ### KSR.is_MESSAGE() ### `bool is_MESSAGE()` Return true if the method type of the SIP message is `MESSAGE`. ### KSR.is_SUBSCRIBE() ### `bool is_SUBSCRIBE()` Return true if the method type of the SIP message is `SUBSCRIBE`. ### KSR.is_PUBLISH() ### `bool is_PUBLISH()` Return true if the method type of the SIP message is `PUBLISH`. ### KSR.is_NOTIFY() ### `bool is_NOTIFY()` Return true if the method type of the SIP message is `NOTIFY`. ### KSR.is_OPTIONS() ### `bool is_OPTIONS()` Return true if the method type of the SIP message is `OPTIONS`. ### KSR.is_INFO() ### `bool is_INFO()` Return true if the method type of the SIP message is `INFO`. ### KSR.is_UPDATE() ### `bool is_UPDATE()` Return true if the method type of the SIP message is `UPDATE`. ### KSR.is_PRACK() ### `bool is_PRACK()` Return true if the method type of the SIP message is `PRACK`. ### KSR.is_myself(...) ### `bool KSR.is_myself(str "uri")` Return true of the URI address provided as parameter matches a local socket (IP) or local domain. ```Lua if KSR.is_myself("sip:127.0.0.1:5060") then ... end ``` ### KSR.is_myself_furi() ### `bool is_myself_furi()` Return true if the URI in From header matches a local socket (IP) or local domain. ```Lua if KSR.is_myself_furi() then ... end ``` ### KSR.is_myself_ruri() ### `bool is_myself_ruri()` Return true if the R-URI matches a local socket (IP) or local domain. ```Lua if KSR.is_myself_ruri() then ... end ``` ### KSR.is_myself_turi() ### `bool is_myself_turi()` Return true if the URI in To header matches a local socket (IP) or local domain. ```Lua if KSR.is_myself_turi() then ... end ``` ### KSR.is_myself_suri() ### `bool is_myself_suri()` Return true if the URI built from source IP, source port and protocol matches a local socket (IP). ```Lua if KSR.is_myself_suri() then ... end ``` ### KSR.is_myself_srcip() ### `bool is_myself_srcip()` Return true if the source IP matches a local socket (IP). ```Lua if KSR.is_myself_srcip() then ... end ``` ### void KSR.log(...) ### `void KSR.log(str "level", str "msg")` Write a log message specifying the level value. The level parameter can be: * "dbg" * "info" * "warn" * "crit" * "err" If level value is not matched, then "err" log level is used. Example: ``` KSR.log("dbg", "debug log message from: " + KSR.pv.getw("$si") + "\r\n"); ``` ### KSR.setflag(...) ### `bool KSR.setflag(int flag)` Set the SIP message/transaction flag at the index provided by the parameter. The flag parameter has to be a number from 0 to 31. ``` KSR.setflag(10); ``` ### KSR.resetflag(...) ### `bool KSR.resetflag(int flag)` Reset the SIP message/transaction flag at the index provided by the parameter. The flag parameter has to be a number from 0 to 31. ``` KSR.resetflag(10); ``` ### KSR.isflagset(...) ### `bool KSR.isflagset(int flag)` Return true if the message/transaction flag at the index provided by the parameter is set (the bit has value 1). ``` if ( KSR.isflagset(10) ) ... ``` ### KSR.setbflag(...) ### `bool KSR.setbflag(int flag)` Set the branch flag at the index provided by the parameter. The flag parameter has to be a number from 0 to 31. ``` KSR.setbflag(10); ``` ### KSR.resetbflag(...) ### `bool KSR.resetbflag(int flag)` Reset the branch flag at the index provided by the parameter. The flag parameter has to be a number from 0 to 31. ``` KSR.resetbflag(10); ``` ### KSR.isbflagset(...) ### `bool KSR.isbflagset(int flag)` Return true if the branch flag at the index provided by the parameter is set (the bit has value 1). ``` if ( KSR.isbflagset(10) ) ... ``` ### KSR.setbiflag(...) ### `bool KSR.setbiflag(int flag, int branch)` Set the flag at the index provided by the first parameter to the branch number specified by the second parameter. The flag parameter has to be a number from 0 to 31. The branch parameter should be between 0 and 12 (a matter of `max_branches` global parameter). ``` KSR.setbiflag(10, 2); ``` ### KSR.resetbiflag(...) ### `bool KSR.resetbiflag(int flag, int branch)` Reset a branch flag by position and branch index. ### KSR.isbiflagset(...) ### `bool KSR.isbiflagset(int flag, int branch)` Test if a branch flag is set by position and branch index. ### KSR.setsflag(...) ### `bool KSR.setsflag(int flag)` Set a script flag. ### KSR.resetsflag(...) ### `bool KSR.resetsflag(int flag)` Reset a script flag. ### KSR.issflagset(...) ### `bool KSR.issflagset(int flag)` Test if a script flag is set. ### KSR.seturi(...) ### `bool KSR.seturi(str "uri")` Set the request URI (R-URI). Example: ``` KSR.seturi("sip:alice@voip.com"); ``` ### KSR.setuser(...) ### `bool KSR.setuser(str "user")` Example: ``` KSR.setuser("alice"); ``` ### KSR.sethost(...) ### `bool KSR.sethost(str "host")` Example: ``` KSR.sethost("voip.com"); ``` ### KSR.setdsturi(...) ### `bool KSR.setdsturi(str "uri")` Example: ``` KSR.setdsturi("sip:voip.com:5061;transport=tls"); ``` ### KSR.resetdsturi(...) ### `bool KSR.resetdsturi()` Reset the destination URI (aka: outbound proxy address, dst_uri, $du). ### KSR.isdsturiset(...) ### `bool KSR.isdsturiset()` Test if destination URI is set. ### KSR.force_rport(...) ### `bool KSR.force_rport()` Set the flag for "rport" handling (send the reply based on source address instead of Via header). Example: ``` KSR.force_rport(); ``` ### KSR.set_drop(...) ### `void KSR.set_drop()` Set the DROP flag, so at the end of KEMI script execution, the SIP request branch or the SIP response is not forwarded. Note: it doesn't not stop the execution of KEMI script, see KSR.x.drop(). Example: ``` KSR.set_drop(); ``` ### KSR.set_advertised_address() ### `int set_advertised_address(str "addr")` Set the address (host or ip) to be advertised in Via header. ### KSR.set_advertised_port() ### `int set_advertised_port(str "port")` Set the port (in string format) to be advertised in Via header. ### KSR.set_forward_close(...) ### `bool KSR.set_forward_close()` Set the flag to close the connection after forwarding the message. ### KSR.set_forward_no_connect(...) ### `bool KSR.set_forward_no_connect()` Set the flag to not open a connection if the connection to the target does not exist when attempting to forward a message. ### KSR.set_reply_close(...) ### `bool KSR.set_reply_close()` Set the flag to close the connection after sending a response. ### KSR.set_reply_no_connect(...) ### `bool KSR.set_reply_no_connect()` Set the flag to not open a connection if the connection for sending the response does not exist. ### KSR.forward(...) ### `int KSR.forward()` Forward the SIP request in stateless mode to the address set in destination URI ($du), or, if this is not set, to the address in request URI ($ru). ### KSR.forward_uri(...) ### `int KSR.forward_uri(str "uri")` Forward the SIP request in stateless mode to the address provided in the SIP URI parameter. ``` KSR.forward_uri("sip:127.0.0.1:5080;transport=tcp"); ``` ### KSR.pv. Submodule ### `KSR.pv` submodule provides the functions to get, set and test the values of pseduo-variables. The `pvname` that appears in the next sections in the function prototypes has to be a valid pseudo-variable name for Kamailio native configuration file (for example `$ru`, `$var(x)`, `$shv(z)`, ...). Note: functions exported by Kamailio's `pv` module are in `KSR.pvx` package. ### KSR.pv.get(...) ### `xval KSR.pv.get(str "pvname")` Return the value of pseudo-variable `pvname`. The returned value can be string or integer. Example: ``` KSR.dbg("ruri is: " + KSR.pv.get("$ru") + "\n"); ``` ### KSR.pv.gete(...) ### `xval KSR.pv.gete(str "pvname")` Return the value of pseudo-variable `pvname` if it is different than `$null` or the empty string ("") if the variable is having the `$null` value. Example: ``` KSR.dbg("avp is: " + KSR.pv.gete("$avp(x)") + "\n"); ``` ### KSR.pv.getvn(...) ### `xval KSR.pv.getvn(str "pvname", int vn)` Return the value of pseudo-variable `pvname` if it is different than `$null` or the parameter `vn` if the variable is having the `$null` value. Example: ``` KSR.dbg("avp is: " + KSR.pv.getvn("$avp(x)", 0) + "\n"); ``` ### KSR.pv.getvs(...) ### `xval KSR.pv.getvs(str "pvname", str "vs")` Return the value of pseudo-variable `pvname` if it is different than `$null` or the parameter `vs` if the variable is having the `$null` value. Example: ``` KSR.dbg("avp is: " + KSR.pv.getvs("$avp(x)", "foo") + "\n"); ``` ### KSR.pv.getw(...) ### `xval KSR.pv.getw(str "pvname")` Return the value of pseudo-variable `pvname` if it is different than `$null` or the string `<>` if the variable is having the `$null` value. This should be used instead of `KSR.pv.get(...)` in the scripting languages that throw and error when attempting to print a `NULL` (or `NIL`) value. Example: ``` KSR.dbg("avp is: " + KSR.pv.getw("$avp(x)") + "\n"); ``` ### KSR.pv.seti(...) ### `void KSR.pv.seti(str "pvname", int val)` Set the value of pseudo-variable `pvname` to integer value provided by parameter `val`. Example: ``` KSR.pv.seti("$var(x)", 10); ``` ### KSR.pv.sets(...) ### `void KSR.pv.sets(str "pvname", str "val")` Set the value of pseudo-variable `pvname` to string value provided by parameter `val`. Example: ``` KSR.pv.sets("$var(x)", "kamailio"); ``` ### KSR.pv.unset(...) ### `void KSR.pv.unset(str "pvname")` Set the value of pseudo-variable `pvname` to `$null`. Example: ``` KSR.pv.unset("$avp(x)"); ``` ### KSR.pv.is_null(...) ### `bool KSR.pv.is_null(str "pvname")` Return true if pseudo-variable `pvname` is `$null`. Example: ``` if(KSR.pv.is_null("$avp(x)")) { ... } ``` ### KSR.hdr Submodule ### ### KSR.hdr.append(...) ### `int KSR.hdr.append(str "hdrval")` Append header to current SIP message (request or reply). It will be added after the last header. Example: ``` KSR.hdr.append("X-My-Hdr: " + KSR.pv.getw("$si") + "\r\n"); ``` ### KSR.hdr.append_after(...) ### `int KSR.hdr.append_after(str "hdrval", str "hdrname")` Append header to current SIP message (request or reply). It will be added after the first header matching the name `hdrname`. Example: ``` KSR.hdr.append_after("X-My-Hdr: " + KSR.pv.getw("$si") + "\r\n", "Call-Id"); ``` ### KSR.hdr.insert(...) ### `int KSR.hdr.insert(str "hdrval")` Insert header to current SIP message (request or reply). It will be added before the first header. Example: ``` KSR.hdr.insert("X-My-Hdr: " + KSR.pv.getw("$si") + "\r\n"); ``` ### KSR.hdr.insert_before(...) ### `int KSR.hdr.insert_before(str "hdrval", str "hdrname")` Insert header to current SIP message (request or reply). It will be added before the header matching the name `hdrname`. Example: ``` KSR.hdr.insert_before("X-My-Hdr: " + KSR.pv.getw("$si") + "\r\n", "Call-Id"); ``` ### KSR.hdr.remove(...) ### `int KSR.hdr.remove(str "hdrval")` Remove all the headers with the name `hdrval`. Example: ``` KSR.hdr.remove("X-My-Hdr"); ``` ### KSR.hdr.rmappend(...) ### `int KSR.hdr.rmappend(str "hrm", str "hadd")` Remove all the headers with the name `hrm` and append `hadd`. The value for `hadd` must include header name name and ending `\r\n`. This function is a a wrapper for `KSR.hdr.remove("hrm")` and `KSR.hdr.append("hadd")`. Example: ``` KSR.hdr.remove("X-My-Hdr", "X-My-Hdr: abc\r\n"); ``` ### KSR.hdr.is_present(...) ### `int KSR.hdr.is_present(str "hdrval")` Return greater than 0 if a header with the name `hdrval` exists and less than 0 if there is no such header. Example: ``` if(KSR.hdr.is_present("X-My-Hdr") > 0) { ... } ``` ### KSR.hdr.append_to_reply(...) ### `int KSR.hdr.append_to_reply(str "hdrval")` Add a header to the SIP response to be generated by Kamailio for the current SIP request. Example: ``` KSR.hdr.append_to_reply("X-My-Hdr: " + KSR.pv.getw("$si") + "\r\n"); ``` ### KSR.hdr.get(...) ### `xval KSR.hdr.get(str "hname")` Return the value of the header matching the name with `hname` or `NULL` if that header is not found. Example: ``` v = KSR.hdr.get("X-My-Hdr"); ``` ### KSR.hdr.gete(...) ### `xval KSR.hdr.gete(str "hname")` Return the value of the header matching the name with `hname` or empty string if that header is not found. Example: ``` v = KSR.hdr.gete("X-My-Hdr"); ``` ### KSR.hdr.getw(...) ### `xval KSR.hdr.getw(str "hname")` Return the value of the header matching the name with `hname` or string `<>` if that header is not found. Example: ``` v = KSR.hdr.getw("X-My-Hdr"); ```