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