Fri Jul 24 00:41:54 2009

Asterisk developer's documentation


pbx_lua.c File Reference

Lua PBX Switch. More...

#include "asterisk.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/term.h"
#include "asterisk/paths.h"
#include "asterisk/hashtab.h"
#include <lua5.1/lua.h>
#include <lua5.1/lauxlib.h>
#include <lua5.1/lualib.h>

Go to the source code of this file.

Defines

#define LUA_BUF_SIZE   4096
#define LUA_EXT_DATA_SIZE   256

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
static int exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
static int exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
static int load_module (void)
static int load_or_reload_lua_stuff (void)
static int lua_autoservice_start (lua_State *L)
 [lua_CFunction] Tell pbx_lua to maintain an autoservice on this channel (for access from lua, don't call directly)
static int lua_autoservice_status (lua_State *L)
 [lua_CFunction] Get the status of the autoservice flag (for access from lua, don't call directly)
static int lua_autoservice_stop (lua_State *L)
 [lua_CFunction] Tell pbx_lua to stop maintaning an autoservice on this channel (for access from lua, don't call directly)
static int lua_check_hangup (lua_State *L)
 [lua_CFunction] Check if this channel has been hungup or not (for access from lua, don't call directly)
static void lua_create_app_table (lua_State *L)
 Create the global 'app' table for executing applications.
static void lua_create_application_metatable (lua_State *L)
 Create the 'application' metatable, used to execute asterisk applications from lua.
static void lua_create_autoservice_functions (lua_State *L)
 Create the autoservice functions.
static void lua_create_channel_table (lua_State *L)
 Create the global 'channel' table for accesing channel variables.
static void lua_create_hangup_function (lua_State *L)
 Create the hangup check function.
static void lua_create_variable_metatable (lua_State *L)
 Create the 'variable' metatable, used to retrieve channel variables.
static int lua_error_function (lua_State *L)
 [lua_CFunction] Handle lua errors (for access from lua, don't call directly)
static int lua_extension_cmp (lua_State *L)
 [lua_CFunction] Compare two extensions (for access from lua, don't call directly)
static int lua_find_extension (lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func)
 Locate an extensions and optionally push the matching function on the stack.
static void lua_free_extensions ()
 Free the internal extensions buffer.
static int lua_func_read (lua_State *L)
 [lua_CFunction] Create a 'variable' object for accessing a dialplan function (for access from lua, don't call directly)
static lua_State * lua_get_state (struct ast_channel *chan)
 Get the lua_State for this channel.
static int lua_get_variable (lua_State *L)
 [lua_CFunction] Return a lua 'variable' object (for access from lua, don't call directly)
static int lua_get_variable_value (lua_State *L)
 [lua_CFunction] Used to get the value of a variable or dialplan function (for access from lua, don't call directly)
static int lua_load_extensions (lua_State *L, struct ast_channel *chan)
 Load the extensions.lua file from the internal buffer.
static int lua_pbx_exec (lua_State *L)
 [lua_CFunction] This function is part of the 'application' metatable and is used to execute applications similar to pbx_exec() (for access from lua, don't call directly)
static int lua_pbx_findapp (lua_State *L)
 [lua_CFunction] Find an app and return it in a lua table (for access from lua, don't call directly)
static void lua_push_variable_table (lua_State *L, const char *name)
 Push a 'variable' table on the stack for access the channel variable with the given name.
static char * lua_read_extensions_file (lua_State *L, long *size)
 Load the extensions.lua file in to a buffer and execute the file.
static int lua_register_switches (lua_State *L)
 Register dialplan switches for our pbx_lua contexs.
static int lua_reload_extensions (lua_State *L)
 Reload the extensions file and update the internal buffers if it loads correctly.
static int lua_set_variable (lua_State *L)
 [lua_CFunction] Set the value of a channel variable or dialplan function (for access from lua, don't call directly)
static int lua_set_variable_value (lua_State *L)
 [lua_CFunction] Used to set the value of a variable or dialplan function (for access from lua, don't call directly)
static int lua_sort_extensions (lua_State *L)
 Store the sort order of each context.
void lua_state_destroy (void *data)
 The destructor for lua_datastore.
static void lua_update_registry (lua_State *L, const char *context, const char *exten, int priority)
 Update the lua registry with the given context, exten, and priority.
static int matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
static int reload (void)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Lua PBX Switch" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, }
static struct ast_module_infoast_module_info = &__mod_info
static char * config = "extensions.lua"
char * config_file_data = NULL
static ast_mutex_t config_file_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP )
long config_file_size = 0
static struct ast_contextlocal_contexts = NULL
static struct ast_hashtablocal_table = NULL
static struct ast_datastore_info lua_datastore
static struct ast_switch lua_switch
static char * registrar = "pbx_lua"


Detailed Description

Lua PBX Switch.

Author:
Matthew Nicholson <mnicholson@digium.com>

Definition in file pbx_lua.c.


Define Documentation

#define LUA_BUF_SIZE   4096

Definition at line 53 of file pbx_lua.c.

Referenced by lua_get_variable(), and lua_get_variable_value().

#define LUA_EXT_DATA_SIZE   256

Definition at line 52 of file pbx_lua.c.

Referenced by lua_func_read(), and lua_pbx_exec().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 1474 of file pbx_lua.c.

static void __unreg_module ( void   )  [static]

Definition at line 1474 of file pbx_lua.c.

static int canmatch ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid,
const char *  data 
) [static]

Definition at line 1161 of file pbx_lua.c.

References ast_log(), ast_module_user_add, ast_module_user_remove, chan, LOG_ERROR, lua_find_extension(), and lua_get_state().

Referenced by lua_find_extension().

01162 {
01163    int res;
01164    lua_State *L;
01165    struct ast_module_user *u = ast_module_user_add(chan);
01166    if (!u) {
01167       ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
01168       return 0;
01169    }
01170 
01171    L = lua_get_state(chan);
01172    if (!L) {
01173       ast_module_user_remove(u);
01174       return 0;
01175    }
01176 
01177    res = lua_find_extension(L, context, exten, priority, &canmatch, 0);
01178 
01179    if (!chan) lua_close(L);
01180    ast_module_user_remove(u);
01181    return res;
01182 }

static int exec ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid,
const char *  data 
) [static]

Definition at line 1208 of file pbx_lua.c.

References ast_log(), ast_module_user_add, ast_module_user_remove, chan, exists(), LOG_ERROR, lua_error_function(), lua_find_extension(), lua_get_state(), and lua_update_registry().

01209 {
01210    int res, error_func;
01211    lua_State *L;
01212    struct ast_module_user *u = ast_module_user_add(chan);
01213    if (!u) {
01214       ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
01215       return -1;
01216    }
01217    
01218    L = lua_get_state(chan);
01219    if (!L) {
01220       ast_module_user_remove(u);
01221       return -1;
01222    }
01223 
01224    lua_pushcfunction(L, &lua_error_function);
01225    error_func = lua_gettop(L);
01226 
01227    /* push the extension function onto the stack */
01228    if (!lua_find_extension(L, context, exten, priority, &exists, 1)) {
01229       lua_pop(L, 1); /* pop the debug function */
01230       ast_log(LOG_ERROR, "Could not find extension %s in context %s\n", exten, context);
01231       if (!chan) lua_close(L);
01232       ast_module_user_remove(u);
01233       return -1;
01234    }
01235       
01236    lua_update_registry(L, context, exten, priority);
01237    
01238    lua_pushstring(L, context);
01239    lua_pushstring(L, exten);
01240    
01241    res = lua_pcall(L, 2, 0, error_func);
01242    if (res) {
01243       if (res == LUA_ERRRUN) {
01244          res = -1;
01245          if (lua_isnumber(L, -1)) {
01246             res = lua_tointeger(L, -1);
01247          } else if (lua_isstring(L, -1)) {
01248             const char *error = lua_tostring(L, -1);
01249             ast_log(LOG_ERROR, "Error executing lua extension: %s\n", error);
01250          }
01251       } else if (res == LUA_ERRERR) {
01252          res = -1;
01253          ast_log(LOG_ERROR, "Error in the lua error handler (this is probably a bug in pbx_lua)\n");
01254       } else if (res == LUA_ERRMEM) {
01255          res = -1;
01256          ast_log(LOG_ERROR, "Memory allocation error\n");
01257       }
01258       lua_pop(L, 1);
01259    }
01260    lua_remove(L, error_func);
01261    if (!chan) lua_close(L);
01262    ast_module_user_remove(u);
01263    return res;
01264 }

static int exists ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid,
const char *  data 
) [static]

Definition at line 1138 of file pbx_lua.c.

References ast_log(), ast_module_user_add, ast_module_user_remove, chan, exists(), LOG_ERROR, lua_find_extension(), and lua_get_state().

01139 {
01140    int res;
01141    lua_State *L;
01142    struct ast_module_user *u = ast_module_user_add(chan);
01143    if (!u) {
01144       ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
01145       return 0;
01146    }
01147 
01148    L = lua_get_state(chan);
01149    if (!L) {
01150       ast_module_user_remove(u);
01151       return 0;
01152    }
01153 
01154    res = lua_find_extension(L, context, exten, priority, &exists, 0);
01155 
01156    if (!chan) lua_close(L);
01157    ast_module_user_remove(u);
01158    return res;
01159 }

static int load_module ( void   )  [static]

Definition at line 1455 of file pbx_lua.c.

References ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_switch(), load_or_reload_lua_stuff(), LOG_ERROR, and lua_switch.

01456 {
01457    int res;
01458 
01459    if ((res = load_or_reload_lua_stuff()))
01460       return res;
01461 
01462    if (ast_register_switch(&lua_switch)) {
01463       ast_log(LOG_ERROR, "Unable to register LUA PBX switch\n");
01464       return AST_MODULE_LOAD_DECLINE;
01465    }
01466 
01467    return AST_MODULE_LOAD_SUCCESS;
01468 }

static int load_or_reload_lua_stuff ( void   )  [static]

Definition at line 1422 of file pbx_lua.c.

References ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, LOG_ERROR, and lua_reload_extensions().

Referenced by load_module(), and reload().

01423 {
01424    int res = AST_MODULE_LOAD_SUCCESS;
01425 
01426    lua_State *L = luaL_newstate();
01427    if (!L) {
01428       ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
01429       return AST_MODULE_LOAD_DECLINE;
01430    }
01431 
01432    if (lua_reload_extensions(L)) {
01433       const char *error = lua_tostring(L, -1);
01434       ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
01435       res = AST_MODULE_LOAD_DECLINE;
01436    }
01437 
01438    lua_close(L);
01439    return res;
01440 }

static int lua_autoservice_start ( lua_State *  L  )  [static]

[lua_CFunction] Tell pbx_lua to maintain an autoservice on this channel (for access from lua, don't call directly)

Parameters:
L the lua_State to use
This function will set a flag that will cause pbx_lua to maintain an autoservice on this channel. The autoservice will automatically be stopped and restarted before calling applications and functions.

Returns:
This function returns the result of the ast_autoservice_start() function as a boolean to its lua caller.

Definition at line 637 of file pbx_lua.c.

References ast_autoservice_start(), and chan.

Referenced by lua_create_autoservice_functions().

00638 {
00639    struct ast_channel *chan;
00640    int res;
00641 
00642    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00643    chan = lua_touserdata(L, -1);
00644    lua_pop(L, 1);
00645 
00646    res = ast_autoservice_start(chan);
00647 
00648    lua_pushboolean(L, !res);
00649    lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
00650 
00651    lua_pushboolean(L, !res);
00652    return 1;
00653 }

static int lua_autoservice_status ( lua_State *  L  )  [static]

[lua_CFunction] Get the status of the autoservice flag (for access from lua, don't call directly)

Parameters:
L the lua_State to use
Returns:
This function returns the status of the autoservice flag as a boolean to its lua caller.

Definition at line 695 of file pbx_lua.c.

Referenced by lua_create_autoservice_functions().

00696 {
00697    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
00698    return 1;
00699 }

static int lua_autoservice_stop ( lua_State *  L  )  [static]

[lua_CFunction] Tell pbx_lua to stop maintaning an autoservice on this channel (for access from lua, don't call directly)

Parameters:
L the lua_State to use
This function will stop any autoservice running and turn off the autoservice flag. If this function returns false, it's probably because no autoservice was running to begin with.

Returns:
This function returns the result of the ast_autoservice_stop() function as a boolean to its lua caller.

Definition at line 668 of file pbx_lua.c.

References ast_autoservice_stop(), and chan.

Referenced by lua_create_autoservice_functions().

00669 {
00670    struct ast_channel *chan;
00671    int res;
00672 
00673    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00674    chan = lua_touserdata(L, -1);
00675    lua_pop(L, 1);
00676 
00677    res = ast_autoservice_stop(chan);
00678 
00679    lua_pushboolean(L, 0);
00680    lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
00681 
00682    lua_pushboolean(L, !res);
00683    return 1;
00684 }

static int lua_check_hangup ( lua_State *  L  )  [static]

[lua_CFunction] Check if this channel has been hungup or not (for access from lua, don't call directly)

Parameters:
L the lua_State to use
Returns:
This function returns true if the channel was hungup

Definition at line 709 of file pbx_lua.c.

References ast_check_hangup(), and chan.

Referenced by lua_create_hangup_function().

00710 {
00711    struct ast_channel *chan;
00712    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00713    chan = lua_touserdata(L, -1);
00714    lua_pop(L, 1);
00715 
00716    lua_pushboolean(L, ast_check_hangup(chan));
00717    return 1;
00718 }

static void lua_create_app_table ( lua_State *  L  )  [static]

Create the global 'app' table for executing applications.

Parameters:
L the lua_State to use

Definition at line 398 of file pbx_lua.c.

References lua_pbx_findapp().

Referenced by lua_load_extensions().

00399 {
00400    lua_newtable(L);
00401    luaL_newmetatable(L, "app");
00402 
00403    lua_pushstring(L, "__index");
00404    lua_pushcfunction(L, &lua_pbx_findapp);
00405    lua_settable(L, -3);
00406 
00407    lua_setmetatable(L, -2);
00408    lua_setglobal(L, "app");
00409 }

static void lua_create_application_metatable ( lua_State *  L  )  [static]

Create the 'application' metatable, used to execute asterisk applications from lua.

Parameters:
L the lua_State to use

Definition at line 455 of file pbx_lua.c.

References lua_pbx_exec().

Referenced by lua_load_extensions().

00456 {
00457    luaL_newmetatable(L, "application");
00458 
00459    lua_pushstring(L, "__call");
00460    lua_pushcfunction(L, &lua_pbx_exec);
00461    lua_settable(L, -3);
00462 
00463    lua_pop(L, 1);
00464 }

static void lua_create_autoservice_functions ( lua_State *  L  )  [static]

Create the autoservice functions.

Parameters:
L the lua_State to use

Definition at line 471 of file pbx_lua.c.

References lua_autoservice_start(), lua_autoservice_status(), and lua_autoservice_stop().

Referenced by lua_load_extensions().

00472 {
00473    lua_pushcfunction(L, &lua_autoservice_start);
00474    lua_setglobal(L, "autoservice_start");
00475    
00476    lua_pushcfunction(L, &lua_autoservice_stop);
00477    lua_setglobal(L, "autoservice_stop");
00478 
00479    lua_pushcfunction(L, &lua_autoservice_status);
00480    lua_setglobal(L, "autoservice_status");
00481 
00482    lua_pushboolean(L, 0);
00483    lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
00484 }

static void lua_create_channel_table ( lua_State *  L  )  [static]

Create the global 'channel' table for accesing channel variables.

Parameters:
L the lua_State to use

Definition at line 416 of file pbx_lua.c.

References lua_get_variable(), and lua_set_variable().

Referenced by lua_load_extensions().

00417 {
00418    lua_newtable(L);
00419    luaL_newmetatable(L, "channel_data");
00420 
00421    lua_pushstring(L, "__index");
00422    lua_pushcfunction(L, &lua_get_variable);
00423    lua_settable(L, -3);
00424 
00425    lua_pushstring(L, "__newindex");
00426    lua_pushcfunction(L, &lua_set_variable);
00427    lua_settable(L, -3);
00428 
00429    lua_setmetatable(L, -2);
00430    lua_setglobal(L, "channel");
00431 }

static void lua_create_hangup_function ( lua_State *  L  )  [static]

Create the hangup check function.

Parameters:
L the lua_State to use

Definition at line 491 of file pbx_lua.c.

References lua_check_hangup().

Referenced by lua_load_extensions().

00492 {
00493    lua_pushcfunction(L, &lua_check_hangup);
00494    lua_setglobal(L, "check_hangup");
00495 }

static void lua_create_variable_metatable ( lua_State *  L  )  [static]

Create the 'variable' metatable, used to retrieve channel variables.

Parameters:
L the lua_State to use

Definition at line 438 of file pbx_lua.c.

References lua_func_read().

Referenced by lua_load_extensions().

00439 {
00440    luaL_newmetatable(L, "variable");
00441 
00442    lua_pushstring(L, "__call");
00443    lua_pushcfunction(L, &lua_func_read);
00444    lua_settable(L, -3);
00445 
00446    lua_pop(L, 1);
00447 }

static int lua_error_function ( lua_State *  L  )  [static]

[lua_CFunction] Handle lua errors (for access from lua, don't call directly)

Parameters:
L the lua_State to use

Definition at line 726 of file pbx_lua.c.

Referenced by exec().

00727 {
00728    int message_index;
00729 
00730    /* pass number arguments right through back to asterisk*/
00731    if (lua_isnumber(L, -1)) {
00732       return 1;
00733    }
00734 
00735    /* if we are here then we have a string error message, let's attach a
00736     * backtrace to it */
00737    message_index = lua_gettop(L);
00738 
00739    lua_getglobal(L, "debug");
00740    lua_getfield(L, -1, "traceback");
00741    lua_remove(L, -2); /* remove the 'debug' table */
00742 
00743    lua_pushvalue(L, message_index);
00744    lua_remove(L, message_index);
00745 
00746    lua_pushnumber(L, 2);
00747 
00748    lua_call(L, 2, 1);
00749 
00750    return 1;
00751 }

static int lua_extension_cmp ( lua_State *  L  )  [static]

[lua_CFunction] Compare two extensions (for access from lua, don't call directly)

This function returns true if the first extension passed should match after the second. It behaves like the '<' operator.

Definition at line 897 of file pbx_lua.c.

References ast_extension_cmp().

Referenced by lua_sort_extensions().

00898 {
00899    const char *a = luaL_checkstring(L, -2);
00900    const char *b = luaL_checkstring(L, -1);
00901 
00902    if (ast_extension_cmp(a, b) == -1)
00903       lua_pushboolean(L, 1);
00904    else
00905       lua_pushboolean(L, 0);
00906 
00907    return 1;
00908 }

static int lua_find_extension ( lua_State *  L,
const char *  context,
const char *  exten,
int  priority,
ast_switch_f func,
int  push_func 
) [static]

Locate an extensions and optionally push the matching function on the stack.

Parameters:
L the lua_State to use
context the context to look in
exten the extension to look up
priority the priority to check, '1' is the only valid priority
func the calling func, used to adjust matching behavior between, match, canmatch, and matchmore
push_func whether or not to push the lua function for the given extension onto the stack

Definition at line 1279 of file pbx_lua.c.

References ast_debug, ast_extension_close(), ast_extension_match(), ast_log(), canmatch(), E_CANMATCH, E_MATCHMORE, LOG_ERROR, match(), and matchmore().

Referenced by canmatch(), exec(), exists(), and matchmore().

01280 {
01281    int context_table, context_order_table, i;
01282 
01283    ast_debug(2, "Looking up %s@%s:%i\n", exten, context, priority);
01284    if (priority != 1)
01285       return 0;
01286 
01287    /* load the 'extensions' table */
01288    lua_getglobal(L, "extensions");
01289    if (lua_isnil(L, -1)) {
01290       ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n");
01291       lua_pop(L, 1);
01292       return 0;
01293    }
01294 
01295    /* load the given context */
01296    lua_getfield(L, -1, context);
01297    if (lua_isnil(L, -1)) {
01298       lua_pop(L, 2);
01299       return 0;
01300    }
01301 
01302    /* remove the extensions table */
01303    lua_remove(L, -2);
01304 
01305    context_table = lua_gettop(L);
01306 
01307    /* load the extensions order table for this context */
01308    lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
01309    lua_getfield(L, -1, context);
01310 
01311    lua_remove(L, -2);  /* remove the extensions order table */
01312 
01313    context_order_table = lua_gettop(L);
01314    
01315    /* step through the extensions looking for a match */
01316    for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) {
01317       int e_index, e_index_copy, match = 0;
01318       const char *e;
01319 
01320       lua_pushinteger(L, i);
01321       lua_gettable(L, context_order_table);
01322       e_index = lua_gettop(L);
01323 
01324       /* copy the key at the top of the stack for use later */
01325       lua_pushvalue(L, -1);
01326       e_index_copy = lua_gettop(L);
01327 
01328       if (!(e = lua_tostring(L, e_index_copy))) {
01329          lua_pop(L, 2);
01330          continue;
01331       }
01332 
01333       /* make sure this is not the 'include' extension */
01334       if (!strcasecmp(e, "include")) {
01335          lua_pop(L, 2);
01336          continue;
01337       }
01338 
01339       if (func == &matchmore)
01340          match = ast_extension_close(e, exten, E_MATCHMORE);
01341       else if (func == &canmatch)
01342          match = ast_extension_close(e, exten, E_CANMATCH);
01343       else
01344          match = ast_extension_match(e, exten);
01345 
01346       /* the extension matching functions return 0 on fail, 1 on
01347        * match, 2 on earlymatch */
01348 
01349       if (!match) {
01350          /* pop the copy and the extension */
01351          lua_pop(L, 2);
01352          continue;   /* keep trying */
01353       }
01354 
01355       if (func == &matchmore && match == 2) {
01356          /* We match an extension ending in '!'. The decision in
01357           * this case is final and counts as no match. */
01358          lua_pop(L, 4);
01359          return 0;
01360       }
01361 
01362       /* remove the context table, the context order table, the
01363        * extension, and the extension copy (or replace the extension
01364        * with the corresponding function) */
01365       if (push_func) {
01366          lua_pop(L, 1);  /* pop the copy */
01367          lua_gettable(L, context_table);
01368          lua_insert(L, -3);
01369          lua_pop(L, 2);
01370       } else {
01371          lua_pop(L, 4);
01372       }
01373 
01374       return 1;
01375    }
01376 
01377    /* load the includes for this context */
01378    lua_getfield(L, context_table, "include");
01379    if (lua_isnil(L, -1)) {
01380       lua_pop(L, 3);
01381       return 0;
01382    }
01383 
01384    /* remove the context and the order table*/
01385    lua_remove(L, context_order_table);
01386    lua_remove(L, context_table);
01387 
01388    /* Now try any includes we have in this context */
01389    for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
01390       const char *c = lua_tostring(L, -1);
01391       if (!c)
01392          continue;
01393 
01394       if (lua_find_extension(L, c, exten, priority, func, push_func)) {
01395          /* remove the value, the key, and the includes table
01396           * from the stack.  Leave the function behind if
01397           * necessary */
01398 
01399          if (push_func)
01400             lua_insert(L, -4);
01401 
01402          lua_pop(L, 3);
01403          return 1;
01404       }
01405    }
01406 
01407    /* pop the includes table */
01408    lua_pop(L, 1);
01409    return 0;
01410 }

static void lua_free_extensions ( void   )  [static]

Free the internal extensions buffer.

Definition at line 1055 of file pbx_lua.c.

References ast_free, ast_mutex_lock(), ast_mutex_unlock(), and config_file_lock.

Referenced by unload_module().

static int lua_func_read ( lua_State *  L  )  [static]

[lua_CFunction] Create a 'variable' object for accessing a dialplan function (for access from lua, don't call directly)

This function is called to create a 'variable' object to access a dialplan function. It would be called in the following example as would be seen in extensions.lua.

 channel.func("arg1", "arg2", "arg3")

To actually do anything with the resulting value you must use the 'get()' and 'set()' methods (the reason is the resulting value is not a value, but an object in the form of a lua table).

Definition at line 590 of file pbx_lua.c.

References ast_build_string(), ast_strdupa, LUA_EXT_DATA_SIZE, lua_push_variable_table(), and name.

Referenced by lua_create_variable_metatable().

00591 {
00592    int nargs = lua_gettop(L);
00593    char fullname[LUA_EXT_DATA_SIZE] = "";
00594    char *fullname_next = fullname, *name;
00595    size_t fullname_left = sizeof(fullname);
00596    
00597    lua_getfield(L, 1, "name");
00598    name = ast_strdupa(lua_tostring(L, -1));
00599    lua_pop(L, 1);
00600 
00601    ast_build_string(&fullname_next, &fullname_left, "%s(", name);
00602    
00603    if (nargs > 1) {
00604       int i;
00605 
00606       if (!lua_isnil(L, 2))
00607          ast_build_string(&fullname_next, &fullname_left, "%s", luaL_checkstring(L, 2));
00608 
00609       for (i = 3; i <= nargs; i++) {
00610          if (lua_isnil(L, i))
00611             ast_build_string(&fullname_next, &fullname_left, ",");
00612          else
00613             ast_build_string(&fullname_next, &fullname_left, ",%s", luaL_checkstring(L, i));
00614       }
00615    }
00616 
00617    ast_build_string(&fullname_next, &fullname_left, ")");
00618    
00619    lua_push_variable_table(L, fullname);
00620    
00621    return 1;
00622 }

static lua_State * lua_get_state ( struct ast_channel chan  )  [static]

Get the lua_State for this channel.

If no channel is passed then a new state is allocated. States with no channel assocatied with them should only be used for matching extensions. If the channel does not yet have a lua state associated with it, one will be created.

Note:
If no channel was passed then the caller is expected to free the state using lua_close().
Returns:
a lua_State

Definition at line 1076 of file pbx_lua.c.

References ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc(), ast_datastore_free(), ast_log(), chan, ast_datastore::data, LOG_ERROR, lua_datastore, lua_load_extensions(), and ast_channel::name.

Referenced by canmatch(), exec(), exists(), and matchmore().

01077 {
01078    struct ast_datastore *datastore = NULL;
01079    lua_State *L;
01080 
01081    if (!chan) {
01082       lua_State *L = luaL_newstate();
01083       if (!L) {
01084          ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
01085          return NULL;
01086       }
01087 
01088       if (lua_load_extensions(L, NULL)) {
01089          const char *error = lua_tostring(L, -1);
01090          ast_log(LOG_ERROR, "Error loading extensions.lua: %s\n", error);
01091          lua_close(L);
01092          return NULL;
01093       }
01094       return L;
01095    } else {
01096       ast_channel_lock(chan);
01097       datastore = ast_channel_datastore_find(chan, &lua_datastore, NULL);
01098       ast_channel_unlock(chan);
01099 
01100       if (!datastore) {
01101          /* nothing found, allocate a new lua state */
01102          datastore = ast_datastore_alloc(&lua_datastore, NULL);
01103          if (!datastore) {
01104             ast_log(LOG_ERROR, "Error allocation channel datastore for lua_State\n");
01105             return NULL;
01106          }
01107 
01108          datastore->data = luaL_newstate();
01109          if (!datastore->data) {
01110             ast_datastore_free(datastore);
01111             ast_log(LOG_ERROR, "Error allocating lua_State, no memory\n");
01112             return NULL;
01113          }
01114 
01115          ast_channel_lock(chan);
01116          ast_channel_datastore_add(chan, datastore);
01117          ast_channel_unlock(chan);
01118 
01119          L = datastore->data;
01120 
01121          if (lua_load_extensions(L, chan)) {
01122             const char *error = lua_tostring(L, -1);
01123             ast_log(LOG_ERROR, "Error loading extensions.lua for %s: %s\n", chan->name, error);
01124 
01125             ast_channel_lock(chan);
01126             ast_channel_datastore_remove(chan, datastore);
01127             ast_channel_unlock(chan);
01128 
01129             ast_datastore_free(datastore);
01130             return NULL;
01131          }
01132       }
01133 
01134       return datastore->data;
01135    }
01136 }

static int lua_get_variable ( lua_State *  L  )  [static]

[lua_CFunction] Return a lua 'variable' object (for access from lua, don't call directly)

This function is called to lookup a variable construct a 'variable' object. It would be called in the following example as would be seen in extensions.lua.

 channel.variable

Definition at line 509 of file pbx_lua.c.

References ast_strdupa, ast_strlen_zero(), chan, LUA_BUF_SIZE, lua_push_variable_table(), name, pbx_retrieve_variable(), and ast_channel::varshead.

Referenced by lua_create_channel_table().

00510 {
00511    struct ast_channel *chan;
00512    char *name = ast_strdupa(luaL_checkstring(L, 2));
00513    char *value = NULL;
00514    char *workspace = alloca(LUA_BUF_SIZE);
00515    workspace[0] = '\0';
00516    
00517    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00518    chan = lua_touserdata(L, -1);
00519    lua_pop(L, 1);
00520 
00521    lua_push_variable_table(L, name);
00522    
00523    /* if this is not a request for a dialplan funciton attempt to retrieve
00524     * the value of the variable */
00525    if (!ast_strlen_zero(name) && name[strlen(name) - 1] != ')') {
00526       pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
00527    }
00528 
00529    if (value) {
00530       lua_pushstring(L, value);
00531       lua_setfield(L, -2, "value");
00532    }
00533 
00534    return 1;   
00535 }

static int lua_get_variable_value ( lua_State *  L  )  [static]

[lua_CFunction] Used to get the value of a variable or dialplan function (for access from lua, don't call directly)

The value of the variable or function is returned. This function is the 'get()' function in the following example as would be seen in extensions.lua.

 channel.variable:get()

Definition at line 254 of file pbx_lua.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_func_read(), ast_strdupa, ast_strlen_zero(), chan, LUA_BUF_SIZE, name, and pbx_retrieve_variable().

Referenced by lua_push_variable_table().

00255 {
00256    struct ast_channel *chan;
00257    char *value = NULL, *name;
00258    char *workspace = alloca(LUA_BUF_SIZE);
00259    int autoservice;
00260 
00261    workspace[0] = '\0';
00262 
00263    if (!lua_istable(L, 1)) {
00264       lua_pushstring(L, "User probably used '.' instead of ':' for retrieving a channel variable value");
00265       return lua_error(L);
00266    }
00267    
00268    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00269    chan = lua_touserdata(L, -1);
00270    lua_pop(L, 1);
00271 
00272    lua_getfield(L, 1, "name");
00273    name = ast_strdupa(lua_tostring(L, -1));
00274    lua_pop(L, 1);
00275    
00276    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
00277    autoservice = lua_toboolean(L, -1);
00278    lua_pop(L, 1);
00279 
00280    if (autoservice)
00281       ast_autoservice_stop(chan);
00282    
00283    /* if this is a dialplan function then use ast_func_read(), otherwise
00284     * use pbx_retrieve_variable() */
00285    if (!ast_strlen_zero(name) && name[strlen(name) - 1] == ')') {
00286       value = ast_func_read(chan, name, workspace, LUA_BUF_SIZE) ? NULL : workspace;
00287    } else {
00288       pbx_retrieve_variable(chan, name, &value, workspace, LUA_BUF_SIZE, &chan->varshead);
00289    }
00290    
00291    if (autoservice)
00292       ast_autoservice_start(chan);
00293 
00294    if (value) {
00295       lua_pushstring(L, value);
00296    } else {
00297       lua_pushnil(L);
00298    }
00299 
00300    return 1;
00301 }

static int lua_load_extensions ( lua_State *  L,
struct ast_channel chan 
) [static]

Load the extensions.lua file from the internal buffer.

Parameters:
L the lua_State to use
chan channel to work on
This function also sets up some constructs used by the extensions.lua file. In the event of an error, an error string will be pushed onto the lua stack.

Return values:
0 success
1 failure

Definition at line 977 of file pbx_lua.c.

References ast_mutex_lock(), ast_mutex_unlock(), chan, config_file_lock, lua_create_app_table(), lua_create_application_metatable(), lua_create_autoservice_functions(), lua_create_channel_table(), lua_create_hangup_function(), lua_create_variable_metatable(), and lua_sort_extensions().

Referenced by lua_get_state().

00978 {
00979    
00980    /* store a pointer to this channel */
00981    lua_pushlightuserdata(L, chan);
00982    lua_setfield(L, LUA_REGISTRYINDEX, "channel");
00983    
00984    luaL_openlibs(L);
00985 
00986    /* load and sort extensions */
00987    ast_mutex_lock(&config_file_lock);
00988    if (luaL_loadbuffer(L, config_file_data, config_file_size, "extensions.lua")
00989          || lua_pcall(L, 0, LUA_MULTRET, 0)
00990          || lua_sort_extensions(L)) {
00991       ast_mutex_unlock(&config_file_lock);
00992       return 1;
00993    }
00994    ast_mutex_unlock(&config_file_lock);
00995 
00996    /* now we setup special tables and functions */
00997 
00998    lua_create_app_table(L);
00999    lua_create_channel_table(L);
01000 
01001    lua_create_variable_metatable(L);
01002    lua_create_application_metatable(L);
01003 
01004    lua_create_autoservice_functions(L);
01005    lua_create_hangup_function(L);
01006 
01007    return 0;
01008 }

static int lua_pbx_exec ( lua_State *  L  )  [static]

[lua_CFunction] This function is part of the 'application' metatable and is used to execute applications similar to pbx_exec() (for access from lua, don't call directly)

Parameters:
L the lua_State to use
Returns:
nothing
This funciton is executed as the '()' operator for apps accessed through the 'app' table.

 app.playback('demo-congrats')

Definition at line 159 of file pbx_lua.c.

References app, ast_autoservice_start(), ast_autoservice_stop(), ast_build_string(), ast_strdupa, ast_verb, chan, COLOR_BRCYAN, COLOR_BRMAGENTA, context, exten, LUA_EXT_DATA_SIZE, ast_channel::name, pbx_exec(), pbx_findapp(), and term_color().

Referenced by lua_create_application_metatable().

00160 {
00161    int res, nargs = lua_gettop(L);
00162    char data[LUA_EXT_DATA_SIZE] = "";
00163    char *data_next = data, *app_name;
00164    char *context, *exten;
00165    char tmp[80], tmp2[80], tmp3[LUA_EXT_DATA_SIZE];
00166    int priority, autoservice;
00167    size_t data_left = sizeof(data);
00168    struct ast_app *app;
00169    struct ast_channel *chan;
00170    
00171    lua_getfield(L, 1, "name");
00172    app_name = ast_strdupa(lua_tostring(L, -1));
00173    lua_pop(L, 1);
00174    
00175    if (!(app = pbx_findapp(app_name))) {
00176       lua_pushstring(L, "application '");
00177       lua_pushstring(L, app_name);
00178       lua_pushstring(L, "' not found");
00179       lua_concat(L, 3);
00180       return lua_error(L);
00181    }
00182    
00183 
00184    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00185    chan = lua_touserdata(L, -1);
00186    lua_pop(L, 1);
00187    
00188    
00189    lua_getfield(L, LUA_REGISTRYINDEX, "context");
00190    context = ast_strdupa(lua_tostring(L, -1));
00191    lua_pop(L, 1);
00192    
00193    lua_getfield(L, LUA_REGISTRYINDEX, "exten");
00194    exten = ast_strdupa(lua_tostring(L, -1));
00195    lua_pop(L, 1);
00196    
00197    lua_getfield(L, LUA_REGISTRYINDEX, "priority");
00198    priority = lua_tointeger(L, -1);
00199    lua_pop(L, 1);
00200 
00201 
00202    if (nargs > 1) {
00203       int i;
00204 
00205       if (!lua_isnil(L, 2))
00206          ast_build_string(&data_next, &data_left, "%s", luaL_checkstring(L, 2));
00207 
00208       for (i = 3; i <= nargs; i++) {
00209          if (lua_isnil(L, i))
00210             ast_build_string(&data_next, &data_left, ",");
00211          else
00212             ast_build_string(&data_next, &data_left, ",%s", luaL_checkstring(L, i));
00213       }
00214    }
00215    
00216    ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\")\n",
00217          exten, context, priority,
00218          term_color(tmp, app_name, COLOR_BRCYAN, 0, sizeof(tmp)),
00219          term_color(tmp2, chan->name, COLOR_BRMAGENTA, 0, sizeof(tmp2)),
00220          term_color(tmp3, data, COLOR_BRMAGENTA, 0, sizeof(tmp3)));
00221 
00222    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
00223    autoservice = lua_toboolean(L, -1);
00224    lua_pop(L, 1);
00225 
00226    if (autoservice)
00227       ast_autoservice_stop(chan);
00228 
00229    res = pbx_exec(chan, app, data);
00230    
00231    if (autoservice)
00232       ast_autoservice_start(chan);
00233 
00234    /* error executing an application, report it */
00235    if (res) {
00236       lua_pushinteger(L, res);
00237       return lua_error(L);
00238    }
00239    return 0;
00240 }

static int lua_pbx_findapp ( lua_State *  L  )  [static]

[lua_CFunction] Find an app and return it in a lua table (for access from lua, don't call directly)

This function would be called in the following example as it would be found in extensions.lua.

 app.dial

Definition at line 128 of file pbx_lua.c.

Referenced by lua_create_app_table().

00129 {
00130    const char *app_name = luaL_checkstring(L, 2);
00131    
00132    lua_newtable(L);
00133 
00134    lua_pushstring(L, "name");
00135    lua_pushstring(L, app_name);
00136    lua_settable(L, -3);
00137 
00138    luaL_getmetatable(L, "application");
00139    lua_setmetatable(L, -2);
00140 
00141    return 1;
00142 }

static void lua_push_variable_table ( lua_State *  L,
const char *  name 
) [static]

Push a 'variable' table on the stack for access the channel variable with the given name.

Parameters:
L the lua_State to use
name the name of the variable

Definition at line 377 of file pbx_lua.c.

References lua_get_variable_value(), and lua_set_variable_value().

Referenced by lua_func_read(), and lua_get_variable().

00378 {
00379    lua_newtable(L);
00380    luaL_getmetatable(L, "variable");
00381    lua_setmetatable(L, -2);
00382 
00383    lua_pushstring(L, name);
00384    lua_setfield(L, -2, "name");
00385    
00386    lua_pushcfunction(L, &lua_get_variable_value);
00387    lua_setfield(L, -2, "get");
00388    
00389    lua_pushcfunction(L, &lua_set_variable_value);
00390    lua_setfield(L, -2, "set");
00391 }

static char * lua_read_extensions_file ( lua_State *  L,
long *  size 
) [static]

Load the extensions.lua file in to a buffer and execute the file.

Parameters:
L the lua_State to use
size a pointer to store the size of the buffer
Note:
The caller is expected to free the buffer at some point.
Returns:
a pointer to the buffer

Definition at line 920 of file pbx_lua.c.

References ast_config_AST_CONFIG_DIR, ast_free, ast_log(), ast_malloc, errno, f, LOG_WARNING, lua_register_switches(), and lua_sort_extensions().

Referenced by lua_reload_extensions().

00921 {
00922    FILE *f;
00923    char *data;
00924    char *path = alloca(strlen(config) + strlen(ast_config_AST_CONFIG_DIR) + 2);
00925    sprintf(path, "%s/%s", ast_config_AST_CONFIG_DIR, config);
00926 
00927    if (!(f = fopen(path, "r"))) {
00928       lua_pushstring(L, "cannot open '");
00929       lua_pushstring(L, path);
00930       lua_pushstring(L, "' for reading: ");
00931       lua_pushstring(L, strerror(errno));
00932       lua_concat(L, 4);
00933 
00934       return NULL;
00935    }
00936 
00937    fseek(f, 0l, SEEK_END);
00938    *size = ftell(f);
00939 
00940    fseek(f, 0l, SEEK_SET);
00941 
00942    if (!(data = ast_malloc(*size))) {
00943       *size = 0;
00944       fclose(f);
00945       lua_pushstring(L, "not enough memory");
00946       return NULL;
00947    }
00948 
00949    if (fread(data, sizeof(char), *size, f) != *size) {
00950       ast_log(LOG_WARNING, "fread() failed: %s\n", strerror(errno));
00951    }
00952    fclose(f);
00953 
00954    if (luaL_loadbuffer(L, data, *size, "extensions.lua")
00955          || lua_pcall(L, 0, LUA_MULTRET, 0)
00956          || lua_sort_extensions(L)
00957          || lua_register_switches(L)) {
00958       ast_free(data);
00959       data = NULL;
00960       *size = 0;
00961    }
00962    return data;
00963 }

static int lua_register_switches ( lua_State *  L  )  [static]

Register dialplan switches for our pbx_lua contexs.

In the event of an error, an error string will be pushed onto the lua stack.

Return values:
0 success
1 failure

Definition at line 839 of file pbx_lua.c.

References ast_context_add_switch2(), ast_context_find_or_create(), ast_hashtab_compare_contexts(), ast_hashtab_create(), ast_hashtab_hash_contexts(), ast_hashtab_newsize_java(), ast_hashtab_resize_java(), context, local_contexts, and local_table.

Referenced by lua_read_extensions_file().

00840 {
00841    int extensions;
00842    struct ast_context *con = NULL;
00843 
00844    /* create the hash table for our contexts */
00845    /* XXX do we ever need to destroy this? pbx_config does not */
00846    if (!local_table)
00847       local_table = ast_hashtab_create(17, ast_hashtab_compare_contexts, ast_hashtab_resize_java, ast_hashtab_newsize_java, ast_hashtab_hash_contexts, 0);
00848 
00849    /* load the 'extensions' table */
00850    lua_getglobal(L, "extensions");
00851    extensions = lua_gettop(L);
00852    if (lua_isnil(L, -1)) {
00853       lua_pop(L, 1);
00854       lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
00855       return 1;
00856    }
00857 
00858    /* iterate through the extensions table and register a context and
00859     * dialplan switch for each lua context
00860     */
00861    for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
00862       int context = lua_gettop(L);
00863       int context_name = context - 1;
00864       const char *context_str = lua_tostring(L, context_name);
00865 
00866       /* find or create this context */
00867       con = ast_context_find_or_create(&local_contexts, local_table, context_str, registrar);
00868       if (!con) {
00869          /* remove extensions table and context key and value */
00870          lua_pop(L, 3);
00871          lua_pushstring(L, "Failed to find or create context\n");
00872          return 1;
00873       }
00874 
00875       /* register the switch */
00876       if (ast_context_add_switch2(con, "Lua", "", 0, registrar)) {
00877          /* remove extensions table and context key and value */
00878          lua_pop(L, 3);
00879          lua_pushstring(L, "Unable to create switch for context\n");
00880          return 1;
00881       }
00882    }
00883    
00884    /* remove the extensions table */
00885    lua_pop(L, 1);
00886    return 0;
00887 }

static int lua_reload_extensions ( lua_State *  L  )  [static]

Reload the extensions file and update the internal buffers if it loads correctly.

Warning:
This function should not be called on a lua_State returned from lua_get_state().
Parameters:
L the lua_State to use (must be freshly allocated with luaL_newstate(), don't use lua_get_state())

Definition at line 1020 of file pbx_lua.c.

References ast_free, ast_merge_contexts_and_delete(), ast_mutex_lock(), ast_mutex_unlock(), config_file_lock, local_contexts, local_table, and lua_read_extensions_file().

Referenced by load_or_reload_lua_stuff().

01021 {
01022    long size = 0;
01023    char *data = NULL;
01024 
01025    luaL_openlibs(L);
01026 
01027    if (!(data = lua_read_extensions_file(L, &size))) {
01028       return 1;
01029    }
01030 
01031    ast_mutex_lock(&config_file_lock);
01032 
01033    if (config_file_data)
01034       ast_free(config_file_data);
01035 
01036    config_file_data = data;
01037    config_file_size = size;
01038    
01039    /* merge our new contexts */
01040    ast_merge_contexts_and_delete(&local_contexts, local_table, registrar);
01041    /* merge_contexts_and_delete will actually, at the correct moment, 
01042       set the global dialplan pointers to your local_contexts and local_table.
01043       It then will free up the old tables itself. Just be sure not to
01044       hang onto the pointers. */
01045    local_table = NULL;
01046    local_contexts = NULL;
01047 
01048    ast_mutex_unlock(&config_file_lock);
01049    return 0;
01050 }

static int lua_set_variable ( lua_State *  L  )  [static]

[lua_CFunction] Set the value of a channel variable or dialplan function (for access from lua, don't call directly)

This function is called to set a variable or dialplan function. It would be called in the following example as would be seen in extensions.lua.

 channel.variable = "value"

Definition at line 548 of file pbx_lua.c.

References ast_autoservice_start(), ast_autoservice_stop(), chan, name, and pbx_builtin_setvar_helper().

Referenced by lua_create_channel_table().

00549 {
00550    struct ast_channel *chan;
00551    int autoservice;
00552    const char *name = luaL_checkstring(L, 2);
00553    const char *value = luaL_checkstring(L, 3);
00554 
00555    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00556    chan = lua_touserdata(L, -1);
00557    lua_pop(L, 1);
00558 
00559    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
00560    autoservice = lua_toboolean(L, -1);
00561    lua_pop(L, 1);
00562 
00563    if (autoservice)
00564       ast_autoservice_stop(chan);
00565 
00566    pbx_builtin_setvar_helper(chan, name, value);
00567    
00568    if (autoservice)
00569       ast_autoservice_start(chan);
00570 
00571    return 0;
00572 }

static int lua_set_variable_value ( lua_State *  L  )  [static]

[lua_CFunction] Used to set the value of a variable or dialplan function (for access from lua, don't call directly)

This function is the 'set()' function in the following example as would be seen in extensions.lua.

 channel.variable:set("value")

Definition at line 314 of file pbx_lua.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_strdupa, chan, name, and pbx_builtin_setvar_helper().

Referenced by lua_push_variable_table().

00315 {
00316    const char *name, *value;
00317    struct ast_channel *chan;
00318    int autoservice;
00319 
00320    if (!lua_istable(L, 1)) {
00321       lua_pushstring(L, "User probably used '.' instead of ':' for setting a channel variable");
00322       return lua_error(L);
00323    }
00324 
00325    lua_getfield(L, 1, "name");
00326    name = ast_strdupa(lua_tostring(L, -1));
00327    lua_pop(L, 1);
00328 
00329    value = luaL_checkstring(L, 2);
00330    
00331    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00332    chan = lua_touserdata(L, -1);
00333    lua_pop(L, 1);
00334 
00335    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
00336    autoservice = lua_toboolean(L, -1);
00337    lua_pop(L, 1);
00338 
00339    if (autoservice)
00340       ast_autoservice_stop(chan);
00341 
00342    pbx_builtin_setvar_helper(chan, name, value);
00343    
00344    if (autoservice)
00345       ast_autoservice_start(chan);
00346 
00347    return 0;
00348 }

static int lua_sort_extensions ( lua_State *  L  )  [static]

Store the sort order of each context.

In the event of an error, an error string will be pushed onto the lua stack.

Return values:
0 success
1 failure

Definition at line 761 of file pbx_lua.c.

References context, exten, and lua_extension_cmp().

Referenced by lua_load_extensions(), and lua_read_extensions_file().

00762 {
00763    int extensions, extensions_order;
00764 
00765    /* create the extensions_order table */
00766    lua_newtable(L);
00767    lua_setfield(L, LUA_REGISTRYINDEX, "extensions_order");
00768    lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
00769    extensions_order = lua_gettop(L);
00770 
00771    /* sort each context in the extensions table */
00772    /* load the 'extensions' table */
00773    lua_getglobal(L, "extensions");
00774    extensions = lua_gettop(L);
00775    if (lua_isnil(L, -1)) {
00776       lua_pop(L, 1);
00777       lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
00778       return 1;
00779    }
00780 
00781    /* iterate through the extensions table and create a
00782     * matching table (holding the sort order) in the
00783     * extensions_order table for each context that is found
00784     */
00785    for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
00786       int context = lua_gettop(L);
00787       int context_name = context - 1;
00788       int context_order;
00789 
00790       lua_pushvalue(L, context_name);
00791       lua_newtable(L);
00792       context_order = lua_gettop(L);
00793 
00794       /* iterate through this context an popluate the corrisponding
00795        * table in the extensions_order table */
00796       for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) {
00797          int exten = lua_gettop(L) - 1;
00798 
00799          lua_pushinteger(L, lua_objlen(L, context_order) + 1);
00800          lua_pushvalue(L, exten);
00801          lua_settable(L, context_order);
00802       }
00803       lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */
00804 
00805       /* now sort the new table */
00806 
00807       /* push the table.sort function */
00808       lua_getglobal(L, "table");
00809       lua_getfield(L, -1, "sort");
00810       lua_remove(L, -2); /* remove the 'table' table */
00811 
00812       /* push the context_order table */
00813       lua_pushvalue(L, context_name);
00814       lua_gettable(L, extensions_order);
00815 
00816       /* push the comp function */
00817       lua_pushcfunction(L, &lua_extension_cmp);
00818 
00819       if (lua_pcall(L, 2, 0, 0)) {
00820          lua_insert(L, -5);
00821          lua_pop(L, 4);
00822          return 1;
00823       }
00824    }
00825    
00826    /* remove the extensions table and the extensions_order table */
00827    lua_pop(L, 2);
00828    return 0;
00829 }

void lua_state_destroy ( void *  data  ) 

The destructor for lua_datastore.

Definition at line 111 of file pbx_lua.c.

00112 {
00113    if (data)
00114       lua_close(data);
00115 }

static void lua_update_registry ( lua_State *  L,
const char *  context,
const char *  exten,
int  priority 
) [static]

Update the lua registry with the given context, exten, and priority.

Parameters:
L the lua_State to use
context the new context
exten the new exten
priority the new priority

Definition at line 358 of file pbx_lua.c.

Referenced by exec().

00359 {
00360    lua_pushstring(L, context);
00361    lua_setfield(L, LUA_REGISTRYINDEX, "context");
00362 
00363    lua_pushstring(L, exten);
00364    lua_setfield(L, LUA_REGISTRYINDEX, "exten");
00365 
00366    lua_pushinteger(L, priority);
00367    lua_setfield(L, LUA_REGISTRYINDEX, "priority");
00368 }

static int matchmore ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority,
const char *  callerid,
const char *  data 
) [static]

Definition at line 1184 of file pbx_lua.c.

References ast_log(), ast_module_user_add, ast_module_user_remove, chan, LOG_ERROR, lua_find_extension(), and lua_get_state().

Referenced by complete_dpreply(), and lua_find_extension().

01185 {
01186    int res;
01187    lua_State *L;
01188    struct ast_module_user *u = ast_module_user_add(chan);
01189    if (!u) {
01190       ast_log(LOG_ERROR, "Error adjusting use count, probably could not allocate memory\n");
01191       return 0;
01192    }
01193 
01194    L = lua_get_state(chan);
01195    if (!L) {
01196       ast_module_user_remove(u);
01197       return 0;
01198    }
01199    
01200    res = lua_find_extension(L, context, exten, priority, &matchmore, 0);
01201 
01202    if (!chan) lua_close(L);
01203    ast_module_user_remove(u);
01204    return res;
01205 }

static int reload ( void   )  [static]

Definition at line 1450 of file pbx_lua.c.

References load_or_reload_lua_stuff().

01451 {
01452    return load_or_reload_lua_stuff();
01453 }

static int unload_module ( void   )  [static]

Definition at line 1442 of file pbx_lua.c.

References ast_context_destroy(), ast_unregister_switch(), lua_free_extensions(), and lua_switch.

01443 {
01444    ast_context_destroy(NULL, registrar);
01445    ast_unregister_switch(&lua_switch);
01446    lua_free_extensions();
01447    return 0;
01448 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Lua PBX Switch" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 1474 of file pbx_lua.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 1474 of file pbx_lua.c.

char* config = "extensions.lua" [static]

Definition at line 49 of file pbx_lua.c.

char* config_file_data = NULL

Definition at line 96 of file pbx_lua.c.

ast_mutex_t config_file_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]

Definition at line 95 of file pbx_lua.c.

Referenced by lua_free_extensions(), lua_load_extensions(), and lua_reload_extensions().

long config_file_size = 0

Definition at line 97 of file pbx_lua.c.

struct ast_context* local_contexts = NULL [static]

Definition at line 99 of file pbx_lua.c.

struct ast_hashtab* local_table = NULL [static]

Definition at line 100 of file pbx_lua.c.

struct ast_datastore_info lua_datastore [static]

Initial value:

 {
   .type = "lua",
   .destroy = lua_state_destroy,
}

Definition at line 102 of file pbx_lua.c.

Referenced by lua_get_state().

struct ast_switch lua_switch [static]

Definition at line 1412 of file pbx_lua.c.

Referenced by load_module(), and unload_module().

char* registrar = "pbx_lua" [static]

Definition at line 50 of file pbx_lua.c.


Generated on Fri Jul 24 00:41:54 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7