#include "asterisk.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/term.h"
#include "asterisk/paths.h"
#include "asterisk/hashtab.h"
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
Go to the source code of this file.
Defines | |
#define | LUA_BUF_SIZE 4096 |
#define | LUA_EXT_DATA_SIZE 256 |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
static int | exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
static int | exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
static int | load_module (void) |
static int | load_or_reload_lua_stuff (void) |
static int | lua_autoservice_start (lua_State *L) |
[lua_CFunction] Tell pbx_lua to maintain an autoservice on this channel (for access from lua, don't call directly) | |
static int | lua_autoservice_status (lua_State *L) |
[lua_CFunction] Get the status of the autoservice flag (for access from lua, don't call directly) | |
static int | lua_autoservice_stop (lua_State *L) |
[lua_CFunction] Tell pbx_lua to stop maintaning an autoservice on this channel (for access from lua, don't call directly) | |
static int | lua_check_hangup (lua_State *L) |
[lua_CFunction] Check if this channel has been hungup or not (for access from lua, don't call directly) | |
static void | lua_create_app_table (lua_State *L) |
Create the global 'app' table for executing applications. | |
static void | lua_create_application_metatable (lua_State *L) |
Create the 'application' metatable, used to execute asterisk applications from lua. | |
static void | lua_create_autoservice_functions (lua_State *L) |
Create the autoservice functions. | |
static void | lua_create_channel_table (lua_State *L) |
Create the global 'channel' table for accesing channel variables. | |
static void | lua_create_hangup_function (lua_State *L) |
Create the hangup check function. | |
static void | lua_create_variable_metatable (lua_State *L) |
Create the 'variable' metatable, used to retrieve channel variables. | |
static int | lua_error_function (lua_State *L) |
[lua_CFunction] Handle lua errors (for access from lua, don't call directly) | |
static int | lua_extension_cmp (lua_State *L) |
[lua_CFunction] Compare two extensions (for access from lua, don't call directly) | |
static int | lua_find_extension (lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func) |
Locate an extensions and optionally push the matching function on the stack. | |
static void | lua_free_extensions () |
Free the internal extensions buffer. | |
static int | lua_func_read (lua_State *L) |
[lua_CFunction] Create a 'variable' object for accessing a dialplan function (for access from lua, don't call directly) | |
static lua_State * | lua_get_state (struct ast_channel *chan) |
Get the lua_State for this channel. | |
static int | lua_get_variable (lua_State *L) |
[lua_CFunction] Return a lua 'variable' object (for access from lua, don't call directly) | |
static int | lua_get_variable_value (lua_State *L) |
[lua_CFunction] Used to get the value of a variable or dialplan function (for access from lua, don't call directly) | |
static int | lua_load_extensions (lua_State *L, struct ast_channel *chan) |
Load the extensions.lua file from the internal buffer. | |
static int | lua_pbx_exec (lua_State *L) |
[lua_CFunction] This function is part of the 'application' metatable and is used to execute applications similar to pbx_exec() (for access from lua, don't call directly) | |
static int | lua_pbx_findapp (lua_State *L) |
[lua_CFunction] Find an app and return it in a lua table (for access from lua, don't call directly) | |
static void | lua_push_variable_table (lua_State *L, const char *name) |
Push a 'variable' table on the stack for access the channel variable with the given name. | |
static char * | lua_read_extensions_file (lua_State *L, long *size) |
Load the extensions.lua file in to a buffer and execute the file. | |
static int | lua_register_switches (lua_State *L) |
Register dialplan switches for our pbx_lua contexs. | |
static int | lua_reload_extensions (lua_State *L) |
Reload the extensions file and update the internal buffers if it loads correctly. | |
static int | lua_set_variable (lua_State *L) |
[lua_CFunction] Set the value of a channel variable or dialplan function (for access from lua, don't call directly) | |
static int | lua_set_variable_value (lua_State *L) |
[lua_CFunction] Used to set the value of a variable or dialplan function (for access from lua, don't call directly) | |
static int | lua_sort_extensions (lua_State *L) |
Store the sort order of each context. | |
void | lua_state_destroy (void *data) |
The destructor for lua_datastore. | |
static void | lua_update_registry (lua_State *L, const char *context, const char *exten, int priority) |
Update the lua registry with the given context, exten, and priority. | |
static int | matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
static int | reload (void) |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Lua PBX Switch" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static char * | config = "extensions.lua" |
char * | config_file_data = NULL |
static ast_mutex_t | config_file_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
long | config_file_size = 0 |
static struct ast_context * | local_contexts = NULL |
static struct ast_hashtab * | local_table = NULL |
static struct ast_datastore_info | lua_datastore |
static struct ast_switch | lua_switch |
static char * | registrar = "pbx_lua" |
Definition in file pbx_lua.c.
#define LUA_BUF_SIZE 4096 |
Definition at line 59 of file pbx_lua.c.
Referenced by lua_get_variable(), and lua_get_variable_value().
#define LUA_EXT_DATA_SIZE 256 |
static int canmatch | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Definition at line 1167 of file pbx_lua.c.
References ast_log(), ast_module_user_add, ast_module_user_remove, chan, LOG_ERROR, lua_find_extension(), and lua_get_state().
Referenced by lua_find_extension().
01168 { 01169 int res; 01170 lua_State *L; 01171 struct ast_module_user *u = ast_module_user_add(chan); 01172 if (!u) { 01173 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01174 return 0; 01175 } 01176 01177 L = lua_get_state(chan); 01178 if (!L) { 01179 ast_module_user_remove(u); 01180 return 0; 01181 } 01182 01183 res = lua_find_extension(L, context, exten, priority, &canmatch, 0); 01184 01185 if (!chan) lua_close(L); 01186 ast_module_user_remove(u); 01187 return res; 01188 }
static int exec | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Definition at line 1214 of file pbx_lua.c.
References ast_log(), ast_module_user_add, ast_module_user_remove, chan, exists(), LOG_ERROR, lua_error_function(), lua_find_extension(), lua_get_state(), and lua_update_registry().
01215 { 01216 int res, error_func; 01217 lua_State *L; 01218 struct ast_module_user *u = ast_module_user_add(chan); 01219 if (!u) { 01220 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01221 return -1; 01222 } 01223 01224 L = lua_get_state(chan); 01225 if (!L) { 01226 ast_module_user_remove(u); 01227 return -1; 01228 } 01229 01230 lua_pushcfunction(L, &lua_error_function); 01231 error_func = lua_gettop(L); 01232 01233 /* push the extension function onto the stack */ 01234 if (!lua_find_extension(L, context, exten, priority, &exists, 1)) { 01235 lua_pop(L, 1); /* pop the debug function */ 01236 ast_log(LOG_ERROR, "Could not find extension %s in context %s\n", exten, context); 01237 if (!chan) lua_close(L); 01238 ast_module_user_remove(u); 01239 return -1; 01240 } 01241 01242 lua_update_registry(L, context, exten, priority); 01243 01244 lua_pushstring(L, context); 01245 lua_pushstring(L, exten); 01246 01247 res = lua_pcall(L, 2, 0, error_func); 01248 if (res) { 01249 if (res == LUA_ERRRUN) { 01250 res = -1; 01251 if (lua_isnumber(L, -1)) { 01252 res = lua_tointeger(L, -1); 01253 } else if (lua_isstring(L, -1)) { 01254 const char *error = lua_tostring(L, -1); 01255 ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error); 01256 } 01257 } else if (res == LUA_ERRERR) { 01258 res = -1; 01259 ast_log(LOG_ERROR, "Error in the lua error handler (this is probably a bug in pbx_lua)\n"); 01260 } else if (res == LUA_ERRMEM) { 01261 res = -1; 01262 ast_log(LOG_ERROR, "Memory allocation error\n"); 01263 } 01264 lua_pop(L, 1); 01265 } 01266 lua_remove(L, error_func); 01267 if (!chan) lua_close(L); 01268 ast_module_user_remove(u); 01269 return res; 01270 }
static int exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Definition at line 1144 of file pbx_lua.c.
References ast_log(), ast_module_user_add, ast_module_user_remove, chan, exists(), LOG_ERROR, lua_find_extension(), and lua_get_state().
01145 { 01146 int res; 01147 lua_State *L; 01148 struct ast_module_user *u = ast_module_user_add(chan); 01149 if (!u) { 01150 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01151 return 0; 01152 } 01153 01154 L = lua_get_state(chan); 01155 if (!L) { 01156 ast_module_user_remove(u); 01157 return 0; 01158 } 01159 01160 res = lua_find_extension(L, context, exten, priority, &exists, 0); 01161 01162 if (!chan) lua_close(L); 01163 ast_module_user_remove(u); 01164 return res; 01165 }
static int load_module | ( | void | ) | [static] |
Definition at line 1461 of file pbx_lua.c.
References ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_switch(), load_or_reload_lua_stuff(), LOG_ERROR, and lua_switch.
01462 { 01463 int res; 01464 01465 if ((res = load_or_reload_lua_stuff())) 01466 return res; 01467 01468 if (ast_register_switch(&lua_switch)) { 01469 ast_log(LOG_ERROR, "Unable to register LUA PBX switch\n"); 01470 return AST_MODULE_LOAD_DECLINE; 01471 } 01472 01473 return AST_MODULE_LOAD_SUCCESS; 01474 }
static int load_or_reload_lua_stuff | ( | void | ) | [static] |
Definition at line 1428 of file pbx_lua.c.
References ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, LOG_ERROR, and lua_reload_extensions().
Referenced by load_module(), and reload().
01429 { 01430 int res = AST_MODULE_LOAD_SUCCESS; 01431 01432 lua_State *L = luaL_newstate(); 01433 if (!L) { 01434 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n"); 01435 return AST_MODULE_LOAD_DECLINE; 01436 } 01437 01438 if (lua_reload_extensions(L)) { 01439 const char *error = lua_tostring(L, -1); 01440 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error); 01441 res = AST_MODULE_LOAD_DECLINE; 01442 } 01443 01444 lua_close(L); 01445 return res; 01446 }
static int lua_autoservice_start | ( | lua_State * | L | ) | [static] |
[lua_CFunction] Tell pbx_lua to maintain an autoservice on this channel (for access from lua, don't call directly)
L | the lua_State to use |
Definition at line 643 of file pbx_lua.c.
References ast_autoservice_start(), and chan.
Referenced by lua_create_autoservice_functions().
00644 { 00645 struct ast_channel *chan; 00646 int res; 00647 00648 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00649 chan = lua_touserdata(L, -1); 00650 lua_pop(L, 1); 00651 00652 res = ast_autoservice_start(chan); 00653 00654 lua_pushboolean(L, !res); 00655 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice"); 00656 00657 lua_pushboolean(L, !res); 00658 return 1; 00659 }
static int lua_autoservice_status | ( | lua_State * | L | ) | [static] |
[lua_CFunction] Get the status of the autoservice flag (for access from lua, don't call directly)
L | the lua_State to use |
Definition at line 701 of file pbx_lua.c.
Referenced by lua_create_autoservice_functions().
static int lua_autoservice_stop | ( | lua_State * | L | ) | [static] |
[lua_CFunction] Tell pbx_lua to stop maintaning an autoservice on this channel (for access from lua, don't call directly)
L | the lua_State to use |
Definition at line 674 of file pbx_lua.c.
References ast_autoservice_stop(), and chan.
Referenced by lua_create_autoservice_functions().
00675 { 00676 struct ast_channel *chan; 00677 int res; 00678 00679 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00680 chan = lua_touserdata(L, -1); 00681 lua_pop(L, 1); 00682 00683 res = ast_autoservice_stop(chan); 00684 00685 lua_pushboolean(L, 0); 00686 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice"); 00687 00688 lua_pushboolean(L, !res); 00689 return 1; 00690 }
static int lua_check_hangup | ( | lua_State * | L | ) | [static] |
[lua_CFunction] Check if this channel has been hungup or not (for access from lua, don't call directly)
L | the lua_State to use |
Definition at line 715 of file pbx_lua.c.
References ast_check_hangup(), and chan.
Referenced by lua_create_hangup_function().
00716 { 00717 struct ast_channel *chan; 00718 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00719 chan = lua_touserdata(L, -1); 00720 lua_pop(L, 1); 00721 00722 lua_pushboolean(L, ast_check_hangup(chan)); 00723 return 1; 00724 }
static void lua_create_app_table | ( | lua_State * | L | ) | [static] |
Create the global 'app' table for executing applications.
L | the lua_State to use |
Definition at line 404 of file pbx_lua.c.
References lua_pbx_findapp().
Referenced by lua_load_extensions().
00405 { 00406 lua_newtable(L); 00407 luaL_newmetatable(L, "app"); 00408 00409 lua_pushstring(L, "__index"); 00410 lua_pushcfunction(L, &lua_pbx_findapp); 00411 lua_settable(L, -3); 00412 00413 lua_setmetatable(L, -2); 00414 lua_setglobal(L, "app"); 00415 }
static void lua_create_application_metatable | ( | lua_State * | L | ) | [static] |
Create the 'application' metatable, used to execute asterisk applications from lua.
L | the lua_State to use |
Definition at line 461 of file pbx_lua.c.
References lua_pbx_exec().
Referenced by lua_load_extensions().
00462 { 00463 luaL_newmetatable(L, "application"); 00464 00465 lua_pushstring(L, "__call"); 00466 lua_pushcfunction(L, &lua_pbx_exec); 00467 lua_settable(L, -3); 00468 00469 lua_pop(L, 1); 00470 }
static void lua_create_autoservice_functions | ( | lua_State * | L | ) | [static] |
Create the autoservice functions.
L | the lua_State to use |
Definition at line 477 of file pbx_lua.c.
References lua_autoservice_start(), lua_autoservice_status(), and lua_autoservice_stop().
Referenced by lua_load_extensions().
00478 { 00479 lua_pushcfunction(L, &lua_autoservice_start); 00480 lua_setglobal(L, "autoservice_start"); 00481 00482 lua_pushcfunction(L, &lua_autoservice_stop); 00483 lua_setglobal(L, "autoservice_stop"); 00484 00485 lua_pushcfunction(L, &lua_autoservice_status); 00486 lua_setglobal(L, "autoservice_status"); 00487 00488 lua_pushboolean(L, 0); 00489 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice"); 00490 }
static void lua_create_channel_table | ( | lua_State * | L | ) | [static] |
Create the global 'channel' table for accesing channel variables.
L | the lua_State to use |
Definition at line 422 of file pbx_lua.c.
References lua_get_variable(), and lua_set_variable().
Referenced by lua_load_extensions().
00423 { 00424 lua_newtable(L); 00425 luaL_newmetatable(L, "channel_data"); 00426 00427 lua_pushstring(L, "__index"); 00428 lua_pushcfunction(L, &lua_get_variable); 00429 lua_settable(L, -3); 00430 00431 lua_pushstring(L, "__newindex"); 00432 lua_pushcfunction(L, &lua_set_variable); 00433 lua_settable(L, -3); 00434 00435 lua_setmetatable(L, -2); 00436 lua_setglobal(L, "channel"); 00437 }
static void lua_create_hangup_function | ( | lua_State * | L | ) | [static] |
Create the hangup check function.
L | the lua_State to use |
Definition at line 497 of file pbx_lua.c.
References lua_check_hangup().
Referenced by lua_load_extensions().
00498 { 00499 lua_pushcfunction(L, &lua_check_hangup); 00500 lua_setglobal(L, "check_hangup"); 00501 }
static void lua_create_variable_metatable | ( | lua_State * | L | ) | [static] |
Create the 'variable' metatable, used to retrieve channel variables.
L | the lua_State to use |
Definition at line 444 of file pbx_lua.c.
References lua_func_read().
Referenced by lua_load_extensions().
00445 { 00446 luaL_newmetatable(L, "variable"); 00447 00448 lua_pushstring(L, "__call"); 00449 lua_pushcfunction(L, &lua_func_read); 00450 lua_settable(L, -3); 00451 00452 lua_pop(L, 1); 00453 }
static int lua_error_function | ( | lua_State * | L | ) | [static] |
[lua_CFunction] Handle lua errors (for access from lua, don't call directly)
L | the lua_State to use |
Definition at line 732 of file pbx_lua.c.
Referenced by exec().
00733 { 00734 int message_index; 00735 00736 /* pass number arguments right through back to asterisk*/ 00737 if (lua_isnumber(L, -1)) { 00738 return 1; 00739 } 00740 00741 /* if we are here then we have a string error message, let's attach a 00742 * backtrace to it */ 00743 message_index = lua_gettop(L); 00744 00745 lua_getglobal(L, "debug"); 00746 lua_getfield(L, -1, "traceback"); 00747 lua_remove(L, -2); /* remove the 'debug' table */ 00748 00749 lua_pushvalue(L, message_index); 00750 lua_remove(L, message_index); 00751 00752 lua_pushnumber(L, 2); 00753 00754 lua_call(L, 2, 1); 00755 00756 return 1; 00757 }
static int lua_extension_cmp | ( | lua_State * | L | ) | [static] |
[lua_CFunction] Compare two extensions (for access from lua, don't call directly)
This function returns true if the first extension passed should match after the second. It behaves like the '<' operator.
Definition at line 903 of file pbx_lua.c.
References ast_extension_cmp().
Referenced by lua_sort_extensions().
00904 { 00905 const char *a = luaL_checkstring(L, -2); 00906 const char *b = luaL_checkstring(L, -1); 00907 00908 if (ast_extension_cmp(a, b) == -1) 00909 lua_pushboolean(L, 1); 00910 else 00911 lua_pushboolean(L, 0); 00912 00913 return 1; 00914 }
static int lua_find_extension | ( | lua_State * | L, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
ast_switch_f * | func, | |||
int | push_func | |||
) | [static] |
Locate an extensions and optionally push the matching function on the stack.
L | the lua_State to use | |
context | the context to look in | |
exten | the extension to look up | |
priority | the priority to check, '1' is the only valid priority | |
func | the calling func, used to adjust matching behavior between, match, canmatch, and matchmore | |
push_func | whether or not to push the lua function for the given extension onto the stack |
Definition at line 1285 of file pbx_lua.c.
References ast_debug, ast_extension_close(), ast_extension_match(), ast_log(), canmatch(), E_CANMATCH, E_MATCHMORE, LOG_ERROR, match(), and matchmore().
Referenced by canmatch(), exec(), exists(), and matchmore().
01286 { 01287 int context_table, context_order_table, i; 01288 01289 ast_debug(2, "Looking up %s@%s:%i\n", exten, context, priority); 01290 if (priority != 1) 01291 return 0; 01292 01293 /* load the 'extensions' table */ 01294 lua_getglobal(L, "extensions"); 01295 if (lua_isnil(L, -1)) { 01296 ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n"); 01297 lua_pop(L, 1); 01298 return 0; 01299 } 01300 01301 /* load the given context */ 01302 lua_getfield(L, -1, context); 01303 if (lua_isnil(L, -1)) { 01304 lua_pop(L, 2); 01305 return 0; 01306 } 01307 01308 /* remove the extensions table */ 01309 lua_remove(L, -2); 01310 01311 context_table = lua_gettop(L); 01312 01313 /* load the extensions order table for this context */ 01314 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order"); 01315 lua_getfield(L, -1, context); 01316 01317 lua_remove(L, -2); /* remove the extensions order table */ 01318 01319 context_order_table = lua_gettop(L); 01320 01321 /* step through the extensions looking for a match */ 01322 for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) { 01323 int e_index, e_index_copy, match = 0; 01324 const char *e; 01325 01326 lua_pushinteger(L, i); 01327 lua_gettable(L, context_order_table); 01328 e_index = lua_gettop(L); 01329 01330 /* copy the key at the top of the stack for use later */ 01331 lua_pushvalue(L, -1); 01332 e_index_copy = lua_gettop(L); 01333 01334 if (!(e = lua_tostring(L, e_index_copy))) { 01335 lua_pop(L, 2); 01336 continue; 01337 } 01338 01339 /* make sure this is not the 'include' extension */ 01340 if (!strcasecmp(e, "include")) { 01341 lua_pop(L, 2); 01342 continue; 01343 } 01344 01345 if (func == &matchmore) 01346 match = ast_extension_close(e, exten, E_MATCHMORE); 01347 else if (func == &canmatch) 01348 match = ast_extension_close(e, exten, E_CANMATCH); 01349 else 01350 match = ast_extension_match(e, exten); 01351 01352 /* the extension matching functions return 0 on fail, 1 on 01353 * match, 2 on earlymatch */ 01354 01355 if (!match) { 01356 /* pop the copy and the extension */ 01357 lua_pop(L, 2); 01358 continue; /* keep trying */ 01359 } 01360 01361 if (func == &matchmore && match == 2) { 01362 /* We match an extension ending in '!'. The decision in 01363 * this case is final and counts as no match. */ 01364 lua_pop(L, 4); 01365 return 0; 01366 } 01367 01368 /* remove the context table, the context order table, the 01369 * extension, and the extension copy (or replace the extension 01370 * with the corresponding function) */ 01371 if (push_func) { 01372 lua_pop(L, 1); /* pop the copy */ 01373 lua_gettable(L, context_table); 01374 lua_insert(L, -3); 01375 lua_pop(L, 2); 01376 } else { 01377 lua_pop(L, 4); 01378 } 01379 01380 return 1; 01381 } 01382 01383 /* load the includes for this context */ 01384 lua_getfield(L, context_table, "include"); 01385 if (lua_isnil(L, -1)) { 01386 lua_pop(L, 3); 01387 return 0; 01388 } 01389 01390 /* remove the context and the order table*/ 01391 lua_remove(L, context_order_table); 01392 lua_remove(L, context_table); 01393 01394 /* Now try any includes we have in this context */ 01395 for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { 01396 const char *c = lua_tostring(L, -1); 01397 if (!c) 01398 continue; 01399 01400 if (lua_find_extension(L, c, exten, priority, func, push_func)) { 01401 /* remove the value, the key, and the includes table 01402 * from the stack. Leave the function behind if 01403 * necessary */ 01404 01405 if (push_func) 01406 lua_insert(L, -4); 01407 01408 lua_pop(L, 3); 01409 return 1; 01410 } 01411 } 01412 01413 /* pop the includes table */ 01414 lua_pop(L, 1); 01415 return 0; 01416 }
static void lua_free_extensions | ( | void | ) | [static] |
Free the internal extensions buffer.
Definition at line 1061 of file pbx_lua.c.
References ast_free, ast_mutex_lock(), ast_mutex_unlock(), and config_file_lock.
Referenced by unload_module().
01062 { 01063 ast_mutex_lock(&config_file_lock); 01064 config_file_size = 0; 01065 ast_free(config_file_data); 01066 ast_mutex_unlock(&config_file_lock); 01067 }
static int lua_func_read | ( | lua_State * | L | ) | [static] |
[lua_CFunction] Create a 'variable' object for accessing a dialplan function (for access from lua, don't call directly)
This function is called to create a 'variable' object to access a dialplan function. It would be called in the following example as would be seen in extensions.lua.
channel.func("arg1", "arg2", "arg3")
To actually do anything with the resulting value you must use the 'get()' and 'set()' methods (the reason is the resulting value is not a value, but an object in the form of a lua table).
Definition at line 596 of file pbx_lua.c.
References ast_build_string(), ast_strdupa, LUA_EXT_DATA_SIZE, lua_push_variable_table(), and name.
Referenced by lua_create_variable_metatable().
00597 { 00598 int nargs = lua_gettop(L); 00599 char fullname[LUA_EXT_DATA_SIZE] = ""; 00600 char *fullname_next = fullname, *name; 00601 size_t fullname_left = sizeof(fullname); 00602 00603 lua_getfield(L, 1, "name"); 00604 name = ast_strdupa(lua_tostring(L, -1)); 00605 lua_pop(L, 1); 00606 00607 ast_build_string(&fullname_next, &fullname_left, "%s(", name); 00608 00609 if (nargs > 1) { 00610 int i; 00611 00612 if (!lua_isnil(L, 2)) 00613 ast_build_string(&fullname_next, &fullname_left, "%s", luaL_checkstring(L, 2)); 00614 00615 for (i = 3; i <= nargs; i++) { 00616 if (lua_isnil(L, i)) 00617 ast_build_string(&fullname_next, &fullname_left, ","); 00618 else 00619 ast_build_string(&fullname_next, &fullname_left, ",%s", luaL_checkstring(L, i)); 00620 } 00621 } 00622 00623 ast_build_string(&fullname_next, &fullname_left, ")"); 00624 00625 lua_push_variable_table(L, fullname); 00626 00627 return 1; 00628 }
static lua_State * lua_get_state | ( | struct ast_channel * | chan | ) | [static] |
Get the lua_State for this channel.
If no channel is passed then a new state is allocated. States with no channel assocatied with them should only be used for matching extensions. If the channel does not yet have a lua state associated with it, one will be created.
Definition at line 1082 of file pbx_lua.c.
References ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc, ast_datastore_free(), ast_log(), chan, ast_datastore::data, LOG_ERROR, lua_datastore, lua_load_extensions(), and ast_channel::name.
Referenced by canmatch(), exec(), exists(), and matchmore().
01083 { 01084 struct ast_datastore *datastore = NULL; 01085 lua_State *L; 01086 01087 if (!chan) { 01088 lua_State *L = luaL_newstate(); 01089 if (!L) { 01090 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n"); 01091 return NULL; 01092 } 01093 01094 if (lua_load_extensions(L, NULL)) { 01095 const char *error = lua_tostring(L, -1); 01096 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error); 01097 lua_close(L); 01098 return NULL; 01099 } 01100 return L; 01101 } else { 01102 ast_channel_lock(chan); 01103 datastore = ast_channel_datastore_find(chan, &lua_datastore, NULL); 01104 ast_channel_unlock(chan); 01105 01106 if (!datastore) { 01107 /* nothing found, allocate a new lua state */ 01108 datastore = ast_datastore_alloc(&lua_datastore, NULL); 01109 if (!datastore) { 01110 ast_log(LOG_ERROR, "Error allocation channel datastore for lua_State\n"); 01111 return NULL; 01112 } 01113 01114 datastore->data = luaL_newstate(); 01115 if (!datastore->data) { 01116 ast_datastore_free(datastore); 01117 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n"); 01118 return NULL; 01119 } 01120 01121 ast_channel_lock(chan); 01122 ast_channel_datastore_add(chan, datastore); 01123 ast_channel_unlock(chan); 01124 01125 L = datastore->data; 01126 01127 if (lua_load_extensions(L, chan)) { 01128 const char *error = lua_tostring(L, -1); 01129 ast_log(LOG_ERROR, "Error loading extensions.lua for %s: %s\n", chan->name, error); 01130 01131 ast_channel_lock(chan); 01132 ast_channel_datastore_remove(chan, datastore); 01133 ast_channel_unlock(chan); 01134 01135 ast_datastore_free(datastore); 01136 return NULL; 01137 } 01138 } 01139 01140 return datastore->data; 01141 } 01142 }
static int lua_get_variable | ( | lua_State * | L | ) | [static] |
[lua_CFunction] Return a lua 'variable' object (for access from lua, don't call directly)
This function is called to lookup a variable construct a 'variable' object. It would be called in the following example as would be seen in extensions.lua.
channel.variable
Definition at line 515 of file pbx_lua.c.
References ast_strdupa, ast_strlen_zero(), chan, LUA_BUF_SIZE, lua_push_variable_table(), name, pbx_retrieve_variable(), and ast_channel::varshead.
Referenced by lua_create_channel_table().
00516 { 00517 struct ast_channel *chan; 00518 char *name = ast_strdupa(luaL_checkstring(L, 2)); 00519 char *value = NULL; 00520 char *workspace = alloca(LUA_BUF_SIZE); 00521 workspace[0] = '\0'; 00522 00523 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00524 chan = lua_touserdata(L, -1); 00525 lua_pop(L, 1); 00526 00527 lua_push_variable_table(L, name); 00528 00529 /* if this is not a request for a dialplan funciton attempt to retrieve 00530 * the value of the variable */ 00531 if (!ast_strlen_zero(name) && name[strlen(name) - 1] != ')') { 00532 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead); 00533 } 00534 00535 if (value) { 00536 lua_pushstring(L, value); 00537 lua_setfield(L, -2, "value"); 00538 } 00539 00540 return 1; 00541 }
static int lua_get_variable_value | ( | lua_State * | L | ) | [static] |
[lua_CFunction] Used to get the value of a variable or dialplan function (for access from lua, don't call directly)
The value of the variable or function is returned. This function is the 'get()' function in the following example as would be seen in extensions.lua.
channel.variable:get()
Definition at line 260 of file pbx_lua.c.
References ast_autoservice_start(), ast_autoservice_stop(), ast_func_read(), ast_strdupa, ast_strlen_zero(), chan, LUA_BUF_SIZE, name, and pbx_retrieve_variable().
Referenced by lua_push_variable_table().
00261 { 00262 struct ast_channel *chan; 00263 char *value = NULL, *name; 00264 char *workspace = alloca(LUA_BUF_SIZE); 00265 int autoservice; 00266 00267 workspace[0] = '\0'; 00268 00269 if (!lua_istable(L, 1)) { 00270 lua_pushstring(L, "User probably used '.' instead of ':' for retrieving a channel variable value"); 00271 return lua_error(L); 00272 } 00273 00274 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00275 chan = lua_touserdata(L, -1); 00276 lua_pop(L, 1); 00277 00278 lua_getfield(L, 1, "name"); 00279 name = ast_strdupa(lua_tostring(L, -1)); 00280 lua_pop(L, 1); 00281 00282 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00283 autoservice = lua_toboolean(L, -1); 00284 lua_pop(L, 1); 00285 00286 if (autoservice) 00287 ast_autoservice_stop(chan); 00288 00289 /* if this is a dialplan function then use ast_func_read(), otherwise 00290 * use pbx_retrieve_variable() */ 00291 if (!ast_strlen_zero(name) && name[strlen(name) - 1] == ')') { 00292 value = ast_func_read(chan, name, workspace, LUA_BUF_SIZE) ? NULL : workspace; 00293 } else { 00294 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead); 00295 } 00296 00297 if (autoservice) 00298 ast_autoservice_start(chan); 00299 00300 if (value) { 00301 lua_pushstring(L, value); 00302 } else { 00303 lua_pushnil(L); 00304 } 00305 00306 return 1; 00307 }
static int lua_load_extensions | ( | lua_State * | L, | |
struct ast_channel * | chan | |||
) | [static] |
Load the extensions.lua file from the internal buffer.
L | the lua_State to use | |
chan | channel to work on |
0 | success | |
1 | failure |
Definition at line 983 of file pbx_lua.c.
References ast_mutex_lock(), ast_mutex_unlock(), chan, config_file_lock, lua_create_app_table(), lua_create_application_metatable(), lua_create_autoservice_functions(), lua_create_channel_table(), lua_create_hangup_function(), lua_create_variable_metatable(), and lua_sort_extensions().
Referenced by lua_get_state().
00984 { 00985 00986 /* store a pointer to this channel */ 00987 lua_pushlightuserdata(L, chan); 00988 lua_setfield(L, LUA_REGISTRYINDEX, "channel"); 00989 00990 luaL_openlibs(L); 00991 00992 /* load and sort extensions */ 00993 ast_mutex_lock(&config_file_lock); 00994 if (luaL_loadbuffer(L, config_file_data, config_file_size, "extensions.lua") 00995 || lua_pcall(L, 0, LUA_MULTRET, 0) 00996 || lua_sort_extensions(L)) { 00997 ast_mutex_unlock(&config_file_lock); 00998 return 1; 00999 } 01000 ast_mutex_unlock(&config_file_lock); 01001 01002 /* now we setup special tables and functions */ 01003 01004 lua_create_app_table(L); 01005 lua_create_channel_table(L); 01006 01007 lua_create_variable_metatable(L); 01008 lua_create_application_metatable(L); 01009 01010 lua_create_autoservice_functions(L); 01011 lua_create_hangup_function(L); 01012 01013 return 0; 01014 }
static int lua_pbx_exec | ( | lua_State * | L | ) | [static] |
[lua_CFunction] This function is part of the 'application' metatable and is used to execute applications similar to pbx_exec() (for access from lua, don't call directly)
L | the lua_State to use |
app.playback('demo-congrats')
Definition at line 165 of file pbx_lua.c.
References app, ast_autoservice_start(), ast_autoservice_stop(), ast_build_string(), ast_strdupa, ast_verb, chan, COLOR_BRCYAN, COLOR_BRMAGENTA, context, exten, LUA_EXT_DATA_SIZE, ast_channel::name, pbx_exec(), pbx_findapp(), and term_color().
Referenced by lua_create_application_metatable().
00166 { 00167 int res, nargs = lua_gettop(L); 00168 char data[LUA_EXT_DATA_SIZE] = ""; 00169 char *data_next = data, *app_name; 00170 char *context, *exten; 00171 char tmp[80], tmp2[80], tmp3[LUA_EXT_DATA_SIZE]; 00172 int priority, autoservice; 00173 size_t data_left = sizeof(data); 00174 struct ast_app *app; 00175 struct ast_channel *chan; 00176 00177 lua_getfield(L, 1, "name"); 00178 app_name = ast_strdupa(lua_tostring(L, -1)); 00179 lua_pop(L, 1); 00180 00181 if (!(app = pbx_findapp(app_name))) { 00182 lua_pushstring(L, "application '"); 00183 lua_pushstring(L, app_name); 00184 lua_pushstring(L, "' not found"); 00185 lua_concat(L, 3); 00186 return lua_error(L); 00187 } 00188 00189 00190 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00191 chan = lua_touserdata(L, -1); 00192 lua_pop(L, 1); 00193 00194 00195 lua_getfield(L, LUA_REGISTRYINDEX, "context"); 00196 context = ast_strdupa(lua_tostring(L, -1)); 00197 lua_pop(L, 1); 00198 00199 lua_getfield(L, LUA_REGISTRYINDEX, "exten"); 00200 exten = ast_strdupa(lua_tostring(L, -1)); 00201 lua_pop(L, 1); 00202 00203 lua_getfield(L, LUA_REGISTRYINDEX, "priority"); 00204 priority = lua_tointeger(L, -1); 00205 lua_pop(L, 1); 00206 00207 00208 if (nargs > 1) { 00209 int i; 00210 00211 if (!lua_isnil(L, 2)) 00212 ast_build_string(&data_next, &data_left, "%s", luaL_checkstring(L, 2)); 00213 00214 for (i = 3; i <= nargs; i++) { 00215 if (lua_isnil(L, i)) 00216 ast_build_string(&data_next, &data_left, ","); 00217 else 00218 ast_build_string(&data_next, &data_left, ",%s", luaL_checkstring(L, i)); 00219 } 00220 } 00221 00222 ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\")\n", 00223 exten, context, priority, 00224 term_color(tmp, app_name, COLOR_BRCYAN, 0, sizeof(tmp)), 00225 term_color(tmp2, chan->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)), 00226 term_color(tmp3, data, COLOR_BRMAGENTA, 0, sizeof(tmp3))); 00227 00228 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00229 autoservice = lua_toboolean(L, -1); 00230 lua_pop(L, 1); 00231 00232 if (autoservice) 00233 ast_autoservice_stop(chan); 00234 00235 res = pbx_exec(chan, app, data); 00236 00237 if (autoservice) 00238 ast_autoservice_start(chan); 00239 00240 /* error executing an application, report it */ 00241 if (res) { 00242 lua_pushinteger(L, res); 00243 return lua_error(L); 00244 } 00245 return 0; 00246 }
static int lua_pbx_findapp | ( | lua_State * | L | ) | [static] |
[lua_CFunction] Find an app and return it in a lua table (for access from lua, don't call directly)
This function would be called in the following example as it would be found in extensions.lua.
app.dial
Definition at line 134 of file pbx_lua.c.
Referenced by lua_create_app_table().
00135 { 00136 const char *app_name = luaL_checkstring(L, 2); 00137 00138 lua_newtable(L); 00139 00140 lua_pushstring(L, "name"); 00141 lua_pushstring(L, app_name); 00142 lua_settable(L, -3); 00143 00144 luaL_getmetatable(L, "application"); 00145 lua_setmetatable(L, -2); 00146 00147 return 1; 00148 }
static void lua_push_variable_table | ( | lua_State * | L, | |
const char * | name | |||
) | [static] |
Push a 'variable' table on the stack for access the channel variable with the given name.
L | the lua_State to use | |
name | the name of the variable |
Definition at line 383 of file pbx_lua.c.
References lua_get_variable_value(), and lua_set_variable_value().
Referenced by lua_func_read(), and lua_get_variable().
00384 { 00385 lua_newtable(L); 00386 luaL_getmetatable(L, "variable"); 00387 lua_setmetatable(L, -2); 00388 00389 lua_pushstring(L, name); 00390 lua_setfield(L, -2, "name"); 00391 00392 lua_pushcfunction(L, &lua_get_variable_value); 00393 lua_setfield(L, -2, "get"); 00394 00395 lua_pushcfunction(L, &lua_set_variable_value); 00396 lua_setfield(L, -2, "set"); 00397 }
static char * lua_read_extensions_file | ( | lua_State * | L, | |
long * | size | |||
) | [static] |
Load the extensions.lua file in to a buffer and execute the file.
L | the lua_State to use | |
size | a pointer to store the size of the buffer |
Definition at line 926 of file pbx_lua.c.
References ast_config_AST_CONFIG_DIR, ast_free, ast_log(), ast_malloc, errno, f, LOG_WARNING, lua_register_switches(), and lua_sort_extensions().
Referenced by lua_reload_extensions().
00927 { 00928 FILE *f; 00929 char *data; 00930 char *path = alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2); 00931 sprintf(path, "%s/%s", ast_config_AST_CONFIG_DIR, config); 00932 00933 if (!(f = fopen(path, "r"))) { 00934 lua_pushstring(L, "cannot open '"); 00935 lua_pushstring(L, path); 00936 lua_pushstring(L, "' for reading: "); 00937 lua_pushstring(L, strerror(errno)); 00938 lua_concat(L, 4); 00939 00940 return NULL; 00941 } 00942 00943 fseek(f, 0l, SEEK_END); 00944 *size = ftell(f); 00945 00946 fseek(f, 0l, SEEK_SET); 00947 00948 if (!(data = ast_malloc(*size))) { 00949 *size = 0; 00950 fclose(f); 00951 lua_pushstring(L, "not enough memory"); 00952 return NULL; 00953 } 00954 00955 if (fread(data, sizeof(char), *size, f) != *size) { 00956 ast_log(LOG_WARNING, "fread() failed: %s\n", strerror(errno)); 00957 } 00958 fclose(f); 00959 00960 if (luaL_loadbuffer(L, data, *size, "extensions.lua") 00961 || lua_pcall(L, 0, LUA_MULTRET, 0) 00962 || lua_sort_extensions(L) 00963 || lua_register_switches(L)) { 00964 ast_free(data); 00965 data = NULL; 00966 *size = 0; 00967 } 00968 return data; 00969 }
static int lua_register_switches | ( | lua_State * | L | ) | [static] |
Register dialplan switches for our pbx_lua contexs.
In the event of an error, an error string will be pushed onto the lua stack.
0 | success | |
1 | failure |
Definition at line 845 of file pbx_lua.c.
References ast_context_add_switch2(), ast_context_find_or_create(), ast_hashtab_compare_contexts(), ast_hashtab_create(), ast_hashtab_hash_contexts(), ast_hashtab_newsize_java(), ast_hashtab_resize_java(), context, local_contexts, and local_table.
Referenced by lua_read_extensions_file().
00846 { 00847 int extensions; 00848 struct ast_context *con = NULL; 00849 00850 /* create the hash table for our contexts */ 00851 /* XXX do we ever need to destroy this? pbx_config does not */ 00852 if (!local_table) 00853 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); 00854 00855 /* load the 'extensions' table */ 00856 lua_getglobal(L, "extensions"); 00857 extensions = lua_gettop(L); 00858 if (lua_isnil(L, -1)) { 00859 lua_pop(L, 1); 00860 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n"); 00861 return 1; 00862 } 00863 00864 /* iterate through the extensions table and register a context and 00865 * dialplan switch for each lua context 00866 */ 00867 for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) { 00868 int context = lua_gettop(L); 00869 int context_name = context - 1; 00870 const char *context_str = lua_tostring(L, context_name); 00871 00872 /* find or create this context */ 00873 con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar); 00874 if (!con) { 00875 /* remove extensions table and context key and value */ 00876 lua_pop(L, 3); 00877 lua_pushstring(L, "Failed to find or create context\n"); 00878 return 1; 00879 } 00880 00881 /* register the switch */ 00882 if (ast_context_add_switch2(con, "Lua", "", 0, registrar)) { 00883 /* remove extensions table and context key and value */ 00884 lua_pop(L, 3); 00885 lua_pushstring(L, "Unable to create switch for context\n"); 00886 return 1; 00887 } 00888 } 00889 00890 /* remove the extensions table */ 00891 lua_pop(L, 1); 00892 return 0; 00893 }
static int lua_reload_extensions | ( | lua_State * | L | ) | [static] |
Reload the extensions file and update the internal buffers if it loads correctly.
L | the lua_State to use (must be freshly allocated with luaL_newstate(), don't use lua_get_state()) |
Definition at line 1026 of file pbx_lua.c.
References ast_free, ast_merge_contexts_and_delete(), ast_mutex_lock(), ast_mutex_unlock(), config_file_lock, local_contexts, local_table, and lua_read_extensions_file().
Referenced by load_or_reload_lua_stuff().
01027 { 01028 long size = 0; 01029 char *data = NULL; 01030 01031 luaL_openlibs(L); 01032 01033 if (!(data = lua_read_extensions_file(L, &size))) { 01034 return 1; 01035 } 01036 01037 ast_mutex_lock(&config_file_lock); 01038 01039 if (config_file_data) 01040 ast_free(config_file_data); 01041 01042 config_file_data = data; 01043 config_file_size = size; 01044 01045 /* merge our new contexts */ 01046 ast_merge_contexts_and_delete(&local_contexts, local_table, registrar); 01047 /* merge_contexts_and_delete will actually, at the correct moment, 01048 set the global dialplan pointers to your local_contexts and local_table. 01049 It then will free up the old tables itself. Just be sure not to 01050 hang onto the pointers. */ 01051 local_table = NULL; 01052 local_contexts = NULL; 01053 01054 ast_mutex_unlock(&config_file_lock); 01055 return 0; 01056 }
static int lua_set_variable | ( | lua_State * | L | ) | [static] |
[lua_CFunction] Set the value of a channel variable or dialplan function (for access from lua, don't call directly)
This function is called to set a variable or dialplan function. It would be called in the following example as would be seen in extensions.lua.
channel.variable = "value"
Definition at line 554 of file pbx_lua.c.
References ast_autoservice_start(), ast_autoservice_stop(), chan, name, and pbx_builtin_setvar_helper().
Referenced by lua_create_channel_table().
00555 { 00556 struct ast_channel *chan; 00557 int autoservice; 00558 const char *name = luaL_checkstring(L, 2); 00559 const char *value = luaL_checkstring(L, 3); 00560 00561 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00562 chan = lua_touserdata(L, -1); 00563 lua_pop(L, 1); 00564 00565 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00566 autoservice = lua_toboolean(L, -1); 00567 lua_pop(L, 1); 00568 00569 if (autoservice) 00570 ast_autoservice_stop(chan); 00571 00572 pbx_builtin_setvar_helper(chan, name, value); 00573 00574 if (autoservice) 00575 ast_autoservice_start(chan); 00576 00577 return 0; 00578 }
static int lua_set_variable_value | ( | lua_State * | L | ) | [static] |
[lua_CFunction] Used to set the value of a variable or dialplan function (for access from lua, don't call directly)
This function is the 'set()' function in the following example as would be seen in extensions.lua.
channel.variable:set("value")
Definition at line 320 of file pbx_lua.c.
References ast_autoservice_start(), ast_autoservice_stop(), ast_strdupa, chan, name, and pbx_builtin_setvar_helper().
Referenced by lua_push_variable_table().
00321 { 00322 const char *name, *value; 00323 struct ast_channel *chan; 00324 int autoservice; 00325 00326 if (!lua_istable(L, 1)) { 00327 lua_pushstring(L, "User probably used '.' instead of ':' for setting a channel variable"); 00328 return lua_error(L); 00329 } 00330 00331 lua_getfield(L, 1, "name"); 00332 name = ast_strdupa(lua_tostring(L, -1)); 00333 lua_pop(L, 1); 00334 00335 value = luaL_checkstring(L, 2); 00336 00337 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00338 chan = lua_touserdata(L, -1); 00339 lua_pop(L, 1); 00340 00341 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00342 autoservice = lua_toboolean(L, -1); 00343 lua_pop(L, 1); 00344 00345 if (autoservice) 00346 ast_autoservice_stop(chan); 00347 00348 pbx_builtin_setvar_helper(chan, name, value); 00349 00350 if (autoservice) 00351 ast_autoservice_start(chan); 00352 00353 return 0; 00354 }
static int lua_sort_extensions | ( | lua_State * | L | ) | [static] |
Store the sort order of each context.
In the event of an error, an error string will be pushed onto the lua stack.
0 | success | |
1 | failure |
Definition at line 767 of file pbx_lua.c.
References context, exten, and lua_extension_cmp().
Referenced by lua_load_extensions(), and lua_read_extensions_file().
00768 { 00769 int extensions, extensions_order; 00770 00771 /* create the extensions_order table */ 00772 lua_newtable(L); 00773 lua_setfield(L, LUA_REGISTRYINDEX, "extensions_order"); 00774 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order"); 00775 extensions_order = lua_gettop(L); 00776 00777 /* sort each context in the extensions table */ 00778 /* load the 'extensions' table */ 00779 lua_getglobal(L, "extensions"); 00780 extensions = lua_gettop(L); 00781 if (lua_isnil(L, -1)) { 00782 lua_pop(L, 1); 00783 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n"); 00784 return 1; 00785 } 00786 00787 /* iterate through the extensions table and create a 00788 * matching table (holding the sort order) in the 00789 * extensions_order table for each context that is found 00790 */ 00791 for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) { 00792 int context = lua_gettop(L); 00793 int context_name = context - 1; 00794 int context_order; 00795 00796 lua_pushvalue(L, context_name); 00797 lua_newtable(L); 00798 context_order = lua_gettop(L); 00799 00800 /* iterate through this context an popluate the corrisponding 00801 * table in the extensions_order table */ 00802 for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) { 00803 int exten = lua_gettop(L) - 1; 00804 00805 lua_pushinteger(L, lua_objlen(L, context_order) + 1); 00806 lua_pushvalue(L, exten); 00807 lua_settable(L, context_order); 00808 } 00809 lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */ 00810 00811 /* now sort the new table */ 00812 00813 /* push the table.sort function */ 00814 lua_getglobal(L, "table"); 00815 lua_getfield(L, -1, "sort"); 00816 lua_remove(L, -2); /* remove the 'table' table */ 00817 00818 /* push the context_order table */ 00819 lua_pushvalue(L, context_name); 00820 lua_gettable(L, extensions_order); 00821 00822 /* push the comp function */ 00823 lua_pushcfunction(L, &lua_extension_cmp); 00824 00825 if (lua_pcall(L, 2, 0, 0)) { 00826 lua_insert(L, -5); 00827 lua_pop(L, 4); 00828 return 1; 00829 } 00830 } 00831 00832 /* remove the extensions table and the extensions_order table */ 00833 lua_pop(L, 2); 00834 return 0; 00835 }
void lua_state_destroy | ( | void * | data | ) |
static void lua_update_registry | ( | lua_State * | L, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) | [static] |
Update the lua registry with the given context, exten, and priority.
L | the lua_State to use | |
context | the new context | |
exten | the new exten | |
priority | the new priority |
Definition at line 364 of file pbx_lua.c.
Referenced by exec().
00365 { 00366 lua_pushstring(L, context); 00367 lua_setfield(L, LUA_REGISTRYINDEX, "context"); 00368 00369 lua_pushstring(L, exten); 00370 lua_setfield(L, LUA_REGISTRYINDEX, "exten"); 00371 00372 lua_pushinteger(L, priority); 00373 lua_setfield(L, LUA_REGISTRYINDEX, "priority"); 00374 }
static int matchmore | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Definition at line 1190 of file pbx_lua.c.
References ast_log(), ast_module_user_add, ast_module_user_remove, chan, LOG_ERROR, lua_find_extension(), and lua_get_state().
Referenced by complete_dpreply(), and lua_find_extension().
01191 { 01192 int res; 01193 lua_State *L; 01194 struct ast_module_user *u = ast_module_user_add(chan); 01195 if (!u) { 01196 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01197 return 0; 01198 } 01199 01200 L = lua_get_state(chan); 01201 if (!L) { 01202 ast_module_user_remove(u); 01203 return 0; 01204 } 01205 01206 res = lua_find_extension(L, context, exten, priority, &matchmore, 0); 01207 01208 if (!chan) lua_close(L); 01209 ast_module_user_remove(u); 01210 return res; 01211 }
static int reload | ( | void | ) | [static] |
Definition at line 1456 of file pbx_lua.c.
References load_or_reload_lua_stuff().
01457 { 01458 return load_or_reload_lua_stuff(); 01459 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1448 of file pbx_lua.c.
References ast_context_destroy(), ast_unregister_switch(), lua_free_extensions(), and lua_switch.
01449 { 01450 ast_context_destroy(NULL, registrar); 01451 ast_unregister_switch(&lua_switch); 01452 lua_free_extensions(); 01453 return 0; 01454 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Lua PBX Switch" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
struct ast_module_info* ast_module_info = &__mod_info [static] |
char* config_file_data = NULL |
ast_mutex_t config_file_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 101 of file pbx_lua.c.
Referenced by lua_free_extensions(), lua_load_extensions(), and lua_reload_extensions().
long config_file_size = 0 |
struct ast_context* local_contexts = NULL [static] |
struct ast_hashtab* local_table = NULL [static] |
struct ast_datastore_info lua_datastore [static] |
Initial value:
{ .type = "lua", .destroy = lua_state_destroy, }
Definition at line 108 of file pbx_lua.c.
Referenced by lua_get_state().
struct ast_switch lua_switch [static] |