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 1235 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().
01236 { 01237 int res; 01238 lua_State *L; 01239 struct ast_module_user *u = ast_module_user_add(chan); 01240 if (!u) { 01241 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01242 return 0; 01243 } 01244 01245 L = lua_get_state(chan); 01246 if (!L) { 01247 ast_module_user_remove(u); 01248 return 0; 01249 } 01250 01251 res = lua_find_extension(L, context, exten, priority, &canmatch, 0); 01252 01253 if (!chan) lua_close(L); 01254 ast_module_user_remove(u); 01255 return res; 01256 }
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 1282 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().
01283 { 01284 int res, error_func; 01285 lua_State *L; 01286 struct ast_module_user *u = ast_module_user_add(chan); 01287 if (!u) { 01288 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01289 return -1; 01290 } 01291 01292 L = lua_get_state(chan); 01293 if (!L) { 01294 ast_module_user_remove(u); 01295 return -1; 01296 } 01297 01298 lua_pushcfunction(L, &lua_error_function); 01299 error_func = lua_gettop(L); 01300 01301 /* push the extension function onto the stack */ 01302 if (!lua_find_extension(L, context, exten, priority, &exists, 1)) { 01303 lua_pop(L, 1); /* pop the debug function */ 01304 ast_log(LOG_ERROR, "Could not find extension %s in context %s\n", exten, context); 01305 if (!chan) lua_close(L); 01306 ast_module_user_remove(u); 01307 return -1; 01308 } 01309 01310 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 01311 if (lua_toboolean(L, -1)) { 01312 ast_autoservice_start(chan); 01313 } 01314 lua_pop(L, 1); 01315 01316 lua_update_registry(L, context, exten, priority); 01317 01318 lua_pushstring(L, context); 01319 lua_pushstring(L, exten); 01320 01321 res = lua_pcall(L, 2, 0, error_func); 01322 if (res) { 01323 if (res == LUA_ERRRUN) { 01324 res = -1; 01325 if (lua_isnumber(L, -1)) { 01326 res = lua_tointeger(L, -1); 01327 } else if (lua_isstring(L, -1)) { 01328 const char *error = lua_tostring(L, -1); 01329 ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error); 01330 } 01331 } else if (res == LUA_ERRERR) { 01332 res = -1; 01333 ast_log(LOG_ERROR, "Error in the lua error handler (this is probably a bug in pbx_lua)\n"); 01334 } else if (res == LUA_ERRMEM) { 01335 res = -1; 01336 ast_log(LOG_ERROR, "Memory allocation error\n"); 01337 } 01338 lua_pop(L, 1); 01339 } 01340 lua_remove(L, error_func); 01341 01342 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice"); 01343 if (lua_toboolean(L, -1)) { 01344 ast_autoservice_stop(chan); 01345 } 01346 lua_pop(L, 1); 01347 01348 if (!chan) lua_close(L); 01349 ast_module_user_remove(u); 01350 return res; 01351 }
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 1212 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().
01213 { 01214 int res; 01215 lua_State *L; 01216 struct ast_module_user *u = ast_module_user_add(chan); 01217 if (!u) { 01218 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01219 return 0; 01220 } 01221 01222 L = lua_get_state(chan); 01223 if (!L) { 01224 ast_module_user_remove(u); 01225 return 0; 01226 } 01227 01228 res = lua_find_extension(L, context, exten, priority, &exists, 0); 01229 01230 if (!chan) lua_close(L); 01231 ast_module_user_remove(u); 01232 return res; 01233 }
static int load_module | ( | void | ) | [static] |
Definition at line 1550 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.
01551 { 01552 int res; 01553 01554 if ((res = load_or_reload_lua_stuff())) 01555 return res; 01556 01557 if (ast_register_switch(&lua_switch)) { 01558 ast_log(LOG_ERROR, "Unable to register LUA PBX switch\n"); 01559 return AST_MODULE_LOAD_DECLINE; 01560 } 01561 01562 return AST_MODULE_LOAD_SUCCESS; 01563 }
static int load_or_reload_lua_stuff | ( | void | ) | [static] |
Definition at line 1513 of file pbx_lua.c.
References ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, LOG_ERROR, LOG_NOTICE, and lua_reload_extensions().
Referenced by load_module(), and reload().
01514 { 01515 int res = AST_MODULE_LOAD_SUCCESS; 01516 01517 lua_State *L = luaL_newstate(); 01518 if (!L) { 01519 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n"); 01520 return AST_MODULE_LOAD_DECLINE; 01521 } 01522 01523 if (lua_reload_extensions(L)) { 01524 const char *error = lua_tostring(L, -1); 01525 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error); 01526 res = AST_MODULE_LOAD_DECLINE; 01527 } 01528 01529 if (!res) { 01530 ast_log(LOG_NOTICE, "Lua PBX Switch loaded.\n"); 01531 } 01532 lua_close(L); 01533 return res; 01534 }
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 952 of file pbx_lua.c.
References ast_extension_cmp().
Referenced by lua_sort_extensions().
00953 { 00954 const char *a = luaL_checkstring(L, -2); 00955 const char *b = luaL_checkstring(L, -1); 00956 00957 if (ast_extension_cmp(a, b) == -1) 00958 lua_pushboolean(L, 1); 00959 else 00960 lua_pushboolean(L, 0); 00961 00962 return 1; 00963 }
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 1366 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().
01367 { 01368 int context_table, context_order_table, i; 01369 01370 ast_debug(2, "Looking up %s@%s:%i\n", exten, context, priority); 01371 if (priority != 1) 01372 return 0; 01373 01374 /* load the 'extensions' table */ 01375 lua_getglobal(L, "extensions"); 01376 if (lua_isnil(L, -1)) { 01377 ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n"); 01378 lua_pop(L, 1); 01379 return 0; 01380 } 01381 01382 /* load the given context */ 01383 lua_getfield(L, -1, context); 01384 if (lua_isnil(L, -1)) { 01385 lua_pop(L, 2); 01386 return 0; 01387 } 01388 01389 /* remove the extensions table */ 01390 lua_remove(L, -2); 01391 01392 context_table = lua_gettop(L); 01393 01394 /* load the extensions order table for this context */ 01395 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order"); 01396 lua_getfield(L, -1, context); 01397 01398 lua_remove(L, -2); /* remove the extensions order table */ 01399 01400 context_order_table = lua_gettop(L); 01401 01402 /* step through the extensions looking for a match */ 01403 #if LUA_VERSION_NUM < 502 01404 for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) { 01405 #else 01406 for (i = 1; i < lua_rawlen(L, context_order_table) + 1; i++) { 01407 #endif 01408 int e_index_copy, match = 0; 01409 const char *e; 01410 01411 lua_pushinteger(L, i); 01412 lua_gettable(L, context_order_table); 01413 lua_gettop(L); 01414 01415 /* copy the key at the top of the stack for use later */ 01416 lua_pushvalue(L, -1); 01417 e_index_copy = lua_gettop(L); 01418 01419 if (!(e = lua_tostring(L, e_index_copy))) { 01420 lua_pop(L, 2); 01421 continue; 01422 } 01423 01424 /* make sure this is not the 'include' extension */ 01425 if (!strcasecmp(e, "include")) { 01426 lua_pop(L, 2); 01427 continue; 01428 } 01429 01430 if (func == &matchmore) 01431 match = ast_extension_close(e, exten, E_MATCHMORE); 01432 else if (func == &canmatch) 01433 match = ast_extension_close(e, exten, E_CANMATCH); 01434 else 01435 match = ast_extension_match(e, exten); 01436 01437 /* the extension matching functions return 0 on fail, 1 on 01438 * match, 2 on earlymatch */ 01439 01440 if (!match) { 01441 /* pop the copy and the extension */ 01442 lua_pop(L, 2); 01443 continue; /* keep trying */ 01444 } 01445 01446 if (func == &matchmore && match == 2) { 01447 /* We match an extension ending in '!'. The decision in 01448 * this case is final and counts as no match. */ 01449 lua_pop(L, 4); 01450 return 0; 01451 } 01452 01453 /* remove the context table, the context order table, the 01454 * extension, and the extension copy (or replace the extension 01455 * with the corresponding function) */ 01456 if (push_func) { 01457 lua_pop(L, 1); /* pop the copy */ 01458 lua_gettable(L, context_table); 01459 lua_insert(L, -3); 01460 lua_pop(L, 2); 01461 } else { 01462 lua_pop(L, 4); 01463 } 01464 01465 return 1; 01466 } 01467 01468 /* load the includes for this context */ 01469 lua_getfield(L, context_table, "include"); 01470 if (lua_isnil(L, -1)) { 01471 lua_pop(L, 3); 01472 return 0; 01473 } 01474 01475 /* remove the context and the order table*/ 01476 lua_remove(L, context_order_table); 01477 lua_remove(L, context_table); 01478 01479 /* Now try any includes we have in this context */ 01480 for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { 01481 const char *c = lua_tostring(L, -1); 01482 if (!c) 01483 continue; 01484 01485 if (lua_find_extension(L, c, exten, priority, func, push_func)) { 01486 /* remove the value, the key, and the includes table 01487 * from the stack. Leave the function behind if 01488 * necessary */ 01489 01490 if (push_func) 01491 lua_insert(L, -4); 01492 01493 lua_pop(L, 3); 01494 return 1; 01495 } 01496 } 01497 01498 /* pop the includes table */ 01499 lua_pop(L, 1); 01500 return 0; 01501 }
static void lua_free_extensions | ( | void | ) | [static] |
Free the internal extensions buffer.
Definition at line 1129 of file pbx_lua.c.
References ast_free, ast_mutex_lock, ast_mutex_unlock, and config_file_lock.
Referenced by unload_module().
01130 { 01131 ast_mutex_lock(&config_file_lock); 01132 config_file_size = 0; 01133 ast_free(config_file_data); 01134 ast_mutex_unlock(&config_file_lock); 01135 }
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 1150 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().
01151 { 01152 struct ast_datastore *datastore = NULL; 01153 lua_State *L; 01154 01155 if (!chan) { 01156 lua_State *L = luaL_newstate(); 01157 if (!L) { 01158 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n"); 01159 return NULL; 01160 } 01161 01162 if (lua_load_extensions(L, NULL)) { 01163 const char *error = lua_tostring(L, -1); 01164 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error); 01165 lua_close(L); 01166 return NULL; 01167 } 01168 return L; 01169 } else { 01170 ast_channel_lock(chan); 01171 datastore = ast_channel_datastore_find(chan, &lua_datastore, NULL); 01172 ast_channel_unlock(chan); 01173 01174 if (!datastore) { 01175 /* nothing found, allocate a new lua state */ 01176 datastore = ast_datastore_alloc(&lua_datastore, NULL); 01177 if (!datastore) { 01178 ast_log(LOG_ERROR, "Error allocation channel datastore for lua_State\n"); 01179 return NULL; 01180 } 01181 01182 datastore->data = luaL_newstate(); 01183 if (!datastore->data) { 01184 ast_datastore_free(datastore); 01185 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n"); 01186 return NULL; 01187 } 01188 01189 ast_channel_lock(chan); 01190 ast_channel_datastore_add(chan, datastore); 01191 ast_channel_unlock(chan); 01192 01193 L = datastore->data; 01194 01195 if (lua_load_extensions(L, chan)) { 01196 const char *error = lua_tostring(L, -1); 01197 ast_log(LOG_ERROR, "Error loading extensions.lua for %s: %s\n", chan->name, error); 01198 01199 ast_channel_lock(chan); 01200 ast_channel_datastore_remove(chan, datastore); 01201 ast_channel_unlock(chan); 01202 01203 ast_datastore_free(datastore); 01204 return NULL; 01205 } 01206 } 01207 01208 return datastore->data; 01209 } 01210 }
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 1051 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().
01052 { 01053 01054 /* store a pointer to this channel */ 01055 lua_pushlightuserdata(L, chan); 01056 lua_setfield(L, LUA_REGISTRYINDEX, "channel"); 01057 01058 luaL_openlibs(L); 01059 01060 /* load and sort extensions */ 01061 ast_mutex_lock(&config_file_lock); 01062 if (luaL_loadbuffer(L, config_file_data, config_file_size, "extensions.lua") 01063 || lua_pcall(L, 0, LUA_MULTRET, 0) 01064 || lua_sort_extensions(L)) { 01065 ast_mutex_unlock(&config_file_lock); 01066 return 1; 01067 } 01068 ast_mutex_unlock(&config_file_lock); 01069 01070 /* now we setup special tables and functions */ 01071 01072 lua_create_app_table(L); 01073 lua_create_channel_table(L); 01074 01075 lua_create_variable_metatable(L); 01076 lua_create_application_metatable(L); 01077 01078 lua_create_autoservice_functions(L); 01079 lua_create_hangup_function(L); 01080 01081 return 0; 01082 }
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 975 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().
00976 { 00977 FILE *f; 00978 int error_func; 00979 char *data; 00980 char *path = ast_alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2); 00981 sprintf(path, "%s/%s", ast_config_AST_CONFIG_DIR, config); 00982 00983 if (!(f = fopen(path, "r"))) { 00984 lua_pushstring(L, "cannot open '"); 00985 lua_pushstring(L, path); 00986 lua_pushstring(L, "' for reading: "); 00987 lua_pushstring(L, strerror(errno)); 00988 lua_concat(L, 4); 00989 00990 return NULL; 00991 } 00992 00993 if (fseek(f, 0l, SEEK_END)) { 00994 fclose(f); 00995 lua_pushliteral(L, "error determining the size of the config file"); 00996 return NULL; 00997 } 00998 00999 *size = ftell(f); 01000 01001 if (fseek(f, 0l, SEEK_SET)) { 01002 *size = 0; 01003 fclose(f); 01004 lua_pushliteral(L, "error reading config file"); 01005 return NULL; 01006 } 01007 01008 if (!(data = ast_malloc(*size))) { 01009 *size = 0; 01010 fclose(f); 01011 lua_pushstring(L, "not enough memory"); 01012 return NULL; 01013 } 01014 01015 if (fread(data, sizeof(char), *size, f) != *size) { 01016 *size = 0; 01017 fclose(f); 01018 lua_pushliteral(L, "problem reading configuration file"); 01019 return NULL; 01020 } 01021 fclose(f); 01022 01023 lua_pushcfunction(L, &lua_error_function); 01024 error_func = lua_gettop(L); 01025 01026 if (luaL_loadbuffer(L, data, *size, "extensions.lua") 01027 || lua_pcall(L, 0, LUA_MULTRET, error_func) 01028 || lua_sort_extensions(L) 01029 || lua_register_switches(L)) { 01030 ast_free(data); 01031 data = NULL; 01032 *size = 0; 01033 } 01034 01035 lua_remove(L, error_func); 01036 return data; 01037 }
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 894 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().
00895 { 00896 int extensions; 00897 struct ast_context *con = NULL; 00898 00899 /* create the hash table for our contexts */ 00900 /* XXX do we ever need to destroy this? pbx_config does not */ 00901 if (!local_table) 00902 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0); 00903 00904 /* load the 'extensions' table */ 00905 lua_getglobal(L, "extensions"); 00906 extensions = lua_gettop(L); 00907 if (lua_isnil(L, -1)) { 00908 lua_pop(L, 1); 00909 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n"); 00910 return 1; 00911 } 00912 00913 /* iterate through the extensions table and register a context and 00914 * dialplan switch for each lua context 00915 */ 00916 for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) { 00917 int context = lua_gettop(L); 00918 int context_name = context - 1; 00919 const char *context_str = lua_tostring(L, context_name); 00920 00921 /* find or create this context */ 00922 con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar); 00923 if (!con) { 00924 /* remove extensions table and context key and value */ 00925 lua_pop(L, 3); 00926 lua_pushstring(L, "Failed to find or create context\n"); 00927 return 1; 00928 } 00929 00930 /* register the switch */ 00931 if (ast_context_add_switch2(con, "Lua", "", 0, registrar)) { 00932 /* remove extensions table and context key and value */ 00933 lua_pop(L, 3); 00934 lua_pushstring(L, "Unable to create switch for context\n"); 00935 return 1; 00936 } 00937 } 00938 00939 /* remove the extensions table */ 00940 lua_pop(L, 1); 00941 return 0; 00942 }
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 1094 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().
01095 { 01096 long size = 0; 01097 char *data = NULL; 01098 01099 luaL_openlibs(L); 01100 01101 if (!(data = lua_read_extensions_file(L, &size))) { 01102 return 1; 01103 } 01104 01105 ast_mutex_lock(&config_file_lock); 01106 01107 if (config_file_data) 01108 ast_free(config_file_data); 01109 01110 config_file_data = data; 01111 config_file_size = size; 01112 01113 /* merge our new contexts */ 01114 ast_merge_contexts_and_delete(&local_contexts, local_table, registrar); 01115 /* merge_contexts_and_delete will actually, at the correct moment, 01116 set the global dialplan pointers to your local_contexts and local_table. 01117 It then will free up the old tables itself. Just be sure not to 01118 hang onto the pointers. */ 01119 local_table = NULL; 01120 local_contexts = NULL; 01121 01122 ast_mutex_unlock(&config_file_lock); 01123 return 0; 01124 }
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 #if LUA_VERSION_NUM < 502 00851 lua_pushinteger(L, lua_objlen(L, context_order) + 1); 00852 #else 00853 lua_pushinteger(L, lua_rawlen(L, context_order) + 1); 00854 #endif 00855 lua_pushvalue(L, exten); 00856 lua_settable(L, context_order); 00857 } 00858 lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */ 00859 00860 /* now sort the new table */ 00861 00862 /* push the table.sort function */ 00863 lua_getglobal(L, "table"); 00864 lua_getfield(L, -1, "sort"); 00865 lua_remove(L, -2); /* remove the 'table' table */ 00866 00867 /* push the context_order table */ 00868 lua_pushvalue(L, context_name); 00869 lua_gettable(L, extensions_order); 00870 00871 /* push the comp function */ 00872 lua_pushcfunction(L, &lua_extension_cmp); 00873 00874 if (lua_pcall(L, 2, 0, 0)) { 00875 lua_insert(L, -5); 00876 lua_pop(L, 4); 00877 return 1; 00878 } 00879 } 00880 00881 /* remove the extensions table and the extensions_order table */ 00882 lua_pop(L, 2); 00883 return 0; 00884 }
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 1258 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().
01259 { 01260 int res; 01261 lua_State *L; 01262 struct ast_module_user *u = ast_module_user_add(chan); 01263 if (!u) { 01264 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n"); 01265 return 0; 01266 } 01267 01268 L = lua_get_state(chan); 01269 if (!L) { 01270 ast_module_user_remove(u); 01271 return 0; 01272 } 01273 01274 res = lua_find_extension(L, context, exten, priority, &matchmore, 0); 01275 01276 if (!chan) lua_close(L); 01277 ast_module_user_remove(u); 01278 return res; 01279 }
static int reload | ( | void | ) | [static] |
Definition at line 1545 of file pbx_lua.c.
References load_or_reload_lua_stuff().
01546 { 01547 return load_or_reload_lua_stuff(); 01548 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1536 of file pbx_lua.c.
References ast_context_destroy(), ast_log(), ast_unregister_switch(), LOG_NOTICE, and lua_free_extensions().
01537 { 01538 ast_context_destroy(NULL, registrar); 01539 ast_unregister_switch(&lua_switch); 01540 lua_free_extensions(); 01541 ast_log(LOG_NOTICE, "Lua PBX Switch unloaded.\n"); 01542 return 0; 01543 }
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] |