Sidebar


kamailio:k43-async-sip-routing-nodejs

This is an old revision of the document!


Async SIP Routing with Kamailio and Node.js

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.

Kamailio Config File

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:

  • load evapi, jansson and rtjson modules
  • instead of routing to location service, request routing information from external application via evapi
  • add the routing blocks specific for evapi module
  • use jansson to investigate returned JSON document and take decision of what to do

The diff of the config file comparing with the default one:

kamailio-config.diff
--- 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;
 }


Copyright 2010-2020 Asipto.com