Asterisk - The Open Source Telephony Project GIT-master-f36a736
pbx_loopback.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 1999 - 2005, Digium, Inc.
5 *
6 * Mark Spencer <markster@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \brief Loopback PBX Module
22 *
23 */
24
25/*** MODULEINFO
26 <support_level>core</support_level>
27 ***/
28
29#include "asterisk.h"
30
31#include "asterisk/file.h"
32#include "asterisk/logger.h"
33#include "asterisk/channel.h"
34#include "asterisk/config.h"
35#include "asterisk/pbx.h"
36#include "asterisk/module.h"
37#include "asterisk/frame.h"
38#include "asterisk/cli.h"
39#include "asterisk/lock.h"
40#include "asterisk/md5.h"
42#include "asterisk/chanvars.h"
43#include "asterisk/sched.h"
44#include "asterisk/io.h"
45#include "asterisk/utils.h"
46#include "asterisk/astdb.h"
47
48
49/* Loopback switch creates a 'tunnel' to another context. When extension
50 lookups pass through the 'tunnel', Asterisk expressions can be used
51 to modify the target extension, context, and priority in any way desired.
52 If there is a match at the far end, execution jumps through the 'tunnel'
53 to the matched context, extension, and priority.
54
55 Global variables as well as ${CONTEXT}, ${EXTEN}, and ${PRIORITY} are
56 available for substitution. After substitution Loopback expects to get
57 a string of the form:
58
59 [exten]@context[:priority][/extramatch]
60
61 Where exten, context, and priority are another extension, context, and priority
62 to lookup and "extramatch" is a dialplan extension pattern which the *original*
63 number must match. If exten or priority are empty, the original values are
64 used.
65
66 Note that the search context MUST be a different context from the current
67 context or the search will not succeed. This is intended to reduce the
68 likelihood of loops (they're still possible if you try hard, so be careful!)
69
70*/
71
72
73#define LOOPBACK_COMMON \
74 char buf[1024]; \
75 int res; \
76 char *newexten=(char *)exten, *newcontext=(char *)context; \
77 int newpriority=priority; \
78 char *newpattern=NULL; \
79 loopback_subst(buf, sizeof(buf), exten, context, priority, data); \
80 loopback_parse(&newexten, &newcontext, &newpriority, &newpattern, buf); \
81 ast_debug(1, "Parsed into %s @ %s priority %d pattern %s\n", newexten, newcontext, newpriority, newpattern); \
82 if (!strcasecmp(newcontext, context)) return -1
83
84static char *loopback_subst(char *buf, int buflen, const char *exten, const char *context, int priority, const char *data)
85{
86 struct ast_var_t *newvariable;
87 struct varshead headp;
88 char tmp[80];
89
90 snprintf(tmp, sizeof(tmp), "%d", priority);
92 if ((newvariable = ast_var_assign("EXTEN", exten))) {
93 AST_LIST_INSERT_HEAD(&headp, newvariable, entries);
94 }
95 if ((newvariable = ast_var_assign("CONTEXT", context))) {
96 AST_LIST_INSERT_HEAD(&headp, newvariable, entries);
97 }
98 if ((newvariable = ast_var_assign("PRIORITY", tmp))) {
99 AST_LIST_INSERT_HEAD(&headp, newvariable, entries);
100 }
101 /* Substitute variables */
102 pbx_substitute_variables_varshead(&headp, data, buf, buflen);
103 /* free the list */
104 while ((newvariable = AST_LIST_REMOVE_HEAD(&headp, entries)))
105 ast_var_delete(newvariable);
106 return buf;
107}
108
109static void loopback_parse(char **newexten, char **newcontext, int *priority, char **newpattern, char *buf)
110{
111 char *con;
112 char *pri;
113 *newpattern = strchr(buf, '/');
114 if (*newpattern)
115 *(*newpattern)++ = '\0';
116 con = strchr(buf, '@');
117 if (con) {
118 *con++ = '\0';
119 pri = strchr(con, ':');
120 } else
121 pri = strchr(buf, ':');
122 if (!ast_strlen_zero(buf))
123 *newexten = buf;
124 if (!ast_strlen_zero(con))
125 *newcontext = con;
126 if (!ast_strlen_zero(pri))
127 sscanf(pri, "%30d", priority);
128}
129
130static int loopback_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
131{
133 if (newpattern && !ast_extension_match(newpattern, exten))
134 res = 0;
135 else
136 res = ast_exists_extension(chan, newcontext, newexten, newpriority, callerid);
137 return res;
138}
139
140static int loopback_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
141{
143 if (newpattern && !ast_extension_match(newpattern, exten))
144 res = 0;
145 else
146 res = ast_canmatch_extension(chan, newcontext, newexten, newpriority, callerid);
147 return res;
148}
149
150static int loopback_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
151{
152 int found;
154 res = ast_spawn_extension(chan, newcontext, newexten, newpriority, callerid, &found, 0);
155 return res;
156}
157
158static int loopback_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
159{
161 if (newpattern && !ast_extension_match(newpattern, exten))
162 res = 0;
163 else
164 res = ast_matchmore_extension(chan, newcontext, newexten, newpriority, callerid);
165 return res;
166}
167
169{
170 .name = "Loopback",
171 .description = "Loopback Dialplan Switch",
172 .exists = loopback_exists,
173 .canmatch = loopback_canmatch,
174 .exec = loopback_exec,
175 .matchmore = loopback_matchmore,
176};
177
178static int unload_module(void)
179{
181 return 0;
182}
183
184static int load_module(void)
185{
189}
190
Persistent data storage (akin to *doze registry)
Asterisk main include file. File version handling, generic pbx functions.
static int tmp()
Definition: bt_open.c:389
static int priority
General Asterisk PBX channel definitions.
Channel Variables.
#define ast_var_assign(name, value)
Definition: chanvars.h:40
void ast_var_delete(struct ast_var_t *var)
Definition: extconf.c:2471
Standard Command Line Interface.
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
Generic File Format Support. Should be included by clients of the file handling routines....
Configuration File Parser.
Asterisk internal frame definitions.
Support for logging to various files, console and syslog Configuration in file logger....
I/O Management (derived from Cheops-NG)
A set of macros to manage forward-linked lists.
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:711
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
Asterisk locking-related definitions:
MD5 digest functions.
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:581
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition: module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
Core PBX routines and definitions.
void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count)
void ast_unregister_switch(struct ast_switch *sw)
Unregister an alternative switch.
Definition: pbx_switch.c:76
int ast_register_switch(struct ast_switch *sw)
Register an alternative dialplan switch.
Definition: pbx_switch.c:58
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4175
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:4190
int ast_spawn_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid, int *found, int combined_find_spawn)
Launch a new extension (i.e. new stack)
Definition: pbx.c:4200
int ast_extension_match(const char *pattern, const char *extension)
Determine if a given extension matches a given pattern (in NXX format)
Definition: extconf.c:4295
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch)
Definition: pbx.c:4195
static void loopback_parse(char **newexten, char **newcontext, int *priority, char **newpattern, char *buf)
Definition: pbx_loopback.c:109
static int loopback_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Definition: pbx_loopback.c:130
static struct ast_switch loopback_switch
Definition: pbx_loopback.c:168
static int loopback_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Definition: pbx_loopback.c:150
#define LOOPBACK_COMMON
Definition: pbx_loopback.c:73
static char * loopback_subst(char *buf, int buflen, const char *exten, const char *context, int priority, const char *data)
Definition: pbx_loopback.c:84
static int loopback_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Definition: pbx_loopback.c:158
static int load_module(void)
Definition: pbx_loopback.c:184
static int unload_module(void)
Definition: pbx_loopback.c:178
static int loopback_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Definition: pbx_loopback.c:140
Scheduler Routines (derived from cheops)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Main Channel structure associated with a channel.
const char * name
Definition: pbx.h:162
Utility functions.