Ver código fonte

app_lua_sr: module relocated to archive

Victor Seva 1 ano atrás
pai
commit
965e6ed40a

+ 89 - 0
src/modules/app_lua_sr/Makefile

@@ -0,0 +1,89 @@
+#
+# WARNING: do not run this directly, it should be run by the main Makefile
+
+include ../../Makefile.defs
+auto_gen=
+NAME=app_lua_sr.so
+
+LUALIB=lua
+
+ifeq ($(LUAJIT),)
+	ifeq ($(CROSS_COMPILE),)
+		BUILDER = $(shell which lua-config)
+	endif
+
+	ifeq ($(BUILDER),)
+		ifeq ($(CROSS_COMPILE),)
+			BUILDER = $(shell which pkg-config)
+		endif
+		ifeq ($(BUILDER),)
+			# no pkg-config - try finding by path
+			ifneq ($(shell ls $(LOCALBASE)/lib/liblua* | grep liblua5.1),)
+				LUALIB=lua5.1
+			else ifneq ($(shell ls $(LOCALBASE)/lib/liblua* | grep liblua5.2),)
+				LUALIB=lua5.2
+			else ifneq ($(shell ls $(LOCALBASE)/lib/liblua* | grep liblua5.3),)
+				LUALIB=lua5.3
+			else ifneq ($(shell ls $(LOCALBASE)/lib/liblua* | grep liblua5.4),)
+				LUALIB=lua5.4
+			endif
+			DEFS+= -DLUA_COMPAT_MODULE -I$(LOCALBASE)/include -I$(LOCALBASE)/include/$(LUALIB)
+			LIBS+= -L$(LOCALBASE)/lib -l$(LUALIB) -lm
+		else
+			ifneq ($(shell pkg-config --silence-errors --libs lua-5.1),)
+				LUALIB=lua-5.1
+			else ifneq ($(shell pkg-config --silence-errors --libs lua5.1),)
+				LUALIB=lua5.1
+			else ifneq ($(shell pkg-config --silence-errors --libs lua5.2),)
+				LUALIB=lua5.2
+			else ifneq ($(shell pkg-config --silence-errors --libs lua5.3),)
+				LUALIB=lua5.3
+			else ifneq ($(shell pkg-config --silence-errors --libs lua5.4),)
+				LUALIB=lua5.4
+			else ifneq ($(shell pkg-config --silence-errors --libs lua),)
+				LUALIB=lua
+			else
+				LUALIB=
+			endif
+			ifeq ($(LUALIB),lua5.1)
+				DEFS+= $(shell pkg-config --cflags lua5.1 | sed -e "s/\\\\/'/" -e "s/\\\\\"/\"'/")
+				LIBS = $(shell pkg-config --libs lua5.1)
+			else ifneq ($(LUALIB),)
+				DEFS+= -DLUA_COMPAT_MODULE
+				DEFS+= $(shell pkg-config --cflags $(LUALIB))
+				LIBS = $(shell pkg-config --libs $(LUALIB))
+			else
+				# pkg-config with no lua library detected - try finding by path
+				LUALIB=lua
+				ifneq ($(shell ls $(LOCALBASE)/lib/liblua* | grep liblua5.1),)
+					LUALIB=lua5.1
+				else ifneq ($(shell ls $(LOCALBASE)/lib/liblua* | grep liblua5.2),)
+					LUALIB=lua5.2
+				else ifneq ($(shell ls $(LOCALBASE)/lib/liblua* | grep liblua5.3),)
+					LUALIB=lua5.3
+				else ifneq ($(shell ls $(LOCALBASE)/lib/liblua* | grep liblua5.4),)
+					LUALIB=lua5.4
+				endif
+				DEFS+= -DLUA_COMPAT_MODULE -I$(LOCALBASE)/include -I$(LOCALBASE)/include/$(LUALIB)
+				LIBS+= -L$(LOCALBASE)/lib -l$(LUALIB) -lm
+			endif
+		endif
+	else
+		DEFS+= $(shell lua-config --include)
+		LIBS = $(shell lua-config --libs)
+	endif
+else
+	# build using LuaJIT
+	ifeq ($(CROSS_COMPILE),)
+		BUILDER = $(shell which pkg-config)
+	endif
+	ifeq ($(BUILDER),)
+		DEFS+= -I/usr/include/luajit-2.1
+		LIBS = -lluajit-5.1
+	else
+		DEFS+= $(shell pkg-config --silence-errors --cflags luajit)
+		LIBS = $(shell pkg-config --silence-errors --libs luajit)
+	endif
+endif
+
+include ../../Makefile.modules

+ 146 - 0
src/modules/app_lua_sr/README

