- Links
100% right
This is an old revision of the document!
The aim is to show how to leverage evapi module to retrieve JSON-formatted routing information from external source, respectively a node.js application.
The module rtjson defines a format for JSON document that makes it straightforward to push new destinations for a SIP request. The module jansson is used to parse the JSON document in kamailio.cfg for fetching additional attributes that are relevant for processing.
The tutorial should be used with Kamailio v4.3.1 or newer. The starting point is kamailio-basic.cfg, a simplified version of default kamailio.cfg, which is included in the installation from sources or packages and it is located in the same directory as kamailio.cfg.
To install Kamailio, you can use the tutorial available at:
To be easy to track changes, some parts that are no longer needed are still left in kamailio.cfg, being just inactive.
The main concepts and changes are:
The diff of the config file comparing with the default one:
--- kamailio-basic.cfg 2015-04-30 23:40:40.104096323 +0200 +++ kamailio-evapi-nodejs.cfg 2015-07-28 11:15:04.946928692 +0200 @@ -187,6 +187,10 @@ loadmodule "debugger.so" #!endif +loadmodule "evapi.so" +loadmodule "jansson.so" +loadmodule "rtjson.so" + # ----------------- setting module-specific parameters --------------- @@ -303,6 +307,10 @@ modparam("debugger", "cfgtrace", 1) #!endif + +# ----- evapi params ----- +modparam("evapi", "bind_addr", "127.0.0.1:8448") + ####### Routing Logic ######## @@ -311,6 +319,8 @@ # - note: this is the same as route { ... } request_route { + sl_send_reply("100", "Trying right now"); + # per request initial checks route(REQINIT); @@ -359,6 +369,9 @@ # handle registrations route(REGISTRAR); + route(TOEVAPI); + exit; + if ($rU==$null) { # request with no Username in RURI sl_send_reply("484","Address Incomplete"); @@ -612,6 +625,7 @@ # Manage outgoing branches branch_route[MANAGE_BRANCH] { xdbg("new branch [$T_branch_idx] to $ru\n"); + rtjson_update_branch(); route(NATMANAGE); } @@ -629,4 +643,62 @@ if (t_is_canceled()) { exit; } + + if(rtjson_next_route()) { + t_on_branch("MANAGE_BRANCH"); + t_on_failure("MANAGE_FAILURE"); + route(RELAY); + exit; + } +} + +event_route[evapi:connection-new] { + xlog("new connection from [$evapi(srcaddr):$evapi(srcport)]\n"); + if($evapi(srcaddr)!="127.0.0.1") { + evapi_close(); + exit; + } +} + +event_route[evapi:connection-closed] { + xlog("connection closed by $evapi(srcaddr):$evapi(srcport)\n"); +} + +event_route[evapi:message-received] { + xlog("received [$evapi(msg)] from $evapi(srcaddr):$evapi(srcport)\n"); + if($evapi(msg)=~"routing" && $evapi(msg)=~"tindex") { + jansson_get("xtra.tindex", "$evapi(msg)", "$var(tindex)"); + jansson_get("xtra.tlabel", "$evapi(msg)", "$var(tlabel)"); + $var(evmsg) = $evapi(msg); + xlog("L_INFO", "preparing to resume transaction for processing: $var(tindex) / $var(tlabel)\n"); + t_continue("$var(tindex)", "$var(tlabel)", "EVAPIRESPONSE"); + } +} + +route[EVAPIRESPONSE] { + xlog("L_INFO", "resumed transaction for processing: $T(id_index) / $T(id_label)\n"); + #if($var(evmsg)=~"location") { + # send_reply("404", "No location yet"); + # exit; + #} + jansson_get("routing", "$var(evmsg)", "$var(routing)"); + if($var(routing)=="location") { + route(LOCATION); + exit; + } + rtjson_init_routes("$var(evmsg)"); + rtjson_push_routes(); + t_on_branch("MANAGE_BRANCH"); + t_on_failure("MANAGE_FAILURE"); + route(RELAY); + exit; +} + +route[TOEVAPI] { + evapi_async_relay("{\n \"event\": \"sip-routing\",\n" + " \"tindex\": $T(id_index), \"tlabel\": $T(id_label)," + " \"caller\": \"$fU\", \"callee\": \"$rU\"\n}"); + + xlog("L_INFO", "suspended transaction: $T(id_index) / $T(id_label)\n"); + exit; }