浏览代码

app_lua: added sl module to Lua

- sl send_reply() function exported to Lua under module sr.sl
- restructured existing code for easier extensibility
- allow to register optional modules to Lua via new parameter 'register'
Daniel-Constantin Mierla 15 年之前
父节点
当前提交
482db59aa2

+ 26 - 6
modules/app_lua/README

@@ -26,6 +26,7 @@ Daniel-Constantin Mierla
         3. Exported Parameters
 
               3.1. load (string)
+              3.2. register (string)
 
         4. Exported Functions
 
@@ -38,9 +39,10 @@ Daniel-Constantin Mierla
    List of Examples
 
    1.1. Set load parameter
-   1.2. lua_dofile usage
-   1.3. lua_doscript usage
+   1.2. Set register parameter
+   1.3. lua_dofile usage
    1.4. lua_doscript usage
+   1.5. lua_doscript usage
 
 Chapter 1. Admin Guide
 
@@ -55,6 +57,7 @@ Chapter 1. Admin Guide
    3. Exported Parameters
 
         3.1. load (string)
+        3.2. register (string)
 
    4. Exported Functions
 
@@ -102,6 +105,7 @@ Chapter 1. Admin Guide
 3. Exported Parameters
 
    3.1. load (string)
+   3.2. register (string)
 
 3.1. load (string)
 
@@ -113,7 +117,23 @@ Chapter 1. Admin Guide
 
    Example 1.1. Set load parameter
 ...
-modparam("lua", "lua", "/usr/local/etc/kamailio/lua/myscript.lua")
+modparam("lua", "load", "/usr/local/etc/kamailio/lua/myscript.lua")
+...
+
+3.2. register (string)
+
+   Use this function to register optional SIP Router submodules to Lua.
+   Available submodules are:
+     * sl - register functions from sl module under 'sr.sl'.
+
+   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("lua", "register", "sr")
 ...
 
 4. Exported Functions
@@ -126,7 +146,7 @@ modparam("lua", "lua", "/usr/local/etc/kamailio/lua/myscript.lua")
 
    Execute the Lua script stored in 'path'.
 
-   Example 1.2. lua_dofile usage
+   Example 1.3. lua_dofile usage
 ...
 lua_dofile("/usr/local/etc/kamailio/lua/myscript.lua");
 ...
@@ -135,7 +155,7 @@ lua_dofile("/usr/local/etc/kamailio/lua/myscript.lua");
 
    Execute the Lua script stored in parameter.
 