@@ -0,0 +1,146 @@
+app_lua_sr Module
+
+Daniel-Constantin Mierla
+
+   asipto.com
+
+Edited by
+
+Daniel-Constantin Mierla
+
+   <[email protected]>
+
+   Copyright © 2010-2019 Daniel-Constantin Mierla (asipto.com)
+     __________________________________________________________________
+
+   Table of Contents
+
+   1. Admin Guide
+
+        1. Overview
+        2. Dependencies
+
+              2.1. Kamailio Modules
+              2.2. External Libraries or Applications
+
+        3. Parameters
+
+              3.1. register (string)
+
+   List of Examples
+
+   1.1. Build against LuaJIT libraries
+   1.2. Set register parameter
+
+Chapter 1. Admin Guide
+
+   Table of Contents
+
+   1. Overview
+   2. Dependencies
+
+        2.1. Kamailio Modules
+        2.2. External Libraries or Applications
+
+   3. Parameters
+
+        3.1. register (string)
+
+1. Overview
+
+   This module exports the Lua module 'sr', the old API existing before
+   the KEMI framework. The module requires 'app_lua' module.
+
+   IMPORTANT: this module is kept to allow a smooth migration of the
+   scripts using 'sr' module in Lua to KEMI framework and the 'KSR'
+   module. It will be marked as obsolete in the near future and removed
+   afterwards. If you find any function exported to Lua via 'sr' that has
+   no alternative in Lua 'KSR' module, report it to sr-dev mailing list.
+
+   Lua (http://www.lua.org) is a fast and easy to embed scripting
+   language. Exported API from Kamailio to Lua is documented in the
+   dokuwiki.
+
+2. Dependencies
+
+   2.1. Kamailio Modules
+   2.2. External Libraries or Applications
+
+2.1. Kamailio Modules
+
+   The following modules must be loaded before this module:
+     * app_lua - the Lua interpreter module.
+     * various - the modules specified by the 'register' modparam.
+
+2.2. External Libraries or Applications
+
+   The following libraries or applications must be installed before
+   running Kamailio with this module loaded:
+     * liblua5.1-dev - Lua devel library.
+
+   This module can be compiled against LuaJIT compiler (instead of
+   standard Lua). Then this library is needed:
+     * libluajit-5.1-dev - LuaJIT devel library.
+
+   To enable that, LUAJIT variable has to be set.
+
+   Example 1.1. Build against LuaJIT libraries
+   E.g: $ LUAJIT="yes" make modules modules=modules/app_lua_sr
+
+   (Warning: LuaJIT version is 5.1, so scripts prepared for higher Lua
+   versions may not work with LuaJIT)
+
+3. Parameters
+
+   3.1. register (string)
+
+3.1. register (string)
+
+   NOTE: Since Kamailio v5.0, KEMI exports are available in Lua script
+   under KSR module exposed by 'app_lua'. These exports cover most of the
+   modules, a lot more than those listed next. The KEMI exports are the
+   recommended to be used, the old 'sr' module might be obsoleted soon. To
+   read more about KEMI exports and available KSR submodules, see:
+     * https://kamailio.org/docs/tutorials/devel/kamailio-kemi-framework/
+
+   Use this parameter to register optional Kamailio submodules to Lua.
+   Available submodules are:
+     * alias_db - register functions from alias_db module under
+       'sr.alias_db'.
+     * auth - register functions from auth module under 'sr.auth'.
+     * auth_db - register functions from auth_db module under
+       'sr.auth_db'.
+     * dispatcher - register functions from dispatcher module under
+       'sr.dispatcher'.
+     * maxfwd - register functions from maxfwd module under 'sr.maxfwd'.
+     * msilo - register functions from msilo module under 'sr.msilo'.
+     * presence - register functions from presence module under
+       'sr.presence'.
+     * presence_xml - register functions from presence_xml module under
+       'sr.presence_xml'.
+     * pua_usrloc - register functions from pua_usrloc module under
+       'sr.pua_usrloc'.
+     * registrar - register functions from registrar module under
+       'sr.registrar'.
+     * rls - register functions from rls module under 'sr.rls'.
+     * rr - register functions from rr module under 'sr.rr'.
+     * sanity - register functions from sanity module under 'sr.sanity'.
+     * sdpops - register functions from sdpops module under 'sr.sdpops'.
+     * siputils - register functions from siputils module under
+       'sr.siputils'.
+     * sl - register functions from sl module under 'sr.sl'.
+     * sqlops - register functions from sqlops module under 'sr.sqlops'.
+     * textops - register functions from textops module under
+       'sr.textops'.
+     * tm - register functions from tm module under 'sr.tm'.
+     * xhttp - register functions from xhttp module under 'sr.xhttp'.
+
+   Note that 'sr', 'sr.hdr' and 'sr.pv' modules are always registered to
+   Lua.
+
+   Default value is “null”.
+
+   Example 1.2. Set register parameter
+...
+modparam("app_lua_sr", "register", "sl")
+...

+ 1515 - 0
src/modules/app_lua_sr/app_lua_sr_api.c

@@ -0,0 +1,1515 @@
+/**
+ * Copyright (C) 2010-2016 Daniel-Constantin Mierla (asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "../../core/action.h"
+#include "../../core/data_lump.h"
+#include "../../core/data_lump_rpl.h"
+#include "../../core/dprint.h"
+#include "../../core/dset.h"
+#include "../../core/flags.h"
+#include "../../core/forward.h"
+#include "../../core/kemi.h"
+#include "../../core/mem/mem.h"
+#include "../../core/parser/parse_uri.h"
+#include "../../core/route_struct.h"
+#include "../../core/sr_module.h"
+#include "../../core/strutils.h"
+#include "../../core/ut.h"
+#include "../../core/xavp.h"
+
+#include "../../modules/app_lua/modapi.h"
+
+#include "app_lua_sr_api.h"
+#include "app_lua_sr_exp.h"
+
+extern app_lua_api_t _app_lua_api;
+
+#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 504
+/**
+ *
+ */
+void ksr_luaL_openlib_mode(lua_State *L, const char *libname,
+                           const luaL_Reg *lfuncs, int nup, int mode) {
+  char modname[256];
+  char *submod = NULL;
+  int tidx = 0;
+  if (mode) {
+    /* support for registering 'module.submodule' functions
+     * - 'module' functions must be registered first  */
+    if (strlen(libname) > 254) {
+      LM_ERR("module name is too long [%s]\n", libname);
+      return;
+    }
+    strcpy(modname, libname);
+    submod = strchr(modname, '.');
+    if (submod != NULL) {
+      *submod = '\0';
+      submod++;
+    }
+    lua_getglobal(L, modname);
+    if (lua_isnil(L, -1)) {
+      if (submod != NULL) {
+        LM_ERR("main module not registered yet [%s]\n", libname);
+        return;
+      }
+      lua_pop(L, 1);
+      lua_newtable(L);
+      luaL_setfuncs(L, lfuncs, 0);
+      lua_setglobal(L, modname);
+      return;
+    }
+    tidx = lua_gettop(L);
+    lua_newtable(L);
+    luaL_setfuncs(L, lfuncs, 0);
+    lua_setfield(L, tidx, submod);
+    return;
+  }
+  lua_newtable(L);
+  luaL_setfuncs(L, lfuncs, 0);
+  lua_setglobal(L, libname);
+}
+
+/**
+ *
+ */
+void ksr_luaL_openlib(lua_State *L, const char *libname, const luaL_Reg *lfuncs,
+                      int nup) {
+  ksr_luaL_openlib_mode(L, libname, lfuncs, nup, 1);
+}
+#endif
+
+/**
+ *
+ */
+int app_lua_return_int(lua_State *L, int v) {
+  lua_pushinteger(L, v);
+  return 1;
+}
+
+/**
+ *
+ */
+int app_lua_return_error(lua_State *L) {
+  lua_pushinteger(L, -1);
+  return 1;
+}
+
+/**
+ *
+ */
+int app_lua_return_boolean(lua_State *L, int b) {
+  if (b == SRLUA_FALSE)
+    lua_pushboolean(L, SRLUA_FALSE);
+  else
+    lua_pushboolean(L, SRLUA_TRUE);
+  return 1;
+}
+
+/**
+ *
+ */
+int app_lua_return_false(lua_State *L) {
+  lua_pushboolean(L, SRLUA_FALSE);
+  return 1;
+}
+
+/**
+ *
+ */
+int app_lua_return_true(lua_State *L) {
+  lua_pushboolean(L, SRLUA_TRUE);
+  return 1;
+}
+
+/**
+ *
+ */
+static int lua_sr_probe(lua_State *L) {
+  LM_DBG("someone probing from lua\n");
+  return 0;
+}
+
+/**
+ *
+ */
+static int lua_sr_dbg(lua_State *L) {
+  char *txt;
+  txt = (char *)lua_tostring(L, -1);
+  if (txt != NULL)
+    LM_DBG("%s", txt);
+  return 0;
+}
+
+/**
+ *
+ */
+static int lua_sr_err(lua_State *L) {
+  char *txt;
+  txt = (char *)lua_tostring(L, -1);
+  if (txt != NULL)
+    LM_ERR("%s", txt);
+  return 0;
+}
+
+/**
+ *
+ */
+static int lua_sr_log(lua_State *L) {
+  char *txt;
+  char *level;
+  level = (char *)lua_tostring(L, -2);
+  txt = (char *)lua_tostring(L, -1);
+  if (txt != NULL) {
+    if (level == NULL) {
+      LM_ERR("%s", txt);
+    } else {
+      if (strcasecmp(level, "dbg") == 0) {
+        LM_DBG("%s", txt);
+      } else if (strcasecmp(level, "info") == 0) {
+        LM_INFO("%s", txt);
+      } else if (strcasecmp(level, "notice") == 0) {
+        LM_NOTICE("%s", txt);
+      } else if (strcasecmp(level, "warn") == 0) {
+        LM_WARN("%s", txt);
+      } else if (strcasecmp(level, "crit") == 0) {
+        LM_CRIT("%s", txt);
+      } else {
+        LM_ERR("%s", txt);
+      }
+    }
+  }
+  return 0;
+}
+
+/**
+ *
+ */
+static int lua_sr_modf(lua_State *L) {
+  int ret;
+  char *luav[MAX_ACTIONS];
+  char *argv[MAX_ACTIONS];
+  int argc;
+  int i;
+  int mod_type;
+  struct run_act_ctx ra_ctx;
+  struct action *act;
+  ksr_cmd_export_t *expf;
+  sr_lua_env_t *env_L;
+
+  ret = 1;
+  act = NULL;
+  argc = 0;
+  memset(luav, 0, MAX_ACTIONS * sizeof(char *));
+  memset(argv, 0, MAX_ACTIONS * sizeof(char *));
+  env_L = _app_lua_api.env_get_f();
+  if (env_L->msg == NULL)
+    goto error;
+
+#if 0
+	app_lua_dump_stack(L);
+#endif
+  argc = lua_gettop(L);
+  if (argc == 0) {
+    LM_ERR("name of module function not provided\n");
+    goto error;
+  }
+  if (argc >= MAX_ACTIONS) {
+    LM_ERR("too many parameters\n");
+    goto error;
+  }
+  /* first is function name, then parameters */
+  for (i = 1; i <= argc; i++) {
+    if (!lua_isstring(L, i)) {
+      LM_ERR("invalid parameter type (%d)\n", i);
+      goto error;
+    }
+    luav[i - 1] = (char *)lua_tostring(L, i);
+  }
+  /* pkg copy only parameters */
+  for (i = 1; i < MAX_ACTIONS; i++) {
+    if (luav[i] != NULL) {
+      argv[i] = (char *)pkg_malloc(strlen(luav[i]) + 1);
+      if (argv[i] == NULL) {
+        PKG_MEM_ERROR;
+        goto error;
+      }
+      strcpy(argv[i], luav[i]);
+    }
+  }
+
+  expf = find_export_record(luav[0], argc - 1, 0);
+  if (expf == NULL) {
+    LM_ERR("function '%s' is not available\n", luav[0]);
+    goto error;
+  }
+  /* check fixups */
+  if (expf->fixup != NULL && expf->free_fixup == NULL) {
+    LM_ERR("function '%s' has fixup - cannot be used\n", luav[0]);
+    goto error;
+  }
+  switch (expf->param_no) {
+  case 0:
+    mod_type = MODULE0_T;
+    break;
+  case 1:
+    mod_type = MODULE1_T;
+    break;
+  case 2:
+    mod_type = MODULE2_T;
+    break;
+  case 3:
+    mod_type = MODULE3_T;
+    break;
+  case 4:
+    mod_type = MODULE4_T;
+    break;
+  case 5:
+    mod_type = MODULE5_T;
+    break;
+  case 6:
+    mod_type = MODULE6_T;
+    break;
+  case VAR_PARAM_NO:
+    mod_type = MODULEX_T;
+    break;
+  default:
+    LM_ERR("unknown/bad definition for function '%s' (%d params)\n", luav[0],
+           expf->param_no);
+    goto error;
+  }
+
+  act = mk_action(mod_type, argc + 1 /* number of (type, value) pairs */,
+                  MODEXP_ST, expf,     /* function */
+                  NUMBER_ST, argc - 1, /* parameter number */
+                  STRING_ST, argv[1],  /* param. 1 */
+                  STRING_ST, argv[2],  /* param. 2 */
+                  STRING_ST, argv[3],  /* param. 3 */
+                  STRING_ST, argv[4],  /* param. 4 */
+                  STRING_ST, argv[5],  /* param. 5 */
+                  STRING_ST, argv[6]   /* param. 6 */
+  );
+
+  if (act == NULL) {
+    LM_ERR("action structure could not be created for '%s'\n", luav[0]);
+    goto error;
+  }
+
+  /* handle fixups */
+  if (expf->fixup) {
+    if (argc == 1) { /* no parameters */
+      if (expf->fixup(0, 0) < 0) {
+        LM_ERR("Error in fixup (0) for '%s'\n", luav[0]);
+        goto error;
+      }
+    } else {
+      for (i = 1; i < argc; i++) {
+        if (expf->fixup(&(act->val[i + 1].u.data), i) < 0) {
+          LM_ERR("Error in fixup (%d) for '%s'\n", i, luav[0]);
+          goto error;
+        }
+        act->val[i + 1].type = MODFIXUP_ST;
+      }
+    }
+  }
+  init_run_actions_ctx(&ra_ctx);
+  ret = do_action(&ra_ctx, act, env_L->msg);
+
+  /* free fixups */
+  if (expf->fixup) {
+    for (i = 1; i < argc; i++) {
+      if ((act->val[i + 1].type == MODFIXUP_ST) && (act->val[i + 1].u.data)) {
+        expf->free_fixup(&(act->val[i + 1].u.data), i);
+      }
+    }
+  }
+  pkg_free(act);
+  for (i = 0; i < MAX_ACTIONS; i++) {
+    if (argv[i] != NULL)
+      pkg_free(argv[i]);
+    argv[i] = 0;
+  }
+  lua_pushinteger(L, ret);
+  return 1;
+
+error:
+  if (act != NULL)
+    pkg_free(act);
+  for (i = 0; i < MAX_ACTIONS; i++) {
+    if (argv[i] != NULL)
+      pkg_free(argv[i]);
+    argv[i] = 0;
+  }
+  lua_pushinteger(L, -1);
+  return 1;
+}
+
+/**
+ *
+ */
+static int lua_sr_is_myself(lua_State *L) {
+  str uri;
+  struct sip_uri puri;
+  int ret;
+
+  uri.s = (char *)lua_tostring(L, -1);
+  if (uri.s == NULL) {
+    LM_ERR("invalid uri parameter\n");
+    return app_lua_return_false(L);
+  }
+  uri.len = strlen(uri.s);
+  if (uri.len > 4 &&
+      (strncmp(uri.s, "sip:", 4) == 0 || strncmp(uri.s, "sips:", 5) == 0)) {
+    if (parse_uri(uri.s, uri.len, &puri) != 0) {
+      LM_ERR("failed to parse uri [%s]\n", uri.s);
+      return app_lua_return_false(L);
+    }
+    ret = check_self(&puri.host, (puri.port.s) ? puri.port_no : 0,
+                     (puri.transport_val.s) ? puri.proto : 0);
+  } else {
+    ret = check_self(&uri, 0, 0);
+  }
+  if (ret == 1)
+    return app_lua_return_true(L);
+  return app_lua_return_false(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_setflag(lua_State *L) {
+  int flag;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+  flag = lua_tointeger(L, -1);
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_false(L);
+  }
+
+  if (!flag_in_range(flag)) {
+    LM_ERR("invalid flag parameter %d\n", flag);
+    return app_lua_return_false(L);
+  }
+
+  setflag(env_L->msg, flag);
+  return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_resetflag(lua_State *L) {
+  int flag;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+  flag = lua_tointeger(L, -1);
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_false(L);
+  }
+
+  if (!flag_in_range(flag)) {
+    LM_ERR("invalid flag parameter %d\n", flag);
+    return app_lua_return_false(L);
+  }
+
+  resetflag(env_L->msg, flag);
+  return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_isflagset(lua_State *L) {
+  int flag;
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+  flag = lua_tointeger(L, -1);
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_false(L);
+  }
+
+  if (!flag_in_range(flag)) {
+    LM_ERR("invalid flag parameter %d\n", flag);
+    return app_lua_return_false(L);
+  }
+
+  ret = isflagset(env_L->msg, flag);
+  if (ret > 0)
+    return app_lua_return_true(L);
+  return app_lua_return_false(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_setbflag(lua_State *L) {
+  int flag;
+  int branch;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+  if (lua_gettop(L) == 1) {
+    flag = lua_tointeger(L, -1);
+    branch = 0;
+  } else if (lua_gettop(L) == 2) {
+    flag = lua_tointeger(L, -2);
+    branch = lua_tointeger(L, -1);
+  } else {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_false(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_false(L);
+  }
+
+  if (!flag_in_range(flag)) {
+    LM_ERR("invalid flag parameter %d\n", flag);
+    return app_lua_return_false(L);
+  }
+
+  setbflag(branch, flag);
+  return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_resetbflag(lua_State *L) {
+  int flag;
+  int branch;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+  if (lua_gettop(L) == 1) {
+    flag = lua_tointeger(L, -1);
+    branch = 0;
+  } else if (lua_gettop(L) == 2) {
+    flag = lua_tointeger(L, -2);
+    branch = lua_tointeger(L, -1);
+  } else {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_false(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_false(L);
+  }
+
+  if (!flag_in_range(flag)) {
+    LM_ERR("invalid flag parameter %d\n", flag);
+    return app_lua_return_false(L);
+  }
+
+  resetbflag(branch, flag);
+  return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_isbflagset(lua_State *L) {
+  int flag;
+  int branch;
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+  if (lua_gettop(L) == 1) {
+    flag = lua_tointeger(L, -1);
+    branch = 0;
+  } else if (lua_gettop(L) == 2) {
+    flag = lua_tointeger(L, -2);
+    branch = lua_tointeger(L, -1);
+  } else {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_false(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_false(L);
+  }
+
+  if (!flag_in_range(flag)) {
+    LM_ERR("invalid flag parameter %d\n", flag);
+    return app_lua_return_false(L);
+  }
+
+  ret = isbflagset(branch, flag);
+  if (ret > 0)
+    return app_lua_return_true(L);
+  return app_lua_return_false(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_seturi(lua_State *L) {
+  struct action act;
+  struct run_act_ctx h;
+  str uri;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+  uri.s = (char *)lua_tostring(L, -1);
+  if (uri.s == NULL) {
+    LM_ERR("invalid uri parameter\n");
+    return app_lua_return_false(L);
+  }
+  uri.len = strlen(uri.s);
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_false(L);
+  }
+
+  memset(&act, 0, sizeof(act));
+  act.val[0].type = STRING_ST;
+  act.val[0].u.string = uri.s;
+  act.type = SET_URI_T;
+  init_run_actions_ctx(&h);
+  if (do_action(&h, &act, env_L->msg) < 0) {
+    LM_ERR("do action failed\n");
+    return app_lua_return_false(L);
+  }
+  return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_setuser(lua_State *L) {
+  struct action act;
+  struct run_act_ctx h;
+  str uri;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+  uri.s = (char *)lua_tostring(L, -1);
+  if (uri.s == NULL) {
+    LM_ERR("invalid uri parameter\n");
+    return app_lua_return_false(L);
+  }
+  uri.len = strlen(uri.s);
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_false(L);
+  }
+
+  memset(&act, 0, sizeof(act));
+  act.val[0].type = STRING_ST;
+  act.val[0].u.string = uri.s;
+  act.type = SET_USER_T;
+  init_run_actions_ctx(&h);
+  if (do_action(&h, &act, env_L->msg) < 0) {
+    LM_ERR("do action failed\n");
+    return app_lua_return_false(L);
+  }
+  return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_sethost(lua_State *L) {
+  struct action act;
+  struct run_act_ctx h;
+  str uri;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+  uri.s = (char *)lua_tostring(L, -1);
+  if (uri.s == NULL) {
+    LM_ERR("invalid uri parameter\n");
+    return app_lua_return_false(L);
+  }
+  uri.len = strlen(uri.s);
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_false(L);
+  }
+
+  memset(&act, 0, sizeof(act));
+  act.val[0].type = STRING_ST;
+  act.val[0].u.string = uri.s;
+  act.type = SET_HOST_T;
+  init_run_actions_ctx(&h);
+  if (do_action(&h, &act, env_L->msg) < 0) {
+    LM_ERR("do action failed\n");
+    return app_lua_return_false(L);
+  }
+  return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_setdsturi(lua_State *L) {
+  str uri;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+  uri.s = (char *)lua_tostring(L, -1);
+  if (uri.s == NULL) {
+    LM_ERR("invalid uri parameter\n");
+    return app_lua_return_false(L);
+  }
+  uri.len = strlen(uri.s);
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_false(L);
+  }
+
+  if (set_dst_uri(env_L->msg, &uri) < 0) {
+    LM_ERR("setting dst uri failed\n");
+    return app_lua_return_false(L);
+  }
+  return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_resetdsturi(lua_State *L) {
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_false(L);
+  }
+
+  reset_dst_uri(env_L->msg);
+  return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_core_Map[] = {{"probe", lua_sr_probe},
+                                        {"dbg", lua_sr_dbg},
+                                        {"err", lua_sr_err},
+                                        {"log", lua_sr_log},
+                                        {"modf", lua_sr_modf},
+                                        {"is_myself", lua_sr_is_myself},
+                                        {"setflag", lua_sr_setflag},
+                                        {"resetflag", lua_sr_resetflag},
+                                        {"isflagset", lua_sr_isflagset},
+                                        {"setbflag", lua_sr_setbflag},
+                                        {"resetbflag", lua_sr_resetbflag},
+                                        {"isbflagset", lua_sr_isbflagset},
+                                        {"seturi", lua_sr_seturi},
+                                        {"setuser", lua_sr_setuser},
+                                        {"sethost", lua_sr_sethost},
+                                        {"setdsturi", lua_sr_setdsturi},
+                                        {"resetdsturi", lua_sr_resetdsturi},
+                                        {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_hdr_append(lua_State *L) {
+  struct lump *anchor;
+  struct hdr_field *hf;
+  char *txt;
+  int len;
+  char *hdr;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  txt = (char *)lua_tostring(L, -1);
+  if (txt == NULL || env_L->msg == NULL)
+    return 0;
+
+  LM_DBG("append hf: %s\n", txt);
+  if (parse_headers(env_L->msg, HDR_EOH_F, 0) == -1) {
+    LM_ERR("error while parsing message\n");
+    return 0;
+  }
+
+  hf = env_L->msg->last_header;
+  len = strlen(txt);
+  hdr = (char *)pkg_malloc(len + 1);
+  if (hdr == NULL) {
+    PKG_MEM_ERROR;
+    return 0;
+  }
+  memcpy(hdr, txt, len);
+  anchor =
+      anchor_lump(env_L->msg, hf->name.s + hf->len - env_L->msg->buf, 0, 0);
+  if (anchor == NULL) {
+    LM_ERR("unable to get the anchor\n");
+    pkg_free(hdr);
+    return 0;
+  }
+  if (insert_new_lump_before(anchor, hdr, len, 0) == 0) {
+    LM_ERR("can't insert lump\n");
+    pkg_free(hdr);
+    return 0;
+  }
+  return 0;
+}
+
+/**
+ *
+ */
+static int lua_sr_hdr_remove(lua_State *L) {
+  struct lump *anchor;
+  struct hdr_field *hf;
+  char *txt;
+  str hname;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  txt = (char *)lua_tostring(L, -1);
+  if (txt == NULL || env_L->msg == NULL)
+    return 0;
+
+  LM_DBG("remove hf: %s\n", txt);
+  if (parse_headers(env_L->msg, HDR_EOH_F, 0) == -1) {
+    LM_ERR("error while parsing message\n");
+    return 0;
+  }
+
+  hname.s = txt;
+  hname.len = strlen(txt);
+  for (hf = env_L->msg->headers; hf; hf = hf->next) {
+    if (cmp_hdrname_str(&hf->name, &hname) == 0) {
+      anchor = del_lump(env_L->msg, hf->name.s - env_L->msg->buf, hf->len, 0);
+      if (anchor == 0) {
+        LM_ERR("cannot remove hdr %s\n", txt);
+        return 0;
+      }
+    }
+  }
+  return 0;
+}
+
+/**
+ *
+ */
+static int lua_sr_hdr_insert(lua_State *L) {
+  struct lump *anchor;
+  struct hdr_field *hf;
+  char *txt;
+  int len;
+  char *hdr;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  txt = (char *)lua_tostring(L, -1);
+  if (txt == NULL || env_L->msg == NULL)
+    return 0;
+
+  LM_DBG("insert hf: %s\n", txt);
+  hf = env_L->msg->headers;
+  len = strlen(txt);
+  hdr = (char *)pkg_malloc(len + 1);
+  if (hdr == NULL) {
+    PKG_MEM_ERROR;
+    return 0;
+  }
+  memcpy(hdr, txt, len);
+  anchor =
+      anchor_lump(env_L->msg, hf->name.s + hf->len - env_L->msg->buf, 0, 0);
+  if ((anchor == NULL) || (insert_new_lump_before(anchor, hdr, len, 0) == 0)) {
+    LM_ERR("can't insert lump\n");
+    pkg_free(hdr);
+    return 0;
+  }
+  return 0;
+}
+
+/**
+ *
+ */
+static int lua_sr_hdr_append_to_reply(lua_State *L) {
+  char *txt;
+  int len;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  txt = (char *)lua_tostring(L, -1);
+  if (txt == NULL || env_L->msg == NULL)
+    return 0;
+
+  LM_DBG("append to reply: %s\n", txt);
+  len = strlen(txt);
+
+  if (add_lump_rpl(env_L->msg, txt, len, LUMP_RPL_HDR) == 0) {
+    LM_ERR("unable to add reply lump\n");
+    return 0;
+  }
+
+  return 0;
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_hdr_Map[] = {
+    {"append", lua_sr_hdr_append},
+    {"remove", lua_sr_hdr_remove},
+    {"insert", lua_sr_hdr_insert},
+    {"append_to_reply", lua_sr_hdr_append_to_reply},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_pv_push_val_null(lua_State *L, int rmode) {
+  if (rmode == 1) {
+    lua_pushlstring(L, "<<null>>", 8);
+  } else if (rmode == 2) {
+    lua_pushlstring(L, "", 0);
+  } else {
+    lua_pushnil(L);
+  }
+  return 1;
+}
+
+/**
+ *
+ */
+static int lua_sr_pv_push_valx(lua_State *L, int rmode, int vi, str *vs) {
+  if (rmode == 1) {
+    lua_pushinteger(L, vi);
+  } else {
+    lua_pushlstring(L, vs->s, vs->len);
+  }
+  return 1;
+}
+
+/**
+ *
+ */
+static int lua_sr_pv_get_val(lua_State *L, int rmode) {
+  str pvn;
+  pv_spec_t *pvs;
+  pv_value_t val;
+  sr_lua_env_t *env_L;
+  int pl;
+
+  env_L = _app_lua_api.env_get_f();
+
+  pvn.s = (char *)lua_tostring(L, -1);
+  if (pvn.s == NULL || env_L->msg == NULL) {
+    return lua_sr_pv_push_val_null(L, rmode);
+  }
+
+  pvn.len = strlen(pvn.s);
+  LM_DBG("pv get: %s\n", pvn.s);
+  pl = pv_locate_name(&pvn);
+  if (pl != pvn.len) {
+    LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len);
+    return lua_sr_pv_push_val_null(L, rmode);
+  }
+  pvs = pv_cache_get(&pvn);
+  if (pvs == NULL) {
+    LM_ERR("cannot get pv spec for [%s]\n", pvn.s);
+    return lua_sr_pv_push_val_null(L, rmode);
+  }
+  memset(&val, 0, sizeof(pv_value_t));
+  if (pv_get_spec_value(env_L->msg, pvs, &val) != 0) {
+    LM_ERR("unable to get pv value for [%s]\n", pvn.s);
+    return lua_sr_pv_push_val_null(L, rmode);
+  }
+  if (val.flags & PV_VAL_NULL) {
+    return lua_sr_pv_push_val_null(L, rmode);
+  }
+  if (val.flags & PV_TYPE_INT) {
+    lua_pushinteger(L, val.ri);
+    return 1;
+  }
+  lua_pushlstring(L, val.rs.s, val.rs.len);
+  return 1;
+}
+
+/**
+ *
+ */
+static int lua_sr_pv_get(lua_State *L) { return lua_sr_pv_get_val(L, 0); }
+
+/**
+ *
+ */
+static int lua_sr_pv_getw(lua_State *L) { return lua_sr_pv_get_val(L, 1); }
+
+/**
+ *
+ */
+static int lua_sr_pv_gete(lua_State *L) { return lua_sr_pv_get_val(L, 2); }
+
+/**
+ *
+ */
+static int lua_sr_pv_get_valx(lua_State *L, int rmode) {
+  str pvn;
+  pv_spec_t *pvs;
+  pv_value_t val;
+  sr_lua_env_t *env_L;
+  int pl;
+  int xival = 0;
+  str xsval = str_init("");
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (lua_gettop(L) < 2) {
+    LM_ERR("to few parameters [%d]\n", lua_gettop(L));
+    return lua_sr_pv_push_val_null(L, 0);
+  }
+  if (rmode == 1) {
+    if (!lua_isnumber(L, -1)) {
+      LM_ERR("invalid int parameter\n");
+      return lua_sr_pv_push_val_null(L, 0);
+    }
+    xival = lua_tointeger(L, -1);
+  } else {
+    if (!lua_isstring(L, -1)) {
+      LM_ERR("invalid str parameter\n");
+      return lua_sr_pv_push_val_null(L, 0);
+    }
+    xsval.s = (char *)lua_tostring(L, -1);
+    xsval.len = strlen(xsval.s);
+  }
+
+  pvn.s = (char *)lua_tostring(L, -2);
+  if (pvn.s == NULL || env_L->msg == NULL)
+    return lua_sr_pv_push_valx(L, rmode, xival, &xsval);
+
+  pvn.len = strlen(pvn.s);
+  LM_DBG("pv set: %s\n", pvn.s);
+  pl = pv_locate_name(&pvn);
+  if (pl != pvn.len) {
+    LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len);
+    return lua_sr_pv_push_valx(L, rmode, xival, &xsval);
+  }
+  pvs = pv_cache_get(&pvn);
+  if (pvs == NULL) {
+    LM_ERR("cannot get pv spec for [%s]\n", pvn.s);
+    return lua_sr_pv_push_valx(L, rmode, xival, &xsval);
+  }
+
+  memset(&val, 0, sizeof(pv_value_t));
+  if (pv_get_spec_value(env_L->msg, pvs, &val) != 0) {
+    LM_ERR("unable to get pv value for [%s]\n", pvn.s);
+    return lua_sr_pv_push_valx(L, rmode, xival, &xsval);
+  }
+  if (val.flags & PV_VAL_NULL) {
+    return lua_sr_pv_push_valx(L, rmode, xival, &xsval);
+  }
+  if (val.flags & PV_TYPE_INT) {
+    lua_pushinteger(L, val.ri);
+    return 1;
+  }
+  lua_pushlstring(L, val.rs.s, val.rs.len);
+  return 1;
+}
+
+/**
+ *
+ */
+static int lua_sr_pv_getvs(lua_State *L) { return lua_sr_pv_get_valx(L, 0); }
+
+/**
+ *
+ */
+static int lua_sr_pv_getvn(lua_State *L) { return lua_sr_pv_get_valx(L, 1); }
+
+/**
+ *
+ */
+static int lua_sr_pv_seti(lua_State *L) {
+  str pvn;
+  pv_spec_t *pvs;
+  pv_value_t val;
+  sr_lua_env_t *env_L;
+  int pl;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (lua_gettop(L) < 2) {
+    LM_ERR("to few parameters [%d]\n", lua_gettop(L));
+    return 0;
+  }
+  if (!lua_isnumber(L, -1)) {
+    LM_ERR("invalid int parameter\n");
+    return 0;
+  }
+  memset(&val, 0, sizeof(pv_value_t));
+  val.ri = lua_tointeger(L, -1);
+  val.flags |= PV_TYPE_INT | PV_VAL_INT;
+
+  pvn.s = (char *)lua_tostring(L, -2);
+  if (pvn.s == NULL || env_L->msg == NULL)
+    return 0;
+
+  pvn.len = strlen(pvn.s);
+  LM_DBG("pv set: %s\n", pvn.s);
+  pl = pv_locate_name(&pvn);
+  if (pl != pvn.len) {
+    LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len);
+    return 0;
+  }
+  pvs = pv_cache_get(&pvn);
+  if (pvs == NULL) {
+    LM_ERR("cannot get pv spec for [%s]\n", pvn.s);
+    return 0;
+  }
+  if (pv_set_spec_value(env_L->msg, pvs, 0, &val) < 0) {
+    LM_ERR("unable to set pv [%s]\n", pvn.s);
+    return 0;
+  }
+
+  return 0;
+}
+
+/**
+ *
+ */
+static int lua_sr_pv_sets(lua_State *L) {
+  str pvn;
+  pv_spec_t *pvs;
+  pv_value_t val;
+  sr_lua_env_t *env_L;
+  int pl;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (lua_gettop(L) < 2) {
+    LM_ERR("to few parameters [%d]\n", lua_gettop(L));
+    return 0;
+  }
+
+  if (!lua_isstring(L, -1)) {
+    LM_ERR("Cannot convert to a string when assigning value to variable: "
+           "%s\n",
+           lua_tostring(L, -2));
+    return 0;
+  }
+
+  memset(&val, 0, sizeof(pv_value_t));
+  val.rs.s = (char *)lua_tostring(L, -1);
+  val.rs.len = strlen(val.rs.s);
+  val.flags |= PV_VAL_STR;
+
+  pvn.s = (char *)lua_tostring(L, -2);
+  if (pvn.s == NULL || env_L->msg == NULL)
+    return 0;
+
+  pvn.len = strlen(pvn.s);
+  LM_DBG("pv set: %s\n", pvn.s);
+  pl = pv_locate_name(&pvn);
+  if (pl != pvn.len) {
+    LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len);
+    return 0;
+  }
+  pvs = pv_cache_get(&pvn);
+  if (pvs == NULL) {
+    LM_ERR("cannot get pv spec for [%s]\n", pvn.s);
+    return 0;
+  }
+  if (pv_set_spec_value(env_L->msg, pvs, 0, &val) < 0) {
+    LM_ERR("unable to set pv [%s]\n", pvn.s);
+    return 0;
+  }
+
+  return 0;
+}
+
+/**
+ *
+ */
+static int lua_sr_pv_unset(lua_State *L) {
+  str pvn;
+  pv_spec_t *pvs;
+  pv_value_t val;
+  sr_lua_env_t *env_L;
+  int pl;
+
+  env_L = _app_lua_api.env_get_f();
+
+  pvn.s = (char *)lua_tostring(L, -1);
+  if (pvn.s == NULL || env_L->msg == NULL)
+    return 0;
+
+  pvn.len = strlen(pvn.s);
+  LM_DBG("pv unset: %s\n", pvn.s);
+  pl = pv_locate_name(&pvn);
+  if (pl != pvn.len) {
+    LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len);
+    return 0;
+  }
+  pvs = pv_cache_get(&pvn);
+  if (pvs == NULL) {
+    LM_ERR("cannot get pv spec for [%s]\n", pvn.s);
+    return 0;
+  }
+  memset(&val, 0, sizeof(pv_value_t));
+  val.flags |= PV_VAL_NULL;
+  if (pv_set_spec_value(env_L->msg, pvs, 0, &val) < 0) {
+    LM_ERR("unable to unset pv [%s]\n", pvn.s);
+    return 0;
+  }
+
+  return 0;
+}
+
+/**
+ *
+ */
+static int lua_sr_pv_is_null(lua_State *L) {
+  str pvn;
+  pv_spec_t *pvs;
+  pv_value_t val;
+  sr_lua_env_t *env_L;
+  int pl;
+
+  env_L = _app_lua_api.env_get_f();
+
+  pvn.s = (char *)lua_tostring(L, -1);
+  if (pvn.s == NULL || env_L->msg == NULL)
+    return 0;
+
+  pvn.len = strlen(pvn.s);
+  LM_DBG("pv is null test: %s\n", pvn.s);
+  pl = pv_locate_name(&pvn);
+  if (pl != pvn.len) {
+    LM_ERR("invalid pv [%s] (%d/%d)\n", pvn.s, pl, pvn.len);
+    return 0;
+  }
+  pvs = pv_cache_get(&pvn);
+  if (pvs == NULL) {
+    LM_ERR("cannot get pv spec for [%s]\n", pvn.s);
+    return 0;
+  }
+  memset(&val, 0, sizeof(pv_value_t));
+  if (pv_get_spec_value(env_L->msg, pvs, &val) != 0) {
+    LM_NOTICE("unable to get pv value for [%s]\n", pvn.s);
+    lua_pushboolean(L, 1);
+    return 1;
+  }
+  if (val.flags & PV_VAL_NULL) {
+    lua_pushboolean(L, 1);
+  } else {
+    lua_pushboolean(L, 0);
+  }
+  return 1;
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_pv_Map[] = {
+    {"get", lua_sr_pv_get},         {"getw", lua_sr_pv_getw},
+    {"gete", lua_sr_pv_gete},       {"getvn", lua_sr_pv_getvn},
+    {"getvs", lua_sr_pv_getvs},     {"seti", lua_sr_pv_seti},
+    {"sets", lua_sr_pv_sets},       {"unset", lua_sr_pv_unset},
+    {"is_null", lua_sr_pv_is_null}, {NULL, NULL}};
+
+/**
+ * creates and push a table to the lua stack with
+ * the elements of the list
+ */
+static int lua_sr_push_str_list_table(lua_State *L, struct str_list *list) {
+  lua_Number i = 1;
+  struct str_list *k = list;
+
+  lua_newtable(L);
+  while (k != NULL) {
+    lua_pushnumber(L, i);
+    lua_pushlstring(L, k->s.s, k->s.len);
+    lua_settable(L, -3);
+    i++;
+    k = k->next;
+  }
+  return 1;
+}
+
+static int lua_sr_push_xavp_table(lua_State *L, sr_xavp_t *xavp,
+                                  const int simple_flag);
+
+/**
+ * creates and push a table for the key name in xavp
+ * if simple_flag is != 0 it will return only the first value
+ */
+static void lua_sr_push_xavp_name_table(lua_State *L, sr_xavp_t *xavp, str name,
+                                        const int simple_flag) {
+  lua_Number i = 1;
+  lua_Number elem = 1;
+  sr_xavp_t *avp = xavp;
+
+  while (avp != NULL && !STR_EQ(avp->name, name)) {
+    avp = avp->next;
+  }
+
+  if (simple_flag == 0)
+    lua_newtable(L);
+
+  while (avp != NULL) {
+    if (simple_flag == 0)
+      lua_pushnumber(L, elem);
+    switch (avp->val.type) {
+    case SR_XTYPE_NULL:
+      lua_pushnil(L);
+      break;
+    case SR_XTYPE_LONG:
+      i = avp->val.v.l;
+      lua_pushnumber(L, i);
+      break;
+    case SR_XTYPE_STR:
+      lua_pushlstring(L, avp->val.v.s.s, avp->val.v.s.len);
+      break;
+    case SR_XTYPE_TIME:
+    case SR_XTYPE_LLONG:
+    case SR_XTYPE_DATA:
+      lua_pushnil(L);
+      LM_WARN("XAVP type:%d value not supported\n", avp->val.type);
+      break;
+    case SR_XTYPE_XAVP:
+      if (!lua_sr_push_xavp_table(L, avp->val.v.xavp, simple_flag)) {
+        LM_ERR("xavp:%.*s subtable error. Nil value added\n", avp->name.len,
+               avp->name.s);
+        lua_pushnil(L);
+      }
+      break;
+    default:
+      LM_ERR("xavp:%.*s unknown type: %d. Nil value added\n", avp->name.len,
+             avp->name.s, avp->val.type);
+      lua_pushnil(L);
+      break;
+    }
+    if (simple_flag == 0) {
+      lua_rawset(L, -3);
+      elem = elem + 1;
+      avp = xavp_get_next(avp);
+    } else {
+      lua_setfield(L, -2, name.s);
+      avp = NULL;
+    }
+  }
+  if (simple_flag == 0)
+    lua_setfield(L, -2, name.s);
+}
+
+/**
+ * creates and push a table to the lua stack with
+ * the elements of the xavp
+ */
+static int lua_sr_push_xavp_table(lua_State *L, sr_xavp_t *xavp,
+                                  const int simple_flag) {
+  sr_xavp_t *avp = NULL;
+  struct str_list *keys;
+  struct str_list *k;
+
+  if (xavp->val.type != SR_XTYPE_XAVP) {
+    LM_ERR("%s not xavp?\n", xavp->name.s);
+    return 0;
+  }
+  avp = xavp->val.v.xavp;
+  keys = xavp_get_list_key_names(xavp);
+
+  lua_newtable(L);
+  if (keys != NULL) {
+    do {
+      lua_sr_push_xavp_name_table(L, avp, keys->s, simple_flag);
+      k = keys;
+      keys = keys->next;
+      pkg_free(k);
+    } while (keys != NULL);
+  }
+
+  return 1;
+}
+
+/**
+ * puts a table with content of a xavp
+ */
+static int lua_sr_xavp_get(lua_State *L) {
+  str xavp_name;
+  int indx = 0;
+  sr_lua_env_t *env_L;
+  sr_xavp_t *avp;
+  int num_param = 0;
+  int param = -1;
+  int all_flag = 0;
+  int simple_flag = 0;
+  lua_Number elem = 1;
+  int xavp_size = 0;
+
+  env_L = _app_lua_api.env_get_f();
+  num_param = lua_gettop(L);
+  if (num_param < 2 || num_param > 3) {
+    LM_ERR("wrong number of parameters [%d]\n", num_param);
+    return 0;
+  }
+
+  if (num_param == 3) {
+    if (!lua_isnumber(L, param)) {
+      LM_ERR("invalid int parameter\n");
+      return 0;
+    }
+    simple_flag = lua_tointeger(L, param);
+    param = param - 1;
+  }
+
+  if (!lua_isnumber(L, param)) {
+    if (lua_isnil(L, param)) {
+      all_flag = 1;
+    } else {
+      LM_ERR("invalid parameter, must be int or nil\n");
+      return 0;
+    }
+  } else {
+    indx = lua_tointeger(L, param);
+  }
+  param = param - 1;
+  xavp_name.s = (char *)lua_tostring(L, param);
+  if (xavp_name.s == NULL || env_L->msg == NULL) {
+    LM_ERR("No xavp name in %d param\n", param);
+    return 0;
+  }
+  xavp_name.len = strlen(xavp_name.s);
+  if (all_flag > 0) {
+    indx = 0;
+    lua_newtable(L);
+  }
+  xavp_size = xavp_count(&xavp_name, NULL);
+  if (indx < 0) {
+    if ((indx * -1) > xavp_size) {
+      LM_ERR("can't get xavp:%.*s index:%d\n", xavp_name.len, xavp_name.s,
+             indx);
+      lua_pushnil(L);
+      return 1;
+    }
+    indx = xavp_size + indx;
+  }
+
+  avp = xavp_get_by_index(&xavp_name, indx, NULL);
+  do {
+    if (avp == NULL) {
+      LM_ERR("can't get xavp:%.*s index:%d\n", xavp_name.len, xavp_name.s,
+             indx);
+      lua_pushnil(L);
+      return 1;
+    }
+    if (all_flag != 0) {
+      lua_pushnumber(L, elem);
+      elem = elem + 1;
+    }
+    lua_sr_push_xavp_table(L, avp, simple_flag);
+    if (all_flag != 0) {
+      lua_rawset(L, -3);
+      indx = indx + 1;
+      avp = xavp_get_by_index(&xavp_name, indx, NULL);
+    } else
+      return 1;
+  } while (avp != NULL);
+
+  return 1;
+}
+
+/**
+ * puts a table with the list of keys of the xavp
+ */
+static int lua_sr_xavp_get_keys(lua_State *L) {
+  str xavp_name;
+  int indx = 0;
+  sr_lua_env_t *env_L;
+  sr_xavp_t *avp;
+  struct str_list *keys, *k;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (lua_gettop(L) < 2) {
+    LM_ERR("to few parameters [%d]\n", lua_gettop(L));
+    return 0;
+  }
+
+  if (!lua_isnumber(L, -1)) {
+    LM_ERR("invalid int parameter\n");
+    return 0;
+  }
+  indx = lua_tointeger(L, -1);
+
+  xavp_name.s = (char *)lua_tostring(L, -2);
+  if (xavp_name.s == NULL || env_L->msg == NULL)
+    return 0;
+  xavp_name.len = strlen(xavp_name.s);
+
+  avp = xavp_get_by_index(&xavp_name, indx, NULL);
+  if (avp == NULL) {
+    LM_ERR("can't get xavp:%.*s index:%d\n", xavp_name.len, xavp_name.s, indx);
+    lua_pushnil(L);
+    return 1;
+  }
+  keys = xavp_get_list_key_names(avp);
+  lua_sr_push_str_list_table(L, keys);
+  // free list
+  while (keys != NULL) {
+    k = keys;
+    keys = k->next;
+    pkg_free(k);
+  }
+  return 1;
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_xavp_Map[] = {
+    {"get", lua_sr_xavp_get}, {"get_keys", lua_sr_xavp_get_keys}, {NULL, NULL}};
+
+/**
+ *
+ */
+void lua_sr_core_openlibs(lua_State *L) {
+  LM_DBG("exporting sr core extensions\n");
+
+  luaL_openlib(L, "sr", _sr_core_Map, 0);
+  luaL_openlib(L, "sr.hdr", _sr_hdr_Map, 0);
+  luaL_openlib(L, "sr.pv", _sr_pv_Map, 0);
+  luaL_openlib(L, "sr.xavp", _sr_xavp_Map, 0);
+}

+ 44 - 0
src/modules/app_lua_sr/app_lua_sr_api.h

@@ -0,0 +1,44 @@
+/**
+ * Copyright (C) 2010-2016 Daniel-Constantin Mierla (asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#ifndef _APP_LUA_SR_H_
+#define _APP_LUA_SR_H_
+
+#include <lua.h>
+
+int app_lua_return_int(lua_State *L, int v);
+int app_lua_return_error(lua_State *L);
+int app_lua_return_boolean(lua_State *L, int b);
+int app_lua_return_false(lua_State *L);
+int app_lua_return_true(lua_State *L);
+
+void lua_sr_core_openlibs(lua_State *L);
+void lua_sr_kemi_register_libs(lua_State *L);
+
+int sr_kemi_lua_exec_func(lua_State *L, int eidx);
+
+#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 504
+void ksr_luaL_openlib(lua_State *L, const char *libname, const luaL_Reg *lfuncs,
+                      int nup);
+#define luaL_openlib ksr_luaL_openlib
+#endif
+
+#endif

+ 3331 - 0
src/modules/app_lua_sr/app_lua_sr_exp.c

@@ -0,0 +1,3331 @@
+/**
+ * Copyright (C) 2010-2016 Daniel-Constantin Mierla (asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "../../core/dprint.h"
+#include "../../core/route.h"
+#include "../../core/sr_module.h"
+#include "../../core/ut.h"
+
+#include "../../modules/alias_db/api.h"
+#include "../../modules/auth/api.h"
+#include "../../modules/auth_db/api.h"
+#include "../../modules/cfgutils/api.h"
+#include "../../modules/dispatcher/api.h"
+#include "../../modules/maxfwd/api.h"
+#include "../../modules/mqueue/api.h"
+#include "../../modules/msilo/api.h"
+#include "../../modules/ndb_mongodb/api.h"
+#include "../../modules/presence/bind_presence.h"
+#include "../../modules/presence_xml/api.h"
+#include "../../modules/pua_usrloc/api.h"
+#include "../../modules/registrar/api.h"
+#include "../../modules/rls/api.h"
+#include "../../modules/rr/api.h"
+#include "../../modules/sanity/api.h"
+#include "../../modules/sdpops/api.h"
+#include "../../modules/siputils/siputils.h"
+#include "../../modules/sl/sl.h"
+#include "../../modules/sqlops/sql_api.h"
+#include "../../modules/textops/api.h"
+#include "../../modules/tm/tm_load.h"
+#include "../../modules/tmx/api.h"
+#include "../../modules/uac/api.h"
+#include "../../modules/xhttp/api.h"
+
+#include "../../modules/app_lua/modapi.h"
+
+#include "app_lua_sr_api.h"
+
+#define SR_LUA_EXP_MOD_SL (1 << 0)
+#define SR_LUA_EXP_MOD_TM (1 << 1)
+#define SR_LUA_EXP_MOD_SQLOPS (1 << 2)
+#define SR_LUA_EXP_MOD_RR (1 << 3)
+#define SR_LUA_EXP_MOD_AUTH (1 << 4)
+#define SR_LUA_EXP_MOD_AUTH_DB (1 << 5)
+#define SR_LUA_EXP_MOD_MAXFWD (1 << 6)
+#define SR_LUA_EXP_MOD_REGISTRAR (1 << 7)
+#define SR_LUA_EXP_MOD_DISPATCHER (1 << 8)
+#define SR_LUA_EXP_MOD_XHTTP (1 << 9)
+#define SR_LUA_EXP_MOD_SDPOPS (1 << 10)
+#define SR_LUA_EXP_MOD_PRESENCE (1 << 11)
+#define SR_LUA_EXP_MOD_PRESENCE_XML (1 << 12)
+#define SR_LUA_EXP_MOD_TEXTOPS (1 << 13)
+#define SR_LUA_EXP_MOD_PUA_USRLOC (1 << 14)
+#define SR_LUA_EXP_MOD_SIPUTILS (1 << 15)
+#define SR_LUA_EXP_MOD_RLS (1 << 16)
+#define SR_LUA_EXP_MOD_ALIAS_DB (1 << 17)
+#define SR_LUA_EXP_MOD_MSILO (1 << 18)
+#define SR_LUA_EXP_MOD_UAC (1 << 19)
+#define SR_LUA_EXP_MOD_SANITY (1 << 20)
+#define SR_LUA_EXP_MOD_CFGUTILS (1 << 21)
+#define SR_LUA_EXP_MOD_TMX (1 << 22)
+#define SR_LUA_EXP_MOD_MQUEUE (1 << 23)
+#define SR_LUA_EXP_MOD_NDB_MONGODB (1 << 24)
+
+extern app_lua_api_t _app_lua_api;
+
+/**
+ *
+ */
+static unsigned int _sr_lua_exp_reg_mods = 0;
+
+/**
+ * auth
+ */
+static auth_api_s_t _lua_authb;
+
+/**
+ * auth_db
+ */
+static auth_db_api_t _lua_auth_dbb;
+
+/**
+ * dispatcher
+ */
+static dispatcher_api_t _lua_dispatcherb;
+
+/**
+ * maxfwd
+ */
+static maxfwd_api_t _lua_maxfwdb;
+
+/**
+ * registrar
+ */
+static registrar_api_t _lua_registrarb;
+
+/**
+ * rr
+ */
+static rr_api_t _lua_rrb;
+
+/**
+ * sqlops
+ */
+static sqlops_api_t _lua_sqlopsb;
+
+/**
+ * sl
+ */
+static sl_api_t _lua_slb;
+
+/**
+ * tm
+ */
+static tm_api_t _lua_tmb;
+static tm_xapi_t _lua_xtmb;
+
+/**
+ * xhttp
+ */
+static xhttp_api_t _lua_xhttpb;
+
+/**
+ * sdpops
+ */
+static sdpops_api_t _lua_sdpopsb;
+
+/**
+ * presence
+ */
+static presence_api_t _lua_presenceb;
+
+/**
+ * presence_xml
+ */
+static presence_xml_api_t _lua_presence_xmlb;
+
+/**
+ * textops
+ */
+static textops_api_t _lua_textopsb;
+
+/**
+ * pua_usrloc
+ */
+static pua_usrloc_api_t _lua_pua_usrlocb;
+
+/**
+ * siputils
+ */
+static siputils_api_t _lua_siputilsb;
+
+/**
+ * rls
+ */
+static rls_api_t _lua_rlsb;
+
+/**
+ * alias_db
+ */
+static alias_db_api_t _lua_alias_dbb;
+
+/**
+ * msilo
+ */
+static msilo_api_t _lua_msilob;
+
+/**
+ * uac
+ */
+static uac_api_t _lua_uacb;
+
+/**
+ * sanity
+ */
+static sanity_api_t _lua_sanityb;
+
+/**
+ * cfgutils
+ */
+static cfgutils_api_t _lua_cfgutilsb;
+
+/**
+ * tmx
+ */
+static tmx_api_t _lua_tmxb;
+
+/**
+ * mqueue
+ */
+static mq_api_t _lua_mqb;
+
+/**
+ * mqueue
+ */
+static ndb_mongodb_api_t _lua_ndb_mongodbb;
+
+/**
+ *
+ */
+static int lua_sr_sl_send_reply(lua_State *L) {
+  str txt;
+  int code;
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SL)) {
+    LM_WARN("weird: sl function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  code = lua_tointeger(L, -2);
+
+  if (code < 100 || code >= 800)
+    return app_lua_return_error(L);
+
+  txt.s = (char *)lua_tostring(L, -1);
+  if (txt.s == NULL || env_L->msg == NULL)
+    return app_lua_return_error(L);
+
+  txt.len = strlen(txt.s);
+  ret = _lua_slb.freply(env_L->msg, code, &txt);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sl_get_reply_totag(lua_State *L) {
+  str txt;
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SL)) {
+    LM_WARN("weird: sl function executed but module not registered\n");
+    return app_lua_return_false(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  ret = _lua_slb.get_reply_totag(env_L->msg, &txt);
+  if (ret < 0) {
+    LM_WARN("sl get_reply_totag returned false\n");
+    return app_lua_return_false(L);
+  }
+  lua_pushlstring(L, txt.s, txt.len);
+  return 1;
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_sl_Map[] = {
+    {"send_reply", lua_sr_sl_send_reply},
+    {"get_reply_totag", lua_sr_sl_get_reply_totag},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_tm_t_reply(lua_State *L) {
+  char *txt;
+  int code;
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)) {
+    LM_WARN("weird: tm function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  code = lua_tointeger(L, -2);
+
+  if (code < 100 || code >= 800)
+    return app_lua_return_error(L);
+
+  txt = (char *)lua_tostring(L, -1);
+  if (txt != NULL && env_L->msg != NULL) {
+    ret = _lua_tmb.t_reply(env_L->msg, code, txt);
+    return app_lua_return_int(L, ret);
+  }
+  return app_lua_return_error(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_relay(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)) {
+    LM_WARN("weird: tm function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  ret = _lua_tmb.t_relay(env_L->msg, NULL, NULL);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_on_failure(lua_State *L) {
+  char *name;
+  int i;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)) {
+    LM_WARN("weird: tm function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  name = (char *)lua_tostring(L, -1);
+  if (name == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+
+  i = route_get(&failure_rt, name);
+  if (failure_rt.rlist[i] == 0) {
+    LM_WARN("no actions in failure_route[%s]\n", name);
+    return app_lua_return_error(L);
+  }
+
+  _lua_xtmb.t_on_failure((unsigned int)i);
+  return app_lua_return_int(L, 1);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_on_branch(lua_State *L) {
+  char *name;
+  int i;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)) {
+    LM_WARN("weird: tm function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  name = (char *)lua_tostring(L, -1);
+  if (name == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+
+  i = route_get(&branch_rt, name);
+  if (branch_rt.rlist[i] == 0) {
+    LM_WARN("no actions in branch_route[%s]\n", name);
+    return app_lua_return_error(L);
+  }
+
+  _lua_xtmb.t_on_branch((unsigned int)i);
+  return app_lua_return_int(L, 1);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_on_reply(lua_State *L) {
+  char *name;
+  int i;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)) {
+    LM_WARN("weird: tm function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  name = (char *)lua_tostring(L, -1);
+  if (name == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+
+  i = route_get(&onreply_rt, name);
+  if (onreply_rt.rlist[i] == 0) {
+    LM_WARN("no actions in onreply_route[%s]\n", name);
+    return app_lua_return_error(L);
+  }
+
+  _lua_xtmb.t_on_reply((unsigned int)i);
+  return app_lua_return_int(L, 1);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_check_trans(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)) {
+    LM_WARN("weird: tm function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_xtmb.t_check_trans(env_L->msg);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_is_canceled(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)) {
+    LM_WARN("weird: tm function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_xtmb.t_is_canceled(env_L->msg);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_newtran(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)) {
+    LM_WARN("weird: tm function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_tmb.t_newtran(env_L->msg);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_release(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)) {
+    LM_WARN("weird: tm function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_tmb.t_release(env_L->msg);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_replicate(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+  str suri;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)) {
+    LM_WARN("weird: tm function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  suri.s = (char *)lua_tostring(L, -1);
+  if (suri.s == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  suri.len = strlen(suri.s);
+
+  ret = _lua_tmb.t_replicate(env_L->msg, &suri);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+#define BRANCH_FAILURE_ROUTE_PREFIX "tm:branch-failure"
+static int lua_sr_tm_t_on_branch_failure(lua_State *L) {
+  static str rt_name = {NULL, 0};
+  char *name;
+  int rt_name_len;
+  int i;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)) {
+    LM_WARN("weird: tm function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  name = (char *)lua_tostring(L, -1);
+  if (name == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  rt_name_len = strlen(BRANCH_FAILURE_ROUTE_PREFIX) + 1 + strlen(name);
+  if (rt_name_len > rt_name.len) {
+    if ((rt_name.s = pkg_reallocxf(rt_name.s, rt_name_len + 1)) == NULL) {
+      PKG_MEM_ERROR;
+      return -1;
+    }
+    rt_name.len = rt_name_len;
+  }
+  snprintf(rt_name.s, rt_name_len + 1, "%s:%s", BRANCH_FAILURE_ROUTE_PREFIX,
+           name);
+
+  i = route_get(&event_rt, rt_name.s);
+  if (i < 0 || event_rt.rlist[i] == 0) {
+    LM_WARN("no actions in branch_failure_route[%s]\n", name);
+    return app_lua_return_error(L);
+  }
+
+  _lua_xtmb.t_on_branch_failure((unsigned int)i);
+  return app_lua_return_int(L, 1);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_load_contacts(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)) {
+    LM_WARN("weird: tm function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_tmb.t_load_contacts(env_L->msg, NULL, NULL);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_tm_t_next_contacts(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)) {
+    LM_WARN("weird: tm function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_tmb.t_next_contacts(env_L->msg, NULL, NULL);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_tm_Map[] = {
+    {"t_reply", lua_sr_tm_t_reply},
+    {"t_relay", lua_sr_tm_t_relay},
+    {"t_on_failure", lua_sr_tm_t_on_failure},
+    {"t_on_branch", lua_sr_tm_t_on_branch},
+    {"t_on_reply", lua_sr_tm_t_on_reply},
+    {"t_check_trans", lua_sr_tm_t_check_trans},
+    {"t_is_canceled", lua_sr_tm_t_is_canceled},
+    {"t_newtran", lua_sr_tm_t_newtran},
+    {"t_release", lua_sr_tm_t_release},
+    {"t_replicate", lua_sr_tm_t_replicate},
+    {"t_on_branch_failure", lua_sr_tm_t_on_branch_failure},
+    {"t_load_contacts", lua_sr_tm_t_load_contacts},
+    {"t_next_contacts", lua_sr_tm_t_next_contacts},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_sqlops_query(lua_State *L) {
+  str scon;
+  str squery;
+  str sres;
+  int ret;
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SQLOPS)) {
+    LM_WARN("weird: sqlops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  scon.s = (char *)lua_tostring(L, -3);
+  squery.s = (char *)lua_tostring(L, -2);
+  sres.s = (char *)lua_tostring(L, -1);
+  if (scon.s == NULL || squery.s == NULL || sres.s == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  scon.len = strlen(scon.s);
+  squery.len = strlen(squery.s);
+  sres.len = strlen(sres.s);
+
+  ret = _lua_sqlopsb.query(&scon, &squery, &sres);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sqlops_value(lua_State *L) {
+  str sres;
+  int col;
+  int row;
+  sql_val_t *val;
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SQLOPS)) {
+    LM_WARN("weird: sqlops function executed but module not registered\n");
+    return app_lua_return_false(L);
+  }
+  sres.s = (char *)lua_tostring(L, -3);
+  row = lua_tointeger(L, -2);
+  col = lua_tointeger(L, -1);
+  if (row < 0 || col < 0 || sres.s == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_false(L);
+  }
+  sres.len = strlen(sres.s);
+  if (_lua_sqlopsb.value(&sres, row, col, &val) < 0)
+    return app_lua_return_false(L);
+  if (val->flags & PV_VAL_NULL) {
+    lua_pushinteger(L, 0);
+    return 1;
+  }
+
+  if (val->flags & PV_VAL_INT) {
+    lua_pushinteger(L, val->value.n);
+    return 1;
+  }
+  lua_pushlstring(L, val->value.s.s, val->value.s.len);
+  return 1;
+}
+
+/**
+ *
+ */
+static int lua_sr_sqlops_is_null(lua_State *L) {
+  str sres;
+  int col;
+  int row;
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SQLOPS)) {
+    LM_WARN("weird: sqlops function executed but module not registered\n");
+    return app_lua_return_false(L);
+  }
+  sres.s = (char *)lua_tostring(L, -3);
+  row = lua_tointeger(L, -2);
+  col = lua_tointeger(L, -1);
+  if (row < 0 || col < 0 || sres.s == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_false(L);
+  }
+  sres.len = strlen(sres.s);
+  if (_lua_sqlopsb.is_null(&sres, row, col) == 1)
+    return app_lua_return_true(L);
+  return app_lua_return_false(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_sqlops_column(lua_State *L) {
+  str sres;
+  int col;
+  str name = {0, 0};
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SQLOPS)) {
+    LM_WARN("weird: sqlops function executed but module not registered\n");
+    return app_lua_return_false(L);
+  }
+  sres.s = (char *)lua_tostring(L, -2);
+  col = lua_tointeger(L, -1);
+  if (col < 0 || sres.s == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_false(L);
+  }
+  sres.len = strlen(sres.s);
+  if (_lua_sqlopsb.column(&sres, col, &name) < 0)
+    return app_lua_return_false(L);
+  lua_pushlstring(L, name.s, name.len);
+  return 1;
+}
+
+/**
+ *
+ */
+static int lua_sr_sqlops_nrows(lua_State *L) {
+  str sres;
+  int rows;
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SQLOPS)) {
+    LM_WARN("weird: sqlops function executed but module not registered\n");
+    return app_lua_return_false(L);
+  }
+  sres.s = (char *)lua_tostring(L, -1);
+  if (sres.s == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_false(L);
+  }
+  sres.len = strlen(sres.s);
+  rows = _lua_sqlopsb.nrows(&sres);
+  if (rows < 0)
+    return app_lua_return_false(L);
+  lua_pushinteger(L, rows);
+  return 1;
+}
+
+/**
+ *
+ */
+static int lua_sr_sqlops_ncols(lua_State *L) {
+  str sres;
+  int cols;
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SQLOPS)) {
+    LM_WARN("weird: sqlops function executed but module not registered\n");
+    return app_lua_return_false(L);
+  }
+  sres.s = (char *)lua_tostring(L, -1);
+  if (sres.s == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_false(L);
+  }
+  sres.len = strlen(sres.s);
+  cols = _lua_sqlopsb.ncols(&sres);
+  if (cols < 0)
+    return app_lua_return_false(L);
+  lua_pushinteger(L, cols);
+  return 1;
+}
+
+/**
+ *
+ */
+static int lua_sr_sqlops_reset(lua_State *L) {
+  str sres;
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SQLOPS)) {
+    LM_WARN("weird: sqlops function executed but module not registered\n");
+    return app_lua_return_false(L);
+  }
+  sres.s = (char *)lua_tostring(L, -1);
+  if (sres.s == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_false(L);
+  }
+  sres.len = strlen(sres.s);
+  _lua_sqlopsb.reset(&sres);
+  return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static int lua_sr_sqlops_xquery(lua_State *L) {
+  str scon;
+  str squery;
+  str sres;
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SQLOPS)) {
+    LM_WARN("weird: sqlops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  scon.s = (char *)lua_tostring(L, -3);
+  squery.s = (char *)lua_tostring(L, -2);
+  sres.s = (char *)lua_tostring(L, -1);
+  if (scon.s == NULL || squery.s == NULL || sres.s == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  scon.len = strlen(scon.s);
+  squery.len = strlen(squery.s);
+  sres.len = strlen(sres.s);
+
+  ret = _lua_sqlopsb.xquery(env_L->msg, &scon, &squery, &sres);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_sqlops_Map[] = {{"query", lua_sr_sqlops_query},
+                                          {"value", lua_sr_sqlops_value},
+                                          {"is_null", lua_sr_sqlops_is_null},
+                                          {"column", lua_sr_sqlops_column},
+                                          {"nrows", lua_sr_sqlops_nrows},
+                                          {"ncols", lua_sr_sqlops_ncols},
+                                          {"reset", lua_sr_sqlops_reset},
+                                          {"xquery", lua_sr_sqlops_xquery},
+                                          {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_rr_record_route(lua_State *L) {
+  int ret;
+  str sv = {0, 0};
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_RR)) {
+    LM_WARN("weird: rr function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) == 1) {
+    sv.s = (char *)lua_tostring(L, -1);
+    if (sv.s != NULL)
+      sv.len = strlen(sv.s);
+  }
+  ret = _lua_rrb.record_route(env_L->msg, (sv.len > 0) ? &sv : NULL);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_rr_loose_route(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_RR)) {
+    LM_WARN("weird: rr function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  ret = _lua_rrb.loose_route(env_L->msg);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_rr_add_rr_param(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+  str param;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_RR)) {
+    LM_WARN("weird: rr function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) != 1) {
+    LM_WARN("invalid number of parameters\n");
+    return app_lua_return_error(L);
+  }
+
+  param.s = (char *)lua_tostring(L, -1);
+  if (param.s != NULL)
+    param.len = strlen(param.s);
+
+  ret = _lua_rrb.add_rr_param(env_L->msg, &param);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_rr_Map[] = {{"record_route", lua_sr_rr_record_route},
+                                      {"loose_route", lua_sr_rr_loose_route},
+                                      {"add_rr_param", lua_sr_rr_add_rr_param},
+                                      {NULL, NULL}};
+
+static int lua_sr_auth_challenge_hftype(lua_State *L, int hftype) {
+  int ret;
+  str realm = {0, 0};
+  int flags;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_AUTH)) {
+    LM_WARN("weird: auth function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) != 2) {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  realm.s = (char *)lua_tostring(L, -2);
+  flags = lua_tointeger(L, -1);
+  if (flags < 0 || realm.s == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  realm.len = strlen(realm.s);
+  ret = _lua_authb.auth_challenge_hftype(env_L->msg, &realm, flags, hftype);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_www_challenge(lua_State *L) {
+  return lua_sr_auth_challenge_hftype(L, HDR_AUTHORIZATION_T);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_proxy_challenge(lua_State *L) {
+  return lua_sr_auth_challenge_hftype(L, HDR_PROXYAUTH_T);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_pv_authenticate(lua_State *L, int hftype) {
+  int ret;
+  str realm = {0, 0};
+  str passwd = {0, 0};
+  int flags;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_AUTH)) {
+    LM_WARN("weird: auth function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) != 3) {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  realm.s = (char *)lua_tostring(L, -3);
+  passwd.s = (char *)lua_tostring(L, -2);
+  flags = lua_tointeger(L, -1);
+  if (flags < 0 || realm.s == NULL || passwd.s == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  realm.len = strlen(realm.s);
+  passwd.len = strlen(passwd.s);
+  ret = _lua_authb.pv_authenticate(env_L->msg, &realm, &passwd, flags, hftype,
+                                   &env_L->msg->first_line.u.request.method);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_pv_www_authenticate(lua_State *L) {
+  return lua_sr_auth_pv_authenticate(L, HDR_AUTHORIZATION_T);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_pv_proxy_authenticate(lua_State *L) {
+  return lua_sr_auth_pv_authenticate(L, HDR_PROXYAUTH_T);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_consume_credentials(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_AUTH)) {
+    LM_WARN("weird: auth function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  ret = _lua_authb.consume_credentials(env_L->msg);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_auth_Map[] = {
+    {"www_challenge", lua_sr_auth_www_challenge},
+    {"proxy_challenge", lua_sr_auth_proxy_challenge},
+    {"pv_www_authenticate", lua_sr_auth_pv_www_authenticate},
+    {"pv_proxy_authenticate", lua_sr_auth_pv_proxy_authenticate},
+    {"consume_credentials", lua_sr_auth_consume_credentials},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_auth_db_authenticate(lua_State *L, hdr_types_t hftype) {
+  int ret;
+  str realm = {0, 0};
+  str table = {0, 0};
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_AUTH_DB)) {
+    LM_WARN("weird: auth function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) != 2) {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  realm.s = (char *)lua_tostring(L, -2);
+  table.s = (char *)lua_tostring(L, -1);
+  if (realm.s == NULL || table.s == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  realm.len = strlen(realm.s);
+  table.len = strlen(table.s);
+  ret = _lua_auth_dbb.digest_authenticate(
+      env_L->msg, &realm, &table, hftype,
+      &env_L->msg->first_line.u.request.method);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_db_www_authenticate(lua_State *L) {
+  return lua_sr_auth_db_authenticate(L, HDR_AUTHORIZATION_T);
+}
+
+/**
+ *
+ */
+static int lua_sr_auth_db_proxy_authenticate(lua_State *L) {
+  return lua_sr_auth_db_authenticate(L, HDR_PROXYAUTH_T);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_auth_db_Map[] = {
+    {"www_authenticate", lua_sr_auth_db_www_authenticate},
+    {"proxy_authenticate", lua_sr_auth_db_proxy_authenticate},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_maxfwd_process_maxfwd(lua_State *L) {
+  int ret;
+  int limit;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_MAXFWD)) {
+    LM_WARN("weird: maxfwd function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) != 1) {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  limit = lua_tointeger(L, -1);
+  if (limit < 0) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  ret = _lua_maxfwdb.process_maxfwd(env_L->msg, limit);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_maxfwd_Map[] = {
+    {"process_maxfwd", lua_sr_maxfwd_process_maxfwd}, {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_registrar_save(lua_State *L) {
+  int ret;
+  int flags;
+  str table = STR_NULL;
+  str uri = STR_NULL;
+  sr_lua_env_t *env_L;
+
+  flags = 0;
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_REGISTRAR)) {
+    LM_WARN("weird: registrar function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) == 1) {
+    table.s = (char *)lua_tostring(L, -1);
+  } else if (lua_gettop(L) == 2) {
+    table.s = (char *)lua_tostring(L, -2);
+    flags = lua_tointeger(L, -1);
+  } else if (lua_gettop(L) == 3) {
+    table.s = (char *)lua_tostring(L, -3);
+    flags = lua_tointeger(L, -2);
+    uri.s = (char *)lua_tostring(L, -1);
+    uri.len = strlen(uri.s);
+  } else {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  if (table.s == NULL || (table.len = strlen(table.s)) == 0) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) == 3) {
+    ret = _lua_registrarb.save_uri(env_L->msg, &table, flags, &uri);
+  } else {
+    ret = _lua_registrarb.save(env_L->msg, &table, flags);
+  }
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_registrar_lookup(lua_State *L) {
+  int ret;
+  str table = STR_NULL;
+  str uri = STR_NULL;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_REGISTRAR)) {
+    LM_WARN("weird: registrar function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) == 1) {
+    table.s = (char *)lua_tostring(L, -1);
+  } else if (lua_gettop(L) == 2) {
+    table.s = (char *)lua_tostring(L, -2);
+    uri.s = (char *)lua_tostring(L, -1);
+    uri.len = strlen(uri.s);
+  } else {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  if (table.s == NULL || (table.len = strlen(table.s)) == 0) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) == 2) {
+    ret = _lua_registrarb.lookup_uri(env_L->msg, &table, &uri);
+  } else {
+    ret = _lua_registrarb.lookup(env_L->msg, &table);
+  }
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_registrar_lookup_to_dset(lua_State *L) {
+  int ret;
+  str table = STR_NULL;
+  str uri = STR_NULL;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_REGISTRAR)) {
+    LM_WARN("weird: registrar function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) == 1) {
+    table.s = (char *)lua_tostring(L, -1);
+  } else if (lua_gettop(L) == 2) {
+    table.s = (char *)lua_tostring(L, -2);
+    uri.s = (char *)lua_tostring(L, -1);
+    uri.len = strlen(uri.s);
+  } else {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  if (table.s == NULL || (table.len = strlen(table.s)) == 0) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) == 2) {
+    ret = _lua_registrarb.lookup_to_dset(env_L->msg, &table, &uri);
+  } else {
+    ret = _lua_registrarb.lookup_to_dset(env_L->msg, &table, NULL);
+  }
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_registrar_registered(lua_State *L) {
+  int ret;
+  str table;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_REGISTRAR)) {
+    LM_WARN("weird: registrar function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) != 1) {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  table.s = (char *)lua_tostring(L, -1);
+  if (table.s == NULL || (table.len = strlen(table.s)) == 0) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  ret = _lua_registrarb.registered(env_L->msg, &table);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_registrar_Map[] = {
+    {"save", lua_sr_registrar_save},
+    {"lookup", lua_sr_registrar_lookup},
+    {"lookup_to_dset", lua_sr_registrar_lookup_to_dset},
+    {"registered", lua_sr_registrar_registered},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_dispatcher_select(lua_State *L) {
+  int ret;
+  int setid;
+  int algid;
+  int mode;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_DISPATCHER)) {
+    LM_WARN("weird: dispatcher function executed but module"
+            " not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) == 3) {
+    setid = lua_tointeger(L, -3);
+    algid = lua_tointeger(L, -2);
+    mode = lua_tointeger(L, -1);
+  } else if (lua_gettop(L) == 2) {
+    setid = lua_tointeger(L, -2);
+    algid = lua_tointeger(L, -1);
+    mode = 0;
+  } else {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  ret = _lua_dispatcherb.select(env_L->msg, setid, algid, mode);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_dispatcher_next(lua_State *L) {
+  int ret;
+  int mode;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_DISPATCHER)) {
+    LM_WARN("weird: dispatcher function executed but module"
+            " not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  mode = 0;
+  if (lua_gettop(L) == 1) {
+    /* mode given as parameter */
+    mode = lua_tointeger(L, -1);
+  }
+  ret = _lua_dispatcherb.next(env_L->msg, mode);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_dispatcher_mark(lua_State *L) {
+  int ret;
+  int mode;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_DISPATCHER)) {
+    LM_WARN("weird: dispatcher function executed but module"
+            " not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  mode = 0;
+  if (lua_gettop(L) == 1) {
+    /* mode given as parameter */
+    mode = lua_tointeger(L, -1);
+  }
+  ret = _lua_dispatcherb.mark(env_L->msg, mode);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_dispatcher_is_from(lua_State *L) {
+  int ret;
+  int mode;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_DISPATCHER)) {
+    LM_WARN("weird: dispatcher function executed but module"
+            " not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  mode = -1;
+  if (lua_gettop(L) == 1) {
+    /* mode given as parameter */
+    mode = lua_tointeger(L, -1);
+  }
+  ret = _lua_dispatcherb.is_from(env_L->msg, mode);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_dispatcher_Map[] = {
+    {"select", lua_sr_dispatcher_select},
+    {"next", lua_sr_dispatcher_next},
+    {"mark", lua_sr_dispatcher_mark},
+    {"is_from", lua_sr_dispatcher_is_from},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_xhttp_reply(lua_State *L) {
+  int rcode;
+  str reason;
+  str ctype;
+  str mbody;
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_XHTTP)) {
+    LM_WARN("weird: xhttp function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  rcode = lua_tointeger(L, -4);
+  reason.s = (char *)lua_tostring(L, -3);
+  ctype.s = (char *)lua_tostring(L, -2);
+  mbody.s = (char *)lua_tostring(L, -1);
+  if (reason.s == NULL || ctype.s == NULL || mbody.s == NULL) {
+    LM_WARN("invalid parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  reason.len = strlen(reason.s);
+  ctype.len = strlen(ctype.s);
+  mbody.len = strlen(mbody.s);
+
+  ret = _lua_xhttpb.reply(env_L->msg, rcode, &reason, &ctype, &mbody);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_xhttp_Map[] = {{"reply", lua_sr_xhttp_reply},
+                                         {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_sdpops_with_media(lua_State *L) {
+  int ret;
+  str media;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)) {
+    LM_WARN("weird: sdpops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 1) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  media.s = (char *)lua_tostring(L, -1);
+  media.len = strlen(media.s);
+
+  ret = _lua_sdpopsb.sdp_with_media(env_L->msg, &media);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sdpops_with_active_media(lua_State *L) {
+  int ret;
+  str media;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)) {
+    LM_WARN("weird: sdpops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 1) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  media.s = (char *)lua_tostring(L, -1);
+  media.len = strlen(media.s);
+
+  ret = _lua_sdpopsb.sdp_with_active_media(env_L->msg, &media);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sdpops_with_transport(lua_State *L) {
+  int ret;
+  str transport;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)) {
+    LM_WARN("weird: sdpops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 1) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  transport.s = (char *)lua_tostring(L, -1);
+  transport.len = strlen(transport.s);
+
+  ret = _lua_sdpopsb.sdp_with_transport(env_L->msg, &transport, 0);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sdpops_with_codecs_by_id(lua_State *L) {
+  int ret;
+  str codecs;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)) {
+    LM_WARN("weird: sdpops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 1) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  codecs.s = (char *)lua_tostring(L, -1);
+  codecs.len = strlen(codecs.s);
+
+  ret = _lua_sdpopsb.sdp_with_codecs_by_id(env_L->msg, &codecs);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sdpops_with_codecs_by_name(lua_State *L) {
+  int ret;
+  str codecs;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)) {
+    LM_WARN("weird: sdpops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 1) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  codecs.s = (char *)lua_tostring(L, -1);
+  codecs.len = strlen(codecs.s);
+
+  ret = _lua_sdpopsb.sdp_with_codecs_by_name(env_L->msg, &codecs);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sdpops_with_ice(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)) {
+    LM_WARN("weird: sdpops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 0) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_sdpopsb.sdp_with_ice(env_L->msg);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sdpops_keep_codecs_by_id(lua_State *L) {
+  int ret;
+  str codecs;
+  str media;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)) {
+    LM_WARN("weird: sdpops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 2) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  codecs.s = (char *)lua_tostring(L, -2);
+  codecs.len = strlen(codecs.s);
+
+  media.s = (char *)lua_tostring(L, -1);
+  media.len = strlen(media.s);
+
+  ret = _lua_sdpopsb.sdp_keep_codecs_by_id(env_L->msg, &codecs, &media);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sdpops_keep_codecs_by_name(lua_State *L) {
+  int ret;
+  str media;
+  str codecs;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)) {
+    LM_WARN("weird: sdpops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 2) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  codecs.s = (char *)lua_tostring(L, -2);
+  codecs.len = strlen(codecs.s);
+
+  media.s = (char *)lua_tostring(L, -1);
+  media.len = strlen(media.s);
+
+  ret = _lua_sdpopsb.sdp_keep_codecs_by_name(env_L->msg, &codecs, &media);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sdpops_remove_media(lua_State *L) {
+  int ret;
+  str media;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)) {
+    LM_WARN("weird: sdpops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 1) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  media.s = (char *)lua_tostring(L, -1);
+  media.len = strlen(media.s);
+
+  ret = _lua_sdpopsb.sdp_remove_media(env_L->msg, &media);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sdpops_remove_transport(lua_State *L) {
+  int ret;
+  str transport;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)) {
+    LM_WARN("weird: sdpops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 1) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  transport.s = (char *)lua_tostring(L, -1);
+  transport.len = strlen(transport.s);
+
+  ret = _lua_sdpopsb.sdp_remove_transport(env_L->msg, &transport);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sdpops_remove_line_by_prefix(lua_State *L) {
+  int ret;
+  str prefix = STR_NULL;
+  str media = STR_NULL;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)) {
+    LM_WARN("weird: sdpops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) == 1) {
+    prefix.s = (char *)lua_tostring(L, -1);
+    prefix.len = strlen(prefix.s);
+  } else if (lua_gettop(L) == 2) {
+    prefix.s = (char *)lua_tostring(L, -2);
+    prefix.len = strlen(prefix.s);
+    media.s = (char *)lua_tostring(L, -1);
+    media.len = strlen(media.s);
+  } else {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_sdpopsb.sdp_remove_line_by_prefix(env_L->msg, &prefix, &media);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sdpops_remove_codecs_by_id(lua_State *L) {
+  int ret;
+  str codecs;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)) {
+    LM_WARN("weird: sdpops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 1) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  codecs.s = (char *)lua_tostring(L, -1);
+  codecs.len = strlen(codecs.s);
+
+  ret = _lua_sdpopsb.sdp_remove_codecs_by_id(env_L->msg, &codecs, NULL);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_sdpops_remove_codecs_by_name(lua_State *L) {
+  int ret;
+  str codecs;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)) {
+    LM_WARN("weird: sdpops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 1) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  codecs.s = (char *)lua_tostring(L, -1);
+  codecs.len = strlen(codecs.s);
+
+  ret = _lua_sdpopsb.sdp_remove_codecs_by_name(env_L->msg, &codecs, NULL);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_sdpops_Map[] = {
+    {"sdp_with_media", lua_sr_sdpops_with_media},
+    {"sdp_with_active_media", lua_sr_sdpops_with_active_media},
+    {"sdp_with_transport", lua_sr_sdpops_with_transport},
+    {"sdp_with_codecs_by_id", lua_sr_sdpops_with_codecs_by_id},
+    {"sdp_with_codecs_by_name", lua_sr_sdpops_with_codecs_by_name},
+    {"sdp_with_ice", lua_sr_sdpops_with_ice},
+    {"sdp_keep_codecs_by_id", lua_sr_sdpops_keep_codecs_by_id},
+    {"sdp_keep_codecs_by_name", lua_sr_sdpops_keep_codecs_by_name},
+    {"sdp_remove_media", lua_sr_sdpops_remove_media},
+    {"sdp_remove_transport", lua_sr_sdpops_remove_transport},
+    {"sdp_remove_line_by_prefix", lua_sr_sdpops_remove_line_by_prefix},
+    {"sdp_remove_codecs_by_id", lua_sr_sdpops_remove_codecs_by_id},
+    {"sdp_remove_codecs_by_name", lua_sr_sdpops_remove_codecs_by_name},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_pres_auth_status(lua_State *L) {
+  str param[2];
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_PRESENCE)) {
+    LM_WARN("weird: presence function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 2) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  param[0].s = (char *)lua_tostring(L, -2);
+  param[0].len = strlen(param[0].s);
+  param[1].s = (char *)lua_tostring(L, -1);
+  param[1].len = strlen(param[1].s);
+
+  ret = _lua_presenceb.pres_auth_status(env_L->msg, param[0], param[1]);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_pres_handle_publish(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_PRESENCE)) {
+    LM_WARN("weird: presence function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 0) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_presenceb.handle_publish(env_L->msg, NULL, NULL);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_pres_handle_subscribe(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_PRESENCE)) {
+    LM_WARN("weird: presence function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) == 0)
+    ret = _lua_presenceb.handle_subscribe0(env_L->msg);
+  else if (lua_gettop(L) == 1) {
+    str wuri;
+    struct sip_uri parsed_wuri;
+
+    wuri.s = (char *)lua_tostring(L, -1);
+    wuri.len = strlen(wuri.s);
+    if (parse_uri(wuri.s, wuri.len, &parsed_wuri)) {
+      LM_ERR("failed to parse watcher URI\n");
+      return app_lua_return_error(L);
+    }
+    ret = _lua_presenceb.handle_subscribe(env_L->msg, parsed_wuri.user,
+                                          parsed_wuri.host);
+  } else {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_presence_Map[] = {
+    {"pres_auth_status", lua_sr_pres_auth_status},
+    {"handle_publish", lua_sr_pres_handle_publish},
+    {"handle_subscribe", lua_sr_pres_handle_subscribe},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_pres_check_basic(lua_State *L) {
+  str param[2];
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_PRESENCE_XML)) {
+    LM_WARN("weird: presence_xml function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 2) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  param[0].s = (char *)lua_tostring(L, -2);
+  param[0].len = strlen(param[0].s);
+  param[1].s = (char *)lua_tostring(L, -1);
+  param[1].len = strlen(param[1].s);
+
+  ret = _lua_presence_xmlb.pres_check_basic(env_L->msg, param[0], param[1]);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_pres_check_activities(lua_State *L) {
+  str param[2];
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_PRESENCE_XML)) {
+    LM_WARN("weird: presence_xml function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 2) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  param[0].s = (char *)lua_tostring(L, -2);
+  param[0].len = strlen(param[0].s);
+  param[1].s = (char *)lua_tostring(L, -1);
+  param[1].len = strlen(param[1].s);
+
+  ret =
+      _lua_presence_xmlb.pres_check_activities(env_L->msg, param[0], param[1]);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_presence_xml_Map[] = {
+    {"pres_check_basic", lua_sr_pres_check_basic},
+    {"pres_check_activities", lua_sr_pres_check_activities},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_textops_is_privacy(lua_State *L) {
+  str param[1];
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TEXTOPS)) {
+    LM_WARN("weird: textops function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 1) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  param[0].s = (char *)lua_tostring(L, -1);
+  param[0].len = strlen(param[0].s);
+
+  ret = _lua_textopsb.is_privacy(env_L->msg, &param[0]);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_textops_Map[] = {
+    {"is_privacy", lua_sr_textops_is_privacy}, {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_pua_usrloc_set_publish(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_PUA_USRLOC)) {
+    LM_WARN("weird: pua_usrloc function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 0) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_pua_usrlocb.pua_set_publish(env_L->msg, NULL, NULL);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_pua_usrloc_Map[] = {
+    {"set_publish", lua_sr_pua_usrloc_set_publish}, {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_siputils_has_totag(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SIPUTILS)) {
+    LM_WARN("weird: siputils function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 0) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_siputilsb.has_totag(env_L->msg, NULL, NULL);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_siputils_is_uri_user_e164(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+  str param[1];
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SIPUTILS)) {
+    LM_WARN("weird: siputils function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 1) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  param[0].s = (char *)lua_tostring(L, -1);
+  param[0].len = strlen(param[0].s);
+
+  ret = _lua_siputilsb.is_uri_user_e164(&param[0]);
+  if (ret < 0)
+    return app_lua_return_false(L);
+
+  return app_lua_return_true(L);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_siputils_Map[] = {
+    {"has_totag", lua_sr_siputils_has_totag},
+    {"is_uri_user_e164", lua_sr_siputils_is_uri_user_e164},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_rls_handle_subscribe(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_RLS)) {
+    LM_WARN("weird: rls function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) == 0)
+    ret = _lua_rlsb.rls_handle_subscribe0(env_L->msg);
+  else if (lua_gettop(L) == 1) {
+    str wuri;
+    struct sip_uri parsed_wuri;
+
+    wuri.s = (char *)lua_tostring(L, -1);
+    wuri.len = strlen(wuri.s);
+    if (parse_uri(wuri.s, wuri.len, &parsed_wuri)) {
+      LM_ERR("failed to parse watcher URI\n");
+      return app_lua_return_error(L);
+    }
+    ret = _lua_rlsb.rls_handle_subscribe(env_L->msg, parsed_wuri.user,
+                                         parsed_wuri.host);
+  } else {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_rls_handle_notify(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_RLS)) {
+    LM_WARN("weird: rls function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 0) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_rlsb.rls_handle_notify(env_L->msg, NULL, NULL);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_rls_Map[] = {
+    {"handle_subscribe", lua_sr_rls_handle_subscribe},
+    {"handle_notify", lua_sr_rls_handle_notify},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_alias_db_lookup(lua_State *L) {
+  int ret;
+  str param[1];
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_ALIAS_DB)) {
+    LM_WARN("weird: alias_db function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) != 1) {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  param[0].s = (char *)lua_tostring(L, -1);
+  param[0].len = strlen(param[0].s);
+
+  ret = _lua_alias_dbb.alias_db_lookup(env_L->msg, param[0]);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_alias_db_Map[] = {{"lookup", lua_sr_alias_db_lookup},
+                                            {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_msilo_store(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_MSILO)) {
+    LM_WARN("weird: msilo function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) == 0) {
+    ret = _lua_msilob.m_store(env_L->msg, NULL);
+  } else if (lua_gettop(L) == 1) {
+    str owner;
+    owner.s = (char *)lua_tostring(L, -1);
+    if (owner.s == NULL) {
+      return app_lua_return_error(L);
+    }
+    owner.len = strlen(owner.s);
+    ret = _lua_msilob.m_store(env_L->msg, &owner);
+  } else {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_msilo_dump(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_MSILO)) {
+    LM_WARN("weird: msilo function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) == 0) {
+    ret = _lua_msilob.m_dump(env_L->msg, NULL);
+  } else if (lua_gettop(L) == 1) {
+    str owner;
+    owner.s = (char *)lua_tostring(L, -1);
+    if (owner.s == NULL) {
+      return app_lua_return_error(L);
+    }
+    owner.len = strlen(owner.s);
+    ret = _lua_msilob.m_dump(env_L->msg, &owner);
+  } else {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_msilo_Map[] = {
+    {"store", lua_sr_msilo_store}, {"dump", lua_sr_msilo_dump}, {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_uac_replace_x(lua_State *L, int htype) {
+  int ret;
+  sr_lua_env_t *env_L;
+  str param[2];
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_UAC)) {
+    LM_WARN("weird:uac function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  if (lua_gettop(L) == 1) {
+    param[0].s = "";
+    param[0].len = 0;
+    param[1].s = (char *)lua_tostring(L, -1);
+    param[1].len = strlen(param[1].s);
+
+  } else if (lua_gettop(L) == 2) {
+    param[0].s = (char *)lua_tostring(L, -2);
+    param[0].len = strlen(param[0].s);
+    param[1].s = (char *)lua_tostring(L, -1);
+    param[1].len = strlen(param[1].s);
+  } else {
+    LM_ERR("incorrect number of arguments\n");
+    return app_lua_return_error(L);
+  }
+
+  if (htype == 1) {
+    ret = _lua_uacb.replace_to(env_L->msg, &param[0], &param[1]);
+  } else {
+    ret = _lua_uacb.replace_from(env_L->msg, &param[0], &param[1]);
+  }
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_uac_replace_from(lua_State *L) {
+  return lua_sr_uac_replace_x(L, 0);
+}
+
+/**
+ *
+ */
+static int lua_sr_uac_replace_to(lua_State *L) {
+  return lua_sr_uac_replace_x(L, 1);
+}
+
+/**
+ *
+ */
+static int lua_sr_uac_req_send(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_UAC)) {
+    LM_WARN("weird:uac function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_uacb.req_send();
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_uac_Map[] = {
+    {"replace_from", lua_sr_uac_replace_from},
+    {"replace_to", lua_sr_uac_replace_to},
+    {"uac_req_send", lua_sr_uac_req_send},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_sanity_check(lua_State *L) {
+  int msg_checks, uri_checks;
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SANITY)) {
+    LM_WARN("weird: sanity function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+  msg_checks = lua_tointeger(L, -1);
+  uri_checks = lua_tointeger(L, -2);
+
+  ret = _lua_sanityb.check(env_L->msg, msg_checks, uri_checks);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_sanity_Map[] = {{"sanity_check", lua_sr_sanity_check},
+                                          {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_cfgutils_lock(lua_State *L) {
+  int ret;
+  str lkey, lkey2;
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_CFGUTILS)) {
+    LM_WARN("weird: cfgutils function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+  ret = lua_gettop(L);
+  if (ret < 1 || ret > 3) {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  if (ret > 1) {
+    lkey2.s = (char *)lua_tostring(L, -1);
+    lkey2.len = strlen(lkey2.s);
+  }
+  lkey.s = (char *)lua_tostring(L, -1);
+  lkey.len = strlen(lkey.s);
+  if (ret > 1) {
+    ret = _lua_cfgutilsb.mlock(&lkey, &lkey2);
+  } else {
+    ret = _lua_cfgutilsb.mlock(&lkey, NULL);
+  }
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_cfgutils_unlock(lua_State *L) {
+  int ret;
+  str lkey, lkey2;
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_CFGUTILS)) {
+    LM_WARN("weird: cfgutils function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+  ret = lua_gettop(L);
+  if (ret < 1 || ret > 3) {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+  if (ret > 1) {
+    lkey2.s = (char *)lua_tostring(L, -1);
+    lkey2.len = strlen(lkey2.s);
+  }
+  lkey.s = (char *)lua_tostring(L, -1);
+  lkey.len = strlen(lkey.s);
+  if (ret > 1) {
+    ret = _lua_cfgutilsb.munlock(&lkey, &lkey2);
+  } else {
+    ret = _lua_cfgutilsb.munlock(&lkey, NULL);
+  }
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_cfgutils_Map[] = {{"lock", lua_sr_cfgutils_lock},
+                                            {"unlock", lua_sr_cfgutils_unlock},
+                                            {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_tmx_t_suspend(lua_State *L) {
+  int ret;
+  sr_lua_env_t *env_L;
+
+  env_L = _app_lua_api.env_get_f();
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TMX)) {
+    LM_WARN("weird: tmx function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (env_L->msg == NULL) {
+    LM_WARN("invalid parameters from Lua env\n");
+    return app_lua_return_error(L);
+  }
+
+  ret = _lua_tmxb.t_suspend(env_L->msg, NULL, NULL);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_tmx_Map[] = {{"t_suspend", lua_sr_tmx_t_suspend},
+                                       {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_mq_add(lua_State *L) {
+  int ret;
+  str param[3];
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_MQUEUE)) {
+    LM_WARN("weird: mqueue function executed but module not registered\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) != 3) {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+
+  param[0].s = (char *)lua_tostring(L, -3);
+  param[0].len = strlen(param[0].s);
+  param[1].s = (char *)lua_tostring(L, -2);
+  param[1].len = strlen(param[1].s);
+  param[2].s = (char *)lua_tostring(L, -1);
+  param[2].len = strlen(param[2].s);
+
+  ret = _lua_mqb.add(&param[0], &param[1], &param[2]);
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_mqueue_Map[] = {{"add", lua_sr_mq_add}, {NULL, NULL}};
+
+/**
+ *
+ */
+static int lua_sr_ndb_mongodb_cmd_x(lua_State *L, int ctype) {
+  int ret = 0;
+  str param[6];
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_NDB_MONGODB)) {
+    LM_WARN("weird: ndb_mongodb function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) != 5) {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+
+  param[0].s = (char *)lua_tostring(L, -5);
+  param[0].len = strlen(param[0].s);
+  param[1].s = (char *)lua_tostring(L, -4);
+  param[1].len = strlen(param[1].s);
+  param[2].s = (char *)lua_tostring(L, -3);
+  param[2].len = strlen(param[2].s);
+  param[3].s = (char *)lua_tostring(L, -2);
+  param[3].len = strlen(param[3].s);
+  param[4].s = (char *)lua_tostring(L, -1);
+  param[4].len = strlen(param[4].s);
+
+  if (ctype == 1) {
+    ret = _lua_ndb_mongodbb.cmd_simple(&param[0], &param[1], &param[2],
+                                       &param[3], &param[4]);
+  } else if (ctype == 2) {
+    ret = _lua_ndb_mongodbb.find(&param[0], &param[1], &param[2], &param[3],
+                                 &param[4]);
+  } else if (ctype == 3) {
+    ret = _lua_ndb_mongodbb.find_one(&param[0], &param[1], &param[2], &param[3],
+                                     &param[4]);
+  } else {
+    ret = _lua_ndb_mongodbb.cmd(&param[0], &param[1], &param[2], &param[3],
+                                &param[4]);
+  }
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_ndb_mongodb_cmd(lua_State *L) {
+  return lua_sr_ndb_mongodb_cmd_x(L, 0);
+}
+
+/**
+ *
+ */
+static int lua_sr_ndb_mongodb_cmd_simple(lua_State *L) {
+  return lua_sr_ndb_mongodb_cmd_x(L, 1);
+}
+
+/**
+ *
+ */
+static int lua_sr_ndb_mongodb_find(lua_State *L) {
+  return lua_sr_ndb_mongodb_cmd_x(L, 2);
+}
+
+/**
+ *
+ */
+static int lua_sr_ndb_mongodb_find_one(lua_State *L) {
+  return lua_sr_ndb_mongodb_cmd_x(L, 3);
+}
+
+/**
+ *
+ */
+static int lua_sr_ndb_mongodb_next_reply(lua_State *L) {
+  int ret = 0;
+  str param[1];
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_NDB_MONGODB)) {
+    LM_WARN("weird: ndb_mongodb function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) != 1) {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+
+  param[0].s = (char *)lua_tostring(L, -1);
+  param[0].len = strlen(param[0].s);
+
+  ret = _lua_ndb_mongodbb.next_reply(&param[0]);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static int lua_sr_ndb_mongodb_free_reply(lua_State *L) {
+  int ret = 0;
+  str param[1];
+
+  if (!(_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_NDB_MONGODB)) {
+    LM_WARN("weird: ndb_mongodb function executed but module not "
+            "registered\n");
+    return app_lua_return_error(L);
+  }
+  if (lua_gettop(L) != 1) {
+    LM_WARN("invalid number of parameters from Lua\n");
+    return app_lua_return_error(L);
+  }
+
+  param[0].s = (char *)lua_tostring(L, -1);
+  param[0].len = strlen(param[0].s);
+
+  ret = _lua_ndb_mongodbb.free_reply(&param[0]);
+
+  return app_lua_return_int(L, ret);
+}
+
+/**
+ *
+ */
+static const luaL_Reg _sr_ndb_mongodb_Map[] = {
+    {"cmd", lua_sr_ndb_mongodb_cmd},
+    {"cmd_simple", lua_sr_ndb_mongodb_cmd_simple},
+    {"find", lua_sr_ndb_mongodb_find},
+    {"find_one", lua_sr_ndb_mongodb_find_one},
+    {"next_reply", lua_sr_ndb_mongodb_next_reply},
+    {"free_reply", lua_sr_ndb_mongodb_free_reply},
+    {NULL, NULL}};
+
+/**
+ *
+ */
+int lua_sr_exp_init_mod(void) {
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SL) {
+    /* bind the SL API */
+    if (sl_load_api(&_lua_slb) < 0) {
+      LM_ERR("cannot bind to SL API\n");
+      return -1;
+    }
+    LM_DBG("loaded sl api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM) {
+    /* bind the TM API */
+    if (tm_load_api(&_lua_tmb) < 0) {
+      LM_ERR("cannot bind to TM API\n");
+      return -1;
+    }
+    LM_DBG("loaded tm api\n");
+    /* bind the TM XAPI */
+    if (tm_load_xapi(&_lua_xtmb) < 0) {
+      LM_ERR("cannot bind to TM XAPI\n");
+      return -1;
+    }
+    LM_DBG("loaded tm xapi\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SQLOPS) {
+    /* bind the SQLOPS API */
+    if (sqlops_load_api(&_lua_sqlopsb) < 0) {
+      LM_ERR("cannot bind to SQLOPS API\n");
+      return -1;
+    }
+    LM_DBG("loaded sqlops api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_RR) {
+    /* bind the RR API */
+    if (rr_load_api(&_lua_rrb) < 0) {
+      LM_ERR("cannot bind to RR API\n");
+      return -1;
+    }
+    LM_DBG("loaded rr api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_AUTH) {
+    /* bind the AUTH API */
+    if (auth_load_api(&_lua_authb) < 0) {
+      LM_ERR("cannot bind to AUTH API\n");
+      return -1;
+    }
+    LM_DBG("loaded auth api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_AUTH_DB) {
+    /* bind the AUTH_DB API */
+    if (auth_db_load_api(&_lua_auth_dbb) < 0) {
+      LM_ERR("cannot bind to AUTH_DB API\n");
+      return -1;
+    }
+    LM_DBG("loaded auth_db api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_MAXFWD) {
+    /* bind the MAXFWD API */
+    if (maxfwd_load_api(&_lua_maxfwdb) < 0) {
+      LM_ERR("cannot bind to MAXFWD API\n");
+      return -1;
+    }
+    LM_DBG("loaded maxfwd api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_REGISTRAR) {
+    /* bind the REGISTRAR API */
+    if (registrar_load_api(&_lua_registrarb) < 0) {
+      LM_ERR("cannot bind to REGISTRAR API\n");
+      return -1;
+    }
+    LM_DBG("loaded registrar api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_DISPATCHER) {
+    /* bind the DISPATCHER API */
+    if (dispatcher_load_api(&_lua_dispatcherb) < 0) {
+      LM_ERR("cannot bind to DISPATCHER API\n");
+      return -1;
+    }
+    LM_DBG("loaded dispatcher api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_XHTTP) {
+    /* bind the XHTTP API */
+    if (xhttp_load_api(&_lua_xhttpb) < 0) {
+      LM_ERR("cannot bind to XHTTP API\n");
+      return -1;
+    }
+    LM_DBG("loaded xhttp api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS) {
+    /* bind the SDPOPS API */
+    if (sdpops_load_api(&_lua_sdpopsb) < 0) {
+      LM_ERR("cannot bind to SDPOPS API\n");
+      return -1;
+    }
+    LM_DBG("loaded sdpops api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_PRESENCE) {
+    /* bind the PRESENCE API */
+    if (presence_load_api(&_lua_presenceb) < 0) {
+      LM_ERR("cannot bind to PRESENCE API\n");
+      return -1;
+    }
+    LM_DBG("loaded presence api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_PRESENCE) {
+    /* bind the PRESENCE_XML API */
+    if (presence_xml_load_api(&_lua_presence_xmlb) < 0) {
+      LM_ERR("cannot bind to PRESENCE_XML API\n");
+      return -1;
+    }
+    LM_DBG("loaded presence_xml api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TEXTOPS) {
+    /* bind the TEXTOPS API */
+    if (load_textops_api(&_lua_textopsb) < 0) {
+      LM_ERR("cannot bind to TEXTOPS API\n");
+      return -1;
+    }
+    LM_DBG("loaded textops api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_PUA_USRLOC) {
+    /* bind the PUA_USRLOC API */
+    if (pua_usrloc_load_api(&_lua_pua_usrlocb) < 0) {
+      LM_ERR("cannot bind to PUA_USRLOC API\n");
+      return -1;
+    }
+    LM_DBG("loaded pua_usrloc api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SIPUTILS) {
+    /* bind the SIPUTILS API */
+    if (siputils_load_api(&_lua_siputilsb) < 0) {
+      LM_ERR("cannot bind to SIPUTILS API\n");
+      return -1;
+    }
+    LM_DBG("loaded siputils api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_RLS) {
+    /* bind the RLS API */
+    if (rls_load_api(&_lua_rlsb) < 0) {
+      LM_ERR("cannot bind to RLS API\n");
+      return -1;
+    }
+    LM_DBG("loaded rls api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_ALIAS_DB) {
+    /* bind the ALIAS_DB API */
+    if (alias_db_load_api(&_lua_alias_dbb) < 0) {
+      LM_ERR("cannot bind to ALIAS_DB API\n");
+      return -1;
+    }
+    LM_DBG("loaded alias_db api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_MSILO) {
+    /* bind the MSILO API */
+    if (load_msilo_api(&_lua_msilob) < 0) {
+      LM_ERR("cannot bind to MSILO API\n");
+      return -1;
+    }
+    LM_DBG("loaded msilo api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_UAC) {
+    /* bind the UAC API */
+    if (load_uac_api(&_lua_uacb) < 0) {
+      LM_ERR("cannot bind to UAC API\n");
+      return -1;
+    }
+    LM_DBG("loaded uac api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SANITY) {
+    /* bind the SANITY API */
+    if (sanity_load_api(&_lua_sanityb) < 0) {
+      LM_ERR("cannot bind to SANITY API\n");
+      return -1;
+    }
+    LM_DBG("loaded sanity api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_CFGUTILS) {
+    /* bind the CFGUTILS API */
+    if (cfgutils_load_api(&_lua_cfgutilsb) < 0) {
+      LM_ERR("cannot bind to CFGUTILS API\n");
+      return -1;
+    }
+    LM_DBG("loaded cfgutils api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TMX) {
+    /* bind the TMX API */
+    if (load_tmx_api(&_lua_tmxb) < 0) {
+      LM_ERR("cannot bind to TMX API\n");
+      return -1;
+    }
+    LM_DBG("loaded tmx api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_MQUEUE) {
+    /* bind the MQUEUE API */
+    if (load_mq_api(&_lua_mqb) < 0) {
+      LM_ERR("cannot bind to MQUEUE API\n");
+      return -1;
+    }
+    LM_DBG("loaded mqueue api\n");
+  }
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_NDB_MONGODB) {
+    /* bind the NDB_MONGODB API */
+    if (ndb_mongodb_load_api(&_lua_ndb_mongodbb) < 0) {
+      LM_ERR("cannot bind to NDB_MONGODB API\n");
+      return -1;
+    }
+    LM_DBG("loaded ndb_mongodb api\n");
+  }
+
+  return 0;
+}
+
+/**
+ *
+ */
+int lua_sr_exp_register_mod(char *mname) {
+  int len;
+
+  len = strlen(mname);
+
+  if (len == 2 && strcmp(mname, "sl") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_SL;
+    return 0;
+  } else if (len == 2 && strcmp(mname, "tm") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_TM;
+    return 0;
+  } else if (len == 6 && strcmp(mname, "sqlops") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_SQLOPS;
+    return 0;
+  } else if (len == 2 && strcmp(mname, "rr") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_RR;
+    return 0;
+  } else if (len == 4 && strcmp(mname, "auth") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_AUTH;
+    return 0;
+  } else if (len == 7 && strcmp(mname, "auth_db") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_AUTH_DB;
+    return 0;
+  } else if (len == 6 && strcmp(mname, "maxfwd") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_MAXFWD;
+    return 0;
+  } else if (len == 9 && strcmp(mname, "registrar") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_REGISTRAR;
+    return 0;
+  } else if (len == 10 && strcmp(mname, "dispatcher") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_DISPATCHER;
+    return 0;
+  } else if (len == 5 && strcmp(mname, "xhttp") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_XHTTP;
+    return 0;
+  } else if (len == 6 && strcmp(mname, "sdpops") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_SDPOPS;
+    return 0;
+  } else if (len == 8 && strcmp(mname, "presence") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_PRESENCE;
+    return 0;
+  } else if (len == 12 && strcmp(mname, "presence_xml") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_PRESENCE_XML;
+    return 0;
+  } else if (len == 7 && strcmp(mname, "textops") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_TEXTOPS;
+    return 0;
+  } else if (len == 10 && strcmp(mname, "pua_usrloc") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_PUA_USRLOC;
+    return 0;
+  } else if (len == 8 && strcmp(mname, "siputils") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_SIPUTILS;
+    return 0;
+  } else if (len == 3 && strcmp(mname, "rls") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_RLS;
+    return 0;
+  } else if (len == 8 && strcmp(mname, "alias_db") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_ALIAS_DB;
+    return 0;
+  } else if (len == 5 && strcmp(mname, "msilo") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_MSILO;
+    return 0;
+  } else if (len == 3 && strcmp(mname, "uac") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_UAC;
+    return 0;
+  } else if (len == 6 && strcmp(mname, "sanity") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_SANITY;
+    return 0;
+  } else if (len == 8 && strcmp(mname, "cfgutils") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_CFGUTILS;
+    return 0;
+  } else if (len == 3 && strcmp(mname, "tmx") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_TMX;
+    return 0;
+  } else if (len == 6 && strcmp(mname, "mqueue") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_MQUEUE;
+    return 0;
+  } else if (len == 11 && strcmp(mname, "ndb_mongodb") == 0) {
+    _sr_lua_exp_reg_mods |= SR_LUA_EXP_MOD_NDB_MONGODB;
+    return 0;
+  }
+
+  return -1;
+}
+
+/**
+ *
+ */
+void lua_sr_exp_openlibs(lua_State *L) {
+  LM_DBG("exporting sr registered extensions\n");
+
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SL)
+    luaL_openlib(L, "sr.sl", _sr_sl_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TM)
+    luaL_openlib(L, "sr.tm", _sr_tm_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SQLOPS)
+    luaL_openlib(L, "sr.sqlops", _sr_sqlops_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_RR)
+    luaL_openlib(L, "sr.rr", _sr_rr_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_AUTH)
+    luaL_openlib(L, "sr.auth", _sr_auth_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_AUTH_DB)
+    luaL_openlib(L, "sr.auth_db", _sr_auth_db_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_MAXFWD)
+    luaL_openlib(L, "sr.maxfwd", _sr_maxfwd_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_REGISTRAR)
+    luaL_openlib(L, "sr.registrar", _sr_registrar_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_DISPATCHER)
+    luaL_openlib(L, "sr.dispatcher", _sr_dispatcher_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_XHTTP)
+    luaL_openlib(L, "sr.xhttp", _sr_xhttp_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SDPOPS)
+    luaL_openlib(L, "sr.sdpops", _sr_sdpops_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_PRESENCE)
+    luaL_openlib(L, "sr.presence", _sr_presence_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_PRESENCE_XML)
+    luaL_openlib(L, "sr.presence_xml", _sr_presence_xml_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TEXTOPS)
+    luaL_openlib(L, "sr.textops", _sr_textops_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_PUA_USRLOC)
+    luaL_openlib(L, "sr.pua_usrloc", _sr_pua_usrloc_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SIPUTILS)
+    luaL_openlib(L, "sr.siputils", _sr_siputils_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_RLS)
+    luaL_openlib(L, "sr.rls", _sr_rls_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_ALIAS_DB)
+    luaL_openlib(L, "sr.alias_db", _sr_alias_db_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_MSILO)
+    luaL_openlib(L, "sr.msilo", _sr_msilo_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_UAC)
+    luaL_openlib(L, "sr.uac", _sr_uac_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_SANITY)
+    luaL_openlib(L, "sr.sanity", _sr_sanity_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_CFGUTILS)
+    luaL_openlib(L, "sr.cfgutils", _sr_cfgutils_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_TMX)
+    luaL_openlib(L, "sr.tmx", _sr_tmx_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_MQUEUE)
+    luaL_openlib(L, "sr.mq", _sr_mqueue_Map, 0);
+  if (_sr_lua_exp_reg_mods & SR_LUA_EXP_MOD_NDB_MONGODB)
+    luaL_openlib(L, "sr.ndb_mongodb", _sr_ndb_mongodb_Map, 0);
+}

+ 31 - 0
src/modules/app_lua_sr/app_lua_sr_exp.h

@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2010-2016 Daniel-Constantin Mierla (asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#ifndef _APP_LUA_SR_EXP_H_
+#define _APP_LUA_SR_EXP_H_
+
+#include <lua.h>
+
+int lua_sr_exp_register_mod(char *mname);
+int lua_sr_exp_init_mod(void);
+void lua_sr_exp_openlibs(lua_State *L);
+
+#endif

+ 95 - 0
src/modules/app_lua_sr/app_lua_sr_mod.c

@@ -0,0 +1,95 @@
+/**
+ * Copyright (C) 2010-2019 Daniel-Constantin Mierla (asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../../core/dprint.h"
+#include "../../core/mod_fix.h"
+#include "../../core/sr_module.h"
+#include "../../core/ut.h"
+
+#include "../../modules/app_lua/modapi.h"
+
+#include "app_lua_sr_api.h"
+#include "app_lua_sr_exp.h"
+
+MODULE_VERSION
+
+/** parameters */
+static int mod_init(void);
+
+static int app_lua_register_param(modparam_t type, void *val);
+
+static int app_lua_sr_openlibs(lua_State *L);
+
+int _ksr_app_lua_log_mode = 0;
+
+app_lua_api_t _app_lua_api = {0};
+
+static param_export_t params[] = {
+    {"register", PARAM_STRING | USE_FUNC_PARAM, (void *)app_lua_register_param},
+    {0, 0, 0}};
+
+struct module_exports exports = {
+    "app_lua_sr",
+    DEFAULT_DLFLAGS, /* dlopen flags */
+    0,               /*·exported·functions·*/
+    params,          /*·exported·params·*/
+    0,               /*·exported·RPC·methods·*/
+    0,               /* exported pseudo-variables */
+    0,               /*·response·function·*/
+    mod_init,        /* initialization module */
+    0,               /* per child init function */
+    0                /* destroy function */
+};
+
+/**
+ * init module function
+ */
+static int mod_init(void) {
+  if (app_lua_load_api(&_app_lua_api) < 0) {
+    return -1;
+  }
+  if (lua_sr_exp_init_mod() < 0) {
+    return -1;
+  }
+
+  _app_lua_api.openlibs_register_f(app_lua_sr_openlibs);
+  return 0;
+}
+
+static int app_lua_register_param(modparam_t type, void *val) {
+  if (val == NULL) {
+    return -1;
+  }
+
+  if (lua_sr_exp_register_mod((char *)val) == 0)
+    return 0;
+  return -1;
+}
+
+static int app_lua_sr_openlibs(lua_State *L) {
+  lua_sr_core_openlibs(L);
+  lua_sr_exp_openlibs(L);
+  return 0;
+}

+ 4 - 0
src/modules/app_lua_sr/doc/Makefile

@@ -0,0 +1,4 @@
+docs = app_lua_sr.xml
+
+docbook_dir = ../../../../doc/docbook
+include $(docbook_dir)/Makefile.module

+ 36 - 0
src/modules/app_lua_sr/doc/app_lua_sr.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding='ISO-8859-1'?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+<!-- Include general documentation entities -->
+<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
+%docentities;
+
+]>
+
+<book xmlns:xi="http://www.w3.org/2001/XInclude">
+    <bookinfo>
+	<title>app_lua_sr Module</title>
+	<productname class="trade">&kamailioname;</productname>
+	<authorgroup>
+	    <author>
+		<firstname>Daniel-Constantin</firstname>
+		<surname>Mierla</surname>
+		<affiliation><orgname>asipto.com</orgname></affiliation>
+	    </author>
+	    <editor>
+		<firstname>Daniel-Constantin</firstname>
+		<surname>Mierla</surname>
+		    <email>[email protected]</email>
+	    </editor>
+	</authorgroup>
+	<copyright>
+	    <year>2010-2019</year>
+	    <holder>Daniel-Constantin Mierla (asipto.com)</holder>
+	</copyright>
+    </bookinfo>
+    <toc></toc>
+
+	<xi:include href="app_lua_sr_admin.xml"/>
+
+</book>

+ 257 - 0
src/modules/app_lua_sr/doc/app_lua_sr_admin.xml

@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding='ISO-8859-1'?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+<!-- Include general documentation entities -->
+<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
+%docentities;
+
+]>
+
+<!-- Module User's Guide -->
+
+<chapter>
+
+    <title>&adminguide;</title>
+
+    <section>
+	<title>Overview</title>
+	<para>
+		This module exports the Lua module 'sr', the old API existing before the
+		KEMI framework. The module requires 'app_lua' module.
+	</para>
+	<para>
+		IMPORTANT: this module is kept to allow a smooth migration of the scripts
+		using 'sr' module in Lua to KEMI framework and the 'KSR' module. It will
+		be marked as obsolete in the near future and removed afterwards. If you
+		find any function exported to Lua via 'sr' that has no alternative in
+		Lua 'KSR' module, report it to sr-dev mailing list.
+	</para>
+	<para>
+		Lua (http://www.lua.org) is a fast and easy to embed scripting
+		language. Exported API from &kamailio; to Lua is documented in the
+		dokuwiki.
+	</para>
+    </section>
+
+    <section>
+	<title>Dependencies</title>
+	<section>
+	    <title>&kamailio; Modules</title>
+	    <para>
+		The following modules must be loaded before this module:
+	    	<itemizedlist>
+		    <listitem>
+			<para>
+			    <emphasis>app_lua</emphasis> - the Lua interpreter module.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+			    <emphasis>various</emphasis> - the modules specified by the
+				'register' modparam.
+			</para>
+		    </listitem>
+	    	</itemizedlist>
+	    </para>
+	</section>
+	<section>
+	    <title>External Libraries or Applications</title>
+	    <para>
+		The following libraries or applications must be installed before running
+		&kamailio; with this module loaded:
+	    	<itemizedlist>
+		    <listitem>
+			<para>
+			    <emphasis>liblua5.1-dev</emphasis> - Lua devel library.
+			</para>
+		    </listitem>
+	    	</itemizedlist>
+			<para>
+			    This module can be compiled against LuaJIT compiler (instead of
+			    standard Lua). Then this library is needed:
+			    <itemizedlist>
+				    <listitem>
+				    <emphasis>libluajit-5.1-dev</emphasis> - LuaJIT devel library.
+				    </listitem>
+				</itemizedlist>
+				<para>
+				    To enable that, LUAJIT variable has to be set.
+					<example>
+					    <title>Build against LuaJIT libraries</title>
+					E.g: $ LUAJIT="yes" make modules modules=modules/app_lua_sr
+					</example>
+			    (Warning: LuaJIT version is 5.1, so scripts prepared for higher Lua versions
+			    may not work with LuaJIT)
+				</para>
+			</para>
+	    </para>
+	</section>
+    </section>
+
+    <section>
+	<title>Parameters</title>
+
+	<section id="app_lua_sr.p.register">
+	    <title><varname>register</varname> (string)</title>
+	    <para>
+	    NOTE: Since &kamailio; v5.0, KEMI exports are available in Lua script
+		under KSR module exposed by 'app_lua'. These exports cover most of the modules,
+		a lot more than those listed next. The KEMI exports are the recommended to
+		be used, the old 'sr' module might be obsoleted soon. To read more about
+		KEMI exports and available KSR submodules, see:
+    	<itemizedlist>
+		    <listitem>
+			<para>
+				<ulink url="https://kamailio.org/docs/tutorials/devel/kamailio-kemi-framework/">https://kamailio.org/docs/tutorials/devel/kamailio-kemi-framework/</ulink>
+			</para>
+		    </listitem>
+    	</itemizedlist>
+		</para>
+	    <para>
+			Use this parameter to register optional &kamailio; submodules
+			to Lua. Available submodules are:
+	    </para>
+	    	<itemizedlist>
+		    <listitem>
+			<para>
+				<emphasis>alias_db</emphasis> - register functions from
+				alias_db module under 'sr.alias_db'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>auth</emphasis> - register functions from auth module
+				under 'sr.auth'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>auth_db</emphasis> - register functions from auth_db
+				module under 'sr.auth_db'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>dispatcher</emphasis> - register functions from
+				dispatcher module under 'sr.dispatcher'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>maxfwd</emphasis> - register functions from maxfwd
+				module under 'sr.maxfwd'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>msilo</emphasis> - register functions from
+				msilo module under 'sr.msilo'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>presence</emphasis> - register functions from
+				presence module under 'sr.presence'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>presence_xml</emphasis> - register functions from
+				presence_xml module under 'sr.presence_xml'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>pua_usrloc</emphasis> - register functions from
+				pua_usrloc module under 'sr.pua_usrloc'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>registrar</emphasis> - register functions from
+				registrar module under 'sr.registrar'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>rls</emphasis> - register functions from
+				rls module under 'sr.rls'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>rr</emphasis> - register functions from rr module
+				under 'sr.rr'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>sanity</emphasis> - register functions from sanity
+				module under 'sr.sanity'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>sdpops</emphasis> - register functions from
+				sdpops module under 'sr.sdpops'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>siputils</emphasis> - register functions from
+				siputils module under 'sr.siputils'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>sl</emphasis> - register functions from sl module
+				under 'sr.sl'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>sqlops</emphasis> - register functions from sqlops
+				module under 'sr.sqlops'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>textops</emphasis> - register functions from
+				textops module under 'sr.textops'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>tm</emphasis> - register functions from tm module
+				under 'sr.tm'.
+			</para>
+		    </listitem>
+		    <listitem>
+			<para>
+				<emphasis>xhttp</emphasis> - register functions from xhttp
+				module under 'sr.xhttp'.
+			</para>
+		    </listitem>
+	    	</itemizedlist>
+	    <para>
+			Note that 'sr', 'sr.hdr' and 'sr.pv' modules are always registered
+			to Lua.
+	    </para>
+	    <para>
+		<emphasis>
+		    Default value is <quote>null</quote>.
+		</emphasis>
+	    </para>
+	    <example>
+		<title>Set <varname>register</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("app_lua_sr", "register", "sl")
+...
+</programlisting>
+	    </example>
+	</section>
+	</section>
+
+</chapter>