Lua PBX Switch. More...
#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 8192 |
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_concat_args (lua_State *L, int start, int nargs) |
Concatenate a list of lua function arguments into a comma separated string. | |
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 void | lua_datastore_fixup (void *data, struct ast_channel *old_chan, struct ast_channel *new_chan) |
The fixup function for the lua_datastore. | |
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) |
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. | |
static 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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static char * | config = "extensions.lua" |
static char * | config_file_data = NULL |
static ast_mutex_t | config_file_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
static 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" |
Lua PBX Switch.
Definition in file pbx_lua.c.
#define LUA_BUF_SIZE 4096 |
Definition at line 58 of file pbx_lua.c.
Referenced by lua_get_variable(), and lua_get_variable_value().
#define LUA_EXT_DATA_SIZE 8192 |
Definition at line 56 of file pbx_lua.c.
Referenced by lua_pbx_exec().
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 1232 of file pbx_lua.c.
References ast_log(), ast_module_user_add, ast_module_user_remove, LOG_ERROR, lua_find_extension(), and lua_get_state().
Referenced by lua_find_extension().
01233 { 01234 int res; 01235 lua_State *L; 01236 struct ast_module_user *u = ast_module_user_add(chan); 01237 if (!u) { 01238 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01239 return 0; 01240 } 01241 01242 L = lua_get_state(chan); 01243 if (!L) { 01244 ast_module_user_remove(u); 01245 return 0; 01246 } 01247 01248 res = lua_find_extension(L, context, exten, priority, &canmatch, 0); 01249 01250 if (!chan) lua_close(L); 01251 ast_module_user_remove(u); 01252 return res; 01253 }
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 1279 of file pbx_lua.c.
References ast_autoservice_start(), ast_autoservice_stop(), ast_log(), ast_module_user_add, ast_module_user_remove, exists(), LOG_ERROR, lua_error_function(), lua_find_extension(), lua_get_state(), and lua_update_registry().
01280 { 01281 int res, error_func; 01282 lua_State *L; 01283 struct ast_module_user *u = ast_module_user_add(chan); 01284 if (!u) { 01285 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01286 return -1; 01287 } 01288 01289 L = lua_get_state(chan); 01290 if (!L) { 01291 ast_module_user_remove(u); 01292 return -1; 01293 } 01294 01295 lua_pushcfunction(L, &lua_error_function); 01296 error_func = lua_gettop(L); 01297 01298 /* push the extension function onto the stack */ 01299 if (!lua_find_extension(L, context, exten, priority, &exists, 1)) { 01300 lua_pop(L, 1); /* pop the debug function */ 01301 ast_log(LOG_ERROR, "Could not find extension %s in context %s\n", exten, context); 01302 if (!chan) lua_close(L); 01303 ast_module_user_remove(u); 01304 return -1; 01305 } 01306 01307 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 01308 if (lua_toboolean(L, -1)) { 01309 ast_autoservice_start(chan); 01310 } 01311 lua_pop(L, 1); 01312 01313 lua_update_registry(L, context, exten, priority); 01314 01315 lua_pushstring(L, context); 01316 lua_pushstring(L, exten); 01317 01318 res = lua_pcall(L, 2, 0, error_func); 01319 if (res) { 01320 if (res == LUA_ERRRUN) { 01321 res = -1; 01322 if (lua_isnumber(L, -1)) { 01323 res = lua_tointeger(L, -1); 01324 } else if (lua_isstring(L, -1)) { 01325 const char *error = lua_tostring(L, -1); 01326 ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error); 01327 } 01328 } else if (res == LUA_ERRERR) { 01329 res = -1; 01330 ast_log(LOG_ERROR, "Error in the lua error handler (this is probably a bug in pbx_lua)\n"); 01331 } else if (res == LUA_ERRMEM) { 01332 res = -1; 01333 ast_log(LOG_ERROR, "Memory allocation error\n"); 01334 } 01335 lua_pop(L, 1); 01336 } 01337 lua_remove(L, error_func); 01338 01339 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 01340 if (lua_toboolean(L, -1)) { 01341 ast_autoservice_stop(chan); 01342 } 01343 lua_pop(L, 1); 01344 01345 if (!chan) lua_close(L); 01346 ast_module_user_remove(u); 01347 return res; 01348 }
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 1209 of file pbx_lua.c.
References ast_log(), ast_module_user_add, ast_module_user_remove, LOG_ERROR, lua_find_extension(), and lua_get_state().
Referenced by exec().
01210 { 01211 int res; 01212 lua_State *L; 01213 struct ast_module_user *u = ast_module_user_add(chan); 01214 if (!u) { 01215 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01216 return 0; 01217 } 01218 01219 L = lua_get_state(chan); 01220 if (!L) { 01221 ast_module_user_remove(u); 01222 return 0; 01223 } 01224 01225 res = lua_find_extension(L, context, exten, priority, &exists, 0); 01226 01227 if (!chan) lua_close(L); 01228 ast_module_user_remove(u); 01229 return res; 01230 }
static int load_module | ( | void | ) | [static] |
Definition at line 1539 of file pbx_lua.c.
References ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_switch(), load_or_reload_lua_stuff(), and LOG_ERROR.
01540 { 01541 int res; 01542 01543 if ((res = load_or_reload_lua_stuff())) 01544 return res; 01545 01546 if (ast_register_switch(&lua_switch)) { 01547 ast_log(LOG_ERROR, "Unable to register LUA PBX switch\n"); 01548 return AST_MODULE_LOAD_DECLINE; 01549 } 01550 01551 return AST_MODULE_LOAD_SUCCESS; 01552 }
static int load_or_reload_lua_stuff | ( | void | ) | [static] |
Definition at line 1506 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().
01507 { 01508 int res = AST_MODULE_LOAD_SUCCESS; 01509 01510 lua_State *L = luaL_newstate(); 01511 if (!L) { 01512 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n"); 01513 return AST_MODULE_LOAD_DECLINE; 01514 } 01515 01516 if (lua_reload_extensions(L)) { 01517 const char *error = lua_tostring(L, -1); 01518 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error); 01519 res = AST_MODULE_LOAD_DECLINE; 01520 } 01521 01522 lua_close(L); 01523 return res; 01524 }
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 |
This function will set a flag that will cause pbx_lua to maintain an autoservice on this channel. The autoservice will automatically be stopped and restarted before calling applications and functions.
Definition at line 665 of file pbx_lua.c.
References ast_autoservice_start().
Referenced by lua_create_autoservice_functions().
00666 { 00667 struct ast_channel *chan; 00668 int res; 00669 00670 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00671 if (lua_toboolean(L, -1)) { 00672 /* autoservice already running */ 00673 return 1; 00674 } 00675 lua_pop(L, 1); 00676 00677 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00678 chan = lua_touserdata(L, -1); 00679 lua_pop(L, 1); 00680 00681 res = ast_autoservice_start(chan); 00682 00683 lua_pushboolean(L, !res); 00684 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice"); 00685 00686 lua_pushboolean(L, !res); 00687 return 1; 00688 }
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 737 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 |
This function will stop any autoservice running and turn off the autoservice flag. If this function returns false, it's probably because no autoservice was running to begin with.
Definition at line 703 of file pbx_lua.c.
References ast_autoservice_stop().
Referenced by lua_create_autoservice_functions().
00704 { 00705 struct ast_channel *chan; 00706 int res; 00707 00708 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00709 if (!lua_toboolean(L, -1)) { 00710 /* no autoservice running */ 00711 return 1; 00712 } 00713 lua_pop(L, 1); 00714 00715 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00716 chan = lua_touserdata(L, -1); 00717 lua_pop(L, 1); 00718 00719 res = ast_autoservice_stop(chan); 00720 00721 lua_pushboolean(L, 0); 00722 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice"); 00723 00724 lua_pushboolean(L, !res); 00725 return 1; 00726 }
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 751 of file pbx_lua.c.
References ast_check_hangup().
Referenced by lua_create_hangup_function().
00752 { 00753 struct ast_channel *chan; 00754 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00755 chan = lua_touserdata(L, -1); 00756 lua_pop(L, 1); 00757 00758 lua_pushboolean(L, ast_check_hangup(chan)); 00759 return 1; 00760 }
static void lua_concat_args | ( | lua_State * | L, | |
int | start, | |||
int | nargs | |||
) | [static] |
Concatenate a list of lua function arguments into a comma separated string.
L | the lua_State to use | |
start | the index of the first argument | |
nargs | the number of args |
The resulting string will be left on the top of the stack.
Definition at line 598 of file pbx_lua.c.
Referenced by lua_func_read(), and lua_pbx_exec().
00598 { 00599 int concat = 0; 00600 int i = start + 1; 00601 00602 if (start <= nargs && !lua_isnil(L, start)) { 00603 lua_pushvalue(L, start); 00604 concat += 1; 00605 } 00606 00607 for (; i <= nargs; i++) { 00608 if (lua_isnil(L, i)) { 00609 lua_pushliteral(L, ","); 00610 concat += 1; 00611 } else { 00612 lua_pushliteral(L, ","); 00613 lua_pushvalue(L, i); 00614 concat += 2; 00615 } 00616 } 00617 00618 lua_concat(L, concat); 00619 }
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 412 of file pbx_lua.c.
References lua_pbx_findapp().
Referenced by lua_load_extensions().
00413 { 00414 lua_newtable(L); 00415 luaL_newmetatable(L, "app"); 00416 00417 lua_pushstring(L, "__index"); 00418 lua_pushcfunction(L, &lua_pbx_findapp); 00419 lua_settable(L, -3); 00420 00421 lua_setmetatable(L, -2); 00422 lua_setglobal(L, "app"); 00423 }
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 469 of file pbx_lua.c.
References lua_pbx_exec().
Referenced by lua_load_extensions().
00470 { 00471 luaL_newmetatable(L, "application"); 00472 00473 lua_pushstring(L, "__call"); 00474 lua_pushcfunction(L, &lua_pbx_exec); 00475 lua_settable(L, -3); 00476 00477 lua_pop(L, 1); 00478 }
static void lua_create_autoservice_functions | ( | lua_State * | L | ) | [static] |
Create the autoservice functions.
L | the lua_State to use |
Definition at line 485 of file pbx_lua.c.
References lua_autoservice_start(), lua_autoservice_status(), and lua_autoservice_stop().
Referenced by lua_load_extensions().
00486 { 00487 lua_pushcfunction(L, &lua_autoservice_start); 00488 lua_setglobal(L, "autoservice_start"); 00489 00490 lua_pushcfunction(L, &lua_autoservice_stop); 00491 lua_setglobal(L, "autoservice_stop"); 00492 00493 lua_pushcfunction(L, &lua_autoservice_status); 00494 lua_setglobal(L, "autoservice_status"); 00495 00496 lua_pushboolean(L, 0); 00497 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice"); 00498 }
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 430 of file pbx_lua.c.
References lua_get_variable(), and lua_set_variable().
Referenced by lua_load_extensions().
00431 { 00432 lua_newtable(L); 00433 luaL_newmetatable(L, "channel_data"); 00434 00435 lua_pushstring(L, "__index"); 00436 lua_pushcfunction(L, &lua_get_variable); 00437 lua_settable(L, -3); 00438 00439 lua_pushstring(L, "__newindex"); 00440 lua_pushcfunction(L, &lua_set_variable); 00441 lua_settable(L, -3); 00442 00443 lua_setmetatable(L, -2); 00444 lua_setglobal(L, "channel"); 00445 }
static void lua_create_hangup_function | ( | lua_State * | L | ) | [static] |
Create the hangup check function.
L | the lua_State to use |
Definition at line 505 of file pbx_lua.c.
References lua_check_hangup().
Referenced by lua_load_extensions().
00506 { 00507 lua_pushcfunction(L, &lua_check_hangup); 00508 lua_setglobal(L, "check_hangup"); 00509 }
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 452 of file pbx_lua.c.
References lua_func_read().
Referenced by lua_load_extensions().
00453 { 00454 luaL_newmetatable(L, "variable"); 00455 00456 lua_pushstring(L, "__call"); 00457 lua_pushcfunction(L, &lua_func_read); 00458 lua_settable(L, -3); 00459 00460 lua_pop(L, 1); 00461 }
static void lua_datastore_fixup | ( | void * | data, | |
struct ast_channel * | old_chan, | |||
struct ast_channel * | new_chan | |||
) | [static] |
The fixup function for the lua_datastore.
data | the datastore data, in this case it will be a lua_State | |
old_chan | the channel we are moving from | |
new_chan | the channel we are moving to |
This function updates our internal channel pointer.
Definition at line 133 of file pbx_lua.c.
00134 { 00135 lua_State *L = data; 00136 lua_pushlightuserdata(L, new_chan); 00137 lua_setfield(L, LUA_REGISTRYINDEX, "channel"); 00138 }
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 768 of file pbx_lua.c.
Referenced by exec(), and lua_read_extensions_file().
00769 { 00770 int message_index; 00771 00772 /* pass number arguments right through back to asterisk*/ 00773 if (lua_isnumber(L, -1)) { 00774 return 1; 00775 } 00776 00777 /* if we are here then we have a string error message, let's attach a 00778 * backtrace to it */ 00779 message_index = lua_gettop(L); 00780 00781 /* prepare to prepend a new line to the traceback */ 00782 lua_pushliteral(L, "\n"); 00783 00784 lua_getglobal(L, "debug"); 00785 lua_getfield(L, -1, "traceback"); 00786 lua_remove(L, -2); /* remove the 'debug' table */ 00787 00788 lua_pushvalue(L, message_index); 00789 lua_remove(L, message_index); 00790 00791 lua_pushnumber(L, 2); 00792 00793 lua_call(L, 2, 1); 00794 00795 /* prepend the new line we prepared above */ 00796 lua_concat(L, 2); 00797 00798 return 1; 00799 }
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 949 of file pbx_lua.c.
References ast_extension_cmp().
Referenced by lua_sort_extensions().
00950 { 00951 const char *a = luaL_checkstring(L, -2); 00952 const char *b = luaL_checkstring(L, -1); 00953 00954 if (ast_extension_cmp(a, b) == -1) 00955 lua_pushboolean(L, 1); 00956 else 00957 lua_pushboolean(L, 0); 00958 00959 return 1; 00960 }
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 1363 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().
01364 { 01365 int context_table, context_order_table, i; 01366 01367 ast_debug(2, "Looking up %s@%s:%i\n", exten, context, priority); 01368 if (priority != 1) 01369 return 0; 01370 01371 /* load the 'extensions' table */ 01372 lua_getglobal(L, "extensions"); 01373 if (lua_isnil(L, -1)) { 01374 ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n"); 01375 lua_pop(L, 1); 01376 return 0; 01377 } 01378 01379 /* load the given context */ 01380 lua_getfield(L, -1, context); 01381 if (lua_isnil(L, -1)) { 01382 lua_pop(L, 2); 01383 return 0; 01384 } 01385 01386 /* remove the extensions table */ 01387 lua_remove(L, -2); 01388 01389 context_table = lua_gettop(L); 01390 01391 /* load the extensions order table for this context */ 01392 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order"); 01393 lua_getfield(L, -1, context); 01394 01395 lua_remove(L, -2); /* remove the extensions order table */ 01396 01397 context_order_table = lua_gettop(L); 01398 01399 /* step through the extensions looking for a match */ 01400 for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) { 01401 int e_index_copy, match = 0; 01402 const char *e; 01403 01404 lua_pushinteger(L, i); 01405 lua_gettable(L, context_order_table); 01406 lua_gettop(L); 01407 01408 /* copy the key at the top of the stack for use later */ 01409 lua_pushvalue(L, -1); 01410 e_index_copy = lua_gettop(L); 01411 01412 if (!(e = lua_tostring(L, e_index_copy))) { 01413 lua_pop(L, 2); 01414 continue; 01415 } 01416 01417 /* make sure this is not the 'include' extension */ 01418 if (!strcasecmp(e, "include")) { 01419 lua_pop(L, 2); 01420 continue; 01421 } 01422 01423 if (func == &matchmore) 01424 match = ast_extension_close(e, exten, E_MATCHMORE); 01425 else if (func == &canmatch) 01426 match = ast_extension_close(e, exten, E_CANMATCH); 01427 else 01428 match = ast_extension_match(e, exten); 01429 01430 /* the extension matching functions return 0 on fail, 1 on 01431 * match, 2 on earlymatch */ 01432 01433 if (!match) { 01434 /* pop the copy and the extension */ 01435 lua_pop(L, 2); 01436 continue; /* keep trying */ 01437 } 01438 01439 if (func == &matchmore && match == 2) { 01440 /* We match an extension ending in '!'. The decision in 01441 * this case is final and counts as no match. */ 01442 lua_pop(L, 4); 01443 return 0; 01444 } 01445 01446 /* remove the context table, the context order table, the 01447 * extension, and the extension copy (or replace the extension 01448 * with the corresponding function) */ 01449 if (push_func) { 01450 lua_pop(L, 1); /* pop the copy */ 01451 lua_gettable(L, context_table); 01452 lua_insert(L, -3); 01453 lua_pop(L, 2); 01454 } else { 01455 lua_pop(L, 4); 01456 } 01457 01458 return 1; 01459 } 01460 01461 /* load the includes for this context */ 01462 lua_getfield(L, context_table, "include"); 01463 if (lua_isnil(L, -1)) { 01464 lua_pop(L, 3); 01465 return 0; 01466 } 01467 01468 /* remove the context and the order table*/ 01469 lua_remove(L, context_order_table); 01470 lua_remove(L, context_table); 01471 01472 /* Now try any includes we have in this context */ 01473 for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { 01474 const char *c = lua_tostring(L, -1); 01475 if (!c) 01476 continue; 01477 01478 if (lua_find_extension(L, c, exten, priority, func, push_func)) { 01479 /* remove the value, the key, and the includes table 01480 * from the stack. Leave the function behind if 01481 * necessary */ 01482 01483 if (push_func) 01484 lua_insert(L, -4); 01485 01486 lua_pop(L, 3); 01487 return 1; 01488 } 01489 } 01490 01491 /* pop the includes table */ 01492 lua_pop(L, 1); 01493 return 0; 01494 }
static void lua_free_extensions | ( | void | ) | [static] |
Free the internal extensions buffer.
Definition at line 1126 of file pbx_lua.c.
References ast_free, ast_mutex_lock, ast_mutex_unlock, and config_file_lock.
Referenced by unload_module().
01127 { 01128 ast_mutex_lock(&config_file_lock); 01129 config_file_size = 0; 01130 ast_free(config_file_data); 01131 ast_mutex_unlock(&config_file_lock); 01132 }
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 637 of file pbx_lua.c.
References lua_concat_args(), and lua_push_variable_table().
Referenced by lua_create_variable_metatable().
00638 { 00639 int nargs = lua_gettop(L); 00640 00641 /* build a string in the form of "func_name(arg1,arg2,arg3)" */ 00642 lua_getfield(L, 1, "name"); 00643 lua_pushliteral(L, "("); 00644 lua_concat_args(L, 2, nargs); 00645 lua_pushliteral(L, ")"); 00646 lua_concat(L, 4); 00647 00648 lua_push_variable_table(L); 00649 return 1; 00650 }
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 1147 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(), ast_datastore::data, LOG_ERROR, and lua_load_extensions().
Referenced by canmatch(), exec(), exists(), and matchmore().
01148 { 01149 struct ast_datastore *datastore = NULL; 01150 lua_State *L; 01151 01152 if (!chan) { 01153 lua_State *L = luaL_newstate(); 01154 if (!L) { 01155 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n"); 01156 return NULL; 01157 } 01158 01159 if (lua_load_extensions(L, NULL)) { 01160 const char *error = lua_tostring(L, -1); 01161 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error); 01162 lua_close(L); 01163 return NULL; 01164 } 01165 return L; 01166 } else { 01167 ast_channel_lock(chan); 01168 datastore = ast_channel_datastore_find(chan, &lua_datastore, NULL); 01169 ast_channel_unlock(chan); 01170 01171 if (!datastore) { 01172 /* nothing found, allocate a new lua state */ 01173 datastore = ast_datastore_alloc(&lua_datastore, NULL); 01174 if (!datastore) { 01175 ast_log(LOG_ERROR, "Error allocation channel datastore for lua_State\n"); 01176 return NULL; 01177 } 01178 01179 datastore->data = luaL_newstate(); 01180 if (!datastore->data) { 01181 ast_datastore_free(datastore); 01182 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n"); 01183 return NULL; 01184 } 01185 01186 ast_channel_lock(chan); 01187 ast_channel_datastore_add(chan, datastore); 01188 ast_channel_unlock(chan); 01189 01190 L = datastore->data; 01191 01192 if (lua_load_extensions(L, chan)) { 01193 const char *error = lua_tostring(L, -1); 01194 ast_log(LOG_ERROR, "Error loading extensions.lua for %s: %s\n", chan->name, error); 01195 01196 ast_channel_lock(chan); 01197 ast_channel_datastore_remove(chan, datastore); 01198 ast_channel_unlock(chan); 01199 01200 ast_datastore_free(datastore); 01201 return NULL; 01202 } 01203 } 01204 01205 return datastore->data; 01206 } 01207 }
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 523 of file pbx_lua.c.
References ast_alloca, ast_strlen_zero(), LUA_BUF_SIZE, lua_push_variable_table(), name, pbx_retrieve_variable(), value, and ast_channel::varshead.
Referenced by lua_create_channel_table().
00524 { 00525 struct ast_channel *chan; 00526 const char *name = luaL_checkstring(L, 2); 00527 char *value = NULL; 00528 char *workspace = ast_alloca(LUA_BUF_SIZE); 00529 workspace[0] = '\0'; 00530 00531 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00532 chan = lua_touserdata(L, -1); 00533 lua_pop(L, 1); 00534 00535 lua_pushvalue(L, 2); 00536 lua_push_variable_table(L); 00537 00538 /* if this is not a request for a dialplan funciton attempt to retrieve 00539 * the value of the variable */ 00540 if (!ast_strlen_zero(name) && name[strlen(name) - 1] != ')') { 00541 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead); 00542 } 00543 00544 if (value) { 00545 lua_pushstring(L, value); 00546 lua_setfield(L, -2, "value"); 00547 } 00548 00549 return 1; 00550 }
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 266 of file pbx_lua.c.
References ast_alloca, ast_autoservice_start(), ast_autoservice_stop(), ast_func_read(), ast_strdupa, ast_strlen_zero(), LUA_BUF_SIZE, name, pbx_retrieve_variable(), value, and ast_channel::varshead.
Referenced by lua_push_variable_table().
00267 { 00268 struct ast_channel *chan; 00269 char *value = NULL, *name; 00270 char *workspace = ast_alloca(LUA_BUF_SIZE); 00271 int autoservice; 00272 00273 workspace[0] = '\0'; 00274 00275 if (!lua_istable(L, 1)) { 00276 lua_pushstring(L, "User probably used '.' instead of ':' for retrieving a channel variable value"); 00277 return lua_error(L); 00278 } 00279 00280 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00281 chan = lua_touserdata(L, -1); 00282 lua_pop(L, 1); 00283 00284 lua_getfield(L, 1, "name"); 00285 name = ast_strdupa(lua_tostring(L, -1)); 00286 lua_pop(L, 1); 00287 00288 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00289 autoservice = lua_toboolean(L, -1); 00290 lua_pop(L, 1); 00291 00292 if (autoservice) 00293 ast_autoservice_stop(chan); 00294 00295 /* if this is a dialplan function then use ast_func_read(), otherwise 00296 * use pbx_retrieve_variable() */ 00297 if (!ast_strlen_zero(name) && name[strlen(name) - 1] == ')') { 00298 value = ast_func_read(chan, name, workspace, LUA_BUF_SIZE) ? NULL : workspace; 00299 } else { 00300 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead); 00301 } 00302 00303 if (autoservice) 00304 ast_autoservice_start(chan); 00305 00306 if (value) { 00307 lua_pushstring(L, value); 00308 } else { 00309 lua_pushnil(L); 00310 } 00311 00312 return 1; 00313 }
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 |
This function also sets up some constructs used by the extensions.lua file. In the event of an error, an error string will be pushed onto the lua stack.
0 | success | |
1 | failure |
Definition at line 1048 of file pbx_lua.c.
References ast_mutex_lock, ast_mutex_unlock, 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().
01049 { 01050 01051 /* store a pointer to this channel */ 01052 lua_pushlightuserdata(L, chan); 01053 lua_setfield(L, LUA_REGISTRYINDEX, "channel"); 01054 01055 luaL_openlibs(L); 01056 01057 /* load and sort extensions */ 01058 ast_mutex_lock(&config_file_lock); 01059 if (luaL_loadbuffer(L, config_file_data, config_file_size, "extensions.lua") 01060 || lua_pcall(L, 0, LUA_MULTRET, 0) 01061 || lua_sort_extensions(L)) { 01062 ast_mutex_unlock(&config_file_lock); 01063 return 1; 01064 } 01065 ast_mutex_unlock(&config_file_lock); 01066 01067 /* now we setup special tables and functions */ 01068 01069 lua_create_app_table(L); 01070 lua_create_channel_table(L); 01071 01072 lua_create_variable_metatable(L); 01073 lua_create_application_metatable(L); 01074 01075 lua_create_autoservice_functions(L); 01076 lua_create_hangup_function(L); 01077 01078 return 0; 01079 }
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 |
This funciton is executed as the '()' operator for apps accessed through the 'app' table.
app.playback('demo-congrats')
Definition at line 182 of file pbx_lua.c.
References app, ast_autoservice_start(), ast_autoservice_stop(), ast_strdupa, ast_verb, COLOR_BRCYAN, COLOR_BRMAGENTA, context, exten, lua_concat_args(), LUA_EXT_DATA_SIZE, pbx_exec(), pbx_findapp(), and term_color().
Referenced by lua_create_application_metatable().
00183 { 00184 int res, nargs = lua_gettop(L); 00185 const char *data = ""; 00186 char *app_name, *context, *exten; 00187 char tmp[80], tmp2[80], tmp3[LUA_EXT_DATA_SIZE]; 00188 int priority, autoservice; 00189 struct ast_app *app; 00190 struct ast_channel *chan; 00191 00192 lua_getfield(L, 1, "name"); 00193 app_name = ast_strdupa(lua_tostring(L, -1)); 00194 lua_pop(L, 1); 00195 00196 if (!(app = pbx_findapp(app_name))) { 00197 lua_pushstring(L, "application '"); 00198 lua_pushstring(L, app_name); 00199 lua_pushstring(L, "' not found"); 00200 lua_concat(L, 3); 00201 return lua_error(L); 00202 } 00203 00204 00205 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00206 chan = lua_touserdata(L, -1); 00207 lua_pop(L, 1); 00208 00209 00210 lua_getfield(L, LUA_REGISTRYINDEX, "context"); 00211 context = ast_strdupa(lua_tostring(L, -1)); 00212 lua_pop(L, 1); 00213 00214 lua_getfield(L, LUA_REGISTRYINDEX, "exten"); 00215 exten = ast_strdupa(lua_tostring(L, -1)); 00216 lua_pop(L, 1); 00217 00218 lua_getfield(L, LUA_REGISTRYINDEX, "priority"); 00219 priority = lua_tointeger(L, -1); 00220 lua_pop(L, 1); 00221 00222 lua_concat_args(L, 2, nargs); 00223 data = lua_tostring(L, -1); 00224 00225 ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\")\n", 00226 exten, context, priority, 00227 term_color(tmp, app_name, COLOR_BRCYAN, 0, sizeof(tmp)), 00228 term_color(tmp2, chan->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)), 00229 term_color(tmp3, data, COLOR_BRMAGENTA, 0, sizeof(tmp3))); 00230 00231 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00232 autoservice = lua_toboolean(L, -1); 00233 lua_pop(L, 1); 00234 00235 if (autoservice) 00236 ast_autoservice_stop(chan); 00237 00238 res = pbx_exec(chan, app, data); 00239 00240 lua_pop(L, 1); /* pop data */ 00241 data = ""; 00242 00243 if (autoservice) 00244 ast_autoservice_start(chan); 00245 00246 /* error executing an application, report it */ 00247 if (res) { 00248 lua_pushinteger(L, res); 00249 return lua_error(L); 00250 } 00251 return 0; 00252 }
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 151 of file pbx_lua.c.
Referenced by lua_create_app_table().
00152 { 00153 const char *app_name = luaL_checkstring(L, 2); 00154 00155 lua_newtable(L); 00156 00157 lua_pushstring(L, "name"); 00158 lua_pushstring(L, app_name); 00159 lua_settable(L, -3); 00160 00161 luaL_getmetatable(L, "application"); 00162 lua_setmetatable(L, -2); 00163 00164 return 1; 00165 }
static void lua_push_variable_table | ( | lua_State * | L | ) | [static] |
Push a 'variable' table on the stack for access the channel variable with the given name.
The value on the top of the stack is popped and used as the name.
L | the lua_State to use | |
name | the name of the variable |
Definition at line 391 of file pbx_lua.c.
References lua_get_variable_value(), and lua_set_variable_value().
Referenced by lua_func_read(), and lua_get_variable().
00392 { 00393 lua_newtable(L); 00394 luaL_getmetatable(L, "variable"); 00395 lua_setmetatable(L, -2); 00396 00397 lua_insert(L, -2); /* move the table after the name */ 00398 lua_setfield(L, -2, "name"); 00399 00400 lua_pushcfunction(L, &lua_get_variable_value); 00401 lua_setfield(L, -2, "get"); 00402 00403 lua_pushcfunction(L, &lua_set_variable_value); 00404 lua_setfield(L, -2, "set"); 00405 }
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 972 of file pbx_lua.c.
References ast_alloca, ast_config_AST_CONFIG_DIR, ast_free, ast_malloc, errno, f, lua_error_function(), lua_register_switches(), and lua_sort_extensions().
Referenced by lua_reload_extensions().
00973 { 00974 FILE *f; 00975 int error_func; 00976 char *data; 00977 char *path = ast_alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2); 00978 sprintf(path, "%s/%s", ast_config_AST_CONFIG_DIR, config); 00979 00980 if (!(f = fopen(path, "r"))) { 00981 lua_pushstring(L, "cannot open '"); 00982 lua_pushstring(L, path); 00983 lua_pushstring(L, "' for reading: "); 00984 lua_pushstring(L, strerror(errno)); 00985 lua_concat(L, 4); 00986 00987 return NULL; 00988 } 00989 00990 if (fseek(f, 0l, SEEK_END)) { 00991 fclose(f); 00992 lua_pushliteral(L, "error determining the size of the config file"); 00993 return NULL; 00994 } 00995 00996 *size = ftell(f); 00997 00998 if (fseek(f, 0l, SEEK_SET)) { 00999 *size = 0; 01000 fclose(f); 01001 lua_pushliteral(L, "error reading config file"); 01002 return NULL; 01003 } 01004 01005 if (!(data = ast_malloc(*size))) { 01006 *size = 0; 01007 fclose(f); 01008 lua_pushstring(L, "not enough memory"); 01009 return NULL; 01010 } 01011 01012 if (fread(data, sizeof(char), *size, f) != *size) { 01013 *size = 0; 01014 fclose(f); 01015 lua_pushliteral(L, "problem reading configuration file"); 01016 return NULL; 01017 } 01018 fclose(f); 01019 01020 lua_pushcfunction(L, &lua_error_function); 01021 error_func = lua_gettop(L); 01022 01023 if (luaL_loadbuffer(L, data, *size, "extensions.lua") 01024 || lua_pcall(L, 0, LUA_MULTRET, error_func) 01025 || lua_sort_extensions(L) 01026 || lua_register_switches(L)) { 01027 ast_free(data); 01028 data = NULL; 01029 *size = 0; 01030 } 01031 01032 lua_remove(L, error_func); 01033 return data; 01034 }
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 891 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(), and context.
Referenced by lua_read_extensions_file().
00892 { 00893 int extensions; 00894 struct ast_context *con = NULL; 00895 00896 /* create the hash table for our contexts */ 00897 /* XXX do we ever need to destroy this? pbx_config does not */ 00898 if (!local_table) 00899 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); 00900 00901 /* load the 'extensions' table */ 00902 lua_getglobal(L, "extensions"); 00903 extensions = lua_gettop(L); 00904 if (lua_isnil(L, -1)) { 00905 lua_pop(L, 1); 00906 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n"); 00907 return 1; 00908 } 00909 00910 /* iterate through the extensions table and register a context and 00911 * dialplan switch for each lua context 00912 */ 00913 for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) { 00914 int context = lua_gettop(L); 00915 int context_name = context - 1; 00916 const char *context_str = lua_tostring(L, context_name); 00917 00918 /* find or create this context */ 00919 con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar); 00920 if (!con) { 00921 /* remove extensions table and context key and value */ 00922 lua_pop(L, 3); 00923 lua_pushstring(L, "Failed to find or create context\n"); 00924 return 1; 00925 } 00926 00927 /* register the switch */ 00928 if (ast_context_add_switch2(con, "Lua", "", 0, registrar)) { 00929 /* remove extensions table and context key and value */ 00930 lua_pop(L, 3); 00931 lua_pushstring(L, "Unable to create switch for context\n"); 00932 return 1; 00933 } 00934 } 00935 00936 /* remove the extensions table */ 00937 lua_pop(L, 1); 00938 return 0; 00939 }
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 1091 of file pbx_lua.c.
References ast_free, ast_merge_contexts_and_delete(), ast_mutex_lock, ast_mutex_unlock, config_file_lock, and lua_read_extensions_file().
Referenced by load_or_reload_lua_stuff().
01092 { 01093 long size = 0; 01094 char *data = NULL; 01095 01096 luaL_openlibs(L); 01097 01098 if (!(data = lua_read_extensions_file(L, &size))) { 01099 return 1; 01100 } 01101 01102 ast_mutex_lock(&config_file_lock); 01103 01104 if (config_file_data) 01105 ast_free(config_file_data); 01106 01107 config_file_data = data; 01108 config_file_size = size; 01109 01110 /* merge our new contexts */ 01111 ast_merge_contexts_and_delete(&local_contexts, local_table, registrar); 01112 /* merge_contexts_and_delete will actually, at the correct moment, 01113 set the global dialplan pointers to your local_contexts and local_table. 01114 It then will free up the old tables itself. Just be sure not to 01115 hang onto the pointers. */ 01116 local_table = NULL; 01117 local_contexts = NULL; 01118 01119 ast_mutex_unlock(&config_file_lock); 01120 return 0; 01121 }
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 563 of file pbx_lua.c.
References ast_autoservice_start(), ast_autoservice_stop(), name, pbx_builtin_setvar_helper(), and value.
Referenced by lua_create_channel_table().
00564 { 00565 struct ast_channel *chan; 00566 int autoservice; 00567 const char *name = luaL_checkstring(L, 2); 00568 const char *value = luaL_checkstring(L, 3); 00569 00570 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00571 chan = lua_touserdata(L, -1); 00572 lua_pop(L, 1); 00573 00574 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00575 autoservice = lua_toboolean(L, -1); 00576 lua_pop(L, 1); 00577 00578 if (autoservice) 00579 ast_autoservice_stop(chan); 00580 00581 pbx_builtin_setvar_helper(chan, name, value); 00582 00583 if (autoservice) 00584 ast_autoservice_start(chan); 00585 00586 return 0; 00587 }
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 326 of file pbx_lua.c.
References ast_autoservice_start(), ast_autoservice_stop(), ast_strdupa, name, pbx_builtin_setvar_helper(), and value.
Referenced by lua_push_variable_table().
00327 { 00328 const char *name, *value; 00329 struct ast_channel *chan; 00330 int autoservice; 00331 00332 if (!lua_istable(L, 1)) { 00333 lua_pushstring(L, "User probably used '.' instead of ':' for setting a channel variable"); 00334 return lua_error(L); 00335 } 00336 00337 lua_getfield(L, 1, "name"); 00338 name = ast_strdupa(lua_tostring(L, -1)); 00339 lua_pop(L, 1); 00340 00341 value = luaL_checkstring(L, 2); 00342 00343 lua_getfield(L, LUA_REGISTRYINDEX, "channel"); 00344 chan = lua_touserdata(L, -1); 00345 lua_pop(L, 1); 00346 00347 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 00348 autoservice = lua_toboolean(L, -1); 00349 lua_pop(L, 1); 00350 00351 if (autoservice) 00352 ast_autoservice_stop(chan); 00353 00354 pbx_builtin_setvar_helper(chan, name, value); 00355 00356 if (autoservice) 00357 ast_autoservice_start(chan); 00358 00359 return 0; 00360 }
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 809 of file pbx_lua.c.
References context, exten, and lua_extension_cmp().
Referenced by lua_load_extensions(), and lua_read_extensions_file().
00810 { 00811 int extensions, extensions_order; 00812 00813 /* create the extensions_order table */ 00814 lua_newtable(L); 00815 lua_setfield(L, LUA_REGISTRYINDEX, "extensions_order"); 00816 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order"); 00817 extensions_order = lua_gettop(L); 00818 00819 /* sort each context in the extensions table */ 00820 /* load the 'extensions' table */ 00821 lua_getglobal(L, "extensions"); 00822 extensions = lua_gettop(L); 00823 if (lua_isnil(L, -1)) { 00824 lua_pop(L, 1); 00825 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n"); 00826 return 1; 00827 } 00828 00829 /* iterate through the extensions table and create a 00830 * matching table (holding the sort order) in the 00831 * extensions_order table for each context that is found 00832 */ 00833 for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) { 00834 int context = lua_gettop(L); 00835 int context_name = context - 1; 00836 int context_order; 00837 00838 /* copy the context_name to be used as the key for the 00839 * context_order table in the extensions_order table later */ 00840 lua_pushvalue(L, context_name); 00841 00842 /* create the context_order table */ 00843 lua_newtable(L); 00844 context_order = lua_gettop(L); 00845 00846 /* iterate through this context an popluate the corrisponding 00847 * table in the extensions_order table */ 00848 for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) { 00849 int exten = lua_gettop(L) - 1; 00850 00851 lua_pushinteger(L, lua_objlen(L, context_order) + 1); 00852 lua_pushvalue(L, exten); 00853 lua_settable(L, context_order); 00854 } 00855 lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */ 00856 00857 /* now sort the new table */ 00858 00859 /* push the table.sort function */ 00860 lua_getglobal(L, "table"); 00861 lua_getfield(L, -1, "sort"); 00862 lua_remove(L, -2); /* remove the 'table' table */ 00863 00864 /* push the context_order table */ 00865 lua_pushvalue(L, context_name); 00866 lua_gettable(L, extensions_order); 00867 00868 /* push the comp function */ 00869 lua_pushcfunction(L, &lua_extension_cmp); 00870 00871 if (lua_pcall(L, 2, 0, 0)) { 00872 lua_insert(L, -5); 00873 lua_pop(L, 4); 00874 return 1; 00875 } 00876 } 00877 00878 /* remove the extensions table and the extensions_order table */ 00879 lua_pop(L, 2); 00880 return 0; 00881 }
static void lua_state_destroy | ( | void * | data | ) | [static] |
static void lua_update_registry | ( | lua_State * | L, | |
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) | [static] |
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 1255 of file pbx_lua.c.
References ast_log(), ast_module_user_add, ast_module_user_remove, LOG_ERROR, lua_find_extension(), and lua_get_state().
Referenced by complete_dpreply(), and lua_find_extension().
01256 { 01257 int res; 01258 lua_State *L; 01259 struct ast_module_user *u = ast_module_user_add(chan); 01260 if (!u) { 01261 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01262 return 0; 01263 } 01264 01265 L = lua_get_state(chan); 01266 if (!L) { 01267 ast_module_user_remove(u); 01268 return 0; 01269 } 01270 01271 res = lua_find_extension(L, context, exten, priority, &matchmore, 0); 01272 01273 if (!chan) lua_close(L); 01274 ast_module_user_remove(u); 01275 return res; 01276 }
static int reload | ( | void | ) | [static] |
Definition at line 1534 of file pbx_lua.c.
References load_or_reload_lua_stuff().
01535 { 01536 return load_or_reload_lua_stuff(); 01537 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1526 of file pbx_lua.c.
References ast_context_destroy(), ast_unregister_switch(), and lua_free_extensions().
01527 { 01528 ast_context_destroy(NULL, registrar); 01529 ast_unregister_switch(&lua_switch); 01530 lua_free_extensions(); 01531 return 0; 01532 }
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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
struct ast_module_info* ast_module_info = &__mod_info [static] |
char* config_file_data = NULL [static] |
ast_mutex_t config_file_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 102 of file pbx_lua.c.
Referenced by lua_free_extensions(), lua_load_extensions(), and lua_reload_extensions().
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] |
{ .type = "lua", .destroy = lua_state_destroy, .chan_fixup = lua_datastore_fixup, }
struct ast_switch lua_switch [static] |