Wed Oct 28 11:46:16 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 <lua.h>
#include <lauxlib.h>
#include <lualib.h>

Include dependency graph for pbx_lua.c:

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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, }
static const struct
ast_module_info
ast_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_MUTEX_INITIALIZER )
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 59 of file pbx_lua.c.

Referenced by lua_get_variable(), and lua_get_variable_value().

#define LUA_EXT_DATA_SIZE   256

Definition at line 58 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 1480 of file pbx_lua.c.

static void __unreg_module ( void   )  [static]

Definition at line 1480 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 1167 of file pbx_lua.c.

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

Referenced by lua_find_extension().

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

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 1214 of file pbx_lua.c.

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

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

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 1144 of file pbx_lua.c.

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

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

static int load_module ( void   )  [static]

Definition at line 1461 of file pbx_lua.c.

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

01462 {
01463    int res;
01464 
01465    if ((res = load_or_reload_lua_stuff()))
01466       return res;
01467 
01468    if (ast_register_switch(&lua_switch)) {
01469       ast_log(LOG_ERROR, "Unable to register LUA PBX switch\n");
01470       return AST_MODULE_LOAD_DECLINE;
01471    }
01472 
01473    return AST_MODULE_LOAD_SUCCESS;
01474 }

static int load_or_reload_lua_stuff ( void   )  [static]

Definition at line 1428 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().

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

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 643 of file pbx_lua.c.

References ast_autoservice_start(), and chan.

Referenced by lua_create_autoservice_functions().

00644 {
00645    struct ast_channel *chan;
00646    int res;
00647 
00648    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00649    chan = lua_touserdata(L, -1);
00650    lua_pop(L, 1);
00651 
00652    res = ast_autoservice_start(chan);
00653 
00654    lua_pushboolean(L, !res);
00655    lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
00656 
00657    lua_pushboolean(L, !res);
00658    return 1;
00659 }

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 701 of file pbx_lua.c.

Referenced by lua_create_autoservice_functions().

00702 {
00703    lua_getfield(L, LUA_REGISTRYINDEX, "autoservice");
00704    return 1;
00705 }

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 674 of file pbx_lua.c.

References ast_autoservice_stop(), and chan.

Referenced by lua_create_autoservice_functions().

00675 {
00676    struct ast_channel *chan;
00677    int res;
00678 
00679    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00680    chan = lua_touserdata(L, -1);
00681    lua_pop(L, 1);
00682 
00683    res = ast_autoservice_stop(chan);
00684 
00685    lua_pushboolean(L, 0);
00686    lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
00687 
00688    lua_pushboolean(L, !res);
00689    return 1;
00690 }

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 715 of file pbx_lua.c.

References ast_check_hangup(), and chan.

Referenced by lua_create_hangup_function().

00716 {
00717    struct ast_channel *chan;
00718    lua_getfield(L, LUA_REGISTRYINDEX, "channel");
00719    chan = lua_touserdata(L, -1);
00720    lua_pop(L, 1);
00721 
00722    lua_pushboolean(L, ast_check_hangup(chan));
00723    return 1;
00724 }

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 404 of file pbx_lua.c.

References lua_pbx_findapp().

Referenced by lua_load_extensions().

00405 {
00406    lua_newtable(L);
00407    luaL_newmetatable(L, "app");
00408 
00409    lua_pushstring(L, "__index");
00410    lua_pushcfunction(L, &lua_pbx_findapp);
00411    lua_settable(L, -3);
00412 
00413    lua_setmetatable(L, -2);
00414    lua_setglobal(L, "app");
00415 }

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 461 of file pbx_lua.c.

References lua_pbx_exec().

Referenced by lua_load_extensions().

00462 {
00463    luaL_newmetatable(L, "application");
00464 
00465    lua_pushstring(L, "__call");
00466    lua_pushcfunction(L, &lua_pbx_exec);
00467    lua_settable(L, -3);
00468 
00469    lua_pop(L, 1);
00470 }

static void lua_create_autoservice_functions ( lua_State *  L  )  [static]

Create the autoservice functions.

Parameters:
L the lua_State to use

Definition at line 477 of file pbx_lua.c.

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

Referenced by lua_load_extensions().

00478 {
00479    lua_pushcfunction(L, &lua_autoservice_start);
00480    lua_setglobal(L, "autoservice_start");
00481    
00482    lua_pushcfunction(L, &lua_autoservice_stop);
00483    lua_setglobal(L, "autoservice_stop");
00484 
00485    lua_pushcfunction(L, &lua_autoservice_status);
00486    lua_setglobal(L, "autoservice_status");
00487 
00488    lua_pushboolean(L, 0);
00489    lua_setfield(L, LUA_REGISTRYINDEX, "autoservice");
00490 }

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 422 of file pbx_lua.c.

References lua_get_variable(), and lua_set_variable().

Referenced by lua_load_extensions().

00423 {
00424    lua_newtable(L);
00425    luaL_newmetatable(L, "channel_data");
00426 
00427    lua_pushstring(L, "__index");
00428    lua_pushcfunction(L, &lua_get_variable);
00429    lua_settable(L, -3);
00430 
00431    lua_pushstring(L, "__newindex");
00432    lua_pushcfunction(L, &lua_set_variable);
00433    lua_settable(L, -3);
00434 
00435    lua_setmetatable(L, -2);
00436    lua_setglobal(L, "channel");
00437 }

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 497 of file pbx_lua.c.

References lua_check_hangup().

