#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/config.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/options.h"
Include dependency graph for app_while.c:
Go to the source code of this file.
Defines | |
#define | ALL_DONE(u, ret) {LOCAL_USER_REMOVE(u); return ret;} |
#define | VAR_SIZE 64 |
Functions | |
static int | _while_exec (struct ast_channel *chan, void *data, int end) |
char * | description (void) |
Provides a description of the module. | |
static int | execif_exec (struct ast_channel *chan, void *data) |
static int | find_matching_endwhile (struct ast_channel *chan) |
static struct ast_exten * | find_matching_priority (struct ast_context *c, const char *exten, int priority, const char *callerid) |
static char * | get_index (struct ast_channel *chan, const char *prefix, int index) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
static int | while_end_exec (struct ast_channel *chan, void *data) |
static int | while_start_exec (struct ast_channel *chan, void *data) |
Variables | |
static char * | exec_app = "ExecIf" |
static char * | exec_desc |
static char * | exec_synopsis = "Conditional exec" |
LOCAL_USER_DECL | |
STANDARD_LOCAL_USER | |
static char * | start_app = "While" |
static char * | start_desc |
static char * | start_synopsis = "Start A While Loop" |
static char * | stop_app = "EndWhile" |
static char * | stop_desc |
static char * | stop_synopsis = "End A While Loop" |
static char * | tdesc = "While Loops and Conditional Execution" |
Definition in file app_while.c.
|
Definition at line 45 of file app_while.c. |
|
Definition at line 122 of file app_while.c. Referenced by _while_exec(), and get_index(). |
|
Definition at line 208 of file app_while.c. References ALL_DONE, ast_log(), ast_parseable_goto(), ast_strdupa, ast_strlen_zero(), ast_verbose(), ast_waitfordigit(), ast_channel::context, ast_channel::exten, find_matching_endwhile(), get_index(), LOCAL_USER_ADD, LOG_WARNING, option_verbose, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_checkcondition(), ast_channel::priority, VAR_SIZE, and VERBOSE_PREFIX_3. Referenced by while_end_exec(), and while_start_exec(). 00209 { 00210 int res=0; 00211 struct localuser *u; 00212 char *while_pri = NULL; 00213 char *goto_str = NULL, *my_name = NULL; 00214 char *condition = NULL, *label = NULL; 00215 char varname[VAR_SIZE], end_varname[VAR_SIZE]; 00216 const char *prefix = "WHILE"; 00217 size_t size=0; 00218 int used_index_i = -1, x=0; 00219 char used_index[VAR_SIZE] = "0", new_index[VAR_SIZE] = "0"; 00220 00221 if (!chan) { 00222 /* huh ? */ 00223 return -1; 00224 } 00225 00226 LOCAL_USER_ADD(u); 00227 00228 /* dont want run away loops if the chan isn't even up 00229 this is up for debate since it slows things down a tad ...... 00230 */ 00231 if (ast_waitfordigit(chan,1) < 0) 00232 ALL_DONE(u,-1); 00233 00234 00235 for (x=0;;x++) { 00236 if (get_index(chan, prefix, x)) { 00237 used_index_i = x; 00238 } else 00239 break; 00240 } 00241 00242 snprintf(used_index, VAR_SIZE, "%d", used_index_i); 00243 snprintf(new_index, VAR_SIZE, "%d", used_index_i + 1); 00244 00245 if (!end) { 00246 condition = ast_strdupa((char *) data); 00247 } 00248 00249 size = strlen(chan->context) + strlen(chan->exten) + 32; 00250 my_name = alloca(size); 00251 memset(my_name, 0, size); 00252 snprintf(my_name, size, "%s_%s_%d", chan->context, chan->exten, chan->priority); 00253 00254 if (ast_strlen_zero(label)) { 00255 if (end) 00256 label = used_index; 00257 else if (!(label = pbx_builtin_getvar_helper(chan, my_name))) { 00258 label = new_index; 00259 pbx_builtin_setvar_helper(chan, my_name, label); 00260 } 00261 00262 } 00263 00264 snprintf(varname, VAR_SIZE, "%s_%s", prefix, label); 00265 while_pri = pbx_builtin_getvar_helper(chan, varname); 00266 00267 if ((while_pri = pbx_builtin_getvar_helper(chan, varname)) && !end) { 00268 snprintf(end_varname,VAR_SIZE,"END_%s",varname); 00269 } 00270 00271 00272 if (!end && !pbx_checkcondition(condition)) { 00273 /* Condition Met (clean up helper vars) */ 00274 pbx_builtin_setvar_helper(chan, varname, NULL); 00275 pbx_builtin_setvar_helper(chan, my_name, NULL); 00276 snprintf(end_varname,VAR_SIZE,"END_%s",varname); 00277 if ((goto_str=pbx_builtin_getvar_helper(chan, end_varname))) { 00278 pbx_builtin_setvar_helper(chan, end_varname, NULL); 00279 ast_parseable_goto(chan, goto_str); 00280 } else { 00281 int pri = find_matching_endwhile(chan); 00282 if (pri > 0) { 00283 if (option_verbose > 2) 00284 ast_verbose(VERBOSE_PREFIX_3 "Jumping to priority %d\n", pri); 00285 chan->priority = pri; 00286 } else { 00287 ast_log(LOG_WARNING, "Couldn't find matching EndWhile? (While at %s@%s priority %d)\n", chan->context, chan->exten, chan->priority); 00288 } 00289 } 00290 ALL_DONE(u,res); 00291 } 00292 00293 if (!end && !while_pri) { 00294 size = strlen(chan->context) + strlen(chan->exten) + 32; 00295 goto_str = alloca(size); 00296 memset(goto_str, 0, size); 00297 snprintf(goto_str, size, "%s|%s|%d", chan->context, chan->exten, chan->priority); 00298 pbx_builtin_setvar_helper(chan, varname, goto_str); 00299 } 00300 00301 else if (end && while_pri) { 00302 /* END of loop */ 00303 snprintf(end_varname, VAR_SIZE, "END_%s", varname); 00304 if (! pbx_builtin_getvar_helper(chan, end_varname)) { 00305 size = strlen(chan->context) + strlen(chan->exten) + 32; 00306 goto_str = alloca(size); 00307 memset(goto_str, 0, size); 00308 snprintf(goto_str, size, "%s|%s|%d", chan->context, chan->exten, chan->priority+1); 00309 pbx_builtin_setvar_helper(chan, end_varname, goto_str); 00310 } 00311 ast_parseable_goto(chan, while_pri); 00312 } 00313 00314 00315 00316 00317 ALL_DONE(u, res); 00318 }
|
|
Provides a description of the module.
Definition at line 353 of file app_while.c. References tdesc. 00354 { 00355 return tdesc; 00356 }
|
|
Definition at line 80 of file app_while.c. References ALL_DONE, app, ast_log(), ast_strdupa, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_ERROR, LOG_WARNING, pbx_checkcondition(), pbx_exec(), and pbx_findapp(). Referenced by load_module(). 00080 { 00081 int res=0; 00082 struct localuser *u; 00083 char *myapp = NULL; 00084 char *mydata = NULL; 00085 char *expr = NULL; 00086 struct ast_app *app = NULL; 00087 00088 LOCAL_USER_ADD(u); 00089 00090 expr = ast_strdupa(data); 00091 if (!expr) { 00092 ast_log(LOG_ERROR, "Out of memory\n"); 00093 LOCAL_USER_REMOVE(u); 00094 return -1; 00095 } 00096 00097 if ((myapp = strchr(expr,'|'))) { 00098 *myapp = '\0'; 00099 myapp++; 00100 if ((mydata = strchr(myapp,'|'))) { 00101 *mydata = '\0'; 00102 mydata++; 00103 } else 00104 mydata = ""; 00105 00106 if (pbx_checkcondition(expr)) { 00107 if ((app = pbx_findapp(myapp))) { 00108 res = pbx_exec(chan, app, mydata, 1); 00109 } else { 00110 ast_log(LOG_WARNING, "Count not find application! (%s)\n", myapp); 00111 res = -1; 00112 } 00113 } 00114 } else { 00115 ast_log(LOG_ERROR,"Invalid Syntax.\n"); 00116 res = -1; 00117 } 00118 00119 ALL_DONE(u,res); 00120 }
|
|
Definition at line 167 of file app_while.c. References ast_get_context_name(), ast_get_extension_app(), ast_lock_context(), ast_lock_contexts(), ast_log(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_contexts(), find_matching_priority(), and LOG_ERROR. Referenced by _while_exec(). 00168 { 00169 struct ast_context *c; 00170 int res=-1; 00171 00172 if (ast_lock_contexts()) { 00173 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 00174 return -1; 00175 } 00176 00177 for (c=ast_walk_contexts(NULL); c; c=ast_walk_contexts(c)) { 00178 struct ast_exten *e; 00179 00180 if (!ast_lock_context(c)) { 00181 if (!strcmp(ast_get_context_name(c), chan->context)) { 00182 /* This is the matching context we want */ 00183 int cur_priority = chan->priority + 1, level=1; 00184 00185 for (e = find_matching_priority(c, chan->exten, cur_priority, chan->cid.cid_num); e; e = find_matching_priority(c, chan->exten, ++cur_priority, chan->cid.cid_num)) { 00186 if (!strcasecmp(ast_get_extension_app(e), "WHILE")) { 00187 level++; 00188 } else if (!strcasecmp(ast_get_extension_app(e), "ENDWHILE")) { 00189 level--; 00190 } 00191 00192 if (level == 0) { 00193 res = cur_priority; 00194 break; 00195 } 00196 } 00197 } 00198 ast_unlock_context(c); 00199 if (res > 0) { 00200 break; 00201 } 00202 } 00203 } 00204 ast_unlock_contexts(); 00205 return res; 00206 }
|
|
|
Definition at line 125 of file app_while.c. References pbx_builtin_getvar_helper(), and VAR_SIZE. Referenced by _while_exec(). 00125 { 00126 char varname[VAR_SIZE]; 00127 00128 snprintf(varname, VAR_SIZE, "%s_%d", prefix, index); 00129 return pbx_builtin_getvar_helper(chan, varname); 00130 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 365 of file app_while.c. References ASTERISK_GPL_KEY. 00366 { 00367 return ASTERISK_GPL_KEY; 00368 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 342 of file app_while.c. References ast_register_application(), exec_app, exec_desc, exec_synopsis, execif_exec(), start_app, start_desc, start_synopsis, stop_app, stop_desc, stop_synopsis, while_end_exec(), and while_start_exec(). 00343 { 00344 int res; 00345 00346 res = ast_register_application(start_app, while_start_exec, start_synopsis, start_desc); 00347 res |= ast_register_application(exec_app, execif_exec, exec_synopsis, exec_desc); 00348 res |= ast_register_application(stop_app, while_end_exec, stop_synopsis, stop_desc); 00349 00350 return res; 00351 }
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 329 of file app_while.c. References ast_unregister_application(), exec_app, STANDARD_HANGUP_LOCALUSERS, start_app, and stop_app. 00330 { 00331 int res; 00332 00333 res = ast_unregister_application(start_app); 00334 res |= ast_unregister_application(exec_app); 00335 res |= ast_unregister_application(stop_app); 00336 00337 STANDARD_HANGUP_LOCALUSERS; 00338 00339 return res; 00340 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 358 of file app_while.c. References STANDARD_USECOUNT. 00359 { 00360 int res; 00361 STANDARD_USECOUNT(res); 00362 return res; 00363 }
|
|
Definition at line 324 of file app_while.c. References _while_exec(). Referenced by load_module(). 00324 { 00325 return _while_exec(chan, data, 1); 00326 }
|
|
Definition at line 320 of file app_while.c. References _while_exec(). Referenced by load_module(). 00320 { 00321 return _while_exec(chan, data, 0); 00322 }
|
|
Definition at line 48 of file app_while.c. Referenced by load_module(), and unload_module(). |
|
Initial value: "Usage: ExecIF (<expr>|<app>|<data>)\n" "If <expr> is true, execute and return the result of <app>(<data>).\n" "If <expr> is true, but <app> is not found, then the application\n" "will return a non-zero value." Definition at line 49 of file app_while.c. Referenced by load_module(). |
|
Definition at line 54 of file app_while.c. |
|
Definition at line 78 of file app_while.c. |
|
Definition at line 76 of file app_while.c. |
|
Definition at line 56 of file app_while.c. Referenced by load_module(), and unload_module(). |
|
Initial value: "Usage: While(<expr>)\n" "Start a While Loop. Execution will return to this point when\n" "EndWhile is called until expr is no longer true.\n" Definition at line 57 of file app_while.c. Referenced by load_module(). |
|
Definition at line 62 of file app_while.c. Referenced by load_module(). |
|
Definition at line 65 of file app_while.c. Referenced by load_module(), and unload_module(). |
|
Initial value: "Usage: EndWhile()\n" "Return to the previous called While\n\n" Definition at line 66 of file app_while.c. Referenced by load_module(). |
|
Definition at line 70 of file app_while.c. Referenced by load_module(). |
|
Definition at line 72 of file app_while.c. |