#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 <lua5.1/lua.h>
#include <lua5.1/lauxlib.h>
#include <lua5.1/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_DEFAULT , .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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, .reload = reload, } |
static const 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 53 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 1161 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().
01162 { 01163 int res; 01164 lua_State *L; 01165 struct ast_module_user *u = ast_module_user_add(chan); 01166 if (!u) { 01167 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01168 return 0; 01169 } 01170 01171 L = lua_get_state(chan); 01172 if (!L) { 01173 ast_module_user_remove(u); 01174 return 0; 01175 } 01176 01177 res = lua_find_extension(L, context, exten, priority, &canmatch, 0); 01178 01179 if (!chan) lua_close(L); 01180 ast_module_user_remove(u); 01181 return res; 01182 }
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 1208 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().
01209 { 01210 int res, error_func; 01211 lua_State *L; 01212 struct ast_module_user *u = ast_module_user_add(chan); 01213 if (!u) { 01214 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01215 return -1; 01216 } 01217 01218 L = lua_get_state(chan); 01219 if (!L) { 01220 ast_module_user_remove(u); 01221 return -1; 01222 } 01223 01224 lua_pushcfunction(L, &lua_error_function); 01225 error_func = lua_gettop(L); 01226 01227 /* push the extension function onto the stack */ 01228 if (!lua_find_extension(L, context, exten, priority, &exists, 1)) { 01229 lua_pop(L, 1); /* pop the debug function */ 01230 ast_log(LOG_ERROR, "Could not find extension %s in context %s\n", exten, context); 01231 if (!chan) lua_close(L); 01232 ast_module_user_remove(u); 01233 return -1; 01234 } 01235 01236 lua_update_registry(L, context, exten, priority); 01237 01238 lua_pushstring(L, context); 01239 lua_pushstring(L, exten); 01240 01241 res = lua_pcall(L, 2, 0, error_func); 01242 if (res) { 01243 if (res == LUA_ERRRUN) { 01244 res = -1; 01245 if (lua_isnumber(L, -1)) { 01246 res = lua_tointeger(L, -1); 01247 } else if (lua_isstring(L, -1)) { 01248 const char *error = lua_tostring(L, -1); 01249 ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error); 01250 } 01251 } else if (res == LUA_ERRERR) { 01252 res = -1; 01253 ast_log(LOG_ERROR, "Error in the lua error handler (this is probably a bug in pbx_lua)\n"); 01254 } else if (res == LUA_ERRMEM) { 01255 res = -1; 01256 ast_log(LOG_ERROR, "Memory allocation error\n"); 01257 } 01258 lua_pop(L, 1); 01259 } 01260 lua_remove(L, error_func); 01261 if (!chan) lua_close(L); 01262 ast_module_user_remove(u); 01263 return res; 01264 }
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 1138 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().
01139 { 01140 int res; 01141 lua_State *L; 01142 struct ast_module_user *u = ast_module_user_add(chan); 01143 if (!u) { 01144 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01145 return 0; 01146 } 01147 01148 L = lua_get_state(chan); 01149 if (!L) { 01150 ast_module_user_remove(u); 01151 return 0; 01152 } 01153 01154 res = lua_find_extension(L, context, exten, priority, &exists, 0); 01155 01156 if (!chan) lua_close(L); 01157 ast_module_user_remove(u); 01158 return res; 01159 }
static int load_module | ( | void | ) | [static] |
Definition at line 1455 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.
01456 { 01457 int res; 01458 01459 if ((res = load_or_reload_lua_stuff())) 01460 return res; 01461 01462 if (ast_register_switch(&lua_switch)) { 01463 ast_log(LOG_ERROR, "Unable to register LUA PBX switch\n"); 01464 return AST_MODULE_LOAD_DECLINE; 01465 } 01466 01467 return AST_MODULE_LOAD_SUCCESS; 01468 }
static int load_or_reload_lua_stuff | ( | void | ) | [static] |
Definition at line 1422 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().
01423 { 01424 int res = AST_MODULE_LOAD_SUCCESS; 01425 01426 lua_State *L = luaL_newstate(); 01427 if (!L) { 01428 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n"); 01429 return AST_MODULE_LOAD_DECLINE; 01430 } 01431 01432 if (lua_reload_extensions(L)) { 01433 const char *error = lua_tostring(L, -1); 01434 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error); 01435 res = AST_MODULE_LOAD_DECLINE; 01436 } 01437 01438 lua_close(L); 01439 return res; 01440 }
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 637 of file pbx_lua.c.
References ast_autoservice_start(), and chan.
Referenced by lua_create_autoservice_functions().
00638 { 00639 struct ast_channel *chan; 00640 int res; 00641 00642 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00643 chan = lua_touserdata(L, -1); 00644 lua_pop(L, 1); 00645 00646 res = ast_autoservice_start(chan); 00647 00648 lua_pushboolean(L, !res); 00649 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice"); 00650 00651 lua_pushboolean(L, !res); 00652 return 1; 00653 }
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 695 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 668 of file pbx_lua.c.
References ast_autoservice_stop(), and chan.
Referenced by lua_create_autoservice_functions().
00669 { 00670 struct ast_channel *chan; 00671 int res; 00672 00673 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00674 chan = lua_touserdata(L, -1); 00675 lua_pop(L, 1); 00676 00677 res = ast_autoservice_stop(chan); 00678 00679 lua_pushboolean(L, 0); 00680 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice"); 00681 00682 lua_pushboolean(L, !res); 00683 return 1; 00684 }
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 709 of file pbx_lua.c.
References ast_check_hangup(), and chan.
Referenced by lua_create_hangup_function().
00710 { 00711 struct ast_channel *chan; 00712 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00713 chan = lua_touserdata(L, -1); 00714 lua_pop(L, 1); 00715 00716 lua_pushboolean(L, ast_check_hangup(chan)); 00717 return 1; 00718 }
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 398 of file pbx_lua.c.
References lua_pbx_findapp().
Referenced by lua_load_extensions().
00399 { 00400 lua_newtable(L); 00401 luaL_newmetatable(L, "app"); 00402 00403 lua_pushstring(L, "__index"); 00404 lua_pushcfunction(L, &lua_pbx_findapp); 00405 lua_settable(L, -3); 00406 00407 lua_setmetatable(L, -2); 00408 lua_setglobal(L, "app"); 00409 }
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 455 of file pbx_lua.c.
References lua_pbx_exec().
Referenced by lua_load_extensions().
00456 { 00457 luaL_newmetatable(L, "application"); 00458 00459 lua_pushstring(L, "__call"); 00460 lua_pushcfunction(L, &lua_pbx_exec); 00461 lua_settable(L, -3); 00462 00463 lua_pop(L, 1); 00464 }
static void lua_create_autoservice_functions | ( | lua_State * | L | ) | [static] |
Create the autoservice functions.
L | the lua_State to use |
Definition at line 471 of file pbx_lua.c.
References lua_autoservice_start(), lua_autoservice_status(), and lua_autoservice_stop().
Referenced by lua_load_extensions().
00472 { 00473 lua_pushcfunction(L, &lua_autoservice_start); 00474 lua_setglobal(L, "autoservice_start"); 00475 00476 lua_pushcfunction(L, &lua_autoservice_stop); 00477 lua_setglobal(L, "autoservice_stop"); 00478 00479 lua_pushcfunction(L, &lua_autoservice_status); 00480 lua_setglobal(L, "autoservice_status"); 00481 00482 lua_pushboolean(L, 0); 00483 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice"); 00484 }
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 416 of file pbx_lua.c.
References lua_get_variable(), and lua_set_variable().
Referenced by lua_load_extensions().
00417 { 00418 lua_newtable(L); 00419 luaL_newmetatable(L, "channel_data"); 00420 00421 lua_pushstring(L, "__index"); 00422 lua_pushcfunction(L, &lua_get_variable); 00423 lua_settable(L, -3); 00424 00425 lua_pushstring(L, "__newindex"); 00426 lua_pushcfunction(L, &lua_set_variable); 00427 lua_settable(L, -3); 00428 00429 lua_setmetatable(L, -2); 00430 lua_setglobal(L, "channel"); 00431 }
static void lua_create_hangup_function | ( | lua_State * | L | ) | [static] |
Create the hangup check function.
L | the lua_State to use |
Definition at line 491 of file pbx_lua.c.
References lua_check_hangup().
Referenced by lua_load_extensions().
00492 { 00493 lua_pushcfunction(L, &lua_check_hangup); 00494 lua_setglobal(L, "check_hangup"); 00495 }
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 438 of file pbx_lua.c.
References lua_func_read().
Referenced by lua_load_extensions().
00439 { 00440 luaL_newmetatable(L, "variable"); 00441 00442 lua_pushstring(L, "__call"); 00443 lua_pushcfunction(L, &lua_func_read); 00444 lua_settable(L, -3); 00445 00446 lua_pop(L, 1); 00447 }
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 726 of file pbx_lua.c.
Referenced by exec().
00727 { 00728 int message_index; 00729 00730 /* pass number arguments right through back to asterisk*/ 00731 if (lua_isnumber(L, -1)) { 00732 return 1; 00733 } 00734 00735 /* if we are here then we have a string error message, let's attach a 00736 * backtrace to it */ 00737 message_index = lua_gettop(L); 00738 00739 lua_getglobal(L, "debug"); 00740 lua_getfield(L, -1, "traceback"); 00741 lua_remove(L, -2); /* remove the 'debug' table */ 00742 00743 lua_pushvalue(L, message_index); 00744 lua_remove(L, message_index); 00745 00746 lua_pushnumber(L, 2); 00747 00748 lua_call(L, 2, 1); 00749 00750 return 1; 00751 }
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 897 of file pbx_lua.c.
References ast_extension_cmp().
Referenced by lua_sort_extensions().
00898 { 00899 const char *a = luaL_checkstring(L, -2); 00900 const char *b = luaL_checkstring(L, -1); 00901 00902 if (ast_extension_cmp(a, b) == -1) 00903 lua_pushboolean(L, 1); 00904 else 00905 lua_pushboolean(L, 0); 00906 00907 return 1; 00908 }
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 1279 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().
01280 { 01281 int context_table, context_order_table, i; 01282 01283 ast_debug(2, "Looking up %s@%s:%i\n", exten, context, priority); 01284 if (priority != 1) 01285 return 0; 01286 01287 /* load the 'extensions' table */ 01288 lua_getglobal(L, "extensions"); 01289 if (lua_isnil(L, -1)) { 01290 ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n"); 01291 lua_pop(L, 1); 01292 return 0; 01293 } 01294 01295 /* load the given context */ 01296 lua_getfield(L, -1, context); 01297 if (lua_isnil(L, -1)) { 01298 lua_pop(L, 2); 01299 return 0; 01300 } 01301 01302 /* remove the extensions table */ 01303 lua_remove(L, -2); 01304 01305 context_table = lua_gettop(L); 01306 01307 /* load the extensions order table for this context */ 01308 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order"); 01309 lua_getfield(L, -1, context); 01310 01311 lua_remove(L, -2); /* remove the extensions order table */ 01312 01313 context_order_table = lua_gettop(L); 01314 01315 /* step through the extensions looking for a match */ 01316 for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) { 01317 int e_index, e_index_copy, match = 0; 01318 const char *e; 01319 01320 lua_pushinteger(L, i); 01321 lua_gettable(L, context_order_table); 01322 e_index = lua_gettop(L); 01323 01324 /* copy the key at the top of the stack for use later */ 01325 lua_pushvalue(L, -1); 01326 e_index_copy = lua_gettop(L); 01327 01328 if (!(e = lua_tostring(L, e_index_copy))) { 01329 lua_pop(L, 2); 01330 continue; 01331 } 01332 01333 /* make sure this is not the 'include' extension */ 01334 if (!strcasecmp(e, "include")) { 01335 lua_pop(L, 2); 01336 continue; 01337 } 01338 01339 if (func == &matchmore) 01340 match = ast_extension_close(e, exten, E_MATCHMORE); 01341 else if (func == &canmatch) 01342 match = ast_extension_close(e, exten, E_CANMATCH); 01343 else 01344 match = ast_extension_match(e, exten); 01345 01346 /* the extension matching functions return 0 on fail, 1 on 01347 * match, 2 on earlymatch */ 01348 01349 if (!match) { 01350 /* pop the copy and the extension */ 01351 lua_pop(L, 2); 01352 continue; /* keep trying */ 01353 } 01354 01355 if (func == &matchmore && match == 2) { 01356 /* We match an extension ending in '!'. The decision in 01357 * this case is final and counts as no match. */ 01358 lua_pop(L, 4); 01359 return 0; 01360 } 01361 01362 /* remove the context table, the context order table, the 01363 * extension, and the extension copy (or replace the extension 01364 * with the corresponding function) */ 01365 if (push_func) { 01366 lua_pop(L, 1); /* pop the copy */ 01367 lua_gettable(L, context_table); 01368 lua_insert(L, -3); 01369 lua_pop(L, 2); 01370 } else { 01371 lua_pop(L, 4); 01372 } 01373 01374 return 1; 01375 } 01376 01377 /* load the includes for this context */ 01378 lua_getfield(L, context_table, "include"); 01379 if (lua_isnil(L, -1)) { 01380 lua_pop(L, 3); 01381 return 0; 01382 } 01383 01384 /* remove the context and the order table*/ 01385 lua_remove(L, context_order_table); 01386 lua_remove(L, context_table); 01387 01388 /* Now try any includes we have in this context */ 01389 for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { 01390 const char *c = lua_tostring(L, -1); 01391 if (!c) 01392 continue; 01393 01394 if (lua_find_extension(L, c, exten, priority, func, push_func)) { 01395 /* remove the value, the key, and the includes table 01396 * from the stack. Leave the function behind if 01397 * necessary */ 01398 01399 if (push_func) 01400 lua_insert(L, -4); 01401 01402 lua_pop(L, 3); 01403 return 1; 01404 } 01405 } 01406 01407 /* pop the includes table */ 01408 lua_pop(L, 1); 01409 return 0; 01410 }
static void lua_free_extensions | ( | void | ) | [static] |
Free the internal extensions buffer.
Definition at line 1055 of file pbx_lua.c.
References ast_free, ast_mutex_lock(), ast_mutex_unlock(), and config_file_lock.
Referenced by unload_module().
01056 { 01057 ast_mutex_lock(&config_file_lock); 01058 config_file_size = 0; 01059 ast_free(config_file_data); 01060 ast_mutex_unlock(&config_file_lock); 01061 }
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 590 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().
00591 { 00592 int nargs = lua_gettop(L); 00593 char fullname[LUA_EXT_DATA_SIZE] = ""; 00594 char *fullname_next = fullname, *name; 00595 size_t fullname_left = sizeof(fullname); 00596 00597 lua_getfield(L, 1, "name"); 00598 name = ast_strdupa(lua_tostring(L, -1)); 00599 lua_pop(L, 1); 00600 00601 ast_build_string(&fullname_next, &fullname_left, "%s(", name); 00602 00603 if (nargs > 1) { 00604 int i; 00605 00606 if (!lua_isnil(L, 2)) 00607 ast_build_string(&fullname_next, &fullname_left, "%s", luaL_checkstring(L, 2)); 00608 00609 for (i = 3; i <= nargs; i++) { 00610 if (lua_isnil(L, i)) 00611 ast_build_string(&fullname_next, &fullname_left, ","); 00612 else 00613 ast_build_string(&fullname_next, &fullname_left, ",%s", luaL_checkstring(L, i)); 00614 } 00615 } 00616 00617 ast_build_string(&fullname_next, &fullname_left, ")"); 00618 00619 lua_push_variable_table(L, fullname); 00620 00621 return 1; 00622 }
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 1076 of file pbx_lua.c.
References ast_channel_datastore_add(), ast_channel_datastore_alloc(), ast_channel_datastore_find(), ast_channel_datastore_free(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_unlock, ast_log(), chan, ast_datastore::data, LOG_ERROR, lua_datastore, lua_load_extensions(), and ast_channel::name.
Referenced by canmatch(), exec(), exists(), and matchmore().
01077 { 01078 struct ast_datastore *datastore = NULL; 01079 lua_State *L; 01080 01081 if (!chan) { 01082 lua_State *L = luaL_newstate(); 01083 if (!L) { 01084 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n"); 01085 return NULL; 01086 } 01087 01088 if (lua_load_extensions(L, NULL)) { 01089 const char *error = lua_tostring(L, -1); 01090 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error); 01091 lua_close(L); 01092 return NULL; 01093 } 01094 return L; 01095 } else { 01096 ast_channel_lock(chan); 01097 datastore = ast_channel_datastore_find(chan, &lua_datastore, NULL); 01098 ast_channel_unlock(chan); 01099 01100 if (!datastore) { 01101 /* nothing found, allocate a new lua state */ 01102 datastore = ast_channel_datastore_alloc(&lua_datastore, NULL); 01103 if (!datastore) { 01104 ast_log(LOG_ERROR, "Error allocation channel datastore for lua_State\n"); 01105 return NULL; 01106 } 01107 01108 datastore->data = luaL_newstate(); 01109 if (!datastore->data) { 01110 ast_channel_datastore_free(datastore); 01111 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n"); 01112 return NULL; 01113 } 01114 01115 ast_channel_lock(chan); 01116 ast_channel_datastore_add(chan, datastore); 01117 ast_channel_unlock(chan); 01118 01119 L = datastore->data; 01120 01121 if (lua_load_extensions(L, chan)) { 01122 const char *error = lua_tostring(L, -1); 01123 ast_log(LOG_ERROR, "Error loading extensions.lua for %s: %s\n", chan->name, error); 01124 01125 ast_channel_lock(chan); 01126 ast_channel_datastore_remove(chan, datastore); 01127 ast_channel_unlock(chan); 01128 01129 ast_channel_datastore_free(datastore); 01130 return NULL; 01131 } 01132 } 01133 01134 return datastore->data; 01135 } 01136 }
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 509 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().
00510 { 00511 struct ast_channel *chan; 00512 char *name = ast_strdupa(luaL_checkstring(L, 2)); 00513 char *value = NULL; 00514 char *workspace = alloca(LUA_BUF_SIZE); 00515 workspace[0] = '\0'; 00516 00517 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00518 chan = lua_touserdata(L, -1); 00519 lua_pop(L, 1); 00520 00521 lua_push_variable_table(L, name); 00522 00523 /* if this is not a request for a dialplan funciton attempt to retrieve 00524 * the value of the variable */ 00525 if (!ast_strlen_zero(name) && name[strlen(name) - 1] != ')') { 00526 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead); 00527 } 00528 00529 if (value) { 00530 lua_pushstring(L, value); 00531 lua_setfield(L, -2, "value"); 00532 } 00533 00534 return 1; 00535 }
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 254 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().
00255 { 00256 struct ast_channel *chan; 00257 char *value = NULL, *name; 00258 char *workspace = alloca(LUA_BUF_SIZE); 00259 int autoservice; 00260 00261 workspace[0] = '\0'; 00262 00263 if (!lua_istable(L, 1)) { 00264 lua_pushstring(L, "User probably used '.' instead of ':' for retrieving a channel variable value"); 00265 return lua_error(L); 00266 } 00267 00268 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00269 chan = lua_touserdata(L, -1); 00270 lua_pop(L, 1); 00271 00272 lua_getfield(L, 1, "name"); 00273 name = ast_strdupa(lua_tostring(L, -1)); 00274 lua_pop(L, 1); 00275 00276 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00277 autoservice = lua_toboolean(L, -1); 00278 lua_pop(L, 1); 00279 00280 if (autoservice) 00281 ast_autoservice_stop(chan); 00282 00283 /* if this is a dialplan function then use ast_func_read(), otherwise 00284 * use pbx_retrieve_variable() */ 00285 if (!ast_strlen_zero(name) && name[strlen(name) - 1] == ')') { 00286 value = ast_func_read(chan, name, workspace, LUA_BUF_SIZE) ? NULL : workspace; 00287 } else { 00288 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead); 00289 } 00290 00291 if (autoservice) 00292 ast_autoservice_start(chan); 00293 00294 if (value) { 00295 lua_pushstring(L, value); 00296 } else { 00297 lua_pushnil(L); 00298 } 00299 00300 return 1; 00301 }
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 977 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().
00978 { 00979 00980 /* store a pointer to this channel */ 00981 lua_pushlightuserdata(L, chan); 00982 lua_setfield(L, LUA_REGISTRYINDEX, "channel"); 00983 00984 luaL_openlibs(L); 00985 00986 /* load and sort extensions */ 00987 ast_mutex_lock(&config_file_lock); 00988 if (luaL_loadbuffer(L, config_file_data, config_file_size, "extensions.lua") 00989 || lua_pcall(L, 0, LUA_MULTRET, 0) 00990 || lua_sort_extensions(L)) { 00991 ast_mutex_unlock(&config_file_lock); 00992 return 1; 00993 } 00994 ast_mutex_unlock(&config_file_lock); 00995 00996 /* now we setup special tables and functions */ 00997 00998 lua_create_app_table(L); 00999 lua_create_channel_table(L); 01000 01001 lua_create_variable_metatable(L); 01002 lua_create_application_metatable(L); 01003 01004 lua_create_autoservice_functions(L); 01005 lua_create_hangup_function(L); 01006 01007 return 0; 01008 }
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 159 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().
00160 { 00161 int res, nargs = lua_gettop(L); 00162 char data[LUA_EXT_DATA_SIZE] = ""; 00163 char *data_next = data, *app_name; 00164 char *context, *exten; 00165 char tmp[80], tmp2[80], tmp3[LUA_EXT_DATA_SIZE]; 00166 int priority, autoservice; 00167 size_t data_left = sizeof(data); 00168 struct ast_app *app; 00169 struct ast_channel *chan; 00170 00171 lua_getfield(L, 1, "name"); 00172 app_name = ast_strdupa(lua_tostring(L, -1)); 00173 lua_pop(L, 1); 00174 00175 if (!(app = pbx_findapp(app_name))) { 00176 lua_pushstring(L, "application '"); 00177 lua_pushstring(L, app_name); 00178 lua_pushstring(L, "' not found"); 00179 lua_concat(L, 3); 00180 return lua_error(L); 00181 } 00182 00183 00184 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00185 chan = lua_touserdata(L, -1); 00186 lua_pop(L, 1); 00187 00188 00189 lua_getfield(L, LUA_REGISTRYINDEX, "context"); 00190 context = ast_strdupa(lua_tostring(L, -1)); 00191 lua_pop(L, 1); 00192 00193 lua_getfield(L, LUA_REGISTRYINDEX, "exten"); 00194 exten = ast_strdupa(lua_tostring(L, -1)); 00195 lua_pop(L, 1); 00196 00197 lua_getfield(L, LUA_REGISTRYINDEX, "priority"); 00198 priority = lua_tointeger(L, -1); 00199 lua_pop(L, 1); 00200 00201 00202 if (nargs > 1) { 00203 int i; 00204 00205 if (!lua_isnil(L, 2)) 00206 ast_build_string(&data_next, &data_left, "%s", luaL_checkstring(L, 2)); 00207 00208 for (i = 3; i <= nargs; i++) { 00209 if (lua_isnil(L, i)) 00210 ast_build_string(&data_next, &data_left, ","); 00211 else 00212 ast_build_string(&data_next, &data_left, ",%s", luaL_checkstring(L, i)); 00213 } 00214 } 00215 00216 ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\")\n", 00217 exten, context, priority, 00218 term_color(tmp, app_name, COLOR_BRCYAN, 0, sizeof(tmp)), 00219 term_color(tmp2, chan->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)), 00220 term_color(tmp3, data, COLOR_BRMAGENTA, 0, sizeof(tmp3))); 00221 00222 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00223 autoservice = lua_toboolean(L, -1); 00224 lua_pop(L, 1); 00225 00226 if (autoservice) 00227 ast_autoservice_stop(chan); 00228 00229 res = pbx_exec(chan, app, data); 00230 00231 if (autoservice) 00232 ast_autoservice_start(chan); 00233 00234 /* error executing an application, report it */ 00235 if (res) { 00236 lua_pushinteger(L, res); 00237 return lua_error(L); 00238 } 00239 return 0; 00240 }
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 128 of file pbx_lua.c.
Referenced by lua_create_app_table().
00129 { 00130 const char *app_name = luaL_checkstring(L, 2); 00131 00132 lua_newtable(L); 00133 00134 lua_pushstring(L, "name"); 00135 lua_pushstring(L, app_name); 00136 lua_settable(L, -3); 00137 00138 luaL_getmetatable(L, "application"); 00139 lua_setmetatable(L, -2); 00140 00141 return 1; 00142 }
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 377 of file pbx_lua.c.
References lua_get_variable_value(), and lua_set_variable_value().
Referenced by lua_func_read(), and lua_get_variable().
00378 { 00379 lua_newtable(L); 00380 luaL_getmetatable(L, "variable"); 00381 lua_setmetatable(L, -2); 00382 00383 lua_pushstring(L, name); 00384 lua_setfield(L, -2, "name"); 00385 00386 lua_pushcfunction(L, &lua_get_variable_value); 00387 lua_setfield(L, -2, "get"); 00388 00389 lua_pushcfunction(L, &lua_set_variable_value); 00390 lua_setfield(L, -2, "set"); 00391 }
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 920 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().
00921 { 00922 FILE *f; 00923 char *data; 00924 char *path = alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2); 00925 sprintf(path, "%s/%s", ast_config_AST_CONFIG_DIR, config); 00926 00927 if (!(f = fopen(path, "r"))) { 00928 lua_pushstring(L, "cannot open '"); 00929 lua_pushstring(L, path); 00930 lua_pushstring(L, "' for reading: "); 00931 lua_pushstring(L, strerror(errno)); 00932 lua_concat(L, 4); 00933 00934 return NULL; 00935 } 00936 00937 fseek(f, 0l, SEEK_END); 00938 *size = ftell(f); 00939 00940 fseek(f, 0l, SEEK_SET); 00941 00942 if (!(data = ast_malloc(*size))) { 00943 *size = 0; 00944 fclose(f); 00945 lua_pushstring(L, "not enough memory"); 00946 return NULL; 00947 } 00948 00949 if (fread(data, sizeof(char), *size, f) != *size) { 00950 ast_log(LOG_WARNING, "fread() failed: %s\n", strerror(errno)); 00951 } 00952 fclose(f); 00953 00954 if (luaL_loadbuffer(L, data, *size, "extensions.lua") 00955 || lua_pcall(L, 0, LUA_MULTRET, 0) 00956 || lua_sort_extensions(L) 00957 || lua_register_switches(L)) { 00958 ast_free(data); 00959 data = NULL; 00960 *size = 0; 00961 } 00962 return data; 00963 }
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 839 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().
00840 { 00841 int extensions; 00842 struct ast_context *con = NULL; 00843 00844 /* create the hash table for our contexts */ 00845 /* XXX do we ever need to destroy this? pbx_config does not */ 00846 if (!local_table) 00847 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); 00848 00849 /* load the 'extensions' table */ 00850 lua_getglobal(L, "extensions"); 00851 extensions = lua_gettop(L); 00852 if (lua_isnil(L, -1)) { 00853 lua_pop(L, 1); 00854 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n"); 00855 return 1; 00856 } 00857 00858 /* iterate through the extensions table and register a context and 00859 * dialplan switch for each lua context 00860 */ 00861 for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) { 00862 int context = lua_gettop(L); 00863 int context_name = context - 1; 00864 const char *context_str = lua_tostring(L, context_name); 00865 00866 /* find or create this context */ 00867 con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar); 00868 if (!con) { 00869 /* remove extensions table and context key and value */ 00870 lua_pop(L, 3); 00871 lua_pushstring(L, "Failed to find or create context\n"); 00872 return 1; 00873 } 00874 00875 /* register the switch */ 00876 if (ast_context_add_switch2(con, "Lua", "", 0, registrar)) { 00877 /* remove extensions table and context key and value */ 00878 lua_pop(L, 3); 00879 lua_pushstring(L, "Unable to create switch for context\n"); 00880 return 1; 00881 } 00882 } 00883 00884 /* remove the extensions table */ 00885 lua_pop(L, 1); 00886 return 0; 00887 }
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 1020 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().
01021 { 01022 long size = 0; 01023 char *data = NULL; 01024 01025 luaL_openlibs(L); 01026 01027 if (!(data = lua_read_extensions_file(L, &size))) { 01028 return 1; 01029 } 01030 01031 ast_mutex_lock(&config_file_lock); 01032 01033 if (config_file_data) 01034 ast_free(config_file_data); 01035 01036 config_file_data = data; 01037 config_file_size = size; 01038 01039 /* merge our new contexts */ 01040 ast_merge_contexts_and_delete(&local_contexts, local_table, registrar); 01041 /* merge_contexts_and_delete will actually, at the correct moment, 01042 set the global dialplan pointers to your local_contexts and local_table. 01043 It then will free up the old tables itself. Just be sure not to 01044 hang onto the pointers. */ 01045 local_table = NULL; 01046 local_contexts = NULL; 01047 01048 ast_mutex_unlock(&config_file_lock); 01049 return 0; 01050 }
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 548 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().
00549 { 00550 struct ast_channel *chan; 00551 int autoservice; 00552 const char *name = luaL_checkstring(L, 2); 00553 const char *value = luaL_checkstring(L, 3); 00554 00555 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00556 chan = lua_touserdata(L, -1); 00557 lua_pop(L, 1); 00558 00559 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00560 autoservice = lua_toboolean(L, -1); 00561 lua_pop(L, 1); 00562 00563 if (autoservice) 00564 ast_autoservice_stop(chan); 00565 00566 pbx_builtin_setvar_helper(chan, name, value); 00567 00568 if (autoservice) 00569 ast_autoservice_start(chan); 00570 00571 return 0; 00572 }
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 314 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().
00315 { 00316 const char *name, *value; 00317 struct ast_channel *chan; 00318 int autoservice; 00319 00320 if (!lua_istable(L, 1)) { 00321 lua_pushstring(L, "User probably used '.' instead of ':' for setting a channel variable"); 00322 return lua_error(L); 00323 } 00324 00325 lua_getfield(L, 1, "name"); 00326 name = ast_strdupa(lua_tostring(L, -1)); 00327 lua_pop(L, 1); 00328 00329 value = luaL_checkstring(L, 2); 00330 00331 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00332 chan = lua_touserdata(L, -1); 00333 lua_pop(L, 1); 00334 00335 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00336 autoservice = lua_toboolean(L, -1); 00337 lua_pop(L, 1); 00338 00339 if (autoservice) 00340 ast_autoservice_stop(chan); 00341 00342 pbx_builtin_setvar_helper(chan, name, value); 00343 00344 if (autoservice) 00345 ast_autoservice_start(chan); 00346 00347 return 0; 00348 }
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 761 of file pbx_lua.c.
References context, exten, and lua_extension_cmp().
Referenced by lua_load_extensions(), and lua_read_extensions_file().
00762 { 00763 int extensions, extensions_order; 00764 00765 /* create the extensions_order table */ 00766 lua_newtable(L); 00767 lua_setfield(L, LUA_REGISTRYINDEX, "extensions_order"); 00768 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order"); 00769 extensions_order = lua_gettop(L); 00770 00771 /* sort each context in the extensions table */ 00772 /* load the 'extensions' table */ 00773 lua_getglobal(L, "extensions"); 00774 extensions = lua_gettop(L); 00775 if (lua_isnil(L, -1)) { 00776 lua_pop(L, 1); 00777 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n"); 00778 return 1; 00779 } 00780 00781 /* iterate through the extensions table and create a 00782 * matching table (holding the sort order) in the 00783 * extensions_order table for each context that is found 00784 */ 00785 for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) { 00786 int context = lua_gettop(L); 00787 int context_name = context - 1; 00788 int context_order; 00789 00790 lua_pushvalue(L, context_name); 00791 lua_newtable(L); 00792 context_order = lua_gettop(L); 00793 00794 /* iterate through this context an popluate the corrisponding 00795 * table in the extensions_order table */ 00796 for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) { 00797 int exten = lua_gettop(L) - 1; 00798 00799 lua_pushinteger(L, lua_objlen(L, context_order) + 1); 00800 lua_pushvalue(L, exten); 00801 lua_settable(L, context_order); 00802 } 00803 lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */ 00804 00805 /* now sort the new table */ 00806 00807 /* push the table.sort function */ 00808 lua_getglobal(L, "table"); 00809 lua_getfield(L, -1, "sort"); 00810 lua_remove(L, -2); /* remove the 'table' table */ 00811 00812 /* push the context_order table */ 00813 lua_pushvalue(L, context_name); 00814 lua_gettable(L, extensions_order); 00815 00816 /* push the comp function */ 00817 lua_pushcfunction(L, &lua_extension_cmp); 00818 00819 if (lua_pcall(L, 2, 0, 0)) { 00820 lua_insert(L, -5); 00821 lua_pop(L, 4); 00822 return 1; 00823 } 00824 } 00825 00826 /* remove the extensions table and the extensions_order table */ 00827 lua_pop(L, 2); 00828 return 0; 00829 }
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 358 of file pbx_lua.c.
Referenced by exec().
00359 { 00360 lua_pushstring(L, context); 00361 lua_setfield(L, LUA_REGISTRYINDEX, "context"); 00362 00363 lua_pushstring(L, exten); 00364 lua_setfield(L, LUA_REGISTRYINDEX, "exten"); 00365 00366 lua_pushinteger(L, priority); 00367 lua_setfield(L, LUA_REGISTRYINDEX, "priority"); 00368 }
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 1184 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().
01185 { 01186 int res; 01187 lua_State *L; 01188 struct ast_module_user *u = ast_module_user_add(chan); 01189 if (!u) { 01190 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01191 return 0; 01192 } 01193 01194 L = lua_get_state(chan); 01195 if (!L) { 01196 ast_module_user_remove(u); 01197 return 0; 01198 } 01199 01200 res = lua_find_extension(L, context, exten, priority, &matchmore, 0); 01201 01202 if (!chan) lua_close(L); 01203 ast_module_user_remove(u); 01204 return res; 01205 }
static int reload | ( | void | ) | [static] |
Definition at line 1450 of file pbx_lua.c.
References load_or_reload_lua_stuff().
01451 { 01452 return load_or_reload_lua_stuff(); 01453 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1442 of file pbx_lua.c.
References ast_context_destroy(), ast_unregister_switch(), lua_free_extensions(), and lua_switch.
01443 { 01444 ast_context_destroy(NULL, registrar); 01445 ast_unregister_switch(&lua_switch); 01446 lua_free_extensions(); 01447 return 0; 01448 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
const 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 95 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 102 of file pbx_lua.c.
Referenced by lua_get_state().
struct ast_switch lua_switch [static] |