Referenced by lua_load_extensions().

00498 {
00499    lua_pushcfunction(L, &lua_check_hangup);
00500    lua_setglobal(L, "check_hangup");
00501 }

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 444 of file pbx_lua.c.

References lua_func_read().

Referenced by lua_load_extensions().

00445 {
00446    luaL_newmetatable(L, "variable");
00447 
00448    lua_pushstring(L, "__call");
00449    lua_pushcfunction(L, &lua_func_read);
00450    lua_settable(L, -3);
00451 
00452    lua_pop(L, 1);
00453 }

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 732 of file pbx_lua.c.

Referenced by exec().

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

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 903 of file pbx_lua.c.

References ast_extension_cmp().

Referenced by lua_sort_extensions().

00904 {
00905    const char *a = luaL_checkstring(L, -2);
00906    const char *b = luaL_checkstring(L, -1);
00907 
00908    if (ast_extension_cmp(a, b) == -1)
00909       lua_pushboolean(L, 1);
00910    else
00911       lua_pushboolean(L, 0);
00912 
00913    return 1;
00914 }

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 1285 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().

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

static void lua_free_extensions ( void   )  [static]

Free the internal extensions buffer.

Definition at line 1061 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 596 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().

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

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 1082 of file pbx_lua.c.

References ast_channel_datastore_add(), ast_channel_datastore_alloc(), ast_channel_datastore_find(), ast_channel_datastore_free(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_unlock, ast_log(), ast_datastore::data, LOG_ERROR, lua_load_extensions(), and ast_channel::name.

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

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

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 515 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().

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

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 260 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, pbx_retrieve_variable(), and ast_channel::varshead.

Referenced by lua_push_variable_table().

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

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 983 of file pbx_lua.c.

References ast_mutex_lock(), ast_mutex_unlock(), 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().

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

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 165 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().

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

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 134 of file pbx_lua.c.

Referenced by lua_create_app_table().

00135 {
00136    const char *app_name = luaL_checkstring(L, 2);
00137    
00138    lua_newtable(L);
00139 
00140    lua_pushstring(L, "name");
00141    lua_pushstring(L, app_name);
00142    lua_settable(L, -3);
00143 
00144    luaL_getmetatable(L, "application");
00145    lua_setmetatable(L, -2);
00146 
00147    return 1;
00148 }

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 383 of file pbx_lua.c.

References lua_get_variable_value(), and lua_set_variable_value().

Referenced by lua_func_read(), and lua_get_variable().

00384 {
00385    lua_newtable(L);
00386    luaL_getmetatable(L, "variable");
00387    lua_setmetatable(L, -2);
00388 
00389    lua_pushstring(L, name);
00390    lua_setfield(L, -2, "name");
00391    
00392    lua_pushcfunction(L, &lua_get_variable_value);
00393    lua_setfield(L, -2, "get");
00394    
00395    lua_pushcfunction(L, &lua_set_variable_value);
00396    lua_setfield(L, -2, "set");
00397 }

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 926 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().

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

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 845 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(), and context.

Referenced by lua_read_extensions_file().

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

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 1026 of file pbx_lua.c.

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

Referenced by load_or_reload_lua_stuff().

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

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 554 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().

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

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 320 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().

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

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 767 of file pbx_lua.c.

References context, exten, and lua_extension_cmp().

Referenced by lua_load_extensions(), and lua_read_extensions_file().

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

void lua_state_destroy ( void *  data  ) 

The destructor for lua_datastore.

Definition at line 117 of file pbx_lua.c.

00118 {
00119    if (data)
00120       lua_close(data);
00121 }

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 364 of file pbx_lua.c.

Referenced by exec().

00365 {
00366    lua_pushstring(L, context);
00367    lua_setfield(L, LUA_REGISTRYINDEX, "context");
00368 
00369    lua_pushstring(L, exten);
00370    lua_setfield(L, LUA_REGISTRYINDEX, "exten");
00371 
00372    lua_pushinteger(L, priority);
00373    lua_setfield(L, LUA_REGISTRYINDEX, "priority");
00374 }

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 1190 of file pbx_lua.c.

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

Referenced by complete_dpreply(), and lua_find_extension().

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

static int reload ( void   )  [static]

Definition at line 1456 of file pbx_lua.c.

References load_or_reload_lua_stuff().

01457 {
01458    return load_or_reload_lua_stuff();
01459 }

static int unload_module ( void   )  [static]

Definition at line 1448 of file pbx_lua.c.

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

01449 {
01450    ast_context_destroy(NULL, registrar);
01451    ast_unregister_switch(&lua_switch);
01452    lua_free_extensions();
01453    return 0;
01454 }


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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 1480 of file pbx_lua.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 1480 of file pbx_lua.c.

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

Definition at line 55 of file pbx_lua.c.

char* config_file_data = NULL

Definition at line 102 of file pbx_lua.c.

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

Definition at line 101 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 103 of file pbx_lua.c.

struct ast_context* local_contexts = NULL [static]

Definition at line 105 of file pbx_lua.c.

struct ast_hashtab* local_table = NULL [static]

Definition at line 106 of file pbx_lua.c.

Initial value:

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

Definition at line 108 of file pbx_lua.c.

struct ast_switch lua_switch [static]

Definition at line 1418 of file pbx_lua.c.

char* registrar = "pbx_lua" [static]

Definition at line 56 of file pbx_lua.c.


Generated on Wed Oct 28 11:46:17 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6