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
29 <support_level>extended</support_level>
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
36 #include "asterisk/logger.h"
37 #include "asterisk/channel.h"
38 #include "asterisk/pbx.h"
39 #include "asterisk/module.h"
40 #include "asterisk/cli.h"
41 #include "asterisk/utils.h"
42 #include "asterisk/term.h"
43 #include "asterisk/paths.h"
44 #include "asterisk/hashtab.h"
50 static char *config = "extensions.lua";
51 static char *registrar = "pbx_lua";
53 #define LUA_EXT_DATA_SIZE 256
54 #define LUA_BUF_SIZE 4096
56 /* This value is used by the lua engine to signal that a Goto or dialplan jump
57 * was detected. Ensure this value does not conflict with any values dialplan
58 * applications might return */
59 #define LUA_GOTO_DETECTED 5
61 static char *lua_read_extensions_file(lua_State *L, long *size);
62 static int lua_load_extensions(lua_State *L, struct ast_channel *chan);
63 static int lua_reload_extensions(lua_State *L);
64 static void lua_free_extensions(void);
65 static int lua_sort_extensions(lua_State *L);
66 static int lua_register_switches(lua_State *L);
67 static int lua_register_hints(lua_State *L);
68 static int lua_extension_cmp(lua_State *L);
69 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func);
70 static int lua_pbx_findapp(lua_State *L);
71 static int lua_pbx_exec(lua_State *L);
73 static int lua_get_variable_value(lua_State *L);
74 static int lua_set_variable_value(lua_State *L);
75 static int lua_get_variable(lua_State *L);
76 static int lua_set_variable(lua_State *L);
77 static int lua_func_read(lua_State *L);
79 static int lua_autoservice_start(lua_State *L);
80 static int lua_autoservice_stop(lua_State *L);
81 static int lua_autoservice_status(lua_State *L);
82 static int lua_check_hangup(lua_State *L);
83 static int lua_error_function(lua_State *L);
85 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority);
86 static void lua_push_variable_table(lua_State *L, const char *name);
87 static void lua_create_app_table(lua_State *L);
88 static void lua_create_channel_table(lua_State *L);
89 static void lua_create_variable_metatable(lua_State *L);
90 static void lua_create_application_metatable(lua_State *L);
91 static void lua_create_autoservice_functions(lua_State *L);
92 static void lua_create_hangup_function(lua_State *L);
93 static void lua_detect_goto(lua_State *L);
95 static void lua_state_destroy(void *data);
96 static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
97 static lua_State *lua_get_state(struct ast_channel *chan);
99 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
100 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
101 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
102 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
104 AST_MUTEX_DEFINE_STATIC(config_file_lock);
105 static char *config_file_data = NULL;
106 static long config_file_size = 0;
108 static struct ast_context *local_contexts = NULL;
109 static struct ast_hashtab *local_table = NULL;
111 static const struct ast_datastore_info lua_datastore = {
113 .destroy = lua_state_destroy,
114 .chan_fixup = lua_datastore_fixup,
119 * \brief The destructor for lua_datastore
121 static void lua_state_destroy(void *data)
128 * \brief The fixup function for the lua_datastore.
129 * \param data the datastore data, in this case it will be a lua_State
130 * \param old_chan the channel we are moving from
131 * \param new_chan the channel we are moving to
133 * This function updates our internal channel pointer.
135 static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
138 lua_pushlightuserdata(L, new_chan);
139 lua_setfield(L, LUA_REGISTRYINDEX, "channel");
143 * \brief [lua_CFunction] Find an app and return it in a lua table (for access from lua, don't
146 * This function would be called in the following example as it would be found
153 static int lua_pbx_findapp(lua_State *L)
155 const char *app_name = luaL_checkstring(L, 2);
159 lua_pushstring(L, "name");
160 lua_pushstring(L, app_name);
163 luaL_getmetatable(L, "application");
164 lua_setmetatable(L, -2);
170 * \brief [lua_CFunction] This function is part of the 'application' metatable
171 * and is used to execute applications similar to pbx_exec() (for access from
172 * lua, don't call directly)
174 * \param L the lua_State to use
177 * This funciton is executed as the '()' operator for apps accessed through the
181 * app.playback('demo-congrats')
184 static int lua_pbx_exec(lua_State *L)
186 int res, nargs = lua_gettop(L);
187 char data[LUA_EXT_DATA_SIZE] = "";
188 char *data_next = data, *app_name;
189 char *context, *exten;
190 char tmp[80], tmp2[80], tmp3[LUA_EXT_DATA_SIZE];
191 int priority, autoservice;
192 size_t data_left = sizeof(data);
194 struct ast_channel *chan;
196 lua_getfield(L, 1, "name");
197 app_name = ast_strdupa(lua_tostring(L, -1));
200 if (!(app = pbx_findapp(app_name))) {
201 lua_pushstring(L, "application '");
202 lua_pushstring(L, app_name);
203 lua_pushstring(L, "' not found");
209 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
210 chan = lua_touserdata(L, -1);
214 lua_getfield(L, LUA_REGISTRYINDEX, "context");
215 context = ast_strdupa(lua_tostring(L, -1));
218 lua_getfield(L, LUA_REGISTRYINDEX, "exten");
219 exten = ast_strdupa(lua_tostring(L, -1));
222 lua_getfield(L, LUA_REGISTRYINDEX, "priority");
223 priority = lua_tointeger(L, -1);
230 if (!lua_isnil(L, 2))
231 ast_build_string(&data_next, &data_left, "%s", luaL_checkstring(L, 2));
233 for (i = 3; i <= nargs; i++) {
235 ast_build_string(&data_next, &data_left, ",");
237 ast_build_string(&data_next, &data_left, ",%s", luaL_checkstring(L, i));
241 ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\")\n",
242 exten, context, priority,
243 term_color(tmp, app_name, COLOR_BRCYAN, 0, sizeof(tmp)),
244 term_color(tmp2, chan->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
245 term_color(tmp3, data, COLOR_BRMAGENTA, 0, sizeof(tmp3)));
247 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
248 autoservice = lua_toboolean(L, -1);
252 ast_autoservice_stop(chan);
254 res = pbx_exec(chan, app, data);
257 ast_autoservice_start(chan);
259 /* error executing an application, report it */
261 lua_pushinteger(L, res);
271 * \brief Detect if a Goto or other dialplan jump has been executed and return
272 * control to the pbx engine.
274 static void lua_detect_goto(lua_State *L)
276 struct ast_channel *chan;
278 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
279 chan = lua_touserdata(L, -1);
283 lua_getfield(L, LUA_REGISTRYINDEX, "context");
284 lua_pushstring(L, chan->context);
285 if (!lua_equal(L, -1, -2)) {
286 lua_pushliteral(L, "context");
287 goto e_goto_detected;
292 lua_getfield(L, LUA_REGISTRYINDEX, "exten");
293 lua_pushstring(L, chan->exten);
294 if (!lua_equal(L, -1, -2)) {
295 lua_pushliteral(L, "exten");
296 goto e_goto_detected;
301 lua_getfield(L, LUA_REGISTRYINDEX, "priority");
302 lua_pushinteger(L, chan->priority);
303 if (!lua_equal(L, -1, -2)) {
304 lua_pushliteral(L, "priority");
305 goto e_goto_detected;
311 /* format our debug message */
314 lua_pushliteral(L, " changed from ");
317 lua_pushliteral(L, " to ");
322 ast_debug(2, "Goto detected: %s\n", lua_tostring(L, -1));
325 /* let the lua engine know it needs to return control to the pbx */
326 lua_pushinteger(L, LUA_GOTO_DETECTED);
331 * \brief [lua_CFunction] Used to get the value of a variable or dialplan
332 * function (for access from lua, don't call directly)
334 * The value of the variable or function is returned. This function is the
335 * 'get()' function in the following example as would be seen in
339 * channel.variable:get()
342 static int lua_get_variable_value(lua_State *L)
344 struct ast_channel *chan;
345 char *value = NULL, *name;
346 char *workspace = alloca(LUA_BUF_SIZE);
351 if (!lua_istable(L, 1)) {
352 lua_pushstring(L, "User probably used '.' instead of ':' for retrieving a channel variable value");
356 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
357 chan = lua_touserdata(L, -1);
360 lua_getfield(L, 1, "name");
361 name = ast_strdupa(lua_tostring(L, -1));
364 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
365 autoservice = lua_toboolean(L, -1);
369 ast_autoservice_stop(chan);
371 /* if this is a dialplan function then use ast_func_read(), otherwise
372 * use pbx_retrieve_variable() */
373 if (!ast_strlen_zero(name) && name[strlen(name) - 1] == ')') {
374 value = ast_func_read(chan, name, workspace, LUA_BUF_SIZE) ? NULL : workspace;
376 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
380 ast_autoservice_start(chan);
383 lua_pushstring(L, value);
392 * \brief [lua_CFunction] Used to set the value of a variable or dialplan
393 * function (for access from lua, don't call directly)
395 * This function is the 'set()' function in the following example as would be
396 * seen in extensions.lua.
399 * channel.variable:set("value")
402 static int lua_set_variable_value(lua_State *L)
404 const char *name, *value;
405 struct ast_channel *chan;
408 if (!lua_istable(L, 1)) {
409 lua_pushstring(L, "User probably used '.' instead of ':' for setting a channel variable");
413 lua_getfield(L, 1, "name");
414 name = ast_strdupa(lua_tostring(L, -1));
417 value = luaL_checkstring(L, 2);
419 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
420 chan = lua_touserdata(L, -1);
423 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
424 autoservice = lua_toboolean(L, -1);
428 ast_autoservice_stop(chan);
430 pbx_builtin_setvar_helper(chan, name, value);
433 ast_autoservice_start(chan);
439 * \brief Update the lua registry with the given context, exten, and priority.
441 * \param L the lua_State to use
442 * \param context the new context
443 * \param exten the new exten
444 * \param priority the new priority
446 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority)
448 lua_pushstring(L, context);
449 lua_setfield(L, LUA_REGISTRYINDEX, "context");
451 lua_pushstring(L, exten);
452 lua_setfield(L, LUA_REGISTRYINDEX, "exten");
454 lua_pushinteger(L, priority);
455 lua_setfield(L, LUA_REGISTRYINDEX, "priority");
459 * \brief Push a 'variable' table on the stack for access the channel variable
460 * with the given name.
462 * \param L the lua_State to use
463 * \param name the name of the variable
465 static void lua_push_variable_table(lua_State *L, const char *name)
468 luaL_getmetatable(L, "variable");
469 lua_setmetatable(L, -2);
471 lua_pushstring(L, name);
472 lua_setfield(L, -2, "name");
474 lua_pushcfunction(L, &lua_get_variable_value);
475 lua_setfield(L, -2, "get");
477 lua_pushcfunction(L, &lua_set_variable_value);
478 lua_setfield(L, -2, "set");
482 * \brief Create the global 'app' table for executing applications
484 * \param L the lua_State to use
486 static void lua_create_app_table(lua_State *L)
489 luaL_newmetatable(L, "app");
491 lua_pushstring(L, "__index");
492 lua_pushcfunction(L, &lua_pbx_findapp);
495 lua_setmetatable(L, -2);
496 lua_setglobal(L, "app");
500 * \brief Create the global 'channel' table for accesing channel variables
502 * \param L the lua_State to use
504 static void lua_create_channel_table(lua_State *L)
507 luaL_newmetatable(L, "channel_data");
509 lua_pushstring(L, "__index");
510 lua_pushcfunction(L, &lua_get_variable);
513 lua_pushstring(L, "__newindex");
514 lua_pushcfunction(L, &lua_set_variable);
517 lua_setmetatable(L, -2);
518 lua_setglobal(L, "channel");
522 * \brief Create the 'variable' metatable, used to retrieve channel variables
524 * \param L the lua_State to use
526 static void lua_create_variable_metatable(lua_State *L)
528 luaL_newmetatable(L, "variable");
530 lua_pushstring(L, "__call");
531 lua_pushcfunction(L, &lua_func_read);
538 * \brief Create the 'application' metatable, used to execute asterisk
539 * applications from lua
541 * \param L the lua_State to use
543 static void lua_create_application_metatable(lua_State *L)
545 luaL_newmetatable(L, "application");
547 lua_pushstring(L, "__call");
548 lua_pushcfunction(L, &lua_pbx_exec);
555 * \brief Create the autoservice functions
557 * \param L the lua_State to use
559 static void lua_create_autoservice_functions(lua_State *L)
561 lua_pushcfunction(L, &lua_autoservice_start);
562 lua_setglobal(L, "autoservice_start");
564 lua_pushcfunction(L, &lua_autoservice_stop);
565 lua_setglobal(L, "autoservice_stop");
567 lua_pushcfunction(L, &lua_autoservice_status);
568 lua_setglobal(L, "autoservice_status");
570 lua_pushboolean(L, 1);
571 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
575 * \brief Create the hangup check function
577 * \param L the lua_State to use
579 static void lua_create_hangup_function(lua_State *L)
581 lua_pushcfunction(L, &lua_check_hangup);
582 lua_setglobal(L, "check_hangup");
586 * \brief [lua_CFunction] Return a lua 'variable' object (for access from lua, don't call
589 * This function is called to lookup a variable construct a 'variable' object.
590 * It would be called in the following example as would be seen in
597 static int lua_get_variable(lua_State *L)
599 struct ast_channel *chan;
600 char *name = ast_strdupa(luaL_checkstring(L, 2));
602 char *workspace = alloca(LUA_BUF_SIZE);
605 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
606 chan = lua_touserdata(L, -1);
609 lua_push_variable_table(L, name);
611 /* if this is not a request for a dialplan funciton attempt to retrieve
612 * the value of the variable */
613 if (!ast_strlen_zero(name) && name[strlen(name) - 1] != ')') {
614 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
618 lua_pushstring(L, value);
619 lua_setfield(L, -2, "value");
626 * \brief [lua_CFunction] Set the value of a channel variable or dialplan
627 * function (for access from lua, don't call directly)
629 * This function is called to set a variable or dialplan function. It would be
630 * called in the following example as would be seen in extensions.lua.
633 * channel.variable = "value"
636 static int lua_set_variable(lua_State *L)
638 struct ast_channel *chan;
640 const char *name = luaL_checkstring(L, 2);
641 const char *value = luaL_checkstring(L, 3);
643 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
644 chan = lua_touserdata(L, -1);
647 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
648 autoservice = lua_toboolean(L, -1);
652 ast_autoservice_stop(chan);
654 pbx_builtin_setvar_helper(chan, name, value);
657 ast_autoservice_start(chan);
663 * \brief [lua_CFunction] Create a 'variable' object for accessing a dialplan
664 * function (for access from lua, don't call directly)
666 * This function is called to create a 'variable' object to access a dialplan
667 * function. It would be called in the following example as would be seen in
671 * channel.func("arg1", "arg2", "arg3")
674 * To actually do anything with the resulting value you must use the 'get()'
675 * and 'set()' methods (the reason is the resulting value is not a value, but
676 * an object in the form of a lua table).
678 static int lua_func_read(lua_State *L)
680 int nargs = lua_gettop(L);
681 char fullname[LUA_EXT_DATA_SIZE] = "";
682 char *fullname_next = fullname, *name;
683 size_t fullname_left = sizeof(fullname);
685 lua_getfield(L, 1, "name");
686 name = ast_strdupa(lua_tostring(L, -1));
689 ast_build_string(&fullname_next, &fullname_left, "%s(", name);
694 if (!lua_isnil(L, 2))
695 ast_build_string(&fullname_next, &fullname_left, "%s", luaL_checkstring(L, 2));
697 for (i = 3; i <= nargs; i++) {
699 ast_build_string(&fullname_next, &fullname_left, ",");
701 ast_build_string(&fullname_next, &fullname_left, ",%s", luaL_checkstring(L, i));
705 ast_build_string(&fullname_next, &fullname_left, ")");
707 lua_push_variable_table(L, fullname);
713 * \brief [lua_CFunction] Tell pbx_lua to maintain an autoservice on this
714 * channel (for access from lua, don't call directly)
716 * \param L the lua_State to use
718 * This function will set a flag that will cause pbx_lua to maintain an
719 * autoservice on this channel. The autoservice will automatically be stopped
720 * and restarted before calling applications and functions.
722 static int lua_autoservice_start(lua_State *L)
724 struct ast_channel *chan;
726 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
727 if (lua_toboolean(L, -1)) {
728 /* autservice already running */
734 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
735 chan = lua_touserdata(L, -1);
738 ast_autoservice_start(chan);
740 lua_pushboolean(L, 1);
741 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
746 * \brief [lua_CFunction] Tell pbx_lua to stop maintaning an autoservice on
747 * this channel (for access from lua, don't call directly)
749 * \param L the lua_State to use
751 * This function will stop any autoservice running and turn off the autoservice
752 * flag. If this function returns false, it's probably because no autoservice
753 * was running to begin with.
755 static int lua_autoservice_stop(lua_State *L)
757 struct ast_channel *chan;
759 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
760 if (!lua_toboolean(L, -1)) {
761 /* no autservice running */
767 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
768 chan = lua_touserdata(L, -1);
771 ast_autoservice_stop(chan);
773 lua_pushboolean(L, 0);
774 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
779 * \brief [lua_CFunction] Get the status of the autoservice flag (for access
780 * from lua, don't call directly)
782 * \param L the lua_State to use
784 * \return This function returns the status of the autoservice flag as a
785 * boolean to its lua caller.
787 static int lua_autoservice_status(lua_State *L)
789 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
794 * \brief [lua_CFunction] Check if this channel has been hungup or not (for
795 * access from lua, don't call directly)
797 * \param L the lua_State to use
799 * \return This function returns true if the channel was hungup
801 static int lua_check_hangup(lua_State *L)
803 struct ast_channel *chan;
804 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
805 chan = lua_touserdata(L, -1);
808 lua_pushboolean(L, ast_check_hangup(chan));
813 * \brief [lua_CFunction] Handle lua errors (for access from lua, don't call
816 * \param L the lua_State to use
818 static int lua_error_function(lua_State *L)
822 /* pass number arguments right through back to asterisk*/
823 if (lua_isnumber(L, -1)) {
827 /* if we are here then we have a string error message, let's attach a
829 message_index = lua_gettop(L);
831 /* prepare to prepend a new line to the traceback */
832 lua_pushliteral(L, "\n");
834 lua_getglobal(L, "debug");
835 lua_getfield(L, -1, "traceback");
836 lua_remove(L, -2); /* remove the 'debug' table */
838 lua_pushvalue(L, message_index);
839 lua_remove(L, message_index);
841 lua_pushnumber(L, 2);
845 /* prepend the new line we prepared above */
852 * \brief Store the sort order of each context
854 * In the event of an error, an error string will be pushed onto the lua stack.
859 static int lua_sort_extensions(lua_State *L)
861 int extensions, extensions_order;
863 /* create the extensions_order table */
865 lua_setfield(L, LUA_REGISTRYINDEX, "extensions_order");
866 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
867 extensions_order = lua_gettop(L);
869 /* sort each context in the extensions table */
870 /* load the 'extensions' table */
871 lua_getglobal(L, "extensions");
872 extensions = lua_gettop(L);
873 if (lua_isnil(L, -1)) {
875 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
879 /* iterate through the extensions table and create a
880 * matching table (holding the sort order) in the
881 * extensions_order table for each context that is found
883 for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
884 int context = lua_gettop(L);
885 int context_name = context - 1;
888 /* copy the context_name to be used as the key for the
889 * context_order table in the extensions_order table later */
890 lua_pushvalue(L, context_name);
892 /* create the context_order table */
894 context_order = lua_gettop(L);
896 /* iterate through this context an popluate the corrisponding
897 * table in the extensions_order table */
898 for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) {
899 int exten = lua_gettop(L) - 1;
901 lua_pushinteger(L, lua_objlen(L, context_order) + 1);
902 lua_pushvalue(L, exten);
903 lua_settable(L, context_order);
905 lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */
907 /* now sort the new table */
909 /* push the table.sort function */
910 lua_getglobal(L, "table");
911 lua_getfield(L, -1, "sort");
912 lua_remove(L, -2); /* remove the 'table' table */
914 /* push the context_order table */
915 lua_pushvalue(L, context_name);
916 lua_gettable(L, extensions_order);
918 /* push the comp function */
919 lua_pushcfunction(L, &lua_extension_cmp);
921 if (lua_pcall(L, 2, 0, 0)) {
928 /* remove the extensions table and the extensions_order table */
934 * \brief Register dialplan switches for our pbx_lua contexs.
936 * In the event of an error, an error string will be pushed onto the lua stack.
941 static int lua_register_switches(lua_State *L)
944 struct ast_context *con = NULL;
946 /* create the hash table for our contexts */
947 /* XXX do we ever need to destroy this? pbx_config does not */
949 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
951 /* load the 'extensions' table */
952 lua_getglobal(L, "extensions");
953 extensions = lua_gettop(L);
954 if (lua_isnil(L, -1)) {
956 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
960 /* iterate through the extensions table and register a context and
961 * dialplan switch for each lua context
963 for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
964 int context = lua_gettop(L);
965 int context_name = context - 1;
966 const char *context_str = lua_tostring(L, context_name);
968 /* find or create this context */
969 con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar);
971 /* remove extensions table and context key and value */
973 lua_pushstring(L, "Failed to find or create context\n");
977 /* register the switch */
978 if (ast_context_add_switch2(con, "Lua", "", 0, registrar)) {
979 /* remove extensions table and context key and value */
981 lua_pushstring(L, "Unable to create switch for context\n");
986 /* remove the extensions table */
992 * \brief Register dialplan hints for our pbx_lua contexs.
994 * In the event of an error, an error string will be pushed onto the lua stack.
999 static int lua_register_hints(lua_State *L)
1002 struct ast_context *con = NULL;
1004 /* create the hash table for our contexts */
1005 /* XXX do we ever need to destroy this? pbx_config does not */
1007 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
1009 /* load the 'hints' table */
1010 lua_getglobal(L, "hints");
1011 hints = lua_gettop(L);
1012 if (lua_isnil(L, -1)) {
1013 /* hints table not found, move along */
1018 /* iterate through the hints table and register each context and
1019 * the hints that go along with it
1021 for (lua_pushnil(L); lua_next(L, hints); lua_pop(L, 1)) {
1022 int context = lua_gettop(L);
1023 int context_name = context - 1;
1024 const char *context_str = lua_tostring(L, context_name);
1026 /* find or create this context */
1027 con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar);
1029 /* remove hints table and context key and value */
1031 lua_pushstring(L, "Failed to find or create context\n");
1035 /* register each hint */
1036 for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) {
1037 const char *hint_value = lua_tostring(L, -1);
1038 const char *hint_name;
1040 /* the hint value is not a string, ignore it */
1045 /* copy the name then convert it to a string */
1046 lua_pushvalue(L, -2);
1047 if (!(hint_name = lua_tostring(L, -1))) {
1048 /* ignore non-string value */
1053 if (ast_add_extension2(con, 0, hint_name, PRIORITY_HINT, NULL, NULL, hint_value, NULL, NULL, registrar)) {
1054 /* remove hints table, hint name, hint value,
1055 * key copy, context name, and contex table */
1057 lua_pushstring(L, "Error creating hint\n");
1061 /* pop the name copy */
1066 /* remove the hints table */
1073 * \brief [lua_CFunction] Compare two extensions (for access from lua, don't
1076 * This function returns true if the first extension passed should match after
1077 * the second. It behaves like the '<' operator.
1079 static int lua_extension_cmp(lua_State *L)
1081 const char *a = luaL_checkstring(L, -2);
1082 const char *b = luaL_checkstring(L, -1);
1084 if (ast_extension_cmp(a, b) == -1)
1085 lua_pushboolean(L, 1);
1087 lua_pushboolean(L, 0);
1093 * \brief Load the extensions.lua file in to a buffer and execute the file
1095 * \param L the lua_State to use
1096 * \param size a pointer to store the size of the buffer
1098 * \note The caller is expected to free the buffer at some point.
1100 * \return a pointer to the buffer
1102 static char *lua_read_extensions_file(lua_State *L, long *size)
1107 char *path = alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2);
1108 sprintf(path, "%s/%s", ast_config_AST_CONFIG_DIR, config);
1110 if (!(f = fopen(path, "r"))) {
1111 lua_pushstring(L, "cannot open '");
1112 lua_pushstring(L, path);
1113 lua_pushstring(L, "' for reading: ");
1114 lua_pushstring(L, strerror(errno));
1120 if (fseek(f, 0l, SEEK_END)) {
1122 lua_pushliteral(L, "error determining the size of the config file");
1128 if (fseek(f, 0l, SEEK_SET)) {
1131 lua_pushliteral(L, "error reading config file");
1135 if (!(data = ast_malloc(*size))) {
1138 lua_pushstring(L, "not enough memory");
1142 if (fread(data, sizeof(char), *size, f) != *size) {
1145 lua_pushliteral(L, "problem reading configuration file");
1150 lua_pushcfunction(L, &lua_error_function);
1151 error_func = lua_gettop(L);
1153 if (luaL_loadbuffer(L, data, *size, "extensions.lua")
1154 || lua_pcall(L, 0, LUA_MULTRET, error_func)
1155 || lua_sort_extensions(L)
1156 || lua_register_switches(L)
1157 || lua_register_hints(L)) {
1163 lua_remove(L, error_func);
1168 * \brief Load the extensions.lua file from the internal buffer
1170 * \param L the lua_State to use
1171 * \param chan channel to work on
1173 * This function also sets up some constructs used by the extensions.lua file.
1174 * In the event of an error, an error string will be pushed onto the lua stack.
1179 static int lua_load_extensions(lua_State *L, struct ast_channel *chan)
1182 /* store a pointer to this channel */
1183 lua_pushlightuserdata(L, chan);
1184 lua_setfield(L, LUA_REGISTRYINDEX, "channel");
1188 /* load and sort extensions */
1189 ast_mutex_lock(&config_file_lock);
1190 if (luaL_loadbuffer(L, config_file_data, config_file_size, "extensions.lua")
1191 || lua_pcall(L, 0, LUA_MULTRET, 0)
1192 || lua_sort_extensions(L)) {
1193 ast_mutex_unlock(&config_file_lock);
1196 ast_mutex_unlock(&config_file_lock);
1198 /* now we setup special tables and functions */
1200 lua_create_app_table(L);
1201 lua_create_channel_table(L);
1203 lua_create_variable_metatable(L);
1204 lua_create_application_metatable(L);
1206 lua_create_autoservice_functions(L);
1207 lua_create_hangup_function(L);
1213 * \brief Reload the extensions file and update the internal buffers if it
1216 * \warning This function should not be called on a lua_State returned from
1219 * \param L the lua_State to use (must be freshly allocated with
1220 * luaL_newstate(), don't use lua_get_state())
1222 static int lua_reload_extensions(lua_State *L)
1229 if (!(data = lua_read_extensions_file(L, &size))) {
1233 ast_mutex_lock(&config_file_lock);
1235 if (config_file_data)
1236 ast_free(config_file_data);
1238 config_file_data = data;
1239 config_file_size = size;
1241 /* merge our new contexts */
1242 ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
1243 /* merge_contexts_and_delete will actually, at the correct moment,
1244 set the global dialplan pointers to your local_contexts and local_table.
1245 It then will free up the old tables itself. Just be sure not to
1246 hang onto the pointers. */
1248 local_contexts = NULL;
1250 ast_mutex_unlock(&config_file_lock);
1255 * \brief Free the internal extensions buffer.
1257 static void lua_free_extensions()
1259 ast_mutex_lock(&config_file_lock);
1260 config_file_size = 0;
1261 ast_free(config_file_data);
1262 ast_mutex_unlock(&config_file_lock);
1266 * \brief Get the lua_State for this channel
1268 * If no channel is passed then a new state is allocated. States with no
1269 * channel assocatied with them should only be used for matching extensions.
1270 * If the channel does not yet have a lua state associated with it, one will be
1273 * \note If no channel was passed then the caller is expected to free the state
1274 * using lua_close().
1276 * \return a lua_State
1278 static lua_State *lua_get_state(struct ast_channel *chan)
1280 struct ast_datastore *datastore = NULL;
1284 lua_State *L = luaL_newstate();
1286 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1290 if (lua_load_extensions(L, NULL)) {
1291 const char *error = lua_tostring(L, -1);
1292 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
1298 ast_channel_lock(chan);
1299 datastore = ast_channel_datastore_find(chan, &lua_datastore, NULL);
1300 ast_channel_unlock(chan);
1303 /* nothing found, allocate a new lua state */
1304 datastore = ast_datastore_alloc(&lua_datastore, NULL);
1306 ast_log(LOG_ERROR, "Error allocation channel datastore for lua_State\n");
1310 datastore->data = luaL_newstate();
1311 if (!datastore->data) {
1312 ast_datastore_free(datastore);
1313 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1317 ast_channel_lock(chan);
1318 ast_channel_datastore_add(chan, datastore);
1319 ast_channel_unlock(chan);
1321 L = datastore->data;
1323 if (lua_load_extensions(L, chan)) {
1324 const char *error = lua_tostring(L, -1);
1325 ast_log(LOG_ERROR, "Error loading extensions.lua for %s: %s\n", chan->name, error);
1327 ast_channel_lock(chan);
1328 ast_channel_datastore_remove(chan, datastore);
1329 ast_channel_unlock(chan);
1331 ast_datastore_free(datastore);
1336 return datastore->data;
1340 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1344 struct ast_module_user *u = ast_module_user_add(chan);
1346 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1350 L = lua_get_state(chan);
1352 ast_module_user_remove(u);
1356 res = lua_find_extension(L, context, exten, priority, &exists, 0);
1358 if (!chan) lua_close(L);
1359 ast_module_user_remove(u);
1363 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1367 struct ast_module_user *u = ast_module_user_add(chan);
1369 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1373 L = lua_get_state(chan);
1375 ast_module_user_remove(u);
1379 res = lua_find_extension(L, context, exten, priority, &canmatch, 0);
1381 if (!chan) lua_close(L);
1382 ast_module_user_remove(u);
1386 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1390 struct ast_module_user *u = ast_module_user_add(chan);
1392 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1396 L = lua_get_state(chan);
1398 ast_module_user_remove(u);
1402 res = lua_find_extension(L, context, exten, priority, &matchmore, 0);
1404 if (!chan) lua_close(L);
1405 ast_module_user_remove(u);
1410 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1412 int res, error_func;
1414 struct ast_module_user *u = ast_module_user_add(chan);
1416 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1420 L = lua_get_state(chan);
1422 ast_module_user_remove(u);
1426 lua_pushcfunction(L, &lua_error_function);
1427 error_func = lua_gettop(L);
1429 /* push the extension function onto the stack */
1430 if (!lua_find_extension(L, context, exten, priority, &exists, 1)) {
1431 lua_pop(L, 1); /* pop the debug function */
1432 ast_log(LOG_ERROR, "Could not find extension %s in context %s\n", exten, context);
1433 if (!chan) lua_close(L);
1434 ast_module_user_remove(u);
1438 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
1439 if (lua_toboolean(L, -1)) {
1440 ast_autoservice_start(chan);
1444 lua_update_registry(L, context, exten, priority);
1446 lua_pushstring(L, context);
1447 lua_pushstring(L, exten);
1449 res = lua_pcall(L, 2, 0, error_func);
1451 if (res == LUA_ERRRUN) {
1453 if (lua_isnumber(L, -1)) {
1454 res = lua_tointeger(L, -1);
1456 if (res == LUA_GOTO_DETECTED) {
1459 } else if (lua_isstring(L, -1)) {
1460 const char *error = lua_tostring(L, -1);
1461 ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error);
1463 } else if (res == LUA_ERRERR) {
1465 ast_log(LOG_ERROR, "Error in the lua error handler (this is probably a bug in pbx_lua)\n");
1466 } else if (res == LUA_ERRMEM) {
1468 ast_log(LOG_ERROR, "Memory allocation error\n");
1472 lua_remove(L, error_func);
1474 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
1475 if (lua_toboolean(L, -1)) {
1476 ast_autoservice_stop(chan);
1480 if (!chan) lua_close(L);
1481 ast_module_user_remove(u);
1486 * \brief Locate an extensions and optionally push the matching function on the
1489 * \param L the lua_State to use
1490 * \param context the context to look in
1491 * \param exten the extension to look up
1492 * \param priority the priority to check, '1' is the only valid priority
1493 * \param func the calling func, used to adjust matching behavior between,
1494 * match, canmatch, and matchmore
1495 * \param push_func whether or not to push the lua function for the given
1496 * extension onto the stack
1498 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func)
1500 int context_table, context_order_table, i;
1502 ast_debug(2, "Looking up %s@%s:%i\n", exten, context, priority);
1506 /* load the 'extensions' table */
1507 lua_getglobal(L, "extensions");
1508 if (lua_isnil(L, -1)) {
1509 ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n");
1514 /* load the given context */
1515 lua_getfield(L, -1, context);
1516 if (lua_isnil(L, -1)) {
1521 /* remove the extensions table */
1524 context_table = lua_gettop(L);
1526 /* load the extensions order table for this context */
1527 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
1528 lua_getfield(L, -1, context);
1530 lua_remove(L, -2); /* remove the extensions order table */
1532 context_order_table = lua_gettop(L);
1534 /* step through the extensions looking for a match */
1535 for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) {
1536 int e_index_copy, match = 0;
1539 lua_pushinteger(L, i);
1540 lua_gettable(L, context_order_table);
1543 /* copy the key at the top of the stack for use later */
1544 lua_pushvalue(L, -1);
1545 e_index_copy = lua_gettop(L);
1547 if (!(e = lua_tostring(L, e_index_copy))) {
1552 /* make sure this is not the 'include' extension */
1553 if (!strcasecmp(e, "include")) {
1558 if (func == &matchmore)
1559 match = ast_extension_close(e, exten, E_MATCHMORE);
1560 else if (func == &canmatch)
1561 match = ast_extension_close(e, exten, E_CANMATCH);
1563 match = ast_extension_match(e, exten);
1565 /* the extension matching functions return 0 on fail, 1 on
1566 * match, 2 on earlymatch */
1569 /* pop the copy and the extension */
1571 continue; /* keep trying */
1574 if (func == &matchmore && match == 2) {
1575 /* We match an extension ending in '!'. The decision in
1576 * this case is final and counts as no match. */
1581 /* remove the context table, the context order table, the
1582 * extension, and the extension copy (or replace the extension
1583 * with the corresponding function) */
1585 lua_pop(L, 1); /* pop the copy */
1586 lua_gettable(L, context_table);
1596 /* load the includes for this context */
1597 lua_getfield(L, context_table, "include");
1598 if (lua_isnil(L, -1)) {
1603 /* remove the context and the order table*/
1604 lua_remove(L, context_order_table);
1605 lua_remove(L, context_table);
1607 /* Now try any includes we have in this context */
1608 for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
1609 const char *c = lua_tostring(L, -1);
1613 if (lua_find_extension(L, c, exten, priority, func, push_func)) {
1614 /* remove the value, the key, and the includes table
1615 * from the stack. Leave the function behind if
1626 /* pop the includes table */
1631 static struct ast_switch lua_switch = {
1633 .description = "Lua PBX Switch",
1635 .canmatch = canmatch,
1637 .matchmore = matchmore,
1641 static int load_or_reload_lua_stuff(void)
1643 int res = AST_MODULE_LOAD_SUCCESS;
1645 lua_State *L = luaL_newstate();
1647 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1648 return AST_MODULE_LOAD_DECLINE;
1651 if (lua_reload_extensions(L)) {
1652 const char *error = lua_tostring(L, -1);
1653 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
1654 res = AST_MODULE_LOAD_DECLINE;
1661 static int unload_module(void)
1663 ast_context_destroy(NULL, registrar);
1664 ast_unregister_switch(&lua_switch);
1665 lua_free_extensions();
1669 static int reload(void)
1671 return load_or_reload_lua_stuff();
1674 static int load_module(void)
1678 if ((res = load_or_reload_lua_stuff()))
1681 if (ast_register_switch(&lua_switch)) {
1682 ast_log(LOG_ERROR, "Unable to register LUA PBX switch\n");
1683 return AST_MODULE_LOAD_DECLINE;
1686 return AST_MODULE_LOAD_SUCCESS;
1689 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Lua PBX Switch",
1690 .load = load_module,
1691 .unload = unload_module,