-   Example 1.3. lua_doscript usage
+   Example 1.4. lua_doscript usage
 ...
 if(!lua_dostring("sr.log([[err]], [[----------- Hello World\n]])"))
 {
@@ -150,7 +170,7 @@ if(!lua_dostring("sr.log([[err]], [[----------- Hello World\n]])"))
    loaded at startup via parameter 'load'. So far the parameters are
    considered static strings (allowing pv is in the roadmap).
 
-   Example 1.4. lua_doscript usage
+   Example 1.5. lua_doscript usage
 ...
 if(!lua_run("sr_append_fu_to_reply"))
 {

+ 336 - 0
modules/app_lua/app_lua_api.c

@@ -0,0 +1,336 @@
+/**
+ * $Id$
+ *
+ * Copyright (C) 2010 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "../../sr_module.h"
+#include "../../dprint.h"
+#include "../../ut.h"
+#include "../../mem/mem.h"
+#include "../../data_lump.h"
+#include "../../data_lump_rpl.h"
+#include "../../lib/kcore/cmpapi.h"
+
+#include "app_lua_api.h"
+#include "app_lua_sr.h"
+#include "app_lua_exp.h"
+
+
+#define SRVERSION "1.0"
+
+
+/**
+ *
+ */
+static sr_lua_env_t _sr_L_env;
+
+/**
+ * @return the static Lua env
+ */
+sr_lua_env_t *sr_lua_env_get(void)
+{
+	return &_sr_L_env;
+}
+
+/**
+ *
+ */
+typedef struct _sr_lua_load
+{
+	char *script;
+	struct _sr_lua_load *next;
+} sr_lua_load_t;
+
+/**
+ *
+ */
+static sr_lua_load_t *_sr_lua_load_list = NULL;
+
+/**
+ *
+ */
+int sr_lua_load_script(char *script)
+{
+	sr_lua_load_t *li;
+
+	li = (sr_lua_load_t*)pkg_malloc(sizeof(sr_lua_load_t));
+	if(li==NULL)
+	{
+		LM_ERR("no more pkg\n");
+		return -1;
+	}
+	memset(li, 0, sizeof(sr_lua_load_t));
+	li->script = script;
+	li->next = _sr_lua_load_list;
+	_sr_lua_load_list = li;
+	return 0;
+}
+
+
+/**
+ *
+ */
+int sr_lua_register_module(char *mname)
+{
+	if(lua_sr_exp_register_mod(mname)==0)
+		return 0;
+	return -1;
+}
+
+/**
+ *
+ */
+void lua_sr_openlibs(lua_State *L)
+{
+	lua_sr_core_openlibs(L);
+	lua_sr_exp_openlibs(L);
+}
+
+/**
+ *
+ */
+int lua_sr_init_mod(void)
+{
+	memset(&_sr_L_env, 0, sizeof(sr_lua_env_t));
+	if(lua_sr_exp_init_mod()<0)
+		return -1;
+	return 0;
+}
+
+/**
+ *
+ */
+int lua_sr_init_child(void)
+{
+	sr_lua_load_t *li;
+	int ret;
+	char *txt;
+	struct stat sbuf;
+
+	memset(&_sr_L_env, 0, sizeof(sr_lua_env_t));
+	_sr_L_env.L = lua_open();
+	if(_sr_L_env.L==NULL)
+	{
+		LM_ERR("cannot open lua\n");
+		return -1;
+	}
+	luaL_openlibs(_sr_L_env.L);
+	lua_sr_openlibs(_sr_L_env.L);
+
+	/* set SR lib version */
+	lua_pushstring(_sr_L_env.L, "SRVERSION");
+	lua_pushstring(_sr_L_env.L, SRVERSION);
+	lua_settable(_sr_L_env.L, LUA_GLOBALSINDEX);
+
+	if(_sr_lua_load_list != NULL)
+	{
+		_sr_L_env.LL = lua_open();
+		if(_sr_L_env.LL==NULL)
+		{
+			LM_ERR("cannot open lua loading state\n");
+			return -1;
+		}
+		luaL_openlibs(_sr_L_env.LL);
+		lua_sr_openlibs(_sr_L_env.LL);
+
+		/* set SR lib version */
+		lua_pushstring(_sr_L_env.LL, "SRVERSION");
+		lua_pushstring(_sr_L_env.LL, SRVERSION);
+		lua_settable(_sr_L_env.LL, LUA_GLOBALSINDEX);
+
+		li = _sr_lua_load_list;
+		while(li)
+		{
+			if(stat(li->script, &sbuf)!=0)
+			{
+				/* file does not exist */
+				LM_ERR("cannot find script: %s (wrong path?)\n",
+						li->script);
+				lua_sr_destroy();
+				return -1;
+			}
+ 			ret = luaL_loadfile(_sr_L_env.LL, (const char*)li->script);
+			if(ret!=0)
+			{
+				LM_ERR("failed to load Lua script: %s (err: %d)\n",
+						li->script, ret);
+				txt = (char*)lua_tostring(_sr_L_env.LL, -1);
+				LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
+				lua_pop(_sr_L_env.LL, 1);
+				lua_sr_destroy();
+				return -1;
+			}
+			ret = lua_pcall(_sr_L_env.LL, 0, 0, 0);
+			if(ret!=0)
+			{
+				LM_ERR("failed to init Lua script: %s (err: %d)\n",
+						li->script, ret);
+				txt = (char*)lua_tostring(_sr_L_env.LL, -1);
+				LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
+				lua_pop(_sr_L_env.LL, 1);
+				lua_sr_destroy();
+				return -1;
+			}
+			li = li->next;
+		}
+	}
+	LM_DBG("Lua initialized!\n");
+	return 0;
+}
+
+/**
+ *
+ */
+void lua_sr_destroy(void)
+{
+	if(_sr_L_env.L!=NULL)
+	{
+		lua_close(_sr_L_env.L);
+		_sr_L_env.L = NULL;
+	}
+	if(_sr_L_env.LL!=NULL)
+	{
+		lua_close(_sr_L_env.LL);
+		_sr_L_env.LL = NULL;
+	}
+	memset(&_sr_L_env, 0, sizeof(sr_lua_env_t));
+}
+
+/**
+ *
+ */
+int lua_sr_initialized(void)
+{
+	if(_sr_L_env.L==NULL)
+		return 0;
+
+	return 1;
+}
+
+/**
+ *
+ */
+int app_lua_dostring(struct sip_msg *msg, char *script)
+{
+	int ret;
+	char *txt;
+
+	LM_DBG("executing Lua string: [[%s]]\n", script);
+	LM_DBG("lua top index is: %d\n", lua_gettop(_sr_L_env.L));
+	_sr_L_env.msg = msg;
+	ret = luaL_dostring(_sr_L_env.L, script);
+	if(ret!=0)
+	{
+		txt = (char*)lua_tostring(_sr_L_env.L, -1);
+		LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
+		lua_pop (_sr_L_env.L, 1);
+	}
+	_sr_L_env.msg = 0;
+	return (ret==0)?1:-1;
+}
+
+/**
+ *
+ */
+int app_lua_dofile(struct sip_msg *msg, char *script)
+{
+	int ret;
+	char *txt;
+
+	LM_DBG("executing Lua file: [[%s]]\n", script);
+	LM_DBG("lua top index is: %d\n", lua_gettop(_sr_L_env.L));
+	_sr_L_env.msg = msg;
+	ret = luaL_dofile(_sr_L_env.L, script);
+	if(ret!=0)
+	{
+		txt = (char*)lua_tostring(_sr_L_env.L, -1);
+		LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
+		lua_pop(_sr_L_env.L, 1);
+	}
+	_sr_L_env.msg = 0;
+	return (ret==0)?1:-1;
+}
+
+/**
+ *
+ */
+int app_lua_run(struct sip_msg *msg, char *func, char *p1, char *p2,
+		char *p3)
+{
+	int n;
+	int ret;
+	char *txt;
+
+	if(_sr_L_env.LL==NULL)
+	{
+		LM_ERR("lua loading state not initialized (call: %s)\n", func);
+		return -1;
+	}
+
+	LM_DBG("executing Lua function: [[%s]]\n", func);
+	LM_DBG("lua top index is: %d\n", lua_gettop(_sr_L_env.LL));
+	lua_getglobal(_sr_L_env.LL, func);
+	if(!lua_isfunction(_sr_L_env.LL, -1))
+	{
+		LM_ERR("no such function [%s] in lua scripts\n", func);
+		LM_ERR("top stack type [%d - %s]\n",
+				lua_type(_sr_L_env.LL, -1),
+				lua_typename(_sr_L_env.LL,lua_type(_sr_L_env.LL, -1)));
+		txt = (char*)lua_tostring(_sr_L_env.LL, -1);
+		LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
+		return -1;
+	}
+	n = 0;
+	if(p1!=NULL)
+	{
+		lua_pushstring(_sr_L_env.LL, p1);
+		n++;
+		if(p2!=NULL)
+		{
+			lua_pushstring(_sr_L_env.LL, p2);
+			n++;
+			if(p3!=NULL)
+			{
+				lua_pushstring(_sr_L_env.LL, p3);
+				n++;
+			}
+		}
+	}
+	_sr_L_env.msg = msg;
+	ret = lua_pcall(_sr_L_env.LL, n, 0, 0);
+	_sr_L_env.msg = 0;
+	if(ret!=0)
+	{
+		LM_ERR("error executing: %s (err: %d)\n", func, ret);
+		txt = (char*)lua_tostring(_sr_L_env.LL, -1);
+		LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
+		lua_pop(_sr_L_env.LL, 1);
+		return -1;
+	}
+
+	return 1;
+}
+

+ 57 - 0
modules/app_lua/app_lua_api.h

@@ -0,0 +1,57 @@
+/**
+ * $Id$
+ *
+ * Copyright (C) 2010 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef _APP_LUA_API_H_
+#define _APP_LUA_API_H_
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+#include "../../parser/msg_parser.h"
+
+typedef struct _sr_lua_env
+{
+	lua_State *L;
+	lua_State *LL;
+	struct sip_msg *msg;
+	unsigned int flags;
+} sr_lua_env_t;
+
+sr_lua_env_t *sr_lua_env_get(void);
+
+int lua_sr_initialized(void);
+int lua_sr_init_mod(void);
+int lua_sr_init_child(void);
+void lua_sr_destroy(void);
+
+int sr_lua_load_script(char *script);
+int sr_lua_register_module(char *mname);
+
+int app_lua_dostring(struct sip_msg *msg, char *script);
+int app_lua_dofile(struct sip_msg *msg, char *script);
+int app_lua_run(struct sip_msg *msg, char *func, char *p1, char *p2,
+		char *p3);
+
+#endif
+

+ 138 - 0
modules/app_lua/app_lua_exp.c

@@ -0,0 +1,138 @@
+/**
+ * $Id$
+ *
+ * Copyright (C) 2010 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "../../sr_module.h"
+#include "../../dprint.h"
+#include "../../ut.h"
+
+#include "../../modules_k/sl/sl_api.h"
+
+#include "app_lua_api.h"
+
+#define SR_LUA_EXP_MOD_SL	(1<<0)
+
+/**
+ *
+ */
+static unsigned int _sr_lua_exp_reg_mods = 0;
+
+/**
+ *
+ */
+static struct sl_binds _lua_slb;
+
+/**
+ *
+ */
+static int lua_sr_sl_send_reply (lua_State *L)
+{
+	str txt;
+	int code;
+	int ret;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
+
+	if(!(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SL))
+	{
+		LM_WARN("weird: sl function executed but module not registered\n");
+		return 0;
+	}
+
+	code = lua_tointeger(L, -2);
+
+	if(code<100 || code>=700)
+		return 0;
+	
+	txt.s = (char*)lua_tostring(L, -1);
+	if(txt.s!=NULL || env_L->msg==NULL)
+	{
+		txt.len = strlen(txt.s);
+		ret = _lua_slb.send_reply(env_L->msg, code, &txt);
+		if(ret<0)
+		{
+			LM_WARN("sl send_reply returned false\n");
+			return 0;
+		}
+	}
+	return 0;
+}
+
+/**
+ *
+ */
+static const luaL_reg _sr_sl_Map [] = {
+	{"send_reply", lua_sr_sl_send_reply},
+	{NULL, NULL}
+};
+
+/**
+ *
+ */
+int lua_sr_exp_init_mod(void)
+{
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SL)
+	{
+		/* load SL API */
+		if(load_sl_api(&_lua_slb)==-1)
+		{
+			LM_ERR("cannot load sl api\n");
+			return -1;
+		}
+		LM_DBG("loaded sl 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;
+	}
+	return -1;
+}
+
+/**
+ *
+ */
+void lua_sr_exp_openlibs(lua_State *L)
+{
+	if(_sr_lua_exp_reg_mods&SR_LUA_EXP_MOD_SL)
+		luaL_openlib(L, "sr.sl",   _sr_sl_Map,   0);
+}
+
+

+ 34 - 0
modules/app_lua/app_lua_exp.h

@@ -0,0 +1,34 @@
+/**
+ * $Id$
+ *
+ * Copyright (C) 2010 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef _APP_LUA_EXP_H_
+#define _APP_LUA_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
+

+ 11 - 2
modules/app_lua/app_lua_mod.c

@@ -30,7 +30,7 @@
 #include "../../ut.h"
 #include "../../mod_fix.h"
 
-#include "app_lua_sr.h"
+#include "app_lua_api.h"
 
 MODULE_VERSION
 
@@ -47,9 +47,11 @@ static int w_app_lua_run(struct sip_msg *msg, char *func, char *p1, char *p2,
 		char *p3);
 
 int app_lua_load_param(modparam_t type, void *val);
+int app_lua_register_param(modparam_t type, void *val);
 
 static param_export_t params[]={
-	{"load",          STR_PARAM|USE_FUNC_PARAM, (void*)app_lua_load_param},
+	{"load",     STR_PARAM|USE_FUNC_PARAM, (void*)app_lua_load_param},
+	{"register", STR_PARAM|USE_FUNC_PARAM, (void*)app_lua_register_param},
 	{0, 0, 0}
 };
 
@@ -149,3 +151,10 @@ int app_lua_load_param(modparam_t type, void *val)
 	return sr_lua_load_script((char*)val);
 }
 
+int app_lua_register_param(modparam_t type, void *val)
+{
+	if(val==NULL)
+		return -1;
+	return sr_lua_register_module((char*)val);
+}
+

+ 104 - 271
modules/app_lua/app_lua_sr.c

@@ -26,10 +26,6 @@
 #include <stdlib.h>
 #include <sys/stat.h>
 
-#include <lua.h>
-#include <lauxlib.h>
-#include <lualib.h>
-
 #include "../../sr_module.h"
 #include "../../dprint.h"
 #include "../../ut.h"
@@ -38,28 +34,12 @@
 #include "../../data_lump_rpl.h"
 #include "../../lib/kcore/cmpapi.h"
 
+#include "app_lua_api.h"
 #include "app_lua_sr.h"
 
-#define SRVERSION "1.0"
-
-typedef struct _sr_lua_env
-{
-	lua_State *L;
-	lua_State *LL;
-	struct sip_msg *msg;
-	unsigned int flags;
-} sr_lua_env_t;
-
-typedef struct _sr_lua_load
-{
-	char *script;
-	struct _sr_lua_load *next;
-} sr_lua_load_t;
-
-static sr_lua_env_t _sr_L_env;
-
-static sr_lua_load_t *_sr_lua_load_list = NULL;
-
+/**
+ *
+ */
 static int lua_sr_dbg (lua_State *L)
 {
 	char *txt;
@@ -69,6 +49,9 @@ static int lua_sr_dbg (lua_State *L)
 	return 0;
 }
 
+/**
+ *
+ */
 static int lua_sr_err (lua_State *L)
 {
 	char *txt;
@@ -78,6 +61,9 @@ static int lua_sr_err (lua_State *L)
 	return 0;
 }
 
+/**
+ *
+ */
 static int lua_sr_log (lua_State *L)
 {
 	char *txt;
@@ -102,6 +88,9 @@ static int lua_sr_log (lua_State *L)
 	return 0;
 }
 
+/**
+ *
+ */
 static const luaL_reg _sr_core_Map [] = {
 	{"dbg", lua_sr_dbg},
 	{"err", lua_sr_err},
@@ -109,6 +98,9 @@ static const luaL_reg _sr_core_Map [] = {
 	{NULL, NULL}
 };
 
+/**
+ *
+ */
 static int lua_sr_hdr_append (lua_State *L)
 {
 	struct lump* anchor;
@@ -116,19 +108,22 @@ static int lua_sr_hdr_append (lua_State *L)
 	char *txt;
 	int len;
 	char *hdr;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
 
 	txt = (char*)lua_tostring(L, -1);
-	if(txt==NULL || _sr_L_env.msg==NULL)
+	if(txt==NULL || env_L->msg==NULL)
 		return 0;
 
 	LM_DBG("append hf: %s\n", txt);
-	if (parse_headers(_sr_L_env.msg, HDR_EOH_F, 0) == -1)
+	if (parse_headers(env_L->msg, HDR_EOH_F, 0) == -1)
 	{
 		LM_ERR("error while parsing message\n");
 		return 0;
 	}
 
-	hf = _sr_L_env.msg->last_header;
+	hf = env_L->msg->last_header;
 	len = strlen(txt);
 	hdr = (char*)pkg_malloc(len);
 	if(hdr==NULL)
@@ -137,8 +132,8 @@ static int lua_sr_hdr_append (lua_State *L)
 		return 0;
 	}
 	memcpy(hdr, txt, len);
-	anchor = anchor_lump(_sr_L_env.msg,
-				hf->name.s + hf->len - _sr_L_env.msg->buf, 0, 0);
+	anchor = anchor_lump(env_L->msg,
+				hf->name.s + hf->len - env_L->msg->buf, 0, 0);
 	if(insert_new_lump_before(anchor, hdr, len, 0) == 0)
 	{
 		LM_ERR("can't insert lump\n");
@@ -148,31 +143,37 @@ static int lua_sr_hdr_append (lua_State *L)
 	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 = sr_lua_env_get();
 
 	txt = (char*)lua_tostring(L, -1);
-	if(txt==NULL || _sr_L_env.msg==NULL)
+	if(txt==NULL || env_L->msg==NULL)
 		return 0;
 
 	LM_DBG("remove hf: %s\n", txt);
-	if (parse_headers(_sr_L_env.msg, HDR_EOH_F, 0) == -1) {
+	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=_sr_L_env.msg->headers; hf; hf=hf->next)
+	for (hf=env_L->msg->headers; hf; hf=hf->next)
 	{
 		if (cmp_hdrname_str(&hf->name, &hname)==0)
 		{
-			anchor=del_lump(_sr_L_env.msg,
-					hf->name.s - _sr_L_env.msg->buf, hf->len, 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);
@@ -183,6 +184,9 @@ static int lua_sr_hdr_remove (lua_State *L)
 	return 0;
 }
 
+/**
+ *
+ */
 static int lua_sr_hdr_insert (lua_State *L)
 {
 	struct lump* anchor;
@@ -190,13 +194,16 @@ static int lua_sr_hdr_insert (lua_State *L)
 	char *txt;
 	int len;
 	char *hdr;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
 
 	txt = (char*)lua_tostring(L, -1);
-	if(txt==NULL || _sr_L_env.msg==NULL)
+	if(txt==NULL || env_L->msg==NULL)
 		return 0;
 
 	LM_DBG("insert hf: %s\n", txt);
-	hf = _sr_L_env.msg->headers;
+	hf = env_L->msg->headers;
 	len = strlen(txt);
 	hdr = (char*)pkg_malloc(len);
 	if(hdr==NULL)
@@ -205,8 +212,8 @@ static int lua_sr_hdr_insert (lua_State *L)
 		return 0;
 	}
 	memcpy(hdr, txt, len);
-	anchor = anchor_lump(_sr_L_env.msg,
-				hf->name.s + hf->len - _sr_L_env.msg->buf, 0, 0);
+	anchor = anchor_lump(env_L->msg,
+				hf->name.s + hf->len - env_L->msg->buf, 0, 0);
 	if(insert_new_lump_before(anchor, hdr, len, 0) == 0)
 	{
 		LM_ERR("can't insert lump\n");
@@ -216,19 +223,25 @@ static int lua_sr_hdr_insert (lua_State *L)
 	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 = sr_lua_env_get();
 
 	txt = (char*)lua_tostring(L, -1);
-	if(txt==NULL || _sr_L_env.msg==NULL)
+	if(txt==NULL || env_L->msg==NULL)
 		return 0;
 
 	LM_DBG("append to reply: %s\n", txt);
 	len = strlen(txt);
 
-	if(add_lump_rpl(_sr_L_env.msg, txt, len, LUMP_RPL_HDR)==0)
+	if(add_lump_rpl(env_L->msg, txt, len, LUMP_RPL_HDR)==0)
 	{
 		LM_ERR("unable to add reply lump\n");
 		return 0;
@@ -238,6 +251,9 @@ static int lua_sr_hdr_append_to_reply (lua_State *L)
 }
 
 
+/**
+ *
+ */
 static const luaL_reg _sr_hdr_Map [] = {
 	{"append", lua_sr_hdr_append},
 	{"remove", lua_sr_hdr_remove},
@@ -247,14 +263,20 @@ static const luaL_reg _sr_hdr_Map [] = {
 };
 
 
+/**
+ *
+ */
 static int lua_sr_pv_get (lua_State *L)
 {
 	str pvn;
 	pv_spec_t pvs;
     pv_value_t val;
+	sr_lua_env_t *env_L;
+
+	env_L = sr_lua_env_get();
 
 	pvn.s = (char*)lua_tostring(L, -1);
-	if(pvn.s==NULL || _sr_L_env.msg==NULL)
+	if(pvn.s==NULL || env_L->msg==NULL)
 		return 0;
 
 	pvn.len = strlen(pvn.s);
@@ -265,7 +287,7 @@ static int lua_sr_pv_get (lua_State *L)
 		return 0;
 	}
 	memset(&val, 0, sizeof(pv_value_t));
-	if(pv_get_spec_value(_sr_L_env.msg, &pvs, &val) != 0)
+	if(pv_get_spec_value(env_L->msg, &pvs, &val) != 0)
 	{
 		LM_ERR("unable to get pv value for [%s]\n", pvn.s);
 		return 0;
@@ -283,15 +305,21 @@ static int lua_sr_pv_get (lua_State *L)
 	return 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;
+
+	env_L = sr_lua_env_get();
 
 	if(lua_gettop(L)<2)
 	{
-		LM_ERR("to few parameters [%d]\n",lua_gettop(L));
+		LM_ERR("to few parameters [%d]\n", lua_gettop(L));
 		return 0;
 	}
 	if(!lua_isnumber(L, -1))
@@ -304,7 +332,7 @@ static int lua_sr_pv_seti (lua_State *L)
 	val.flags |= PV_TYPE_INT|PV_VAL_INT;
 	
 	pvn.s = (char*)lua_tostring(L, -2);
-	if(pvn.s==NULL || _sr_L_env.msg==NULL)
+	if(pvn.s==NULL || env_L->msg==NULL)
 		return 0;
 
 	pvn.len = strlen(pvn.s);
@@ -314,7 +342,7 @@ static int lua_sr_pv_seti (lua_State *L)
 		LM_ERR("unable to parse pv [%s]\n", pvn.s);
 		return 0;
 	}
-	if(pv_set_spec_value(_sr_L_env.msg, &pvs, 0, &val)<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;
@@ -323,11 +351,17 @@ static int lua_sr_pv_seti (lua_State *L)
 	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;
+
+	env_L = sr_lua_env_get();
 
 	if(lua_gettop(L)<2)
 	{
@@ -340,7 +374,7 @@ static int lua_sr_pv_sets (lua_State *L)
 	val.flags |= PV_VAL_STR;
 	
 	pvn.s = (char*)lua_tostring(L, -2);
-	if(pvn.s==NULL || _sr_L_env.msg==NULL)
+	if(pvn.s==NULL || env_L->msg==NULL)
 		return 0;
 
 	pvn.len = strlen(pvn.s);
@@ -350,7 +384,7 @@ static int lua_sr_pv_sets (lua_State *L)
 		LM_ERR("unable to parse pv [%s]\n", pvn.s);
 		return 0;
 	}
-	if(pv_set_spec_value(_sr_L_env.msg, &pvs, 0, &val)<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;
@@ -359,14 +393,20 @@ static int lua_sr_pv_sets (lua_State *L)
 	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;
+
+	env_L = sr_lua_env_get();
 
 	pvn.s = (char*)lua_tostring(L, -1);
-	if(pvn.s==NULL || _sr_L_env.msg==NULL)
+	if(pvn.s==NULL || env_L->msg==NULL)
 		return 0;
 
 	pvn.len = strlen(pvn.s);
@@ -378,7 +418,7 @@ static int lua_sr_pv_unset (lua_State *L)
 	}
 	memset(&val, 0, sizeof(pv_value_t));
 	val.flags |= PV_VAL_NULL;
-	if(pv_set_spec_value(_sr_L_env.msg, &pvs, 0, &val)<0)
+	if(pv_set_spec_value(env_L->msg, &pvs, 0, &val)<0)
 	{
 		LM_ERR("unable to unset pv [%s]\n", pvn.s);
 		return 0;
@@ -387,14 +427,20 @@ static int lua_sr_pv_unset (lua_State *L)
 	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;
+
+	env_L = sr_lua_env_get();
 
 	pvn.s = (char*)lua_tostring(L, -1);
-	if(pvn.s==NULL || _sr_L_env.msg==NULL)
+	if(pvn.s==NULL || env_L->msg==NULL)
 		return 0;
 
 	pvn.len = strlen(pvn.s);
@@ -405,7 +451,7 @@ static int lua_sr_pv_is_null (lua_State *L)
 		return 0;
 	}
 	memset(&val, 0, sizeof(pv_value_t));
-	if(pv_get_spec_value(_sr_L_env.msg, &pvs, &val) != 0)
+	if(pv_get_spec_value(env_L->msg, &pvs, &val) != 0)
 	{
 		LM_ERR("unable to get pv value for [%s]\n", pvn.s);
 		return 0;
@@ -419,6 +465,9 @@ static int lua_sr_pv_is_null (lua_State *L)
 	return 1;
 }
 
+/**
+ *
+ */
 static const luaL_reg _sr_pv_Map [] = {
 	{"get",      lua_sr_pv_get},
 	{"seti",     lua_sr_pv_seti},
@@ -428,230 +477,14 @@ static const luaL_reg _sr_pv_Map [] = {
 	{NULL, NULL}
 };
 
-void lua_sr_openlibs(lua_State *L)
+/**
+ *
+ */
+void lua_sr_core_openlibs(lua_State *L)
 {
 	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);
 }
 
-int sr_lua_load_script(char *script)
-{
-	sr_lua_load_t *li;
-
-	li = (sr_lua_load_t*)pkg_malloc(sizeof(sr_lua_load_t));
-	if(li==NULL)
-	{
-		LM_ERR("no more pkg\n");
-		return -1;
-	}
-	memset(li, 0, sizeof(sr_lua_load_t));
-	li->script = script;
-	li->next = _sr_lua_load_list;
-	_sr_lua_load_list = li;
-	return 0;
-}
-
-
-int lua_sr_init_mod(void)
-{
-	memset(&_sr_L_env, 0, sizeof(sr_lua_env_t));
-	return 0;
-}
-
-int lua_sr_init_child(void)
-{
-	sr_lua_load_t *li;
-	int ret;
-	char *txt;
-	struct stat sbuf;
-
-	memset(&_sr_L_env, 0, sizeof(sr_lua_env_t));
-	_sr_L_env.L = lua_open();
-	if(_sr_L_env.L==NULL)
-	{
-		LM_ERR("cannot open lua\n");
-		return -1;
-	}
-	luaL_openlibs(_sr_L_env.L);
-	lua_sr_openlibs(_sr_L_env.L);
-
-	/* set SR lib version */
-	lua_pushstring(_sr_L_env.L, "SRVERSION");
-	lua_pushstring(_sr_L_env.L, SRVERSION);
-	lua_settable(_sr_L_env.L, LUA_GLOBALSINDEX);
-
-	if(_sr_lua_load_list != NULL)
-	{
-		_sr_L_env.LL = lua_open();
-		if(_sr_L_env.LL==NULL)
-		{
-			LM_ERR("cannot open lua loading state\n");
-			return -1;
-		}
-		luaL_openlibs(_sr_L_env.LL);
-		lua_sr_openlibs(_sr_L_env.LL);
-
-		/* set SR lib version */
-		lua_pushstring(_sr_L_env.LL, "SRVERSION");
-		lua_pushstring(_sr_L_env.LL, SRVERSION);
-		lua_settable(_sr_L_env.LL, LUA_GLOBALSINDEX);
-
-		li = _sr_lua_load_list;
-		while(li)
-		{
-			if(stat(li->script, &sbuf)!=0)
-			{
-				/* file does not exist */
-				LM_ERR("cannot find script: %s (wrong path?)\n",
-						li->script);
-				lua_sr_destroy();
-				return -1;
-			}
- 			ret = luaL_loadfile(_sr_L_env.LL, (const char*)li->script);
-			if(ret!=0)
-			{
-				LM_ERR("failed to load Lua script: %s (err: %d)\n",
-						li->script, ret);
-				txt = (char*)lua_tostring(_sr_L_env.LL, -1);
-				LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
-				lua_pop(_sr_L_env.LL, 1);
-				lua_sr_destroy();
-				return -1;
-			}
-			ret = lua_pcall(_sr_L_env.LL, 0, 0, 0);
-			if(ret!=0)
-			{
-				LM_ERR("failed to init Lua script: %s (err: %d)\n",
-						li->script, ret);
-				txt = (char*)lua_tostring(_sr_L_env.LL, -1);
-				LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
-				lua_pop(_sr_L_env.LL, 1);
-				lua_sr_destroy();
-				return -1;
-			}
-			li = li->next;
-		}
-	}
-	LM_DBG("Lua initialized!\n");
-	return 0;
-}
-
-void lua_sr_destroy(void)
-{
-	if(_sr_L_env.L!=NULL)
-	{
-		lua_close(_sr_L_env.L);
-		_sr_L_env.L = NULL;
-	}
-	if(_sr_L_env.LL!=NULL)
-	{
-		lua_close(_sr_L_env.LL);
-		_sr_L_env.LL = NULL;
-	}
-	memset(&_sr_L_env, 0, sizeof(sr_lua_env_t));
-}
-
-int lua_sr_initialized(void)
-{
-	if(_sr_L_env.L==NULL)
-		return 0;
-
-	return 1;
-}
-
-int app_lua_dostring(struct sip_msg *msg, char *script)
-{
-	int ret;
-	char *txt;
-
-	LM_DBG("executing Lua string: [[%s]]\n", script);
-	LM_DBG("lua top index is: %d\n", lua_gettop(_sr_L_env.L));
-	_sr_L_env.msg = msg;
-	ret = luaL_dostring(_sr_L_env.L, script);
-	if(ret!=0)
-	{
-		txt = (char*)lua_tostring(_sr_L_env.L, -1);
-		LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
-		lua_pop (_sr_L_env.L, 1);
-	}
-	_sr_L_env.msg = 0;
-	return (ret==0)?1:-1;
-}
-
-int app_lua_dofile(struct sip_msg *msg, char *script)
-{
-	int ret;
-	char *txt;
-
-	LM_DBG("executing Lua file: [[%s]]\n", script);
-	LM_DBG("lua top index is: %d\n", lua_gettop(_sr_L_env.L));
-	_sr_L_env.msg = msg;
-	ret = luaL_dofile(_sr_L_env.L, script);
-	if(ret!=0)
-	{
-		txt = (char*)lua_tostring(_sr_L_env.L, -1);
-		LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
-		lua_pop(_sr_L_env.L, 1);
-	}
-	_sr_L_env.msg = 0;
-	return (ret==0)?1:-1;
-}
-
-int app_lua_run(struct sip_msg *msg, char *func, char *p1, char *p2,
-		char *p3)
-{
-	int n;
-	int ret;
-	char *txt;
-
-	if(_sr_L_env.LL==NULL)
-	{
-		LM_ERR("lua loading state not initialized (call: %s)\n", func);
-		return -1;
-	}
-
-	LM_DBG("executing Lua function: [[%s]]\n", func);
-	LM_DBG("lua top index is: %d\n", lua_gettop(_sr_L_env.LL));
-	lua_getglobal(_sr_L_env.LL, func);
-	if(!lua_isfunction(_sr_L_env.LL, -1))
-	{
-		LM_ERR("no such function [%s] in lua scripts\n", func);
-		LM_ERR("top stack type [%d - %s]\n",
-				lua_type(_sr_L_env.LL, -1),
-				lua_typename(_sr_L_env.LL,lua_type(_sr_L_env.LL, -1)));
-		txt = (char*)lua_tostring(_sr_L_env.LL, -1);
-		LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
-		return -1;
-	}
-	n = 0;
-	if(p1!=NULL)
-	{
-		lua_pushstring(_sr_L_env.LL, p1);
-		n++;
-		if(p2!=NULL)
-		{
-			lua_pushstring(_sr_L_env.LL, p2);
-			n++;
-			if(p3!=NULL)
-			{
-				lua_pushstring(_sr_L_env.LL, p3);
-				n++;
-			}
-		}
-	}
-	_sr_L_env.msg = msg;
-	ret = lua_pcall(_sr_L_env.LL, n, 0, 0);
-	_sr_L_env.msg = 0;
-	if(ret!=0)
-	{
-		LM_ERR("error executing: %s (err: %d)\n", func, ret);
-		txt = (char*)lua_tostring(_sr_L_env.LL, -1);
-		LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
-		lua_pop(_sr_L_env.LL, 1);
-		return -1;
-	}
-
-	return 1;
-}
 

+ 2 - 12
modules/app_lua/app_lua_sr.h

@@ -24,19 +24,9 @@
 #ifndef _APP_LUA_SR_H_
 #define _APP_LUA_SR_H_
 
-#include "../../parser/msg_parser.h"
+#include <lua.h>
 
-int lua_sr_initialized(void);
-int lua_sr_init_mod(void);
-int lua_sr_init_child(void);
-void lua_sr_destroy(void);
-
-int sr_lua_load_script(char *script);
-
-int app_lua_dostring(struct sip_msg *msg, char *script);
-int app_lua_dofile(struct sip_msg *msg, char *script);
-int app_lua_run(struct sip_msg *msg, char *func, char *p1, char *p2,
-		char *p3);
+void lua_sr_core_openlibs(lua_State *L);
 
 #endif
 

+ 34 - 1
modules/app_lua/doc/app_lua_admin.xml

@@ -96,7 +96,40 @@
 		<title>Set <varname>load</varname> parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lua", "lua", "/usr/local/etc/kamailio/lua/myscript.lua")
+modparam("lua", "load", "/usr/local/etc/kamailio/lua/myscript.lua")
+...
+</programlisting>
+	    </example>
+	</section>
+
+	<section>
+	    <title><varname>register</varname> (string)</title>
+	    <para>
+			Use this function to register optional SIP Router submodules
+			to Lua. Available submodules are:
+	    </para>
+	    	<itemizedlist>
+		    <listitem>
+			<para>
+				<emphasis>sl</emphasis> - register functions from sl module
+				under 'sr.sl'.
+			</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("lua", "register", "sr")
 ...
 </programlisting>
 	    </example>