2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2007, Digium, Inc.
6 * Matthew Nicholson <mnicholson@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
22 * \author Matthew Nicholson <mnicholson@digium.com>
23 * \brief Lua PBX Switch
33 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
40 #include "asterisk/logger.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/pbx.h"
43 #include "asterisk/module.h"
44 #include "asterisk/cli.h"
45 #include "asterisk/utils.h"
46 #include "asterisk/term.h"
52 static char *config = "extensions.lua";
54 #define LUA_EXT_DATA_SIZE 256
55 #define LUA_BUF_SIZE 4096
57 static char *lua_read_extensions_file(lua_State *L, long *size);
58 static int lua_load_extensions(lua_State *L, struct ast_channel *chan);
59 static int lua_reload_extensions(lua_State *L);
60 static void lua_free_extensions(void);
61 static int lua_sort_extensions(lua_State *L);
62 static int lua_extension_cmp(lua_State *L);
63 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func);
64 static int lua_pbx_findapp(lua_State *L);
65 static int lua_pbx_exec(lua_State *L);
67 static int lua_get_variable_value(lua_State *L);
68 static int lua_set_variable_value(lua_State *L);
69 static int lua_get_variable(lua_State *L);
70 static int lua_set_variable(lua_State *L);
71 static int lua_func_read(lua_State *L);
73 static int lua_autoservice_start(lua_State *L);
74 static int lua_autoservice_stop(lua_State *L);
75 static int lua_autoservice_status(lua_State *L);
77 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority);
78 static void lua_push_variable_table(lua_State *L, const char *name);
79 static void lua_create_app_table(lua_State *L);
80 static void lua_create_channel_table(lua_State *L);
81 static void lua_create_variable_metatable(lua_State *L);
82 static void lua_create_application_metatable(lua_State *L);
83 static void lua_create_autoservice_functions(lua_State *L);
85 void lua_state_destroy(void *data);
86 static lua_State *lua_get_state(struct ast_channel *chan);
88 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
89 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
90 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
91 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
93 AST_MUTEX_DEFINE_STATIC(config_file_lock);
94 char *config_file_data = NULL;
95 long config_file_size = 0;
97 static const struct ast_datastore_info lua_datastore = {
99 .destroy = lua_state_destroy,
104 * \brief The destructor for lua_datastore
106 void lua_state_destroy(void *data)
113 * \brief [lua_CFunction] Find an app and return it in a lua table (for access from lua, don't
116 * This function would be called in the following example as it would be found
123 static int lua_pbx_findapp(lua_State *L)
125 const char *app_name = luaL_checkstring(L, 2);
129 lua_pushstring(L, "name");
130 lua_pushstring(L, app_name);
133 luaL_getmetatable(L, "application");
134 lua_setmetatable(L, -2);
140 * \brief [lua_CFunction] This function is part of the 'application' metatable
141 * and is used to execute applications similar to pbx_exec() (for access from
142 * lua, don't call directly)
144 * \param L the lua_State to use
147 * This funciton is executed as the '()' operator for apps accessed through the
151 * app.playback('demo-congrats')
154 static int lua_pbx_exec(lua_State *L)
156 int res, nargs = lua_gettop(L);
157 char data[LUA_EXT_DATA_SIZE] = "";
158 char *data_next = data, *app_name;
159 char *context, *exten;
160 char tmp[80], tmp2[80], tmp3[LUA_EXT_DATA_SIZE];
161 int priority, autoservice;
162 size_t data_left = sizeof(data);
164 struct ast_channel *chan;
166 lua_getfield(L, 1, "name");
167 app_name = ast_strdupa(lua_tostring(L, -1));
170 if (!(app = pbx_findapp(app_name))) {
171 lua_pushstring(L, "application '");
172 lua_pushstring(L, app_name);
173 lua_pushstring(L, "' not found");
179 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
180 chan = lua_touserdata(L, -1);
184 lua_getfield(L, LUA_REGISTRYINDEX, "context");
185 context = ast_strdupa(lua_tostring(L, -1));
188 lua_getfield(L, LUA_REGISTRYINDEX, "exten");
189 exten = ast_strdupa(lua_tostring(L, -1));
192 lua_getfield(L, LUA_REGISTRYINDEX, "priority");
193 priority = lua_tointeger(L, -1);
200 if (!lua_isnil(L, 2))
201 ast_build_string(&data_next, &data_left, "%s", luaL_checkstring(L, 2));
203 for (i = 3; i <= nargs; i++) {
205 ast_build_string(&data_next, &data_left, ",");
207 ast_build_string(&data_next, &data_left, ",%s", luaL_checkstring(L, i));
211 ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\")\n",
212 exten, context, priority,
213 term_color(tmp, app_name, COLOR_BRCYAN, 0, sizeof(tmp)),
214 term_color(tmp2, chan->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
215 term_color(tmp3, data, COLOR_BRMAGENTA, 0, sizeof(tmp3)));
217 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
218 autoservice = lua_toboolean(L, -1);
222 ast_autoservice_stop(chan);
224 res = pbx_exec(chan, app, data);
227 ast_autoservice_start(chan);
229 /* error executing an application, report it */
231 lua_pushinteger(L, res);
238 * \brief [lua_CFunction] Used to get the value of a variable or dialplan
239 * function (for access from lua, don't call directly)
241 * The value of the variable or function is returned. This function is the
242 * 'get()' function in the following example as would be seen in
246 * channel.variable:get()
249 static int lua_get_variable_value(lua_State *L)
251 struct ast_channel *chan;
252 char *value = NULL, *name;
253 char *workspace = alloca(LUA_BUF_SIZE);
258 if (!lua_istable(L, 1)) {
259 lua_pushstring(L, "User probably used '.' instead of ':' for retrieving a channel variable value");
263 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
264 chan = lua_touserdata(L, -1);
267 lua_getfield(L, 1, "name");
268 name = ast_strdupa(lua_tostring(L, -1));
271 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
272 autoservice = lua_toboolean(L, -1);
276 ast_autoservice_stop(chan);
278 /* if this is a dialplan function then use ast_func_read(), otherwise
279 * use pbx_retrieve_variable() */
280 if (!ast_strlen_zero(name) && name[strlen(name) - 1] == ')') {
281 value = ast_func_read(chan, name, workspace, LUA_BUF_SIZE) ? NULL : workspace;
283 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
287 ast_autoservice_start(chan);
290 lua_pushstring(L, value);
299 * \brief [lua_CFunction] Used to set the value of a variable or dialplan
300 * function (for access from lua, don't call directly)
302 * This function is the 'set()' function in the following example as would be
303 * seen in extensions.lua.
306 * channel.variable:set()
309 static int lua_set_variable_value(lua_State *L)
311 const char *name, *value;
312 struct ast_channel *chan;
315 if (!lua_istable(L, 1)) {
316 lua_pushstring(L, "User probably used '.' instead of ':' for setting a channel variable");
320 lua_getfield(L, 1, "name");
321 name = ast_strdupa(lua_tostring(L, -1));
324 value = luaL_checkstring(L, 2);
326 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
327 chan = lua_touserdata(L, -1);
330 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
331 autoservice = lua_toboolean(L, -1);
335 ast_autoservice_stop(chan);
337 pbx_builtin_setvar_helper(chan, name, value);
340 ast_autoservice_start(chan);
346 * \brief Update the lua registry with the given context, exten, and priority.
348 * \param L the lua_State to use
349 * \param context the new context
350 * \param exten the new exten
351 * \param priority the new priority
353 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority)
355 lua_pushstring(L, context);
356 lua_setfield(L, LUA_REGISTRYINDEX, "context");
358 lua_pushstring(L, exten);
359 lua_setfield(L, LUA_REGISTRYINDEX, "exten");
361 lua_pushinteger(L, priority);
362 lua_setfield(L, LUA_REGISTRYINDEX, "priority");
366 * \brief Push a 'variable' table on the stack for access the channel variable
367 * with the given name.
369 * \param L the lua_State to use
370 * \param name the name of the variable
372 static void lua_push_variable_table(lua_State *L, const char *name)
375 luaL_getmetatable(L, "variable");
376 lua_setmetatable(L, -2);
378 lua_pushstring(L, name);
379 lua_setfield(L, -2, "name");
381 lua_pushcfunction(L, &lua_get_variable_value);
382 lua_setfield(L, -2, "get");
384 lua_pushcfunction(L, &lua_set_variable_value);
385 lua_setfield(L, -2, "set");
389 * \brief Create the global 'app' table for executing applications
391 * \param L the lua_State to use
393 static void lua_create_app_table(lua_State *L)
396 luaL_newmetatable(L, "app");
398 lua_pushstring(L, "__index");
399 lua_pushcfunction(L, &lua_pbx_findapp);
402 lua_setmetatable(L, -2);
403 lua_setglobal(L, "app");
407 * \brief Create the global 'channel' table for accesing channel variables
409 * \param L the lua_State to use
411 static void lua_create_channel_table(lua_State *L)
414 luaL_newmetatable(L, "channel_data");
416 lua_pushstring(L, "__index");
417 lua_pushcfunction(L, &lua_get_variable);
420 lua_pushstring(L, "__newindex");
421 lua_pushcfunction(L, &lua_set_variable);
424 lua_setmetatable(L, -2);
425 lua_setglobal(L, "channel");
429 * \brief Create the 'variable' metatable, used to retrieve channel variables
431 * \param L the lua_State to use
433 static void lua_create_variable_metatable(lua_State *L)
435 luaL_newmetatable(L, "variable");
437 lua_pushstring(L, "__call");
438 lua_pushcfunction(L, &lua_func_read);
445 * \brief Create the 'application' metatable, used to execute asterisk
446 * applications from lua
448 * \param L the lua_State to use
450 static void lua_create_application_metatable(lua_State *L)
452 luaL_newmetatable(L, "application");
454 lua_pushstring(L, "__call");
455 lua_pushcfunction(L, &lua_pbx_exec);
462 * \brief Create the autoservice functions
464 * \param L the lua_State to use
466 static void lua_create_autoservice_functions(lua_State *L)
468 lua_pushcfunction(L, &lua_autoservice_start);
469 lua_setglobal(L, "autoservice_start");
471 lua_pushcfunction(L, &lua_autoservice_stop);
472 lua_setglobal(L, "autoservice_stop");
474 lua_pushcfunction(L, &lua_autoservice_status);
475 lua_setglobal(L, "autoservice_status");
477 lua_pushboolean(L, 0);
478 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
482 * \brief [lua_CFunction] Return a lua 'variable' object (for access from lua, don't call
485 * This function is called to lookup a variable construct a 'variable' object.
486 * It would be called in the following example as would be seen in
493 static int lua_get_variable(lua_State *L)
495 struct ast_channel *chan;
496 char *name = ast_strdupa(luaL_checkstring(L, 2));
498 char *workspace = alloca(LUA_BUF_SIZE);
501 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
502 chan = lua_touserdata(L, -1);
505 lua_push_variable_table(L, name);
507 /* if this is not a request for a dialplan funciton attempt to retrieve
508 * the value of the variable */
509 if (!ast_strlen_zero(name) && name[strlen(name) - 1] != ')') {
510 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
514 lua_pushstring(L, value);
515 lua_setfield(L, -2, "value");
522 * \brief [lua_CFunction] Set the value of a channel variable or dialplan
523 * function (for access from lua, don't call directly)
525 * This function is called to set a variable or dialplan function. It would be
526 * called in the following example as would be seen in extensions.lua.
529 * channel.variable = "value"
532 static int lua_set_variable(lua_State *L)
534 struct ast_channel *chan;
536 const char *name = luaL_checkstring(L, 2);
537 const char *value = luaL_checkstring(L, 3);
539 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
540 chan = lua_touserdata(L, -1);
543 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
544 autoservice = lua_toboolean(L, -1);
548 ast_autoservice_stop(chan);
550 pbx_builtin_setvar_helper(chan, name, value);
553 ast_autoservice_start(chan);
559 * \brief [lua_CFunction] Create a 'variable' object for accessing a dialplan
560 * function (for access from lua, don't call directly)
562 * This function is called to create a 'variable' object to access a dialplan
563 * function. It would be called in the following example as would be seen in
567 * channel.func("arg1", "arg2", "arg3")
570 * To actually do anything with the resulting value you must use the 'get()'
571 * and 'set()' methods (the reason is the resulting value is not a value, but
572 * an object in the form of a lua table).
574 static int lua_func_read(lua_State *L)
576 int nargs = lua_gettop(L);
577 char fullname[LUA_EXT_DATA_SIZE] = "";
578 char *fullname_next = fullname, *name;
579 size_t fullname_left = sizeof(fullname);
581 lua_getfield(L, 1, "name");
582 name = ast_strdupa(lua_tostring(L, -1));
585 ast_build_string(&fullname_next, &fullname_left, "%s(", name);
590 if (!lua_isnil(L, 2))
591 ast_build_string(&fullname_next, &fullname_left, "%s", luaL_checkstring(L, 2));
593 for (i = 3; i <= nargs; i++) {
595 ast_build_string(&fullname_next, &fullname_left, ",");
597 ast_build_string(&fullname_next, &fullname_left, ",%s", luaL_checkstring(L, i));
601 ast_build_string(&fullname_next, &fullname_left, ")");
603 lua_push_variable_table(L, fullname);
609 * \brief [lua_CFunction] Tell pbx_lua to maintain an autoservice on this
610 * channel (for access from lua, don't call directly)
612 * \param L the lua_State to use
614 * This function will set a flag that will cause pbx_lua to maintain an
615 * autoservice on this channel. The autoservice will automatically be stopped
616 * and restarted before calling applications and functions.
618 * \return This function returns the result of the ast_autoservice_start()
619 * function as a boolean to its lua caller.
621 static int lua_autoservice_start(lua_State *L)
623 struct ast_channel *chan;
626 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
627 chan = lua_touserdata(L, -1);
630 res = ast_autoservice_start(chan);
632 lua_pushboolean(L, !res);
633 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
635 lua_pushboolean(L, !res);
640 * \brief [lua_CFunction] Tell pbx_lua to stop maintaning an autoservice on
641 * this channel (for access from lua, don't call directly)
643 * \param L the lua_State to use
645 * This function will stop any autoservice running and turn off the autoservice
646 * flag. If this function returns false, it's probably because no autoservice
647 * was running to begin with.
649 * \return This function returns the result of the ast_autoservice_stop()
650 * function as a boolean to its lua caller.
652 static int lua_autoservice_stop(lua_State *L)
654 struct ast_channel *chan;
657 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
658 chan = lua_touserdata(L, -1);
661 res = ast_autoservice_stop(chan);
663 lua_pushboolean(L, 0);
664 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
666 lua_pushboolean(L, !res);
671 * \brief [lua_CFunction] Get the status of the autoservice flag (for access
672 * from lua, don't call directly)
674 * \param L the lua_State to use
676 * \return This function returns the status of the autoservice flag as a
677 * boolean to its lua caller.
679 static int lua_autoservice_status(lua_State *L)
681 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
686 * \brief Store the sort order of each context
688 * In the event of an error, an error string will be pushed onto the lua stack.
693 static int lua_sort_extensions(lua_State *L)
695 int extensions, extensions_order;
697 /* create the extensions_order table */
699 lua_setfield(L, LUA_REGISTRYINDEX, "extensions_order");
700 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
701 extensions_order = lua_gettop(L);
703 /* sort each context in the extensions table */
704 /* load the 'extensions' table */
705 lua_getglobal(L, "extensions");
706 extensions = lua_gettop(L);
707 if (lua_isnil(L, -1)) {
709 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
713 /* iterate through the extensions table and create a
714 * matching table (holding the sort order) in the
715 * extensions_order table for each context that is found
717 for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
718 int context = lua_gettop(L);
719 int context_name = context - 1;
722 lua_pushvalue(L, context_name);
724 context_order = lua_gettop(L);
726 /* iterate through this context an popluate the corrisponding
727 * table in the extensions_order table */
728 for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) {
729 int exten = lua_gettop(L) - 1;
731 lua_pushinteger(L, lua_objlen(L, context_order) + 1);
732 lua_pushvalue(L, exten);
733 lua_settable(L, context_order);
735 lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */
737 /* now sort the new table */
739 /* push the table.sort function */
740 lua_getglobal(L, "table");
741 lua_getfield(L, -1, "sort");
742 lua_remove(L, -2); /* remove the 'table' table */
744 /* push the context_order table */
745 lua_pushvalue(L, context_name);
746 lua_gettable(L, extensions_order);
748 /* push the comp function */
749 lua_pushcfunction(L, &lua_extension_cmp);
751 if (lua_pcall(L, 2, 0, 0)) {
758 /* remove the extensions table and the extensions_order table */
764 * \brief [lua_CFunction] Compare two extensions (for access from lua, don't
767 * This function returns true if the first extension passed should match after
768 * the second. It behaves like the '<' operator.
770 static int lua_extension_cmp(lua_State *L)
772 const char *a = luaL_checkstring(L, -2);
773 const char *b = luaL_checkstring(L, -1);
775 if (ast_extension_cmp(a, b) == -1)
776 lua_pushboolean(L, 1);
778 lua_pushboolean(L, 0);
784 * \brief Load the extensions.lua file in to a buffer and execute the file
786 * \param L the lua_State to use
787 * \param size a pointer to store the size of the buffer
789 * \note The caller is expected to free the buffer at some point.
791 * \return a pointer to the buffer
793 static char *lua_read_extensions_file(lua_State *L, long *size)
797 char *path = alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2);
798 sprintf(path, "%s/%s", ast_config_AST_CONFIG_DIR, config);
800 if (!(f = fopen(path, "r"))) {
801 lua_pushstring(L, "cannot open '");
802 lua_pushstring(L, path);
803 lua_pushstring(L, "' for reading: ");
804 lua_pushstring(L, strerror(errno));
810 fseek(f, 0l, SEEK_END);
813 fseek(f, 0l, SEEK_SET);
815 if (!(data = ast_malloc(*size))) {
818 lua_pushstring(L, "not enough memory");
822 fread(data, sizeof(char), *size, f);
825 if (luaL_loadbuffer(L, data, *size, "extensions.lua")
826 || lua_pcall(L, 0, LUA_MULTRET, 0)
827 || lua_sort_extensions(L)) {
836 * \brief Load the extensions.lua file from the internal buffer
838 * \param L the lua_State to use
840 * This function also sets up some constructs used by the extensions.lua file.
842 * In the event of an error, an error string will be pushed onto the lua stack.
847 static int lua_load_extensions(lua_State *L, struct ast_channel *chan)
850 /* store a pointer to this channel */
851 lua_pushlightuserdata(L, chan);
852 lua_setfield(L, LUA_REGISTRYINDEX, "channel");
856 /* load and sort extensions */
857 ast_mutex_lock(&config_file_lock);
858 if (luaL_loadbuffer(L, config_file_data, config_file_size, "extensions.lua")
859 || lua_pcall(L, 0, LUA_MULTRET, 0)
860 || lua_sort_extensions(L)) {
861 ast_mutex_unlock(&config_file_lock);
864 ast_mutex_unlock(&config_file_lock);
866 /* now we setup special tables and functions */
868 lua_create_app_table(L);
869 lua_create_channel_table(L);
871 lua_create_variable_metatable(L);
872 lua_create_application_metatable(L);
874 lua_create_autoservice_functions(L);
880 * \brief Reload the extensions file and update the internal buffers if it
883 * \warning This function should not be called on a lua_State returned from
886 * \param L the lua_State to use (must be freshly allocated with
887 * luaL_newstate(), don't use lua_get_state())
889 static int lua_reload_extensions(lua_State *L)
896 if (!(data = lua_read_extensions_file(L, &size))) {
900 ast_mutex_lock(&config_file_lock);
902 if (config_file_data)
903 ast_free(config_file_data);
905 config_file_data = data;
906 config_file_size = size;
908 ast_mutex_unlock(&config_file_lock);
913 * \brief Free the internal extensions buffer.
915 static void lua_free_extensions()
917 ast_mutex_lock(&config_file_lock);
918 config_file_size = 0;
919 ast_free(config_file_data);
920 ast_mutex_unlock(&config_file_lock);
924 * \brief Get the lua_State for this channel
926 * If no channel is passed then a new state is allocated. States with no
927 * channel assocatied with them should only be used for matching extensions.
928 * If the channel does not yet have a lua state associated with it, one will be
931 * \note If no channel was passed then the caller is expected to free the state
934 * \return a lua_State
936 static lua_State *lua_get_state(struct ast_channel *chan)
938 struct ast_datastore *datastore = NULL;
942 lua_State *L = luaL_newstate();
944 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
948 if (lua_load_extensions(L, NULL)) {
949 const char *error = lua_tostring(L, -1);
950 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
956 datastore = ast_channel_datastore_find(chan, &lua_datastore, NULL);
959 /* nothing found, allocate a new lua state */
960 datastore = ast_channel_datastore_alloc(&lua_datastore, NULL);
962 ast_log(LOG_ERROR, "Error allocation channel datastore for lua_State\n");
966 datastore->data = luaL_newstate();
967 if (!datastore->data) {
968 ast_channel_datastore_free(datastore);
969 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
973 ast_channel_lock(chan);
974 ast_channel_datastore_add(chan, datastore);
975 ast_channel_unlock(chan);
979 if (lua_load_extensions(L, chan)) {
980 const char *error = lua_tostring(L, -1);
981 ast_log(LOG_ERROR, "Error loading extensions.lua for %s: %s\n", chan->name, error);
983 ast_channel_lock(chan);
984 ast_channel_datastore_remove(chan, datastore);
985 ast_channel_unlock(chan);
987 ast_channel_datastore_free(datastore);
992 return datastore->data;
996 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1000 struct ast_module_user *u = ast_module_user_add(chan);
1002 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1006 L = lua_get_state(chan);
1008 ast_module_user_remove(u);
1012 res = lua_find_extension(L, context, exten, priority, &exists, 0);
1014 if (!chan) lua_close(L);
1015 ast_module_user_remove(u);
1019 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1023 struct ast_module_user *u = ast_module_user_add(chan);
1025 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1029 L = lua_get_state(chan);
1031 ast_module_user_remove(u);
1035 res = lua_find_extension(L, context, exten, priority, &canmatch, 0);
1037 if (!chan) lua_close(L);
1038 ast_module_user_remove(u);
1042 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1046 struct ast_module_user *u = ast_module_user_add(chan);
1048 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1052 L = lua_get_state(chan);
1054 ast_module_user_remove(u);
1058 res = lua_find_extension(L, context, exten, priority, &matchmore, 0);
1060 if (!chan) lua_close(L);
1061 ast_module_user_remove(u);
1066 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1070 struct ast_module_user *u = ast_module_user_add(chan);
1072 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1076 L = lua_get_state(chan);
1078 ast_module_user_remove(u);
1082 /* push the extension function onto the stack */
1083 if (!lua_find_extension(L, context, exten, priority, &exists, 1)) {
1084 ast_log(LOG_ERROR, "Could not find extension %s in context %s\n", exten, context);
1085 if (!chan) lua_close(L);
1086 ast_module_user_remove(u);
1090 lua_update_registry(L, context, exten, priority);
1092 lua_pushstring(L, context);
1093 lua_pushstring(L, exten);
1095 res = lua_pcall(L, 2, 0, 0);
1097 if (res == LUA_ERRRUN) {
1098 if (lua_isnumber(L, -1)) {
1099 res = lua_tointeger(L, -1);
1100 } else if (lua_isstring(L, -1)) {
1101 const char *error = lua_tostring(L, -1);
1102 ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error);
1109 if (!chan) lua_close(L);
1110 ast_module_user_remove(u);
1115 * \brief Locate an extensions and optionally push the matching function on the
1118 * \param L the lua_State to use
1119 * \param context the context to look in
1120 * \param exten the extension to look up
1121 * \param priority the priority to check, '1' is the only valid priority
1122 * \param func the calling func, used to adjust matching behavior between,
1123 * match, canmatch, and matchmore
1124 * \param push_func whether or not to push the lua function for the given
1125 * extension onto the stack
1127 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func)
1129 int context_table, context_order_table, i;
1131 ast_debug(2, "Looking up %s@%s:%i\n", exten, context, priority);
1135 /* load the 'extensions' table */
1136 lua_getglobal(L, "extensions");
1137 if (lua_isnil(L, -1)) {
1138 ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n");
1143 /* load the given context */
1144 lua_getfield(L, -1, context);
1145 if (lua_isnil(L, -1)) {
1150 /* remove the extensions table */
1153 context_table = lua_gettop(L);
1155 /* load the extensions order table for this context */
1156 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
1157 lua_getfield(L, -1, context);
1159 lua_remove(L, -2); /* remove the extensions order table */
1161 context_order_table = lua_gettop(L);
1163 /* step through the extensions looking for a match */
1164 for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) {
1165 int e_index, isnumber, match = 0;
1168 lua_pushinteger(L, i);
1169 lua_gettable(L, context_order_table);
1170 e_index = lua_gettop(L);
1171 isnumber = lua_isnumber(L, e_index);
1173 if (!(e = lua_tostring(L, e_index))) {
1178 /* make sure this is not the 'include' extension */
1179 if (!strcasecmp(e, "include")) {
1184 if (func == &matchmore)
1185 match = ast_extension_close(e, exten, E_MATCHMORE);
1186 else if (func == &canmatch)
1187 match = ast_extension_close(e, exten, E_CANMATCH);
1189 match = ast_extension_match(e, exten);
1191 /* the extension matching functions return 0 on fail, 1 on
1192 * match, 2 on earlymatch */
1196 continue; /* keep trying */
1199 if (func == &matchmore && match == 2) {
1200 /* We match an extension ending in '!'. The decision in
1201 * this case is final and counts as no match. */
1206 /* remove the context table, the context order table, and the
1207 * extension (or replace the extension with the corisponding
1210 /* here we must convert the exten back to an integer
1211 * because lua_tostring will change the value on the
1212 * stack to a string */
1214 int e_int = lua_tointeger(L, e_index);
1215 lua_pop(L, 1); /* the exten should be the top of the stack */
1216 lua_pushinteger(L, e_int);
1218 lua_gettable(L, context_table);
1228 /* load the includes for this context */
1229 lua_getfield(L, context_table, "include");
1230 if (lua_isnil(L, -1)) {
1235 /* remove the context and the order table*/
1236 lua_remove(L, context_order_table);
1237 lua_remove(L, context_table);
1239 /* Now try any includes we have in this context */
1240 for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
1241 const char *c = lua_tostring(L, -1);
1245 if (lua_find_extension(L, c, exten, priority, func, push_func)) {
1246 /* remove the value, the key, and the includes table
1247 * from the stack. Leave the function behind if
1258 /* pop the includes table */
1263 static struct ast_switch lua_switch = {
1265 .description = "Lua PBX Switch",
1267 .canmatch = canmatch,
1269 .matchmore = matchmore,
1273 static int load_or_reload_lua_stuff(void)
1275 int res = AST_MODULE_LOAD_SUCCESS;
1277 lua_State *L = luaL_newstate();
1279 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1280 return AST_MODULE_LOAD_DECLINE;
1283 if (lua_reload_extensions(L)) {
1284 const char *error = lua_tostring(L, -1);
1285 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
1286 res = AST_MODULE_LOAD_DECLINE;
1293 static int unload_module(void)
1295 ast_unregister_switch(&lua_switch);
1296 lua_free_extensions();
1300 static int reload(void)
1302 return load_or_reload_lua_stuff();
1305 static int load_module(void)
1309 if ((res = load_or_reload_lua_stuff()))
1312 if (ast_register_switch(&lua_switch)) {
1313 ast_log(LOG_ERROR, "Unable to register LUA PBX switch\n");
1314 return AST_MODULE_LOAD_DECLINE;
1317 return AST_MODULE_LOAD_SUCCESS;
1320 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Lua PBX Switch",
1321 .load = load_module,
1322 .unload = unload_module,