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";
54 #define LUA_EXT_DATA_SIZE 256
56 #define LUA_EXT_DATA_SIZE 8192
58 #define LUA_BUF_SIZE 4096
60 /* This value is used by the lua engine to signal that a Goto or dialplan jump
61 * was detected. Ensure this value does not conflict with any values dialplan
62 * applications might return */
63 #define LUA_GOTO_DETECTED 5
65 static char *lua_read_extensions_file(lua_State *L, long *size);
66 static int lua_load_extensions(lua_State *L, struct ast_channel *chan);
67 static int lua_reload_extensions(lua_State *L);
68 static void lua_free_extensions(void);
69 static int lua_sort_extensions(lua_State *L);
70 static int lua_register_switches(lua_State *L);
71 static int lua_register_hints(lua_State *L);
72 static int lua_extension_cmp(lua_State *L);
73 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func);
74 static int lua_pbx_findapp(lua_State *L);
75 static int lua_pbx_exec(lua_State *L);
77 static int lua_get_variable_value(lua_State *L);
78 static int lua_set_variable_value(lua_State *L);
79 static int lua_get_variable(lua_State *L);
80 static int lua_set_variable(lua_State *L);
81 static int lua_func_read(lua_State *L);
83 static int lua_autoservice_start(lua_State *L);
84 static int lua_autoservice_stop(lua_State *L);
85 static int lua_autoservice_status(lua_State *L);
86 static int lua_check_hangup(lua_State *L);
87 static int lua_error_function(lua_State *L);
89 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority);
90 static void lua_push_variable_table(lua_State *L);
91 static void lua_create_app_table(lua_State *L);
92 static void lua_create_channel_table(lua_State *L);
93 static void lua_create_variable_metatable(lua_State *L);
94 static void lua_create_application_metatable(lua_State *L);
95 static void lua_create_autoservice_functions(lua_State *L);
96 static void lua_create_hangup_function(lua_State *L);
97 static void lua_concat_args(lua_State *L, int start, int nargs);
99 static void lua_state_destroy(void *data);
100 static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
101 static lua_State *lua_get_state(struct ast_channel *chan);
103 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
104 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
105 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
106 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
108 AST_MUTEX_DEFINE_STATIC(config_file_lock);
109 static char *config_file_data = NULL;
110 static long config_file_size = 0;
112 static struct ast_context *local_contexts = NULL;
113 static struct ast_hashtab *local_table = NULL;
115 static const struct ast_datastore_info lua_datastore = {
117 .destroy = lua_state_destroy,
118 .chan_fixup = lua_datastore_fixup,
123 * \brief The destructor for lua_datastore
125 static void lua_state_destroy(void *data)
132 * \brief The fixup function for the lua_datastore.
133 * \param data the datastore data, in this case it will be a lua_State
134 * \param old_chan the channel we are moving from
135 * \param new_chan the channel we are moving to
137 * This function updates our internal channel pointer.
139 static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
142 lua_pushlightuserdata(L, new_chan);
143 lua_setfield(L, LUA_REGISTRYINDEX, "channel");
147 * \brief [lua_CFunction] Find an app and return it in a lua table (for access from lua, don't
150 * This function would be called in the following example as it would be found
157 static int lua_pbx_findapp(lua_State *L)
159 const char *app_name = luaL_checkstring(L, 2);
163 lua_pushstring(L, "name");
164 lua_pushstring(L, app_name);
167 luaL_getmetatable(L, "application");
168 lua_setmetatable(L, -2);
174 * \brief [lua_CFunction] This function is part of the 'application' metatable
175 * and is used to execute applications similar to pbx_exec() (for access from
176 * lua, don't call directly)
178 * \param L the lua_State to use
181 * This funciton is executed as the '()' operator for apps accessed through the
185 * app.playback('demo-congrats')
188 static int lua_pbx_exec(lua_State *L)
190 int res, nargs = lua_gettop(L);
191 const char *data = "";
192 char *app_name, *context, *exten;
193 char tmp[80], tmp2[80], tmp3[LUA_EXT_DATA_SIZE];
194 int priority, autoservice;
196 struct ast_channel *chan;
198 lua_getfield(L, 1, "name");
199 app_name = ast_strdupa(lua_tostring(L, -1));
202 if (!(app = pbx_findapp(app_name))) {
203 lua_pushstring(L, "application '");
204 lua_pushstring(L, app_name);
205 lua_pushstring(L, "' not found");
211 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
212 chan = lua_touserdata(L, -1);
215 context = ast_strdupa(ast_channel_context(chan));
216 exten = ast_strdupa(ast_channel_exten(chan));
217 priority = ast_channel_priority(chan);
219 lua_concat_args(L, 2, nargs);
220 data = lua_tostring(L, -1);
222 ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\")\n",
223 exten, context, priority,
224 term_color(tmp, app_name, COLOR_BRCYAN, 0, sizeof(tmp)),
225 term_color(tmp2, ast_channel_name(chan), COLOR_BRMAGENTA, 0, sizeof(tmp2)),
226 term_color(tmp3, data, COLOR_BRMAGENTA, 0, sizeof(tmp3)));
228 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
229 autoservice = lua_toboolean(L, -1);
233 ast_autoservice_stop(chan);
235 res = pbx_exec(chan, app, data);
237 lua_pop(L, 1); /* pop data */
241 ast_autoservice_start(chan);
243 /* error executing an application, report it */
245 lua_pushinteger(L, res);
249 if (strcmp(context, ast_channel_context(chan))) {
250 lua_pushstring(L, context);
251 lua_pushstring(L, ast_channel_context(chan));
252 lua_pushliteral(L, "context");
253 } else if (strcmp(exten, ast_channel_exten(chan))) {
254 lua_pushstring(L, exten);
255 lua_pushstring(L, ast_channel_exten(chan));
256 lua_pushliteral(L, "exten");
257 } else if (priority != ast_channel_priority(chan)) {
258 lua_pushinteger(L, priority);
259 lua_pushinteger(L, ast_channel_priority(chan));
260 lua_pushliteral(L, "priority");
262 /* no goto - restore the original position back
263 * to lua state, in case this was a recursive dialplan
264 * call (a dialplan application re-entering dialplan) */
265 lua_update_registry(L, context, exten, priority);
269 /* goto detected - construct error message */
272 lua_pushliteral(L, " changed from ");
275 lua_pushliteral(L, " to ");
280 ast_debug(2, "Goto detected: %s\n", lua_tostring(L, -1));
283 /* let the lua engine know it needs to return control to the pbx */
284 lua_pushinteger(L, LUA_GOTO_DETECTED);
291 * \brief [lua_CFunction] Used to get the value of a variable or dialplan
292 * function (for access from lua, don't call directly)
294 * The value of the variable or function is returned. This function is the
295 * 'get()' function in the following example as would be seen in
299 * channel.variable:get()
302 static int lua_get_variable_value(lua_State *L)
304 struct ast_channel *chan;
305 char *value = NULL, *name;
306 char *workspace = ast_alloca(LUA_BUF_SIZE);
311 if (!lua_istable(L, 1)) {
312 lua_pushstring(L, "User probably used '.' instead of ':' for retrieving a channel variable value");
316 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
317 chan = lua_touserdata(L, -1);
320 lua_getfield(L, 1, "name");
321 name = ast_strdupa(lua_tostring(L, -1));
324 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
325 autoservice = lua_toboolean(L, -1);
329 ast_autoservice_stop(chan);
331 /* if this is a dialplan function then use ast_func_read(), otherwise
332 * use pbx_retrieve_variable() */
333 if (!ast_strlen_zero(name) && name[strlen(name) - 1] == ')') {
334 value = ast_func_read(chan, name, workspace, LUA_BUF_SIZE) ? NULL : workspace;
336 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, ast_channel_varshead(chan));
340 ast_autoservice_start(chan);
343 lua_pushstring(L, value);
352 * \brief [lua_CFunction] Used to set the value of a variable or dialplan
353 * function (for access from lua, don't call directly)
355 * This function is the 'set()' function in the following example as would be
356 * seen in extensions.lua.
359 * channel.variable:set("value")
362 static int lua_set_variable_value(lua_State *L)
364 const char *name, *value;
365 struct ast_channel *chan;
368 if (!lua_istable(L, 1)) {
369 lua_pushstring(L, "User probably used '.' instead of ':' for setting a channel variable");
373 lua_getfield(L, 1, "name");
374 name = ast_strdupa(lua_tostring(L, -1));
377 value = luaL_checkstring(L, 2);
379 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
380 chan = lua_touserdata(L, -1);
383 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
384 autoservice = lua_toboolean(L, -1);
388 ast_autoservice_stop(chan);
390 pbx_builtin_setvar_helper(chan, name, value);
393 ast_autoservice_start(chan);
399 * \brief Update the lua registry with the given context, exten, and priority.
401 * \param L the lua_State to use
402 * \param context the new context
403 * \param exten the new exten
404 * \param priority the new priority
406 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority)
408 lua_pushstring(L, context);
409 lua_setfield(L, LUA_REGISTRYINDEX, "context");
411 lua_pushstring(L, exten);
412 lua_setfield(L, LUA_REGISTRYINDEX, "exten");
414 lua_pushinteger(L, priority);
415 lua_setfield(L, LUA_REGISTRYINDEX, "priority");
419 * \brief Push a 'variable' table on the stack for access the channel variable
420 * with the given name.
422 * The value on the top of the stack is popped and used as the name.
424 * \param L the lua_State to use
426 static void lua_push_variable_table(lua_State *L)
429 luaL_getmetatable(L, "variable");
430 lua_setmetatable(L, -2);
432 lua_insert(L, -2); /* move the table after the name */
433 lua_setfield(L, -2, "name");
435 lua_pushcfunction(L, &lua_get_variable_value);
436 lua_setfield(L, -2, "get");
438 lua_pushcfunction(L, &lua_set_variable_value);
439 lua_setfield(L, -2, "set");
443 * \brief Create the global 'app' table for executing applications
445 * \param L the lua_State to use
447 static void lua_create_app_table(lua_State *L)
450 luaL_newmetatable(L, "app");
452 lua_pushstring(L, "__index");
453 lua_pushcfunction(L, &lua_pbx_findapp);
456 lua_setmetatable(L, -2);
457 lua_setglobal(L, "app");
461 * \brief Create the global 'channel' table for accesing channel variables
463 * \param L the lua_State to use
465 static void lua_create_channel_table(lua_State *L)
468 luaL_newmetatable(L, "channel_data");
470 lua_pushstring(L, "__index");
471 lua_pushcfunction(L, &lua_get_variable);
474 lua_pushstring(L, "__newindex");
475 lua_pushcfunction(L, &lua_set_variable);
478 lua_setmetatable(L, -2);
479 lua_setglobal(L, "channel");
483 * \brief Create the 'variable' metatable, used to retrieve channel variables
485 * \param L the lua_State to use
487 static void lua_create_variable_metatable(lua_State *L)
489 luaL_newmetatable(L, "variable");
491 lua_pushstring(L, "__call");
492 lua_pushcfunction(L, &lua_func_read);
499 * \brief Create the 'application' metatable, used to execute asterisk
500 * applications from lua
502 * \param L the lua_State to use
504 static void lua_create_application_metatable(lua_State *L)
506 luaL_newmetatable(L, "application");
508 lua_pushstring(L, "__call");
509 lua_pushcfunction(L, &lua_pbx_exec);
516 * \brief Create the autoservice functions
518 * \param L the lua_State to use
520 static void lua_create_autoservice_functions(lua_State *L)
522 lua_pushcfunction(L, &lua_autoservice_start);
523 lua_setglobal(L, "autoservice_start");
525 lua_pushcfunction(L, &lua_autoservice_stop);
526 lua_setglobal(L, "autoservice_stop");
528 lua_pushcfunction(L, &lua_autoservice_status);
529 lua_setglobal(L, "autoservice_status");
531 lua_pushboolean(L, 1);
532 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
536 * \brief Create the hangup check function
538 * \param L the lua_State to use
540 static void lua_create_hangup_function(lua_State *L)
542 lua_pushcfunction(L, &lua_check_hangup);
543 lua_setglobal(L, "check_hangup");
547 * \brief [lua_CFunction] Return a lua 'variable' object (for access from lua, don't call
550 * This function is called to lookup a variable construct a 'variable' object.
551 * It would be called in the following example as would be seen in
558 static int lua_get_variable(lua_State *L)
560 struct ast_channel *chan;
561 const char *name = luaL_checkstring(L, 2);
563 char *workspace = ast_alloca(LUA_BUF_SIZE);
566 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
567 chan = lua_touserdata(L, -1);
571 lua_push_variable_table(L);
573 /* if this is not a request for a dialplan funciton attempt to retrieve
574 * the value of the variable */
575 if (!ast_strlen_zero(name) && name[strlen(name) - 1] != ')') {
576 pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, ast_channel_varshead(chan));
580 lua_pushstring(L, value);
581 lua_setfield(L, -2, "value");
588 * \brief [lua_CFunction] Set the value of a channel variable or dialplan
589 * function (for access from lua, don't call directly)
591 * This function is called to set a variable or dialplan function. It would be
592 * called in the following example as would be seen in extensions.lua.
595 * channel.variable = "value"
598 static int lua_set_variable(lua_State *L)
600 struct ast_channel *chan;
602 const char *name = luaL_checkstring(L, 2);
603 const char *value = luaL_checkstring(L, 3);
605 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
606 chan = lua_touserdata(L, -1);
609 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
610 autoservice = lua_toboolean(L, -1);
614 ast_autoservice_stop(chan);
616 pbx_builtin_setvar_helper(chan, name, value);
619 ast_autoservice_start(chan);
625 * \brief Concatenate a list of lua function arguments into a comma separated
627 * \param L the lua_State to use
628 * \param start the index of the first argument
629 * \param nargs the number of args
631 * The resulting string will be left on the top of the stack.
633 static void lua_concat_args(lua_State *L, int start, int nargs) {
637 if (start <= nargs && !lua_isnil(L, start)) {
638 lua_pushvalue(L, start);
642 for (; i <= nargs; i++) {
643 if (lua_isnil(L, i)) {
644 lua_pushliteral(L, ",");
647 lua_pushliteral(L, ",");
653 lua_concat(L, concat);
657 * \brief [lua_CFunction] Create a 'variable' object for accessing a dialplan
658 * function (for access from lua, don't call directly)
660 * This function is called to create a 'variable' object to access a dialplan
661 * function. It would be called in the following example as would be seen in
665 * channel.func("arg1", "arg2", "arg3")
668 * To actually do anything with the resulting value you must use the 'get()'
669 * and 'set()' methods (the reason is the resulting value is not a value, but
670 * an object in the form of a lua table).
672 static int lua_func_read(lua_State *L)
674 int nargs = lua_gettop(L);
676 /* build a string in the form of "func_name(arg1,arg2,arg3)" */
677 lua_getfield(L, 1, "name");
678 lua_pushliteral(L, "(");
679 lua_concat_args(L, 2, nargs);
680 lua_pushliteral(L, ")");
683 lua_push_variable_table(L);
688 * \brief [lua_CFunction] Tell pbx_lua to maintain an autoservice on this
689 * channel (for access from lua, don't call directly)
691 * \param L the lua_State to use
693 * This function will set a flag that will cause pbx_lua to maintain an
694 * autoservice on this channel. The autoservice will automatically be stopped
695 * and restarted before calling applications and functions.
697 static int lua_autoservice_start(lua_State *L)
699 struct ast_channel *chan;
701 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
702 if (lua_toboolean(L, -1)) {
703 /* autservice already running */
709 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
710 chan = lua_touserdata(L, -1);
713 ast_autoservice_start(chan);
715 lua_pushboolean(L, 1);
716 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
721 * \brief [lua_CFunction] Tell pbx_lua to stop maintaning an autoservice on
722 * this channel (for access from lua, don't call directly)
724 * \param L the lua_State to use
726 * This function will stop any autoservice running and turn off the autoservice
727 * flag. If this function returns false, it's probably because no autoservice
728 * was running to begin with.
730 static int lua_autoservice_stop(lua_State *L)
732 struct ast_channel *chan;
734 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
735 if (!lua_toboolean(L, -1)) {
736 /* no autservice running */
742 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
743 chan = lua_touserdata(L, -1);
746 ast_autoservice_stop(chan);
748 lua_pushboolean(L, 0);
749 lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
754 * \brief [lua_CFunction] Get the status of the autoservice flag (for access
755 * from lua, don't call directly)
757 * \param L the lua_State to use
759 * \return This function returns the status of the autoservice flag as a
760 * boolean to its lua caller.
762 static int lua_autoservice_status(lua_State *L)
764 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
769 * \brief [lua_CFunction] Check if this channel has been hungup or not (for
770 * access from lua, don't call directly)
772 * \param L the lua_State to use
774 * \return This function returns true if the channel was hungup
776 static int lua_check_hangup(lua_State *L)
778 struct ast_channel *chan;
779 lua_getfield(L, LUA_REGISTRYINDEX, "channel");
780 chan = lua_touserdata(L, -1);
783 lua_pushboolean(L, ast_check_hangup(chan));
788 * \brief [lua_CFunction] Handle lua errors (for access from lua, don't call
791 * \param L the lua_State to use
793 static int lua_error_function(lua_State *L)
797 /* pass number arguments right through back to asterisk*/
798 if (lua_isnumber(L, -1)) {
802 /* if we are here then we have a string error message, let's attach a
804 message_index = lua_gettop(L);
806 /* prepare to prepend a new line to the traceback */
807 lua_pushliteral(L, "\n");
809 lua_getglobal(L, "debug");
810 lua_getfield(L, -1, "traceback");
811 lua_remove(L, -2); /* remove the 'debug' table */
813 lua_pushvalue(L, message_index);
814 lua_remove(L, message_index);
816 lua_pushnumber(L, 2);
820 /* prepend the new line we prepared above */
827 * \brief Store the sort order of each context
829 * In the event of an error, an error string will be pushed onto the lua stack.
834 static int lua_sort_extensions(lua_State *L)
836 int extensions, extensions_order;
838 /* create the extensions_order table */
840 lua_setfield(L, LUA_REGISTRYINDEX, "extensions_order");
841 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
842 extensions_order = lua_gettop(L);
844 /* sort each context in the extensions table */
845 /* load the 'extensions' table */
846 lua_getglobal(L, "extensions");
847 extensions = lua_gettop(L);
848 if (lua_isnil(L, -1)) {
850 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
854 /* iterate through the extensions table and create a
855 * matching table (holding the sort order) in the
856 * extensions_order table for each context that is found
858 for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
859 int context = lua_gettop(L);
860 int context_name = context - 1;
863 /* copy the context_name to be used as the key for the
864 * context_order table in the extensions_order table later */
865 lua_pushvalue(L, context_name);
867 /* create the context_order table */
869 context_order = lua_gettop(L);
871 /* iterate through this context an popluate the corrisponding
872 * table in the extensions_order table */
873 for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) {
874 int exten = lua_gettop(L) - 1;
875 #if LUA_VERSION_NUM < 502
876 lua_pushinteger(L, lua_objlen(L, context_order) + 1);
878 lua_pushinteger(L, lua_rawlen(L, context_order) + 1);
880 lua_pushvalue(L, exten);
881 lua_settable(L, context_order);
883 lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */
885 /* now sort the new table */
887 /* push the table.sort function */
888 lua_getglobal(L, "table");
889 lua_getfield(L, -1, "sort");
890 lua_remove(L, -2); /* remove the 'table' table */
892 /* push the context_order table */
893 lua_pushvalue(L, context_name);
894 lua_gettable(L, extensions_order);
896 /* push the comp function */
897 lua_pushcfunction(L, &lua_extension_cmp);
899 if (lua_pcall(L, 2, 0, 0)) {
906 /* remove the extensions table and the extensions_order table */
912 * \brief Register dialplan switches for our pbx_lua contexs.
914 * In the event of an error, an error string will be pushed onto the lua stack.
919 static int lua_register_switches(lua_State *L)
922 struct ast_context *con = NULL;
924 /* create the hash table for our contexts */
925 /* XXX do we ever need to destroy this? pbx_config does not */
927 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
929 /* load the 'extensions' table */
930 lua_getglobal(L, "extensions");
931 extensions = lua_gettop(L);
932 if (lua_isnil(L, -1)) {
934 lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
938 /* iterate through the extensions table and register a context and
939 * dialplan switch for each lua context
941 for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
942 int context = lua_gettop(L);
943 int context_name = context - 1;
944 const char *context_str = lua_tostring(L, context_name);
946 /* find or create this context */
947 con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar);
949 /* remove extensions table and context key and value */
951 lua_pushstring(L, "Failed to find or create context\n");
955 /* register the switch */
956 if (ast_context_add_switch2(con, "Lua", "", 0, registrar)) {
957 /* remove extensions table and context key and value */
959 lua_pushstring(L, "Unable to create switch for context\n");
964 /* remove the extensions table */
970 * \brief Register dialplan hints for our pbx_lua contexs.
972 * In the event of an error, an error string will be pushed onto the lua stack.
977 static int lua_register_hints(lua_State *L)
980 struct ast_context *con = NULL;
982 /* create the hash table for our contexts */
983 /* XXX do we ever need to destroy this? pbx_config does not */
985 local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
987 /* load the 'hints' table */
988 lua_getglobal(L, "hints");
989 hints = lua_gettop(L);
990 if (lua_isnil(L, -1)) {
991 /* hints table not found, move along */
996 /* iterate through the hints table and register each context and
997 * the hints that go along with it
999 for (lua_pushnil(L); lua_next(L, hints); lua_pop(L, 1)) {
1000 int context = lua_gettop(L);
1001 int context_name = context - 1;
1002 const char *context_str = lua_tostring(L, context_name);
1004 /* find or create this context */
1005 con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar);
1007 /* remove hints table and context key and value */
1009 lua_pushstring(L, "Failed to find or create context\n");
1013 /* register each hint */
1014 for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) {
1015 const char *hint_value = lua_tostring(L, -1);
1016 const char *hint_name;
1018 /* the hint value is not a string, ignore it */
1023 /* copy the name then convert it to a string */
1024 lua_pushvalue(L, -2);
1025 if (!(hint_name = lua_tostring(L, -1))) {
1026 /* ignore non-string value */
1031 if (ast_add_extension2(con, 0, hint_name, PRIORITY_HINT, NULL, NULL, hint_value, NULL, NULL, registrar)) {
1032 /* remove hints table, hint name, hint value,
1033 * key copy, context name, and contex table */
1035 lua_pushstring(L, "Error creating hint\n");
1039 /* pop the name copy */
1044 /* remove the hints table */
1051 * \brief [lua_CFunction] Compare two extensions (for access from lua, don't
1054 * This function returns true if the first extension passed should match after
1055 * the second. It behaves like the '<' operator.
1057 static int lua_extension_cmp(lua_State *L)
1059 const char *a = luaL_checkstring(L, -2);
1060 const char *b = luaL_checkstring(L, -1);
1062 if (ast_extension_cmp(a, b) == -1)
1063 lua_pushboolean(L, 1);
1065 lua_pushboolean(L, 0);
1071 * \brief Load the extensions.lua file in to a buffer and execute the file
1073 * \param L the lua_State to use
1074 * \param size a pointer to store the size of the buffer
1076 * \note The caller is expected to free the buffer at some point.
1078 * \return a pointer to the buffer
1080 static char *lua_read_extensions_file(lua_State *L, long *size)
1085 char *path = ast_alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2);
1086 sprintf(path, "%s/%s", ast_config_AST_CONFIG_DIR, config);
1088 if (!(f = fopen(path, "r"))) {
1089 lua_pushstring(L, "cannot open '");
1090 lua_pushstring(L, path);
1091 lua_pushstring(L, "' for reading: ");
1092 lua_pushstring(L, strerror(errno));
1098 if (fseek(f, 0l, SEEK_END)) {
1100 lua_pushliteral(L, "error determining the size of the config file");
1106 if (fseek(f, 0l, SEEK_SET)) {
1109 lua_pushliteral(L, "error reading config file");
1113 if (!(data = ast_malloc(*size))) {
1116 lua_pushstring(L, "not enough memory");
1120 if (fread(data, sizeof(char), *size, f) != *size) {
1123 lua_pushliteral(L, "problem reading configuration file");
1128 lua_pushcfunction(L, &lua_error_function);
1129 error_func = lua_gettop(L);
1131 if (luaL_loadbuffer(L, data, *size, "extensions.lua")
1132 || lua_pcall(L, 0, LUA_MULTRET, error_func)
1133 || lua_sort_extensions(L)
1134 || lua_register_switches(L)
1135 || lua_register_hints(L)) {
1141 lua_remove(L, error_func);
1146 * \brief Load the extensions.lua file from the internal buffer
1148 * \param L the lua_State to use
1149 * \param chan channel to work on
1151 * This function also sets up some constructs used by the extensions.lua file.
1152 * In the event of an error, an error string will be pushed onto the lua stack.
1157 static int lua_load_extensions(lua_State *L, struct ast_channel *chan)
1160 /* store a pointer to this channel */
1161 lua_pushlightuserdata(L, chan);
1162 lua_setfield(L, LUA_REGISTRYINDEX, "channel");
1166 /* load and sort extensions */
1167 ast_mutex_lock(&config_file_lock);
1168 if (luaL_loadbuffer(L, config_file_data, config_file_size, "extensions.lua")
1169 || lua_pcall(L, 0, LUA_MULTRET, 0)
1170 || lua_sort_extensions(L)) {
1171 ast_mutex_unlock(&config_file_lock);
1174 ast_mutex_unlock(&config_file_lock);
1176 /* now we setup special tables and functions */
1178 lua_create_app_table(L);
1179 lua_create_channel_table(L);
1181 lua_create_variable_metatable(L);
1182 lua_create_application_metatable(L);
1184 lua_create_autoservice_functions(L);
1185 lua_create_hangup_function(L);
1191 * \brief Reload the extensions file and update the internal buffers if it
1194 * \warning This function should not be called on a lua_State returned from
1197 * \param L the lua_State to use (must be freshly allocated with
1198 * luaL_newstate(), don't use lua_get_state())
1200 static int lua_reload_extensions(lua_State *L)
1207 if (!(data = lua_read_extensions_file(L, &size))) {
1211 ast_mutex_lock(&config_file_lock);
1213 if (config_file_data)
1214 ast_free(config_file_data);
1216 config_file_data = data;
1217 config_file_size = size;
1219 /* merge our new contexts */
1220 ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
1221 /* merge_contexts_and_delete will actually, at the correct moment,
1222 set the global dialplan pointers to your local_contexts and local_table.
1223 It then will free up the old tables itself. Just be sure not to
1224 hang onto the pointers. */
1226 local_contexts = NULL;
1228 ast_mutex_unlock(&config_file_lock);
1233 * \brief Free the internal extensions buffer.
1235 static void lua_free_extensions()
1237 ast_mutex_lock(&config_file_lock);
1238 config_file_size = 0;
1239 ast_free(config_file_data);
1240 ast_mutex_unlock(&config_file_lock);
1244 * \brief Get the lua_State for this channel
1246 * If no channel is passed then a new state is allocated. States with no
1247 * channel assocatied with them should only be used for matching extensions.
1248 * If the channel does not yet have a lua state associated with it, one will be
1251 * \note If no channel was passed then the caller is expected to free the state
1252 * using lua_close().
1254 * \return a lua_State
1256 static lua_State *lua_get_state(struct ast_channel *chan)
1258 struct ast_datastore *datastore = NULL;
1262 L = luaL_newstate();
1264 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1268 if (lua_load_extensions(L, NULL)) {
1269 const char *error = lua_tostring(L, -1);
1270 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
1276 ast_channel_lock(chan);
1277 datastore = ast_channel_datastore_find(chan, &lua_datastore, NULL);
1278 ast_channel_unlock(chan);
1281 /* nothing found, allocate a new lua state */
1282 datastore = ast_datastore_alloc(&lua_datastore, NULL);
1284 ast_log(LOG_ERROR, "Error allocation channel datastore for lua_State\n");
1288 datastore->data = luaL_newstate();
1289 if (!datastore->data) {
1290 ast_datastore_free(datastore);
1291 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1295 ast_channel_lock(chan);
1296 ast_channel_datastore_add(chan, datastore);
1297 ast_channel_unlock(chan);
1299 L = datastore->data;
1301 if (lua_load_extensions(L, chan)) {
1302 const char *error = lua_tostring(L, -1);
1303 ast_log(LOG_ERROR, "Error loading extensions.lua for %s: %s\n", ast_channel_name(chan), error);
1305 ast_channel_lock(chan);
1306 ast_channel_datastore_remove(chan, datastore);
1307 ast_channel_unlock(chan);
1309 ast_datastore_free(datastore);
1314 return datastore->data;
1318 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1322 struct ast_module_user *u = ast_module_user_add(chan);
1324 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1328 L = lua_get_state(chan);
1330 ast_module_user_remove(u);
1334 res = lua_find_extension(L, context, exten, priority, &exists, 0);
1336 if (!chan) lua_close(L);
1337 ast_module_user_remove(u);
1341 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1345 struct ast_module_user *u = ast_module_user_add(chan);
1347 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1351 L = lua_get_state(chan);
1353 ast_module_user_remove(u);
1357 res = lua_find_extension(L, context, exten, priority, &canmatch, 0);
1359 if (!chan) lua_close(L);
1360 ast_module_user_remove(u);
1364 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1368 struct ast_module_user *u = ast_module_user_add(chan);
1370 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1374 L = lua_get_state(chan);
1376 ast_module_user_remove(u);
1380 res = lua_find_extension(L, context, exten, priority, &matchmore, 0);
1382 if (!chan) lua_close(L);
1383 ast_module_user_remove(u);
1388 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1390 int res, error_func;
1392 struct ast_module_user *u = ast_module_user_add(chan);
1394 ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1398 L = lua_get_state(chan);
1400 ast_module_user_remove(u);
1404 lua_pushcfunction(L, &lua_error_function);
1405 error_func = lua_gettop(L);
1407 /* push the extension function onto the stack */
1408 if (!lua_find_extension(L, context, exten, priority, &exists, 1)) {
1409 lua_pop(L, 1); /* pop the debug function */
1410 ast_log(LOG_ERROR, "Could not find extension %s in context %s\n", exten, context);
1411 if (!chan) lua_close(L);
1412 ast_module_user_remove(u);
1416 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
1417 if (lua_toboolean(L, -1)) {
1418 ast_autoservice_start(chan);
1422 lua_update_registry(L, context, exten, priority);
1424 lua_pushstring(L, context);
1425 lua_pushstring(L, exten);
1427 res = lua_pcall(L, 2, 0, error_func);
1429 if (res == LUA_ERRRUN) {
1431 if (lua_isnumber(L, -1)) {
1432 res = lua_tointeger(L, -1);
1434 if (res == LUA_GOTO_DETECTED) {
1437 } else if (lua_isstring(L, -1)) {
1438 const char *error = lua_tostring(L, -1);
1439 ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error);
1441 } else if (res == LUA_ERRERR) {
1443 ast_log(LOG_ERROR, "Error in the lua error handler (this is probably a bug in pbx_lua)\n");
1444 } else if (res == LUA_ERRMEM) {
1446 ast_log(LOG_ERROR, "Memory allocation error\n");
1450 lua_remove(L, error_func);
1452 lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
1453 if (lua_toboolean(L, -1)) {
1454 ast_autoservice_stop(chan);
1458 if (!chan) lua_close(L);
1459 ast_module_user_remove(u);
1464 * \brief Locate an extensions and optionally push the matching function on the
1467 * \param L the lua_State to use
1468 * \param context the context to look in
1469 * \param exten the extension to look up
1470 * \param priority the priority to check, '1' is the only valid priority
1471 * \param func the calling func, used to adjust matching behavior between,
1472 * match, canmatch, and matchmore
1473 * \param push_func whether or not to push the lua function for the given
1474 * extension onto the stack
1476 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func)
1478 int context_table, context_order_table, i;
1480 ast_debug(2, "Looking up %s@%s:%i\n", exten, context, priority);
1484 /* load the 'extensions' table */
1485 lua_getglobal(L, "extensions");
1486 if (lua_isnil(L, -1)) {
1487 ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n");
1492 /* load the given context */
1493 lua_getfield(L, -1, context);
1494 if (lua_isnil(L, -1)) {
1499 /* remove the extensions table */
1502 context_table = lua_gettop(L);
1504 /* load the extensions order table for this context */
1505 lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
1506 lua_getfield(L, -1, context);
1508 lua_remove(L, -2); /* remove the extensions order table */
1510 context_order_table = lua_gettop(L);
1512 /* step through the extensions looking for a match */
1513 #if LUA_VERSION_NUM < 502
1514 for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) {
1516 for (i = 1; i < lua_rawlen(L, context_order_table) + 1; i++) {
1518 int e_index_copy, match = 0;
1521 lua_pushinteger(L, i);
1522 lua_gettable(L, context_order_table);
1525 /* copy the key at the top of the stack for use later */
1526 lua_pushvalue(L, -1);
1527 e_index_copy = lua_gettop(L);
1529 if (!(e = lua_tostring(L, e_index_copy))) {
1534 /* make sure this is not the 'include' extension */
1535 if (!strcasecmp(e, "include")) {
1540 if (func == &matchmore)
1541 match = ast_extension_close(e, exten, E_MATCHMORE);
1542 else if (func == &canmatch)
1543 match = ast_extension_close(e, exten, E_CANMATCH);
1545 match = ast_extension_match(e, exten);
1547 /* the extension matching functions return 0 on fail, 1 on
1548 * match, 2 on earlymatch */
1551 /* pop the copy and the extension */
1553 continue; /* keep trying */
1556 if (func == &matchmore && match == 2) {
1557 /* We match an extension ending in '!'. The decision in
1558 * this case is final and counts as no match. */
1563 /* remove the context table, the context order table, the
1564 * extension, and the extension copy (or replace the extension
1565 * with the corresponding function) */
1567 lua_pop(L, 1); /* pop the copy */
1568 lua_gettable(L, context_table);
1578 /* load the includes for this context */
1579 lua_getfield(L, context_table, "include");
1580 if (lua_isnil(L, -1)) {
1585 /* remove the context and the order table*/
1586 lua_remove(L, context_order_table);
1587 lua_remove(L, context_table);
1589 /* Now try any includes we have in this context */
1590 for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
1591 const char *c = lua_tostring(L, -1);
1595 if (lua_find_extension(L, c, exten, priority, func, push_func)) {
1596 /* remove the value, the key, and the includes table
1597 * from the stack. Leave the function behind if
1608 /* pop the includes table */
1613 static struct ast_switch lua_switch = {
1615 .description = "Lua PBX Switch",
1617 .canmatch = canmatch,
1619 .matchmore = matchmore,
1623 static int load_or_reload_lua_stuff(void)
1625 int res = AST_MODULE_LOAD_SUCCESS;
1627 lua_State *L = luaL_newstate();
1629 ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1630 return AST_MODULE_LOAD_DECLINE;
1633 if (lua_reload_extensions(L)) {
1634 const char *error = lua_tostring(L, -1);
1635 ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
1636 res = AST_MODULE_LOAD_DECLINE;
1640 ast_log(LOG_NOTICE, "Lua PBX Switch loaded.\n");
1646 static int unload_module(void)
1648 ast_context_destroy(NULL, registrar);
1649 ast_unregister_switch(&lua_switch);
1650 lua_free_extensions();
1651 ast_log(LOG_NOTICE, "Lua PBX Switch unloaded.\n");
1655 static int reload(void)
1657 return load_or_reload_lua_stuff();
1660 static int load_module(void)
1664 if ((res = load_or_reload_lua_stuff()))
1667 if (ast_register_switch(&lua_switch)) {
1668 ast_log(LOG_ERROR, "Unable to register LUA PBX switch\n");
1669 return AST_MODULE_LOAD_DECLINE;
1672 return AST_MODULE_LOAD_SUCCESS;
1675 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Lua PBX Switch",
1676 .support_level = AST_MODULE_SUPPORT_EXTENDED,
1677 .load = load_module,
1678 .unload = unload_module,