diff --git a/pbx/Makefile b/pbx/Makefile index 3bb8d33cf6..28ca0e0b42 100755 --- a/pbx/Makefile +++ b/pbx/Makefile @@ -13,7 +13,7 @@ -PBX_LIBS=pbx_config.so pbx_spool.so pbx_dundi.so pbx_loopback.so +PBX_LIBS=pbx_config.so pbx_spool.so pbx_dundi.so pbx_loopback.so pbx_realtime.so # Add GTK console if appropriate #PBX_LIBS+=$(shell gtk-config --cflags >/dev/null 2>/dev/null && echo "pbx_gtkconsole.so") diff --git a/pbx/pbx_realtime.c b/pbx/pbx_realtime.c new file mode 100755 index 0000000000..6b1e6304cc --- /dev/null +++ b/pbx/pbx_realtime.c @@ -0,0 +1,181 @@ +/* + * Realtime PBX Module + * + * Copyright (C) 2004, Digium Inc. + * + * Written by Mark Spencer + * + * This program is Free Software distributed under the terms of + * of the GNU General Public License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static char *tdesc = "Realtime Switch"; + +/* Realtime switch looks up extensions in the supplied realtime table. + + [context@][realtimetable][/options] + + If the realtimetable is omitted it is assumed to be "extensions". If no context is + specified the context is assumed to be whatever is the container. + + The realtime table should have entries for context,exten,priority,app,args + + The realtime table currently does not support patterns or callerid fields. + +*/ + + +#define REALTIME_COMMON \ + char *buf; \ + char *opts; \ + const char *cxt; \ + char *table; \ + int res=-1; \ + struct ast_variable *var; \ + buf = ast_strdupa(data); \ + if (buf) { \ + opts = strchr(buf, '/'); \ + if (opts) { \ + *opts='\0'; \ + opts++; \ + } else \ + opts=""; \ + table = strchr(buf, '@'); \ + if (table) { \ + *table = '\0'; \ + table++;\ + cxt = buf; \ + } else cxt = NULL; \ + if (!cxt || ast_strlen_zero(cxt)) \ + cxt = context;\ + if (!table || ast_strlen_zero(table)) \ + table = "extensions"; \ + var = realtime_switch_common(table, cxt, exten, priority); \ + } else \ + return -1; + +static struct ast_variable *realtime_switch_common(const char *table, const char *context, const char *exten, int priority) +{ + struct ast_variable *var; + char pri[20]; + snprintf(pri, sizeof(pri), "%d", priority); + printf("%s/%s/%s/%s exists\n", table, context, exten, pri); + var = ast_load_realtime(table, "context", context, "exten", exten, "priority", pri, NULL); + return var; +} + +static int realtime_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) +{ + REALTIME_COMMON; + if (var) ast_destroy_realtime(var); + if (var) + res = 1; + return res > 0 ? res : 0; +} + +static int realtime_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) +{ + REALTIME_COMMON; + if (var) ast_destroy_realtime(var); + if (var) + res = 1; + return res; +} + +static int realtime_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data) +{ + char app[256]; + char *appdata=""; + struct ast_app *a; + struct ast_variable *v; + REALTIME_COMMON; + if (var) { + v = var; + while(v) { + if (!strcasecmp(v->name, "app")) + strncpy(app, v->value, sizeof(app) -1 ); + else if (!strcasecmp(v->name, "appdata")) + appdata = ast_strdupa(v->value); + v = v->next; + } + if (!ast_strlen_zero(app)) { + a = pbx_findapp(app); + if (a) { + res = pbx_exec(chan, a, appdata, newstack); + } else + ast_log(LOG_NOTICE, "No such application '%s' for extension '%s' in context '%s'\n", app, exten, context); + } + ast_destroy_realtime(var); + } + return res; +} + +static int realtime_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) +{ + REALTIME_COMMON; + if (var) ast_destroy_realtime(var); + return res; +} + +static struct ast_switch realtime_switch = +{ + name: "Realtime", + description: "Realtime Dialplan Switch", + exists: realtime_exists, + canmatch: realtime_canmatch, + exec: realtime_exec, + matchmore: realtime_matchmore, +}; + +char *description(void) +{ + return tdesc; +} + +int usecount(void) +{ + return 1; +} + +char *key() +{ + return ASTERISK_GPL_KEY; +} + +int unload_module(void) +{ + ast_unregister_switch(&realtime_switch); + return 0; +} + +int load_module(void) +{ + ast_register_switch(&realtime_switch); + return 0; +} +