4 * Copyright (C) 2004, Digium Inc.
6 * Written by Mark Spencer <markster@digium.com>
8 * This program is Free Software distributed under the terms of
9 * of the GNU General Public License.
12 #include <asterisk/file.h>
13 #include <asterisk/logger.h>
14 #include <asterisk/channel.h>
15 #include <asterisk/config.h>
16 #include <asterisk/config_pvt.h>
17 #include <asterisk/options.h>
18 #include <asterisk/pbx.h>
19 #include <asterisk/module.h>
20 #include <asterisk/frame.h>
21 #include <asterisk/file.h>
22 #include <asterisk/cli.h>
23 #include <asterisk/lock.h>
24 #include <asterisk/md5.h>
25 #include <asterisk/linkedlists.h>
26 #include <asterisk/chanvars.h>
27 #include <asterisk/sched.h>
28 #include <asterisk/io.h>
29 #include <asterisk/utils.h>
30 #include <asterisk/crypto.h>
31 #include <asterisk/astdb.h>
39 #define MODE_MATCHMORE 1
40 #define MODE_CANMATCH 2
42 static char *tdesc = "Realtime Switch";
44 /* Realtime switch looks up extensions in the supplied realtime table.
46 [context@][realtimetable][/options]
48 If the realtimetable is omitted it is assumed to be "extensions". If no context is
49 specified the context is assumed to be whatever is the container.
51 The realtime table should have entries for context,exten,priority,app,args
53 The realtime table currently does not support callerid fields.
58 #define REALTIME_COMMON(mode) \
64 struct ast_variable *var=NULL; \
65 buf = ast_strdupa(data); \
67 opts = strchr(buf, '/'); \
73 table = strchr(buf, '@'); \
79 if (!cxt || ast_strlen_zero(cxt)) \
81 if (!table || ast_strlen_zero(table)) \
82 table = "extensions"; \
83 var = realtime_switch_common(table, cxt, exten, priority, mode); \
87 static struct ast_variable *realtime_switch_common(const char *table, const char *context, const char *exten, int priority, int mode)
89 struct ast_variable *var;
90 struct ast_config *cfg;
91 struct ast_category *cat;
94 char rexten[AST_MAX_EXTENSION + 20]="";
96 snprintf(pri, sizeof(pri), "%d", priority);
99 ematch = "exten LIKE";
100 snprintf(rexten, sizeof(rexten), "%s_%%", exten);
103 ematch = "exten LIKE";
104 snprintf(rexten, sizeof(rexten), "%s%%", exten);
109 strncpy(rexten, exten, sizeof(rexten) - 1);
111 var = ast_load_realtime(table, ematch, rexten, "context", context, "priority", pri, NULL);
113 cfg = ast_load_realtime_multientry(table, "exten RLIKE", "_.*", "context", context, "priority", pri, NULL);
119 match = ast_extension_close(cat->name, exten, 1);
122 match = ast_extension_close(cat->name, exten, 0);
126 match = ast_extension_match(cat->name, exten);
141 static int realtime_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
143 REALTIME_COMMON(MODE_MATCH);
144 if (var) ast_destroy_realtime(var);
147 return res > 0 ? res : 0;
150 static int realtime_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
152 REALTIME_COMMON(MODE_CANMATCH);
153 if (var) ast_destroy_realtime(var);
156 return res > 0 ? res : 0;
159 static int realtime_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data)
164 struct ast_variable *v;
165 REALTIME_COMMON(MODE_MATCH);
169 if (!strcasecmp(v->name, "app"))
170 strncpy(app, v->value, sizeof(app) -1 );
171 else if (!strcasecmp(v->name, "appdata"))
172 appdata = ast_strdupa(v->value);
175 ast_destroy_realtime(var);
176 if (!ast_strlen_zero(app)) {
177 a = pbx_findapp(app);
179 res = pbx_exec(chan, a, appdata, newstack);
181 ast_log(LOG_NOTICE, "No such application '%s' for extension '%s' in context '%s'\n", app, exten, context);
187 static int realtime_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
189 REALTIME_COMMON(MODE_MATCHMORE);
190 if (var) ast_destroy_realtime(var);
193 return res > 0 ? res : 0;
196 static struct ast_switch realtime_switch =
199 description: "Realtime Dialplan Switch",
200 exists: realtime_exists,
201 canmatch: realtime_canmatch,
203 matchmore: realtime_matchmore,
206 char *description(void)
218 return ASTERISK_GPL_KEY;
221 int unload_module(void)
223 ast_unregister_switch(&realtime_switch);
227 int load_module(void)
229 ast_register_switch(&realtime_switch);