Wed Jan 8 2020 09:49:49

Asterisk developer's documentation


pbx_lua.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2007, Digium, Inc.
5  *
6  * Matthew Nicholson <mnicholson@digium.com>
7  *
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.
13  *
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.
17  */
18 
19 /*!
20  * \file
21  *
22  * \author Matthew Nicholson <mnicholson@digium.com>
23  * \brief Lua PBX Switch
24  *
25  */
26 
27 /*** MODULEINFO
28  <depend>lua</depend>
29  <support_level>extended</support_level>
30  ***/
31 
32 #include "asterisk.h"
33 
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 420146 $")
35 
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"
45 
46 #include <lua.h>
47 #include <lauxlib.h>
48 #include <lualib.h>
49 
50 static char *config = "extensions.lua";
51 static char *registrar = "pbx_lua";
52 
53 #ifdef LOW_MEMORY
54 #define LUA_EXT_DATA_SIZE 256
55 #else
56 #define LUA_EXT_DATA_SIZE 8192
57 #endif
58 #define LUA_BUF_SIZE 4096
59 
60 static char *lua_read_extensions_file(lua_State *L, long *size);
61 static int lua_load_extensions(lua_State *L, struct ast_channel *chan);
62 static int lua_reload_extensions(lua_State *L);
63 static void lua_free_extensions(void);
64 static int lua_sort_extensions(lua_State *L);
65 static int lua_register_switches(lua_State *L);
66 static int lua_extension_cmp(lua_State *L);
67 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func);
68 static int lua_pbx_findapp(lua_State *L);
69 static int lua_pbx_exec(lua_State *L);
70 
71 static int lua_get_variable_value(lua_State *L);
72 static int lua_set_variable_value(lua_State *L);
73 static int lua_get_variable(lua_State *L);
74 static int lua_set_variable(lua_State *L);
75 static int lua_func_read(lua_State *L);
76 
77 static int lua_autoservice_start(lua_State *L);
78 static int lua_autoservice_stop(lua_State *L);
79 static int lua_autoservice_status(lua_State *L);
80 static int lua_check_hangup(lua_State *L);
81 static int lua_error_function(lua_State *L);
82 
83 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority);
84 static void lua_push_variable_table(lua_State *L);
85 static void lua_create_app_table(lua_State *L);
86 static void lua_create_channel_table(lua_State *L);
87 static void lua_create_variable_metatable(lua_State *L);
88 static void lua_create_application_metatable(lua_State *L);
89 static void lua_create_autoservice_functions(lua_State *L);
90 static void lua_create_hangup_function(lua_State *L);
91 static void lua_concat_args(lua_State *L, int start, int nargs);
92 
93 static void lua_state_destroy(void *data);
94 static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
95 static lua_State *lua_get_state(struct ast_channel *chan);
96 
97 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
98 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
99 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
100 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data);
101 
103 static char *config_file_data = NULL;
104 static long config_file_size = 0;
105 
106 static struct ast_context *local_contexts = NULL;
107 static struct ast_hashtab *local_table = NULL;
108 
109 static const struct ast_datastore_info lua_datastore = {
110  .type = "lua",
111  .destroy = lua_state_destroy,
112  .chan_fixup = lua_datastore_fixup,
113 };
114 
115 
116 /*!
117  * \brief The destructor for lua_datastore
118  */
119 static void lua_state_destroy(void *data)
120 {
121  if (data)
122  lua_close(data);
123 }
124 
125 /*!
126  * \brief The fixup function for the lua_datastore.
127  * \param data the datastore data, in this case it will be a lua_State
128  * \param old_chan the channel we are moving from
129  * \param new_chan the channel we are moving to
130  *
131  * This function updates our internal channel pointer.
132  */
133 static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
134 {
135  lua_State *L = data;
136  lua_pushlightuserdata(L, new_chan);
137  lua_setfield(L, LUA_REGISTRYINDEX, "channel");
138 }
139 
140 /*!
141  * \brief [lua_CFunction] Find an app and return it in a lua table (for access from lua, don't
142  * call directly)
143  *
144  * This function would be called in the following example as it would be found
145  * in extensions.lua.
146  *
147  * \code
148  * app.dial
149  * \endcode
150  */
151 static int lua_pbx_findapp(lua_State *L)
152 {
153  const char *app_name = luaL_checkstring(L, 2);
154 
155  lua_newtable(L);
156 
157  lua_pushstring(L, "name");
158  lua_pushstring(L, app_name);
159  lua_settable(L, -3);
160 
161  luaL_getmetatable(L, "application");
162  lua_setmetatable(L, -2);
163 
164  return 1;
165 }
166 
167 /*!
168  * \brief [lua_CFunction] This function is part of the 'application' metatable
169  * and is used to execute applications similar to pbx_exec() (for access from
170  * lua, don't call directly)
171  *
172  * \param L the lua_State to use
173  * \return nothing
174  *
175  * This funciton is executed as the '()' operator for apps accessed through the
176  * 'app' table.
177  *
178  * \code
179  * app.playback('demo-congrats')
180  * \endcode
181  */
182 static int lua_pbx_exec(lua_State *L)
183 {
184  int res, nargs = lua_gettop(L);
185  const char *data = "";
186  char *app_name, *context, *exten;
187  char tmp[80], tmp2[80], tmp3[LUA_EXT_DATA_SIZE];
188  int priority, autoservice;
189  struct ast_app *app;
190  struct ast_channel *chan;
191 
192  lua_getfield(L, 1, "name");
193  app_name = ast_strdupa(lua_tostring(L, -1));
194  lua_pop(L, 1);
195 
196  if (!(app = pbx_findapp(app_name))) {
197  lua_pushstring(L, "application '");
198  lua_pushstring(L, app_name);
199  lua_pushstring(L, "' not found");
200  lua_concat(L, 3);
201  return lua_error(L);
202  }
203 
204 
205  lua_getfield(L, LUA_REGISTRYINDEX, "channel");
206  chan = lua_touserdata(L, -1);
207  lua_pop(L, 1);
208 
209 
210  lua_getfield(L, LUA_REGISTRYINDEX, "context");
211  context = ast_strdupa(lua_tostring(L, -1));
212  lua_pop(L, 1);
213 
214  lua_getfield(L, LUA_REGISTRYINDEX, "exten");
215  exten = ast_strdupa(lua_tostring(L, -1));
216  lua_pop(L, 1);
217 
218  lua_getfield(L, LUA_REGISTRYINDEX, "priority");
219  priority = lua_tointeger(L, -1);
220  lua_pop(L, 1);
221 
222  lua_concat_args(L, 2, nargs);
223  data = lua_tostring(L, -1);
224 
225  ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\")\n",
226  exten, context, priority,
227  term_color(tmp, app_name, COLOR_BRCYAN, 0, sizeof(tmp)),
228  term_color(tmp2, chan->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
229  term_color(tmp3, data, COLOR_BRMAGENTA, 0, sizeof(tmp3)));
230 
231  lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
232  autoservice = lua_toboolean(L, -1);
233  lua_pop(L, 1);
234 
235  if (autoservice)
236  ast_autoservice_stop(chan);
237 
238  res = pbx_exec(chan, app, data);
239 
240  lua_pop(L, 1); /* pop data */
241  data = "";
242 
243  if (autoservice)
244  ast_autoservice_start(chan);
245 
246  /* error executing an application, report it */
247  if (res) {
248  lua_pushinteger(L, res);
249  return lua_error(L);
250  }
251  return 0;
252 }
253 
254 /*!
255  * \brief [lua_CFunction] Used to get the value of a variable or dialplan
256  * function (for access from lua, don't call directly)
257  *
258  * The value of the variable or function is returned. This function is the
259  * 'get()' function in the following example as would be seen in
260  * extensions.lua.
261  *
262  * \code
263  * channel.variable:get()
264  * \endcode
265  */
266 static int lua_get_variable_value(lua_State *L)
267 {
268  struct ast_channel *chan;
269  char *value = NULL, *name;
270  char *workspace = ast_alloca(LUA_BUF_SIZE);
271  int autoservice;
272 
273  workspace[0] = '\0';
274 
275  if (!lua_istable(L, 1)) {
276  lua_pushstring(L, "User probably used '.' instead of ':' for retrieving a channel variable value");
277  return lua_error(L);
278  }
279 
280  lua_getfield(L, LUA_REGISTRYINDEX, "channel");
281  chan = lua_touserdata(L, -1);
282  lua_pop(L, 1);
283 
284  lua_getfield(L, 1, "name");
285  name = ast_strdupa(lua_tostring(L, -1));
286  lua_pop(L, 1);
287 
288  lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
289  autoservice = lua_toboolean(L, -1);
290  lua_pop(L, 1);
291 
292  if (autoservice)
293  ast_autoservice_stop(chan);
294 
295  /* if this is a dialplan function then use ast_func_read(), otherwise
296  * use pbx_retrieve_variable() */
297  if (!ast_strlen_zero(name) && name[strlen(name) - 1] == ')') {
298  value = ast_func_read(chan, name, workspace, LUA_BUF_SIZE) ? NULL : workspace;
299  } else {
300  pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
301  }
302 
303  if (autoservice)
304  ast_autoservice_start(chan);
305 
306  if (value) {
307  lua_pushstring(L, value);
308  } else {
309  lua_pushnil(L);
310  }
311 
312  return 1;
313 }
314 
315 /*!
316  * \brief [lua_CFunction] Used to set the value of a variable or dialplan
317  * function (for access from lua, don't call directly)
318  *
319  * This function is the 'set()' function in the following example as would be
320  * seen in extensions.lua.
321  *
322  * \code
323  * channel.variable:set("value")
324  * \endcode
325  */
326 static int lua_set_variable_value(lua_State *L)
327 {
328  const char *name, *value;
329  struct ast_channel *chan;
330  int autoservice;
331 
332  if (!lua_istable(L, 1)) {
333  lua_pushstring(L, "User probably used '.' instead of ':' for setting a channel variable");
334  return lua_error(L);
335  }
336 
337  lua_getfield(L, 1, "name");
338  name = ast_strdupa(lua_tostring(L, -1));
339  lua_pop(L, 1);
340 
341  value = luaL_checkstring(L, 2);
342 
343  lua_getfield(L, LUA_REGISTRYINDEX, "channel");
344  chan = lua_touserdata(L, -1);
345  lua_pop(L, 1);
346 
347  lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
348  autoservice = lua_toboolean(L, -1);
349  lua_pop(L, 1);
350 
351  if (autoservice)
352  ast_autoservice_stop(chan);
353 
354  pbx_builtin_setvar_helper(chan, name, value);
355 
356  if (autoservice)
357  ast_autoservice_start(chan);
358 
359  return 0;
360 }
361 
362 /*!
363  * \brief Update the lua registry with the given context, exten, and priority.
364  *
365  * \param L the lua_State to use
366  * \param context the new context
367  * \param exten the new exten
368  * \param priority the new priority
369  */
370 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority)
371 {
372  lua_pushstring(L, context);
373  lua_setfield(L, LUA_REGISTRYINDEX, "context");
374 
375  lua_pushstring(L, exten);
376  lua_setfield(L, LUA_REGISTRYINDEX, "exten");
377 
378  lua_pushinteger(L, priority);
379  lua_setfield(L, LUA_REGISTRYINDEX, "priority");
380 }
381 
382 /*!
383  * \brief Push a 'variable' table on the stack for access the channel variable
384  * with the given name.
385  *
386  * The value on the top of the stack is popped and used as the name.
387  *
388  * \param L the lua_State to use
389  * \param name the name of the variable
390  */
391 static void lua_push_variable_table(lua_State *L)
392 {
393  lua_newtable(L);
394  luaL_getmetatable(L, "variable");
395  lua_setmetatable(L, -2);
396 
397  lua_insert(L, -2); /* move the table after the name */
398  lua_setfield(L, -2, "name");
399 
400  lua_pushcfunction(L, &lua_get_variable_value);
401  lua_setfield(L, -2, "get");
402 
403  lua_pushcfunction(L, &lua_set_variable_value);
404  lua_setfield(L, -2, "set");
405 }
406 
407 /*!
408  * \brief Create the global 'app' table for executing applications
409  *
410  * \param L the lua_State to use
411  */
412 static void lua_create_app_table(lua_State *L)
413 {
414  lua_newtable(L);
415  luaL_newmetatable(L, "app");
416 
417  lua_pushstring(L, "__index");
418  lua_pushcfunction(L, &lua_pbx_findapp);
419  lua_settable(L, -3);
420 
421  lua_setmetatable(L, -2);
422  lua_setglobal(L, "app");
423 }
424 
425 /*!
426  * \brief Create the global 'channel' table for accesing channel variables
427  *
428  * \param L the lua_State to use
429  */
430 static void lua_create_channel_table(lua_State *L)
431 {
432  lua_newtable(L);
433  luaL_newmetatable(L, "channel_data");
434 
435  lua_pushstring(L, "__index");
436  lua_pushcfunction(L, &lua_get_variable);
437  lua_settable(L, -3);
438 
439  lua_pushstring(L, "__newindex");
440  lua_pushcfunction(L, &lua_set_variable);
441  lua_settable(L, -3);
442 
443  lua_setmetatable(L, -2);
444  lua_setglobal(L, "channel");
445 }
446 
447 /*!
448  * \brief Create the 'variable' metatable, used to retrieve channel variables
449  *
450  * \param L the lua_State to use
451  */
452 static void lua_create_variable_metatable(lua_State *L)
453 {
454  luaL_newmetatable(L, "variable");
455 
456  lua_pushstring(L, "__call");
457  lua_pushcfunction(L, &lua_func_read);
458  lua_settable(L, -3);
459 
460  lua_pop(L, 1);
461 }
462 
463 /*!
464  * \brief Create the 'application' metatable, used to execute asterisk
465  * applications from lua
466  *
467  * \param L the lua_State to use
468  */
469 static void lua_create_application_metatable(lua_State *L)
470 {
471  luaL_newmetatable(L, "application");
472 
473  lua_pushstring(L, "__call");
474  lua_pushcfunction(L, &lua_pbx_exec);
475  lua_settable(L, -3);
476 
477  lua_pop(L, 1);
478 }
479 
480 /*!
481  * \brief Create the autoservice functions
482  *
483  * \param L the lua_State to use
484  */
485 static void lua_create_autoservice_functions(lua_State *L)
486 {
487  lua_pushcfunction(L, &lua_autoservice_start);
488  lua_setglobal(L, "autoservice_start");
489 
490  lua_pushcfunction(L, &lua_autoservice_stop);
491  lua_setglobal(L, "autoservice_stop");
492 
493  lua_pushcfunction(L, &lua_autoservice_status);
494  lua_setglobal(L, "autoservice_status");
495 
496  lua_pushboolean(L, 0);
497  lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
498 }
499 
500 /*!
501  * \brief Create the hangup check function
502  *
503  * \param L the lua_State to use
504  */
505 static void lua_create_hangup_function(lua_State *L)
506 {
507  lua_pushcfunction(L, &lua_check_hangup);
508  lua_setglobal(L, "check_hangup");
509 }
510 
511 /*!
512  * \brief [lua_CFunction] Return a lua 'variable' object (for access from lua, don't call
513  * directly)
514  *
515  * This function is called to lookup a variable construct a 'variable' object.
516  * It would be called in the following example as would be seen in
517  * extensions.lua.
518  *
519  * \code
520  * channel.variable
521  * \endcode
522  */
523 static int lua_get_variable(lua_State *L)
524 {
525  struct ast_channel *chan;
526  const char *name = luaL_checkstring(L, 2);
527  char *value = NULL;
528  char *workspace = ast_alloca(LUA_BUF_SIZE);
529  workspace[0] = '\0';
530 
531  lua_getfield(L, LUA_REGISTRYINDEX, "channel");
532  chan = lua_touserdata(L, -1);
533  lua_pop(L, 1);
534 
535  lua_pushvalue(L, 2);
537 
538  /* if this is not a request for a dialplan funciton attempt to retrieve
539  * the value of the variable */
540  if (!ast_strlen_zero(name) && name[strlen(name) - 1] != ')') {
541  pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
542  }
543 
544  if (value) {
545  lua_pushstring(L, value);
546  lua_setfield(L, -2, "value");
547  }
548 
549  return 1;
550 }
551 
552 /*!
553  * \brief [lua_CFunction] Set the value of a channel variable or dialplan
554  * function (for access from lua, don't call directly)
555  *
556  * This function is called to set a variable or dialplan function. It would be
557  * called in the following example as would be seen in extensions.lua.
558  *
559  * \code
560  * channel.variable = "value"
561  * \endcode
562  */
563 static int lua_set_variable(lua_State *L)
564 {
565  struct ast_channel *chan;
566  int autoservice;
567  const char *name = luaL_checkstring(L, 2);
568  const char *value = luaL_checkstring(L, 3);
569 
570  lua_getfield(L, LUA_REGISTRYINDEX, "channel");
571  chan = lua_touserdata(L, -1);
572  lua_pop(L, 1);
573 
574  lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
575  autoservice = lua_toboolean(L, -1);
576  lua_pop(L, 1);
577 
578  if (autoservice)
579  ast_autoservice_stop(chan);
580 
581  pbx_builtin_setvar_helper(chan, name, value);
582 
583  if (autoservice)
584  ast_autoservice_start(chan);
585 
586  return 0;
587 }
588 
589 /*!
590  * \brief Concatenate a list of lua function arguments into a comma separated
591  * string.
592  * \param L the lua_State to use
593  * \param start the index of the first argument
594  * \param nargs the number of args
595  *
596  * The resulting string will be left on the top of the stack.
597  */
598 static void lua_concat_args(lua_State *L, int start, int nargs) {
599  int concat = 0;
600  int i = start + 1;
601 
602  if (start <= nargs && !lua_isnil(L, start)) {
603  lua_pushvalue(L, start);
604  concat += 1;
605  }
606 
607  for (; i <= nargs; i++) {
608  if (lua_isnil(L, i)) {
609  lua_pushliteral(L, ",");
610  concat += 1;
611  } else {
612  lua_pushliteral(L, ",");
613  lua_pushvalue(L, i);
614  concat += 2;
615  }
616  }
617 
618  lua_concat(L, concat);
619 }
620 
621 /*!
622  * \brief [lua_CFunction] Create a 'variable' object for accessing a dialplan
623  * function (for access from lua, don't call directly)
624  *
625  * This function is called to create a 'variable' object to access a dialplan
626  * function. It would be called in the following example as would be seen in
627  * extensions.lua.
628  *
629  * \code
630  * channel.func("arg1", "arg2", "arg3")
631  * \endcode
632  *
633  * To actually do anything with the resulting value you must use the 'get()'
634  * and 'set()' methods (the reason is the resulting value is not a value, but
635  * an object in the form of a lua table).
636  */
637 static int lua_func_read(lua_State *L)
638 {
639  int nargs = lua_gettop(L);
640 
641  /* build a string in the form of "func_name(arg1,arg2,arg3)" */
642  lua_getfield(L, 1, "name");
643  lua_pushliteral(L, "(");
644  lua_concat_args(L, 2, nargs);
645  lua_pushliteral(L, ")");
646  lua_concat(L, 4);
647 
649  return 1;
650 }
651 
652 /*!
653  * \brief [lua_CFunction] Tell pbx_lua to maintain an autoservice on this
654  * channel (for access from lua, don't call directly)
655  *
656  * \param L the lua_State to use
657  *
658  * This function will set a flag that will cause pbx_lua to maintain an
659  * autoservice on this channel. The autoservice will automatically be stopped
660  * and restarted before calling applications and functions.
661  *
662  * \return This function returns the result of the ast_autoservice_start()
663  * function as a boolean to its lua caller.
664  */
665 static int lua_autoservice_start(lua_State *L)
666 {
667  struct ast_channel *chan;
668  int res;
669 
670  lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
671  if (lua_toboolean(L, -1)) {
672  /* autoservice already running */
673  return 1;
674  }
675  lua_pop(L, 1);
676 
677  lua_getfield(L, LUA_REGISTRYINDEX, "channel");
678  chan = lua_touserdata(L, -1);
679  lua_pop(L, 1);
680 
681  res = ast_autoservice_start(chan);
682 
683  lua_pushboolean(L, !res);
684  lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
685 
686  lua_pushboolean(L, !res);
687  return 1;
688 }
689 
690 /*!
691  * \brief [lua_CFunction] Tell pbx_lua to stop maintaning an autoservice on
692  * this channel (for access from lua, don't call directly)
693  *
694  * \param L the lua_State to use
695  *
696  * This function will stop any autoservice running and turn off the autoservice
697  * flag. If this function returns false, it's probably because no autoservice
698  * was running to begin with.
699  *
700  * \return This function returns the result of the ast_autoservice_stop()
701  * function as a boolean to its lua caller.
702  */
703 static int lua_autoservice_stop(lua_State *L)
704 {
705  struct ast_channel *chan;
706  int res;
707 
708  lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
709  if (!lua_toboolean(L, -1)) {
710  /* no autoservice running */
711  return 1;
712  }
713  lua_pop(L, 1);
714 
715  lua_getfield(L, LUA_REGISTRYINDEX, "channel");
716  chan = lua_touserdata(L, -1);
717  lua_pop(L, 1);
718 
719  res = ast_autoservice_stop(chan);
720 
721  lua_pushboolean(L, 0);
722  lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
723 
724  lua_pushboolean(L, !res);
725  return 1;
726 }
727 
728 /*!
729  * \brief [lua_CFunction] Get the status of the autoservice flag (for access
730  * from lua, don't call directly)
731  *
732  * \param L the lua_State to use
733  *
734  * \return This function returns the status of the autoservice flag as a
735  * boolean to its lua caller.
736  */
737 static int lua_autoservice_status(lua_State *L)
738 {
739  lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
740  return 1;
741 }
742 
743 /*!
744  * \brief [lua_CFunction] Check if this channel has been hungup or not (for
745  * access from lua, don't call directly)
746  *
747  * \param L the lua_State to use
748  *
749  * \return This function returns true if the channel was hungup
750  */
751 static int lua_check_hangup(lua_State *L)
752 {
753  struct ast_channel *chan;
754  lua_getfield(L, LUA_REGISTRYINDEX, "channel");
755  chan = lua_touserdata(L, -1);
756  lua_pop(L, 1);
757 
758  lua_pushboolean(L, ast_check_hangup(chan));
759  return 1;
760 }
761 
762 /*!
763  * \brief [lua_CFunction] Handle lua errors (for access from lua, don't call
764  * directly)
765  *
766  * \param L the lua_State to use
767  */
768 static int lua_error_function(lua_State *L)
769 {
770  int message_index;
771 
772  /* pass number arguments right through back to asterisk*/
773  if (lua_isnumber(L, -1)) {
774  return 1;
775  }
776 
777  /* if we are here then we have a string error message, let's attach a
778  * backtrace to it */
779  message_index = lua_gettop(L);
780 
781  /* prepare to prepend a new line to the traceback */
782  lua_pushliteral(L, "\n");
783 
784  lua_getglobal(L, "debug");
785  lua_getfield(L, -1, "traceback");
786  lua_remove(L, -2); /* remove the 'debug' table */
787 
788  lua_pushvalue(L, message_index);
789  lua_remove(L, message_index);
790 
791  lua_pushnumber(L, 2);
792 
793  lua_call(L, 2, 1);
794 
795  /* prepend the new line we prepared above */
796  lua_concat(L, 2);
797 
798  return 1;
799 }
800 
801 /*!
802  * \brief Store the sort order of each context
803 
804  * In the event of an error, an error string will be pushed onto the lua stack.
805  *
806  * \retval 0 success
807  * \retval 1 failure
808  */
809 static int lua_sort_extensions(lua_State *L)
810 {
811  int extensions, extensions_order;
812 
813  /* create the extensions_order table */
814  lua_newtable(L);
815  lua_setfield(L, LUA_REGISTRYINDEX, "extensions_order");
816  lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
817  extensions_order = lua_gettop(L);
818 
819  /* sort each context in the extensions table */
820  /* load the 'extensions' table */
821  lua_getglobal(L, "extensions");
822  extensions = lua_gettop(L);
823  if (lua_isnil(L, -1)) {
824  lua_pop(L, 1);
825  lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
826  return 1;
827  }
828 
829  /* iterate through the extensions table and create a
830  * matching table (holding the sort order) in the
831  * extensions_order table for each context that is found
832  */
833  for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
834  int context = lua_gettop(L);
835  int context_name = context - 1;
836  int context_order;
837 
838  /* copy the context_name to be used as the key for the
839  * context_order table in the extensions_order table later */
840  lua_pushvalue(L, context_name);
841 
842  /* create the context_order table */
843  lua_newtable(L);
844  context_order = lua_gettop(L);
845 
846  /* iterate through this context an popluate the corrisponding
847  * table in the extensions_order table */
848  for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) {
849  int exten = lua_gettop(L) - 1;
850 #if LUA_VERSION_NUM < 502
851  lua_pushinteger(L, lua_objlen(L, context_order) + 1);
852 #else
853  lua_pushinteger(L, lua_rawlen(L, context_order) + 1);
854 #endif
855  lua_pushvalue(L, exten);
856  lua_settable(L, context_order);
857  }
858  lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */
859 
860  /* now sort the new table */
861 
862  /* push the table.sort function */
863  lua_getglobal(L, "table");
864  lua_getfield(L, -1, "sort");
865  lua_remove(L, -2); /* remove the 'table' table */
866 
867  /* push the context_order table */
868  lua_pushvalue(L, context_name);
869  lua_gettable(L, extensions_order);
870 
871  /* push the comp function */
872  lua_pushcfunction(L, &lua_extension_cmp);
873 
874  if (lua_pcall(L, 2, 0, 0)) {
875  lua_insert(L, -5);
876  lua_pop(L, 4);
877  return 1;
878  }
879  }
880 
881  /* remove the extensions table and the extensions_order table */
882  lua_pop(L, 2);
883  return 0;
884 }
885 
886 /*!
887  * \brief Register dialplan switches for our pbx_lua contexs.
888  *
889  * In the event of an error, an error string will be pushed onto the lua stack.
890  *
891  * \retval 0 success
892  * \retval 1 failure
893  */
894 static int lua_register_switches(lua_State *L)
895 {
896  int extensions;
897  struct ast_context *con = NULL;
898 
899  /* create the hash table for our contexts */
900  /* XXX do we ever need to destroy this? pbx_config does not */
901  if (!local_table)
903 
904  /* load the 'extensions' table */
905  lua_getglobal(L, "extensions");
906  extensions = lua_gettop(L);
907  if (lua_isnil(L, -1)) {
908  lua_pop(L, 1);
909  lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
910  return 1;
911  }
912 
913  /* iterate through the extensions table and register a context and
914  * dialplan switch for each lua context
915  */
916  for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
917  int context = lua_gettop(L);
918  int context_name = context - 1;
919  const char *context_str = lua_tostring(L, context_name);
920 
921  /* find or create this context */
922  con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar);
923  if (!con) {
924  /* remove extensions table and context key and value */
925  lua_pop(L, 3);
926  lua_pushstring(L, "Failed to find or create context\n");
927  return 1;
928  }
929 
930  /* register the switch */
931  if (ast_context_add_switch2(con, "Lua", "", 0, registrar)) {
932  /* remove extensions table and context key and value */
933  lua_pop(L, 3);
934  lua_pushstring(L, "Unable to create switch for context\n");
935  return 1;
936  }
937  }
938 
939  /* remove the extensions table */
940  lua_pop(L, 1);
941  return 0;
942 }
943 
944 
945 /*!
946  * \brief [lua_CFunction] Compare two extensions (for access from lua, don't
947  * call directly)
948  *
949  * This function returns true if the first extension passed should match after
950  * the second. It behaves like the '<' operator.
951  */
952 static int lua_extension_cmp(lua_State *L)
953 {
954  const char *a = luaL_checkstring(L, -2);
955  const char *b = luaL_checkstring(L, -1);
956 
957  if (ast_extension_cmp(a, b) == -1)
958  lua_pushboolean(L, 1);
959  else
960  lua_pushboolean(L, 0);
961 
962  return 1;
963 }
964 
965 /*!
966  * \brief Load the extensions.lua file in to a buffer and execute the file
967  *
968  * \param L the lua_State to use
969  * \param size a pointer to store the size of the buffer
970  *
971  * \note The caller is expected to free the buffer at some point.
972  *
973  * \return a pointer to the buffer
974  */
975 static char *lua_read_extensions_file(lua_State *L, long *size)
976 {
977  FILE *f;
978  int error_func;
979  char *data;
980  char *path = ast_alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2);
981  sprintf(path, "%s/%s", ast_config_AST_CONFIG_DIR, config);
982 
983  if (!(f = fopen(path, "r"))) {
984  lua_pushstring(L, "cannot open '");
985  lua_pushstring(L, path);
986  lua_pushstring(L, "' for reading: ");
987  lua_pushstring(L, strerror(errno));
988  lua_concat(L, 4);
989 
990  return NULL;
991  }
992 
993  if (fseek(f, 0l, SEEK_END)) {
994  fclose(f);
995  lua_pushliteral(L, "error determining the size of the config file");
996  return NULL;
997  }
998 
999  *size = ftell(f);
1000 
1001  if (fseek(f, 0l, SEEK_SET)) {
1002  *size = 0;
1003  fclose(f);
1004  lua_pushliteral(L, "error reading config file");
1005  return NULL;
1006  }
1007 
1008  if (!(data = ast_malloc(*size))) {
1009  *size = 0;
1010  fclose(f);
1011  lua_pushstring(L, "not enough memory");
1012  return NULL;
1013  }
1014 
1015  if (fread(data, sizeof(char), *size, f) != *size) {
1016  *size = 0;
1017  fclose(f);
1018  lua_pushliteral(L, "problem reading configuration file");
1019  return NULL;
1020  }
1021  fclose(f);
1022 
1023  lua_pushcfunction(L, &lua_error_function);
1024  error_func = lua_gettop(L);
1025 
1026  if (luaL_loadbuffer(L, data, *size, "extensions.lua")
1027  || lua_pcall(L, 0, LUA_MULTRET, error_func)
1028  || lua_sort_extensions(L)
1029  || lua_register_switches(L)) {
1030  ast_free(data);
1031  data = NULL;
1032  *size = 0;
1033  }
1034 
1035  lua_remove(L, error_func);
1036  return data;
1037 }
1038 
1039 /*!
1040  * \brief Load the extensions.lua file from the internal buffer
1041  *
1042  * \param L the lua_State to use
1043  * \param chan channel to work on
1044  *
1045  * This function also sets up some constructs used by the extensions.lua file.
1046  * In the event of an error, an error string will be pushed onto the lua stack.
1047  *
1048  * \retval 0 success
1049  * \retval 1 failure
1050  */
1051 static int lua_load_extensions(lua_State *L, struct ast_channel *chan)
1052 {
1053 
1054  /* store a pointer to this channel */
1055  lua_pushlightuserdata(L, chan);
1056  lua_setfield(L, LUA_REGISTRYINDEX, "channel");
1057 
1058  luaL_openlibs(L);
1059 
1060  /* load and sort extensions */
1062  if (luaL_loadbuffer(L, config_file_data, config_file_size, "extensions.lua")
1063  || lua_pcall(L, 0, LUA_MULTRET, 0)
1064  || lua_sort_extensions(L)) {
1066  return 1;
1067  }
1069 
1070  /* now we setup special tables and functions */
1071 
1074 
1077 
1080 
1081  return 0;
1082 }
1083 
1084 /*!
1085  * \brief Reload the extensions file and update the internal buffers if it
1086  * loads correctly.
1087  *
1088  * \warning This function should not be called on a lua_State returned from
1089  * lua_get_state().
1090  *
1091  * \param L the lua_State to use (must be freshly allocated with
1092  * luaL_newstate(), don't use lua_get_state())
1093  */
1094 static int lua_reload_extensions(lua_State *L)
1095 {
1096  long size = 0;
1097  char *data = NULL;
1098 
1099  luaL_openlibs(L);
1100 
1101  if (!(data = lua_read_extensions_file(L, &size))) {
1102  return 1;
1103  }
1104 
1106 
1107  if (config_file_data)
1108  ast_free(config_file_data);
1109 
1110  config_file_data = data;
1111  config_file_size = size;
1112 
1113  /* merge our new contexts */
1114  ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
1115  /* merge_contexts_and_delete will actually, at the correct moment,
1116  set the global dialplan pointers to your local_contexts and local_table.
1117  It then will free up the old tables itself. Just be sure not to
1118  hang onto the pointers. */
1119  local_table = NULL;
1120  local_contexts = NULL;
1121 
1123  return 0;
1124 }
1125 
1126 /*!
1127  * \brief Free the internal extensions buffer.
1128  */
1129 static void lua_free_extensions()
1130 {
1132  config_file_size = 0;
1133  ast_free(config_file_data);
1135 }
1136 
1137 /*!
1138  * \brief Get the lua_State for this channel
1139  *
1140  * If no channel is passed then a new state is allocated. States with no
1141  * channel assocatied with them should only be used for matching extensions.
1142  * If the channel does not yet have a lua state associated with it, one will be
1143  * created.
1144  *
1145  * \note If no channel was passed then the caller is expected to free the state
1146  * using lua_close().
1147  *
1148  * \return a lua_State
1149  */
1150 static lua_State *lua_get_state(struct ast_channel *chan)
1151 {
1152  struct ast_datastore *datastore = NULL;
1153  lua_State *L;
1154 
1155  if (!chan) {
1156  lua_State *L = luaL_newstate();
1157  if (!L) {
1158  ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1159  return NULL;
1160  }
1161 
1162  if (lua_load_extensions(L, NULL)) {
1163  const char *error = lua_tostring(L, -1);
1164  ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
1165  lua_close(L);
1166  return NULL;
1167  }
1168  return L;
1169  } else {
1170  ast_channel_lock(chan);
1171  datastore = ast_channel_datastore_find(chan, &lua_datastore, NULL);
1172  ast_channel_unlock(chan);
1173 
1174  if (!datastore) {
1175  /* nothing found, allocate a new lua state */
1176  datastore = ast_datastore_alloc(&lua_datastore, NULL);
1177  if (!datastore) {
1178  ast_log(LOG_ERROR, "Error allocation channel datastore for lua_State\n");
1179  return NULL;
1180  }
1181 
1182  datastore->data = luaL_newstate();
1183  if (!datastore->data) {
1184  ast_datastore_free(datastore);
1185  ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1186  return NULL;
1187  }
1188 
1189  ast_channel_lock(chan);
1190  ast_channel_datastore_add(chan, datastore);
1191  ast_channel_unlock(chan);
1192 
1193  L = datastore->data;
1194 
1195  if (lua_load_extensions(L, chan)) {
1196  const char *error = lua_tostring(L, -1);
1197  ast_log(LOG_ERROR, "Error loading extensions.lua for %s: %s\n", chan->name, error);
1198 
1199  ast_channel_lock(chan);
1200  ast_channel_datastore_remove(chan, datastore);
1201  ast_channel_unlock(chan);
1202 
1203  ast_datastore_free(datastore);
1204  return NULL;
1205  }
1206  }
1207 
1208  return datastore->data;
1209  }
1210 }
1211 
1212 static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1213 {
1214  int res;
1215  lua_State *L;
1216  struct ast_module_user *u = ast_module_user_add(chan);
1217  if (!u) {
1218  ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1219  return 0;
1220  }
1221 
1222  L = lua_get_state(chan);
1223  if (!L) {
1225  return 0;
1226  }
1227 
1228  res = lua_find_extension(L, context, exten, priority, &exists, 0);
1229 
1230  if (!chan) lua_close(L);
1232  return res;
1233 }
1234 
1235 static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1236 {
1237  int res;
1238  lua_State *L;
1239  struct ast_module_user *u = ast_module_user_add(chan);
1240  if (!u) {
1241  ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1242  return 0;
1243  }
1244 
1245  L = lua_get_state(chan);
1246  if (!L) {
1248  return 0;
1249  }
1250 
1251  res = lua_find_extension(L, context, exten, priority, &canmatch, 0);
1252 
1253  if (!chan) lua_close(L);
1255  return res;
1256 }
1257 
1258 static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1259 {
1260  int res;
1261  lua_State *L;
1262  struct ast_module_user *u = ast_module_user_add(chan);
1263  if (!u) {
1264  ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1265  return 0;
1266  }
1267 
1268  L = lua_get_state(chan);
1269  if (!L) {
1271  return 0;
1272  }
1273 
1274  res = lua_find_extension(L, context, exten, priority, &matchmore, 0);
1275 
1276  if (!chan) lua_close(L);
1278  return res;
1279 }
1280 
1281 
1282 static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
1283 {
1284  int res, error_func;
1285  lua_State *L;
1286  struct ast_module_user *u = ast_module_user_add(chan);
1287  if (!u) {
1288  ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
1289  return -1;
1290  }
1291 
1292  L = lua_get_state(chan);
1293  if (!L) {
1295  return -1;
1296  }
1297 
1298  lua_pushcfunction(L, &lua_error_function);
1299  error_func = lua_gettop(L);
1300 
1301  /* push the extension function onto the stack */
1302  if (!lua_find_extension(L, context, exten, priority, &exists, 1)) {
1303  lua_pop(L, 1); /* pop the debug function */
1304  ast_log(LOG_ERROR, "Could not find extension %s in context %s\n", exten, context);
1305  if (!chan) lua_close(L);
1307  return -1;
1308  }
1309 
1310  lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
1311  if (lua_toboolean(L, -1)) {
1312  ast_autoservice_start(chan);
1313  }
1314  lua_pop(L, 1);
1315 
1316  lua_update_registry(L, context, exten, priority);
1317 
1318  lua_pushstring(L, context);
1319  lua_pushstring(L, exten);
1320 
1321  res = lua_pcall(L, 2, 0, error_func);
1322  if (res) {
1323  if (res == LUA_ERRRUN) {
1324  res = -1;
1325  if (lua_isnumber(L, -1)) {
1326  res = lua_tointeger(L, -1);
1327  } else if (lua_isstring(L, -1)) {
1328  const char *error = lua_tostring(L, -1);
1329  ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error);
1330  }
1331  } else if (res == LUA_ERRERR) {
1332  res = -1;
1333  ast_log(LOG_ERROR, "Error in the lua error handler (this is probably a bug in pbx_lua)\n");
1334  } else if (res == LUA_ERRMEM) {
1335  res = -1;
1336  ast_log(LOG_ERROR, "Memory allocation error\n");
1337  }
1338  lua_pop(L, 1);
1339  }
1340  lua_remove(L, error_func);
1341 
1342  lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
1343  if (lua_toboolean(L, -1)) {
1344  ast_autoservice_stop(chan);
1345  }
1346  lua_pop(L, 1);
1347 
1348  if (!chan) lua_close(L);
1350  return res;
1351 }
1352 
1353 /*!
1354  * \brief Locate an extensions and optionally push the matching function on the
1355  * stack
1356  *
1357  * \param L the lua_State to use
1358  * \param context the context to look in
1359  * \param exten the extension to look up
1360  * \param priority the priority to check, '1' is the only valid priority
1361  * \param func the calling func, used to adjust matching behavior between,
1362  * match, canmatch, and matchmore
1363  * \param push_func whether or not to push the lua function for the given
1364  * extension onto the stack
1365  */
1366 static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func)
1367 {
1368  int context_table, context_order_table, i;
1369 
1370  ast_debug(2, "Looking up %s@%s:%i\n", exten, context, priority);
1371  if (priority != 1)
1372  return 0;
1373 
1374  /* load the 'extensions' table */
1375  lua_getglobal(L, "extensions");
1376  if (lua_isnil(L, -1)) {
1377  ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n");
1378  lua_pop(L, 1);
1379  return 0;
1380  }
1381 
1382  /* load the given context */
1383  lua_getfield(L, -1, context);
1384  if (lua_isnil(L, -1)) {
1385  lua_pop(L, 2);
1386  return 0;
1387  }
1388 
1389  /* remove the extensions table */
1390  lua_remove(L, -2);
1391 
1392  context_table = lua_gettop(L);
1393 
1394  /* load the extensions order table for this context */
1395  lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
1396  lua_getfield(L, -1, context);
1397 
1398  lua_remove(L, -2); /* remove the extensions order table */
1399 
1400  context_order_table = lua_gettop(L);
1401 
1402  /* step through the extensions looking for a match */
1403 #if LUA_VERSION_NUM < 502
1404  for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) {
1405 #else
1406  for (i = 1; i < lua_rawlen(L, context_order_table) + 1; i++) {
1407 #endif
1408  int e_index_copy, match = 0;
1409  const char *e;
1410 
1411  lua_pushinteger(L, i);
1412  lua_gettable(L, context_order_table);
1413  lua_gettop(L);
1414 
1415  /* copy the key at the top of the stack for use later */
1416  lua_pushvalue(L, -1);
1417  e_index_copy = lua_gettop(L);
1418 
1419  if (!(e = lua_tostring(L, e_index_copy))) {
1420  lua_pop(L, 2);
1421  continue;
1422  }
1423 
1424  /* make sure this is not the 'include' extension */
1425  if (!strcasecmp(e, "include")) {
1426  lua_pop(L, 2);
1427  continue;
1428  }
1429 
1430  if (func == &matchmore)
1431  match = ast_extension_close(e, exten, E_MATCHMORE);
1432  else if (func == &canmatch)
1433  match = ast_extension_close(e, exten, E_CANMATCH);
1434  else
1435  match = ast_extension_match(e, exten);
1436 
1437  /* the extension matching functions return 0 on fail, 1 on
1438  * match, 2 on earlymatch */
1439 
1440  if (!match) {
1441  /* pop the copy and the extension */
1442  lua_pop(L, 2);
1443  continue; /* keep trying */
1444  }
1445 
1446  if (func == &matchmore && match == 2) {
1447  /* We match an extension ending in '!'. The decision in
1448  * this case is final and counts as no match. */
1449  lua_pop(L, 4);
1450  return 0;
1451  }
1452 
1453  /* remove the context table, the context order table, the
1454  * extension, and the extension copy (or replace the extension
1455  * with the corresponding function) */
1456  if (push_func) {
1457  lua_pop(L, 1); /* pop the copy */
1458  lua_gettable(L, context_table);
1459  lua_insert(L, -3);
1460  lua_pop(L, 2);
1461  } else {
1462  lua_pop(L, 4);
1463  }
1464 
1465  return 1;
1466  }
1467 
1468  /* load the includes for this context */
1469  lua_getfield(L, context_table, "include");
1470  if (lua_isnil(L, -1)) {
1471  lua_pop(L, 3);
1472  return 0;
1473  }
1474 
1475  /* remove the context and the order table*/
1476  lua_remove(L, context_order_table);
1477  lua_remove(L, context_table);
1478 
1479  /* Now try any includes we have in this context */
1480  for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
1481  const char *c = lua_tostring(L, -1);
1482  if (!c)
1483  continue;
1484 
1485  if (lua_find_extension(L, c, exten, priority, func, push_func)) {
1486  /* remove the value, the key, and the includes table
1487  * from the stack. Leave the function behind if
1488  * necessary */
1489 
1490  if (push_func)
1491  lua_insert(L, -4);
1492 
1493  lua_pop(L, 3);
1494  return 1;
1495  }
1496  }
1497 
1498  /* pop the includes table */
1499  lua_pop(L, 1);
1500  return 0;
1501 }
1502 
1503 static struct ast_switch lua_switch = {
1504  .name = "Lua",
1505  .description = "Lua PBX Switch",
1506  .exists = exists,
1507  .canmatch = canmatch,
1508  .exec = exec,
1509  .matchmore = matchmore,
1510 };
1511 
1512 
1514 {
1515  int res = AST_MODULE_LOAD_SUCCESS;
1516 
1517  lua_State *L = luaL_newstate();
1518  if (!L) {
1519  ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
1520  return AST_MODULE_LOAD_DECLINE;
1521  }
1522 
1523  if (lua_reload_extensions(L)) {
1524  const char *error = lua_tostring(L, -1);
1525  ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
1527  }
1528 
1529  if (!res) {
1530  ast_log(LOG_NOTICE, "Lua PBX Switch loaded.\n");
1531  }
1532  lua_close(L);
1533  return res;
1534 }
1535 
1536 static int unload_module(void)
1537 {
1538  ast_context_destroy(NULL, registrar);
1539  ast_unregister_switch(&lua_switch);
1541  ast_log(LOG_NOTICE, "Lua PBX Switch unloaded.\n");
1542  return 0;
1543 }
1544 
1545 static int reload(void)
1546 {
1547  return load_or_reload_lua_stuff();
1548 }
1549 
1550 static int load_module(void)
1551 {
1552  int res;
1553 
1554  if ((res = load_or_reload_lua_stuff()))
1555  return res;
1556 
1557  if (ast_register_switch(&lua_switch)) {
1558  ast_log(LOG_ERROR, "Unable to register LUA PBX switch\n");
1559  return AST_MODULE_LOAD_DECLINE;
1560  }
1561 
1562  return AST_MODULE_LOAD_SUCCESS;
1563 }
1564 
1566  .load = load_module,
1567  .unload = unload_module,
1568  .reload = reload,
1569  );
1570 
const char * type
Definition: datastore.h:32
int ast_hashtab_compare_contexts(const void *ah_a, const void *ah_b)
hashtable functions for contexts
Definition: pbx.c:1136
static int lua_autoservice_start(lua_State *L)
[lua_CFunction] Tell pbx_lua to maintain an autoservice on this channel (for access from lua...
Definition: pbx_lua.c:665
static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func)
Locate an extensions and optionally push the matching function on the stack.
Definition: pbx_lua.c:1366
int( ast_switch_f)(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
All switch functions have the same interface, so define a type for them.
Definition: pbx.h:124
static struct ast_hashtab * local_table
Definition: pbx_lua.c:107
#define ast_channel_lock(chan)
Definition: channel.h:2466
static int reload(void)
Definition: pbx_lua.c:1545
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
executes a read operation on a function
Definition: pbx.c:4177
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
static char * registrar
Definition: pbx_lua.c:51
Asterisk main include file. File version handling, generic pbx functions.
static int lua_get_variable_value(lua_State *L)
[lua_CFunction] Used to get the value of a variable or dialplan function (for access from lua...
Definition: pbx_lua.c:266
int ast_hashtab_newsize_java(struct ast_hashtab *tab)
Create a prime number roughly 2x the current table size.
Definition: hashtab.c:131
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
Definition: autoservice.c:179
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: pbx.c:1537
static void lua_create_application_metatable(lua_State *L)
Create the &#39;application&#39; metatable, used to execute asterisk applications from lua.
Definition: pbx_lua.c:469
int priority
Definition: channel.h:841
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx.c:1497
static void lua_create_variable_metatable(lua_State *L)
Create the &#39;variable&#39; metatable, used to retrieve channel variables.
Definition: pbx_lua.c:452
#define LUA_EXT_DATA_SIZE
Definition: pbx_lua.c:56
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
static void lua_state_destroy(void *data)
The destructor for lua_datastore.
Definition: pbx_lua.c:119
static void lua_concat_args(lua_State *L, int start, int nargs)
Concatenate a list of lua function arguments into a comma separated string.
Definition: pbx_lua.c:598
int ast_extension_cmp(const char *a, const char *b)
Determine if one extension should match before another.
Definition: pbx.c:2713
Generic (perhaps overly so) hashtable implementation Hash Table support in Asterisk.
static int lua_autoservice_status(lua_State *L)
[lua_CFunction] Get the status of the autoservice flag (for access from lua, don&#39;t call directly) ...
Definition: pbx_lua.c:737
static int lua_autoservice_stop(lua_State *L)
[lua_CFunction] Tell pbx_lua to stop maintaning an autoservice on this channel (for access from lua...
Definition: pbx_lua.c:703
Structure for a data store type.
Definition: datastore.h:31
void ast_unregister_switch(struct ast_switch *sw)
Unregister an alternative switch.
Definition: pbx.c:6457
static void lua_create_app_table(lua_State *L)
Create the global &#39;app&#39; table for executing applications.
Definition: pbx_lua.c:412
static int matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Definition: pbx_lua.c:1258
static int lua_sort_extensions(lua_State *L)
Store the sort order of each context.
Definition: pbx_lua.c:809
#define ast_mutex_lock(a)
Definition: lock.h:155
static void lua_push_variable_table(lua_State *L)
Push a &#39;variable&#39; table on the stack for access the channel variable with the given name...
Definition: pbx_lua.c:391
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:374
Structure for a data store object.
Definition: datastore.h:54
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2604
static int load_or_reload_lua_stuff(void)
Definition: pbx_lua.c:1513
int value
Definition: syslog.c:39
#define ast_module_user_remove(user)
Definition: module.h:269
int ast_context_add_switch2(struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar)
Adds a switch (first param is a ast_context)
Definition: pbx.c:8494
#define ast_verb(level,...)
Definition: logger.h:243
int ast_hashtab_resize_java(struct ast_hashtab *tab)
Determines if a table resize should occur using the Java algorithm (if the table load factor is 75% o...
Definition: hashtab.c:88
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:65
#define COLOR_BRCYAN
Definition: term.h:60
Utility functions.
static int lua_check_hangup(lua_State *L)
[lua_CFunction] Check if this channel has been hungup or not (for access from lua, don&#39;t call directly)
Definition: pbx_lua.c:751
static int lua_register_switches(lua_State *L)
Register dialplan switches for our pbx_lua contexs.
Definition: pbx_lua.c:894
static ast_mutex_t config_file_lock
Definition: pbx_lua.c:102
static char * config
Definition: pbx_lua.c:50
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int lua_extension_cmp(lua_State *L)
[lua_CFunction] Compare two extensions (for access from lua, don&#39;t call directly) ...
Definition: pbx_lua.c:952
const char * name
Definition: pbx.h:130
static int lua_get_variable(lua_State *L)
[lua_CFunction] Return a lua &#39;variable&#39; object (for access from lua, don&#39;t call directly) ...
Definition: pbx_lua.c:523
static const char app[]
Definition: app_adsiprog.c:49
General Asterisk PBX channel definitions.
Asterisk file paths, configured in asterisk.conf.
static long config_file_size
Definition: pbx_lua.c:104
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int lua_func_read(lua_State *L)
[lua_CFunction] Create a &#39;variable&#39; object for accessing a dialplan function (for access from lua...
Definition: pbx_lua.c:637
static struct ast_context * local_contexts
Definition: pbx_lua.c:106
static int lua_pbx_findapp(lua_State *L)
[lua_CFunction] Find an app and return it in a lua table (for access from lua, don&#39;t call directly) ...
Definition: pbx_lua.c:151
static int unload_module(void)
Definition: pbx_lua.c:1536
static char * config_file_data
Definition: pbx_lua.c:103
static struct ast_switch lua_switch
Definition: pbx_lua.c:1503
struct ast_hashtab * ast_hashtab_create(int initial_buckets, int(*compare)(const void *a, const void *b), int(*resize)(struct ast_hashtab *), int(*newsize)(struct ast_hashtab *tab), unsigned int(*hash)(const void *obj), int do_locking)
Create the hashtable list.
Definition: hashtab.c:226
static int lua_load_extensions(lua_State *L, struct ast_channel *chan)
Load the extensions.lua file from the internal buffer.
Definition: pbx_lua.c:1051
#define ast_module_user_add(chan)
Definition: module.h:268
Core PBX routines and definitions.
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
Definition: autoservice.c:238
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
static void lua_create_hangup_function(lua_State *L)
Create the hangup check function.
Definition: pbx_lua.c:505
struct ast_channel * chan
Definition: loader.c:73
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Definition: term.c:184
#define COLOR_BRMAGENTA
Definition: term.h:58
static int load_module(void)
Definition: pbx_lua.c:1550
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static void lua_create_autoservice_functions(lua_State *L)
Create the autoservice functions.
Definition: pbx_lua.c:485
#define LOG_ERROR
Definition: logger.h:155
static int canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Definition: pbx_lua.c:1235
const char * ast_config_AST_CONFIG_DIR
Definition: asterisk.c:256
void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
Retrieve the value of a builtin variable or variable from the channel variable stack.
Definition: pbx.c:3434
void ast_merge_contexts_and_delete(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *registrar)
Merge the temporary contexts into a global contexts list and delete from the global list the ones tha...
Definition: pbx.c:7937
static int lua_reload_extensions(lua_State *L)
Reload the extensions file and update the internal buffers if it loads correctly. ...
Definition: pbx_lua.c:1094
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
Definition: datastore.c:98
#define LOG_NOTICE
Definition: logger.h:133
static char * lua_read_extensions_file(lua_State *L, long *size)
Load the extensions.lua file in to a buffer and execute the file.
Definition: pbx_lua.c:975
static int exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Definition: pbx_lua.c:1212
static int lua_set_variable(lua_State *L)
[lua_CFunction] Set the value of a channel variable or dialplan function (for access from lua...
Definition: pbx_lua.c:563
#define ast_channel_unlock(chan)
Definition: channel.h:2467
int errno
static const char name[]
static int lua_error_function(lua_State *L)
[lua_CFunction] Handle lua errors (for access from lua, don&#39;t call directly)
Definition: pbx_lua.c:768
#define ast_free(a)
Definition: astmm.h:97
unsigned int ast_hashtab_hash_contexts(const void *obj)
Definition: pbx.c:1188
int ast_register_switch(struct ast_switch *sw)
Register an alternative dialplan switch.
Definition: pbx.c:6439
static struct ast_format f[]
Definition: format_g726.c:181
int ast_extension_close(const char *pattern, const char *data, int needmore)
Definition: pbx.c:2948
int ast_extension_match(const char *pattern, const char *extension)
Determine if a given extension matches a given pattern (in NXX format)
Definition: pbx.c:2943
static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
The fixup function for the lua_datastore.
Definition: pbx_lua.c:133
static void lua_free_extensions(void)
Free the internal extensions buffer.
Definition: pbx_lua.c:1129
static int lua_set_variable_value(lua_State *L)
[lua_CFunction] Used to set the value of a variable or dialplan function (for access from lua...
Definition: pbx_lua.c:326
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
static int exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Definition: pbx_lua.c:1282
void * data
Definition: datastore.h:56
Standard Command Line Interface.
ast_app: A registered application
Definition: pbx.c:971
static void lua_create_channel_table(lua_State *L)
Create the global &#39;channel&#39; table for accesing channel variables.
Definition: pbx_lua.c:430
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context (or ANY context if NULL)
Definition: pbx.c:9875
Handy terminal functions for vt* terms.
#define LUA_BUF_SIZE
Definition: pbx_lua.c:58
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:7726
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
#define ast_malloc(a)
Definition: astmm.h:91
Asterisk module definitions.
static lua_State * lua_get_state(struct ast_channel *chan)
Get the lua_State for this channel.
Definition: pbx_lua.c:1150
static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2069
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2590
static int lua_pbx_exec(lua_State *L)
[lua_CFunction] This function is part of the &#39;application&#39; metatable and is used to execute applicati...
Definition: pbx_lua.c:182
ast_context: An extension context
Definition: pbx.c:955
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2599
struct varshead varshead
Definition: channel.h:817
static struct ast_datastore_info lua_datastore
Definition: pbx_lua.c:109
#define AST_MUTEX_DEFINE_STATIC(mutex)
Definition: lock.h:526
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority)
Update the lua registry with the given context, exten, and priority.
Definition: pbx_lua.c:370