00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "asterisk.h"
00026
00027 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 211528 $")
00028
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <unistd.h>
00032 #include <string.h>
00033 #include <errno.h>
00034
00035 #include "asterisk/file.h"
00036 #include "asterisk/logger.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/config.h"
00039 #include "asterisk/options.h"
00040 #include "asterisk/pbx.h"
00041 #include "asterisk/module.h"
00042 #include "asterisk/frame.h"
00043 #include "asterisk/file.h"
00044 #include "asterisk/cli.h"
00045 #include "asterisk/lock.h"
00046 #include "asterisk/md5.h"
00047 #include "asterisk/linkedlists.h"
00048 #include "asterisk/chanvars.h"
00049 #include "asterisk/sched.h"
00050 #include "asterisk/io.h"
00051 #include "asterisk/utils.h"
00052 #include "asterisk/crypto.h"
00053 #include "asterisk/astdb.h"
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 #define LOOPBACK_COMMON \
00081 char buf[1024]; \
00082 int res; \
00083 char *newexten=(char *)exten, *newcontext=(char *)context; \
00084 int newpriority=priority; \
00085 char *newpattern=NULL; \
00086 loopback_subst(buf, sizeof(buf), exten, context, priority, data); \
00087 loopback_parse(&newexten, &newcontext, &newpriority, &newpattern, buf); \
00088 ast_log(LOG_DEBUG, "Parsed into %s @ %s priority %d\n", newexten, newcontext, newpriority); \
00089 if (!strcasecmp(newcontext, context)) return -1
00090
00091 static char *loopback_subst(char *buf, int buflen, const char *exten, const char *context, int priority, const char *data)
00092 {
00093 struct ast_var_t *newvariable;
00094 struct varshead headp;
00095 char tmp[80];
00096
00097 snprintf(tmp, sizeof(tmp), "%d", priority);
00098 memset(buf, 0, buflen);
00099 AST_LIST_HEAD_INIT_NOLOCK(&headp);
00100 newvariable = ast_var_assign("EXTEN", exten);
00101 AST_LIST_INSERT_HEAD(&headp, newvariable, entries);
00102 newvariable = ast_var_assign("CONTEXT", context);
00103 AST_LIST_INSERT_HEAD(&headp, newvariable, entries);
00104 newvariable = ast_var_assign("PRIORITY", tmp);
00105 AST_LIST_INSERT_HEAD(&headp, newvariable, entries);
00106
00107 pbx_substitute_variables_varshead(&headp, data, buf, buflen);
00108
00109 while ((newvariable = AST_LIST_REMOVE_HEAD(&headp, entries)))
00110 ast_var_delete(newvariable);
00111 return buf;
00112 }
00113
00114 static void loopback_parse(char **newexten, char **newcontext, int *priority, char **newpattern, char *buf)
00115 {
00116 char *con;
00117 char *pri;
00118 *newpattern = strchr(buf, '/');
00119 if (*newpattern)
00120 *(*newpattern)++ = '\0';
00121 con = strchr(buf, '@');
00122 if (con) {
00123 *con++ = '\0';
00124 pri = strchr(con, ':');
00125 } else
00126 pri = strchr(buf, ':');
00127 if (!ast_strlen_zero(buf))
00128 *newexten = buf;
00129 if (!ast_strlen_zero(con))
00130 *newcontext = con;
00131 if (!ast_strlen_zero(pri))
00132 sscanf(pri, "%30d", priority);
00133 }
00134
00135 static int loopback_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
00136 {
00137 LOOPBACK_COMMON;
00138 res = ast_exists_extension(chan, newcontext, newexten, newpriority, callerid);
00139 if (newpattern && !ast_extension_match(newpattern, exten))
00140 res = 0;
00141 return res;
00142 }
00143
00144 static int loopback_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
00145 {
00146 LOOPBACK_COMMON;
00147 res = ast_canmatch_extension(chan, newcontext, newexten, newpriority, callerid);
00148 if (newpattern && !ast_extension_match(newpattern, exten))
00149 res = 0;
00150 return res;
00151 }
00152
00153 static int loopback_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
00154 {
00155 LOOPBACK_COMMON;
00156 res = ast_spawn_extension(chan, newcontext, newexten, newpriority, callerid);
00157 return res;
00158 }
00159
00160 static int loopback_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
00161 {
00162 LOOPBACK_COMMON;
00163 res = ast_matchmore_extension(chan, newcontext, newexten, newpriority, callerid);
00164 if (newpattern && !ast_extension_match(newpattern, exten))
00165 res = 0;
00166 return res;
00167 }
00168
00169 static struct ast_switch loopback_switch =
00170 {
00171 name: "Loopback",
00172 description: "Loopback Dialplan Switch",
00173 exists: loopback_exists,
00174 canmatch: loopback_canmatch,
00175 exec: loopback_exec,
00176 matchmore: loopback_matchmore,
00177 };
00178
00179 static int unload_module(void)
00180 {
00181 ast_unregister_switch(&loopback_switch);
00182 return 0;
00183 }
00184
00185 static int load_module(void)
00186 {
00187 ast_register_switch(&loopback_switch);
00188 return 0;
00189 }
00190
00191 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Loopback Switch");