#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. |
1.4.2