From bccba53bcff743512c4c70265cad46fc034288fc Mon Sep 17 00:00:00 2001 From: Matthew Nicholson Date: Fri, 6 May 2011 18:04:23 +0000 Subject: Detect Goto in pbx_lua. This code will actually detect any dialplan jump from any application that calls ast_explicit_goto(). This change is only being done in trunk as it may change the way some dialplans execute. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@317721 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- pbx/pbx_lua.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'pbx/pbx_lua.c') diff --git a/pbx/pbx_lua.c b/pbx/pbx_lua.c index b181b3b78..61f93ab63 100644 --- a/pbx/pbx_lua.c +++ b/pbx/pbx_lua.c @@ -52,6 +52,11 @@ static char *registrar = "pbx_lua"; #define LUA_EXT_DATA_SIZE 256 #define LUA_BUF_SIZE 4096 +/* This value is used by the lua engine to signal that a Goto or dialplan jump + * was detected. Ensure this value does not conflict with any values dialplan + * applications might return */ +#define LUA_GOTO_DETECTED 5 + static char *lua_read_extensions_file(lua_State *L, long *size); static int lua_load_extensions(lua_State *L, struct ast_channel *chan); static int lua_reload_extensions(lua_State *L); @@ -84,6 +89,7 @@ static void lua_create_variable_metatable(lua_State *L); static void lua_create_application_metatable(lua_State *L); static void lua_create_autoservice_functions(lua_State *L); static void lua_create_hangup_function(lua_State *L); +static void lua_detect_goto(lua_State *L); static void lua_state_destroy(void *data); static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan); @@ -254,9 +260,72 @@ static int lua_pbx_exec(lua_State *L) lua_pushinteger(L, res); return lua_error(L); } + + lua_detect_goto(L); + return 0; } +/*! + * \brief Detect if a Goto or other dialplan jump has been executed and return + * control to the pbx engine. + */ +static void lua_detect_goto(lua_State *L) +{ + struct ast_channel *chan; + + lua_getfield(L, LUA_REGISTRYINDEX, "channel"); + chan = lua_touserdata(L, -1); + lua_pop(L, 1); + + /* check context */ + lua_getfield(L, LUA_REGISTRYINDEX, "context"); + lua_pushstring(L, chan->context); + if (!lua_equal(L, -1, -2)) { + lua_pushliteral(L, "context"); + goto e_goto_detected; + } + lua_pop(L, 2); + + /* check exten */ + lua_getfield(L, LUA_REGISTRYINDEX, "exten"); + lua_pushstring(L, chan->exten); + if (!lua_equal(L, -1, -2)) { + lua_pushliteral(L, "exten"); + goto e_goto_detected; + } + lua_pop(L, 2); + + /* check priority */ + lua_getfield(L, LUA_REGISTRYINDEX, "priority"); + lua_pushinteger(L, chan->priority); + if (!lua_equal(L, -1, -2)) { + lua_pushliteral(L, "priority"); + goto e_goto_detected; + } + lua_pop(L, 2); + return; + +e_goto_detected: + /* format our debug message */ + lua_insert(L, -3); + + lua_pushliteral(L, " changed from "); + lua_insert(L, -3); + + lua_pushliteral(L, " to "); + lua_insert(L, -2); + + lua_concat(L, 5); + + ast_debug(2, "Goto detected: %s\n", lua_tostring(L, -1)); + lua_pop(L, 1); + + /* let the lua engine know it needs to return control to the pbx */ + lua_pushinteger(L, LUA_GOTO_DETECTED); + lua_error(L); +} + /*! * \brief [lua_CFunction] Used to get the value of a variable or dialplan * function (for access from lua, don't call directly) @@ -1372,6 +1441,10 @@ static int exec(struct ast_channel *chan, const char *context, const char *exten res = -1; if (lua_isnumber(L, -1)) { res = lua_tointeger(L, -1); + + if (res == LUA_GOTO_DETECTED) { + res = 0; + } } else if (lua_isstring(L, -1)) { const char *error = lua_tostring(L, -1); ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error); -- cgit v1.2.3