Wed Aug 18 22:33:58 2010

Asterisk developer's documentation


app_macro.c File Reference

Dial plan macro Implementation. More...

#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"

Go to the source code of this file.

Defines

#define MACRO_EXIT_RESULT   1024
#define MAX_ARGS   80
#define WAITEXTENWARNING

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int _macro_exec (struct ast_channel *chan, void *data, int exclusive)
static struct ast_extenfind_matching_priority (struct ast_context *c, const char *exten, int priority, const char *callerid)
static int load_module (void)
static int macro_exec (struct ast_channel *chan, void *data)
static int macro_exit_exec (struct ast_channel *chan, void *data)
static void macro_fixup (void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
static int macroexclusive_exec (struct ast_channel *chan, void *data)
static int macroif_exec (struct ast_channel *chan, void *data)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Extension Macros" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, }
static char * app = "Macro"
static struct ast_module_infoast_module_info = &__mod_info
static char * descrip
static char * exclusive_app = "MacroExclusive"
static char * exclusive_descrip
static char * exclusive_synopsis = "Exclusive Macro Implementation"
static char * exit_app = "MacroExit"
static char * exit_descrip
static char * exit_synopsis = "Exit From Macro"
static char * if_app = "MacroIf"
static char * if_descrip
static char * if_synopsis = "Conditional Macro Implementation"
ast_datastore_info macro_ds_info
static char * synopsis = "Macro Implementation"


Detailed Description

Dial plan macro Implementation.

Author:
Mark Spencer <markster@digium.com>

Definition in file app_macro.c.


Define Documentation

#define MACRO_EXIT_RESULT   1024

Definition at line 43 of file app_macro.c.

Referenced by _macro_exec(), and macro_exit_exec().

#define MAX_ARGS   80

Definition at line 40 of file app_macro.c.

Referenced by _macro_exec(), agi_exec_full(), agi_handle_command(), and parse_args().

#define WAITEXTENWARNING

Value:

"Use of the application WaitExten within a macro will not function as expected.\n" \
   "Please use the Read application in order to read DTMF from a channel currently\n" \
   "executing a macro.\n"

Definition at line 45 of file app_macro.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 567 of file app_macro.c.

static void __unreg_module ( void   )  [static]

Definition at line 567 of file app_macro.c.

static int _macro_exec ( struct ast_channel chan,
void *  data,
int  exclusive 
) [static]

Definition at line 163 of file app_macro.c.

References app2, ast_autoservice_start(), ast_autoservice_stop(), ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_context_find(), ast_context_lockmacro(), ast_context_unlockmacro(), ast_copy_string(), ast_datastore_alloc, ast_debug, ast_exists_extension(), AST_FLAG_IN_AUTOLOOP, ast_free, ast_get_context_name(), ast_get_extension_app(), ast_get_extension_app_data(), ast_log(), AST_MAX_CONTEXT, ast_rdlock_context(), ast_rdlock_contexts(), ast_set2_flag, ast_set_flag, AST_SOFTHANGUP_ASYNCGOTO, ast_spawn_extension(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_unlock_context(), ast_unlock_contexts(), ast_verb, ast_walk_contexts(), chan, ast_channel::cid, ast_callerid::cid_num, cond, ast_channel::context, DATASTORE_INHERIT_FOREVER, ast_channel::exten, find_matching_priority(), ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, macro_ds_info, MACRO_EXIT_RESULT, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::macropriority, MAX_ARGS, ast_channel::name, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_checkcondition(), pbx_substitute_variables_helper(), ast_channel::priority, s, and strsep().

Referenced by macro_exec(), and macroexclusive_exec().

00164 {
00165    const char *s;
00166    char *tmp;
00167    char *cur, *rest;
00168    char *macro;
00169    char fullmacro[80];
00170    char varname[80];
00171    char runningapp[80], runningdata[1024];
00172    char *oldargs[MAX_ARGS + 1] = { NULL, };
00173    int argc, x;
00174    int res=0;
00175    char oldexten[256]="";
00176    int oldpriority, gosub_level = 0;
00177    char pc[80], depthc[12];
00178    char oldcontext[AST_MAX_CONTEXT] = "";
00179    const char *inhangupc;
00180    int offset, depth = 0, maxdepth = 7;
00181    int setmacrocontext=0;
00182    int autoloopflag, inhangup = 0;
00183   
00184    char *save_macro_exten;
00185    char *save_macro_context;
00186    char *save_macro_priority;
00187    char *save_macro_offset;
00188    struct ast_datastore *macro_store = ast_channel_datastore_find(chan, &macro_ds_info, NULL);
00189  
00190    if (ast_strlen_zero(data)) {
00191       ast_log(LOG_WARNING, "Macro() requires arguments. See \"core show application macro\" for help.\n");
00192       return -1;
00193    }
00194 
00195    do {
00196       if (macro_store) {
00197          break;
00198       }
00199       if (!(macro_store = ast_datastore_alloc(&macro_ds_info, NULL))) {
00200          ast_log(LOG_WARNING, "Unable to allocate new datastore.\n");
00201          break;
00202       }
00203       /* Just the existence of this datastore is enough. */
00204       macro_store->inheritance = DATASTORE_INHERIT_FOREVER;
00205       ast_channel_datastore_add(chan, macro_store);
00206    } while (0);
00207 
00208    /* does the user want a deeper rabbit hole? */
00209    ast_channel_lock(chan);
00210    if ((s = pbx_builtin_getvar_helper(chan, "MACRO_RECURSION"))) {
00211       sscanf(s, "%30d", &maxdepth);
00212    }
00213    
00214    /* Count how many levels deep the rabbit hole goes */
00215    if ((s = pbx_builtin_getvar_helper(chan, "MACRO_DEPTH"))) {
00216       sscanf(s, "%30d", &depth);
00217    }
00218    
00219    /* Used for detecting whether to return when a Macro is called from another Macro after hangup */
00220    if (strcmp(chan->exten, "h") == 0)
00221       pbx_builtin_setvar_helper(chan, "MACRO_IN_HANGUP", "1");
00222    
00223    if ((inhangupc = pbx_builtin_getvar_helper(chan, "MACRO_IN_HANGUP"))) {
00224       sscanf(inhangupc, "%30d", &inhangup);
00225    }
00226    ast_channel_unlock(chan);
00227 
00228    if (depth >= maxdepth) {
00229       ast_log(LOG_ERROR, "Macro():  possible infinite loop detected.  Returning early.\n");
00230       return 0;
00231    }
00232    snprintf(depthc, sizeof(depthc), "%d", depth + 1);
00233    pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
00234 
00235    tmp = ast_strdupa(data);
00236    rest = tmp;
00237    macro = strsep(&rest, ",");
00238    if (ast_strlen_zero(macro)) {
00239       ast_log(LOG_WARNING, "Invalid macro name specified\n");
00240       return 0;
00241    }
00242 
00243    snprintf(fullmacro, sizeof(fullmacro), "macro-%s", macro);
00244    if (!ast_exists_extension(chan, fullmacro, "s", 1, chan->cid.cid_num)) {
00245       if (!ast_context_find(fullmacro)) 
00246          ast_log(LOG_WARNING, "No such context '%s' for macro '%s'\n", fullmacro, macro);
00247       else
00248          ast_log(LOG_WARNING, "Context '%s' for macro '%s' lacks 's' extension, priority 1\n", fullmacro, macro);
00249       return 0;
00250    }
00251 
00252    /* If we are to run the macro exclusively, take the mutex */
00253    if (exclusive) {
00254       ast_debug(1, "Locking macrolock for '%s'\n", fullmacro);
00255       ast_autoservice_start(chan);
00256       if (ast_context_lockmacro(fullmacro)) {
00257          ast_log(LOG_WARNING, "Failed to lock macro '%s' as in-use\n", fullmacro);
00258          ast_autoservice_stop(chan);
00259          return 0;
00260       }
00261       ast_autoservice_stop(chan);
00262    }
00263    
00264    /* Save old info */
00265    oldpriority = chan->priority;
00266    ast_copy_string(oldexten, chan->exten, sizeof(oldexten));
00267    ast_copy_string(oldcontext, chan->context, sizeof(oldcontext));
00268    if (ast_strlen_zero(chan->macrocontext)) {
00269       ast_copy_string(chan->macrocontext, chan->context, sizeof(chan->macrocontext));
00270       ast_copy_string(chan->macroexten, chan->exten, sizeof(chan->macroexten));
00271       chan->macropriority = chan->priority;
00272       setmacrocontext=1;
00273    }
00274    argc = 1;
00275    /* Save old macro variables */
00276    save_macro_exten = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_EXTEN"));
00277    pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", oldexten);
00278 
00279    save_macro_context = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_CONTEXT"));
00280    pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", oldcontext);
00281 
00282    save_macro_priority = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_PRIORITY"));
00283    snprintf(pc, sizeof(pc), "%d", oldpriority);
00284    pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", pc);
00285   
00286    save_macro_offset = ast_strdup(pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"));
00287    pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", NULL);
00288 
00289    /* Setup environment for new run */
00290    chan->exten[0] = 's';
00291    chan->exten[1] = '\0';
00292    ast_copy_string(chan->context, fullmacro, sizeof(chan->context));
00293    chan->priority = 1;
00294 
00295    ast_channel_lock(chan);
00296    while((cur = strsep(&rest, ",")) && (argc < MAX_ARGS)) {
00297       const char *argp;
00298       /* Save copy of old arguments if we're overwriting some, otherwise
00299          let them pass through to the other macro */
00300       snprintf(varname, sizeof(varname), "ARG%d", argc);
00301       if ((argp = pbx_builtin_getvar_helper(chan, varname))) {
00302          oldargs[argc] = ast_strdup(argp);
00303       }
00304       pbx_builtin_setvar_helper(chan, varname, cur);
00305       argc++;
00306    }
00307    ast_channel_unlock(chan);
00308    autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP);
00309    ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP);
00310    while(ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
00311       struct ast_context *c;
00312       struct ast_exten *e;
00313       int foundx;
00314       runningapp[0] = '\0';
00315       runningdata[0] = '\0';
00316 
00317       /* What application will execute? */
00318       if (ast_rdlock_contexts()) {
00319          ast_log(LOG_WARNING, "Failed to lock contexts list\n");
00320       } else {
00321          for (c = ast_walk_contexts(NULL), e = NULL; c; c = ast_walk_contexts(c)) {
00322             if (!strcmp(ast_get_context_name(c), chan->context)) {
00323                if (ast_rdlock_context(c)) {
00324                   ast_log(LOG_WARNING, "Unable to lock context?\n");
00325                } else {
00326                   e = find_matching_priority(c, chan->exten, chan->priority, chan->cid.cid_num);
00327                   if (e) { /* This will only be undefined for pbx_realtime, which is majorly broken. */
00328                      ast_copy_string(runningapp, ast_get_extension_app(e), sizeof(runningapp));
00329                      ast_copy_string(runningdata, ast_get_extension_app_data(e), sizeof(runningdata));
00330                   }
00331                   ast_unlock_context(c);
00332                }
00333                break;
00334             }
00335          }
00336       }
00337       ast_unlock_contexts();
00338 
00339       /* Reset the macro depth, if it was changed in the last iteration */
00340       pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
00341 
00342       if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &foundx,1))) {
00343          /* Something bad happened, or a hangup has been requested. */
00344          if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
00345             (res == '*') || (res == '#')) {
00346             /* Just return result as to the previous application as if it had been dialed */
00347             ast_debug(1, "Oooh, got something to jump out with ('%c')!\n", res);
00348             break;
00349          }
00350          switch(res) {
00351          case MACRO_EXIT_RESULT:
00352             res = 0;
00353             goto out;
00354          default:
00355             ast_debug(2, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
00356             ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
00357             goto out;
00358          }
00359       }
00360 
00361       ast_debug(1, "Executed application: %s\n", runningapp);
00362 
00363       if (!strcasecmp(runningapp, "GOSUB")) {
00364          gosub_level++;
00365          ast_debug(1, "Incrementing gosub_level\n");
00366       } else if (!strcasecmp(runningapp, "GOSUBIF")) {
00367          char tmp2[1024], *cond, *app_arg, *app2 = tmp2;
00368          pbx_substitute_variables_helper(chan, runningdata, tmp2, sizeof(tmp2) - 1);
00369          cond = strsep(&app2, "?");
00370          app_arg = strsep(&app2, ":");
00371          if (pbx_checkcondition(cond)) {
00372             if (!ast_strlen_zero(app_arg)) {
00373                gosub_level++;
00374                ast_debug(1, "Incrementing gosub_level\n");
00375             }
00376          } else {
00377             if (!ast_strlen_zero(app2)) {
00378                gosub_level++;
00379                ast_debug(1, "Incrementing gosub_level\n");
00380             }
00381          }
00382       } else if (!strcasecmp(runningapp, "RETURN")) {
00383          gosub_level--;
00384          ast_debug(1, "Decrementing gosub_level\n");
00385       } else if (!strcasecmp(runningapp, "STACKPOP")) {
00386          gosub_level--;
00387          ast_debug(1, "Decrementing gosub_level\n");
00388       } else if (!strncasecmp(runningapp, "EXEC", 4)) {
00389          /* Must evaluate args to find actual app */
00390          char tmp2[1024], *tmp3 = NULL;
00391          pbx_substitute_variables_helper(chan, runningdata, tmp2, sizeof(tmp2) - 1);
00392          if (!strcasecmp(runningapp, "EXECIF")) {
00393             tmp3 = strchr(tmp2, '|');
00394             if (tmp3)
00395                *tmp3++ = '\0';
00396             if (!pbx_checkcondition(tmp2))
00397                tmp3 = NULL;
00398          } else
00399             tmp3 = tmp2;
00400 
00401          if (tmp3)
00402             ast_debug(1, "Last app: %s\n", tmp3);
00403 
00404          if (tmp3 && !strncasecmp(tmp3, "GOSUB", 5)) {
00405             gosub_level++;
00406             ast_debug(1, "Incrementing gosub_level\n");
00407          } else if (tmp3 && !strncasecmp(tmp3, "RETURN", 6)) {
00408             gosub_level--;
00409             ast_debug(1, "Decrementing gosub_level\n");
00410          } else if (tmp3 && !strncasecmp(tmp3, "STACKPOP", 8)) {
00411             gosub_level--;
00412             ast_debug(1, "Decrementing gosub_level\n");
00413          }
00414       }
00415 
00416       if (gosub_level == 0 && strcasecmp(chan->context, fullmacro)) {
00417          ast_verb(2, "Channel '%s' jumping out of macro '%s'\n", chan->name, macro);
00418          break;
00419       }
00420 
00421       /* don't stop executing extensions when we're in "h" */
00422       if (ast_check_hangup(chan) && !inhangup) {
00423          ast_debug(1, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n", chan->exten, chan->macroexten, chan->priority);
00424          goto out;
00425       }
00426       chan->priority++;
00427    }
00428    out:
00429 
00430    /* Don't let the channel change now. */
00431    ast_channel_lock(chan);
00432 
00433    /* Reset the depth back to what it was when the routine was entered (like if we called Macro recursively) */
00434    snprintf(depthc, sizeof(depthc), "%d", depth);
00435    pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
00436    ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP);
00437 
00438    for (x = 1; x < argc; x++) {
00439       /* Restore old arguments and delete ours */
00440       snprintf(varname, sizeof(varname), "ARG%d", x);
00441       if (oldargs[x]) {
00442          pbx_builtin_setvar_helper(chan, varname, oldargs[x]);
00443          ast_free(oldargs[x]);
00444       } else {
00445          pbx_builtin_setvar_helper(chan, varname, NULL);
00446       }
00447    }
00448 
00449    /* Restore macro variables */
00450    pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten);
00451    pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context);
00452    pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority);
00453    if (save_macro_exten)
00454       ast_free(save_macro_exten);
00455    if (save_macro_context)
00456       ast_free(save_macro_context);
00457    if (save_macro_priority)
00458       ast_free(save_macro_priority);
00459 
00460    if (setmacrocontext) {
00461       chan->macrocontext[0] = '\0';
00462       chan->macroexten[0] = '\0';
00463       chan->macropriority = 0;
00464    }
00465 
00466    if (!strcasecmp(chan->context, fullmacro)) {
00467       /* If we're leaving the macro normally, restore original information */
00468       chan->priority = oldpriority;
00469       ast_copy_string(chan->context, oldcontext, sizeof(chan->context));
00470       if (!(ast_check_hangup(chan) & AST_SOFTHANGUP_ASYNCGOTO)) {
00471          /* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */
00472          const char *offsets;
00473          ast_copy_string(chan->exten, oldexten, sizeof(chan->exten));
00474          if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) {
00475             /* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue
00476                normally if there is any problem */
00477             if (sscanf(offsets, "%30d", &offset) == 1) {
00478                if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + offset + 1, chan->cid.cid_num)) {
00479                   chan->priority += offset;
00480                }
00481             }
00482          }
00483       }
00484    }
00485 
00486    pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset);
00487    if (save_macro_offset)
00488       ast_free(save_macro_offset);
00489 
00490    /* Unlock the macro */
00491    if (exclusive) {
00492       ast_debug(1, "Unlocking macrolock for '%s'\n", fullmacro);
00493       if (ast_context_unlockmacro(fullmacro)) {
00494          ast_log(LOG_ERROR, "Failed to unlock macro '%s' - that isn't good\n", fullmacro);
00495          res = 0;
00496       }
00497    }
00498    ast_channel_unlock(chan);
00499 
00500    return res;
00501 }

static struct ast_exten* find_matching_priority ( struct ast_context c,
const char *  exten,
int  priority,
const char *  callerid 
) [static]

Definition at line 128 of file app_macro.c.

References ast_extension_match(), ast_get_context_name(), ast_get_extension_cidmatch(), ast_get_extension_matchcid(), ast_get_extension_name(), ast_get_extension_priority(), ast_get_include_name(), ast_walk_context_extensions(), ast_walk_context_includes(), ast_walk_contexts(), and ast_walk_extension_priorities().

Referenced by _macro_exec(), find_matching_endwhile(), and find_matching_priority().

00129 {
00130    struct ast_exten *e;
00131    struct ast_include *i;
00132    struct ast_context *c2;
00133 
00134    for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) {
00135       if (ast_extension_match(ast_get_extension_name(e), exten)) {
00136          int needmatch = ast_get_extension_matchcid(e);
00137          if ((needmatch && ast_extension_match(ast_get_extension_cidmatch(e), callerid)) ||
00138             (!needmatch)) {
00139             /* This is the matching extension we want */
00140             struct ast_exten *p;
00141             for (p=ast_walk_extension_priorities(e, NULL); p; p=ast_walk_extension_priorities(e, p)) {
00142                if (priority != ast_get_extension_priority(p))
00143                   continue;
00144                return p;
00145             }
00146          }
00147       }
00148    }
00149 
00150    /* No match; run through includes */
00151    for (i=ast_walk_context_includes(c, NULL); i; i=ast_walk_context_includes(c, i)) {
00152       for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) {
00153          if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) {
00154             e = find_matching_priority(c2, exten, priority, callerid);
00155             if (e)
00156                return e;
00157          }
00158       }
00159    }
00160    return NULL;
00161 }

static int load_module ( void   )  [static]

Definition at line 555 of file app_macro.c.

References ast_register_application, macro_exec(), macro_exit_exec(), macroexclusive_exec(), and macroif_exec().

static int macro_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 503 of file app_macro.c.

References _macro_exec(), and chan.

Referenced by load_module(), and macroif_exec().

00504 {
00505    return _macro_exec(chan, data, 0);
00506 }

static int macro_exit_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 538 of file app_macro.c.

References MACRO_EXIT_RESULT.

Referenced by load_module().

00539 {
00540    return MACRO_EXIT_RESULT;
00541 }

static void macro_fixup ( void *  data,
struct ast_channel old_chan,
struct ast_channel new_chan 
) [static]

Definition at line 110 of file app_macro.c.

References pbx_builtin_getvar_helper(), and pbx_builtin_setvar_helper().

00111 {
00112    int i;
00113    char varname[10];
00114    pbx_builtin_setvar_helper(new_chan, "MACRO_DEPTH", "0");
00115    pbx_builtin_setvar_helper(new_chan, "MACRO_CONTEXT", NULL);
00116    pbx_builtin_setvar_helper(new_chan, "MACRO_EXTEN", NULL);
00117    pbx_builtin_setvar_helper(new_chan, "MACRO_PRIORITY", NULL);
00118    pbx_builtin_setvar_helper(new_chan, "MACRO_OFFSET", NULL);
00119    for (i = 1; i < 100; i++) {
00120       snprintf(varname, sizeof(varname), "ARG%d", i);
00121       while (pbx_builtin_getvar_helper(new_chan, varname)) {
00122          /* Kill all levels of arguments */
00123          pbx_builtin_setvar_helper(new_chan, varname, NULL);
00124       }
00125    }
00126 }

static int macroexclusive_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 508 of file app_macro.c.

References _macro_exec(), and chan.

Referenced by load_module().

00509 {
00510    return _macro_exec(chan, data, 1);
00511 }

static int macroif_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 513 of file app_macro.c.

References ast_log(), ast_strdupa, chan, LOG_WARNING, macro_exec(), and pbx_checkcondition().

Referenced by load_module().

00514 {
00515    char *expr = NULL, *label_a = NULL, *label_b = NULL;
00516    int res = 0;
00517 
00518    if (!(expr = ast_strdupa(data)))
00519       return -1;
00520 
00521    if ((label_a = strchr(expr, '?'))) {
00522       *label_a = '\0';
00523       label_a++;
00524       if ((label_b = strchr(label_a, ':'))) {
00525          *label_b = '\0';
00526          label_b++;
00527       }
00528       if (pbx_checkcondition(expr))
00529          res = macro_exec(chan, label_a);
00530       else if (label_b) 
00531          res = macro_exec(chan, label_b);
00532    } else
00533       ast_log(LOG_WARNING, "Invalid Syntax.\n");
00534 
00535    return res;
00536 }

static int unload_module ( void   )  [static]

Definition at line 543 of file app_macro.c.

References ast_unregister_application().

00544 {
00545    int res;
00546 
00547    res = ast_unregister_application(if_app);
00548    res |= ast_unregister_application(exit_app);
00549    res |= ast_unregister_application(app);
00550    res |= ast_unregister_application(exclusive_app);
00551 
00552    return res;
00553 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Extension Macros" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static]

Definition at line 567 of file app_macro.c.

char* app = "Macro" [static]

Definition at line 93 of file app_macro.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 567 of file app_macro.c.

char* descrip [static]

Definition at line 49 of file app_macro.c.

char* exclusive_app = "MacroExclusive" [static]

Definition at line 95 of file app_macro.c.

char* exclusive_descrip [static]

Definition at line 78 of file app_macro.c.

char* exclusive_synopsis = "Exclusive Macro Implementation" [static]

Definition at line 100 of file app_macro.c.

char* exit_app = "MacroExit" [static]

Definition at line 96 of file app_macro.c.

char* exit_descrip [static]

Definition at line 86 of file app_macro.c.

char* exit_synopsis = "Exit From Macro" [static]

Definition at line 101 of file app_macro.c.

char* if_app = "MacroIf" [static]

Definition at line 94 of file app_macro.c.

char* if_descrip [static]

Definition at line 71 of file app_macro.c.

char* if_synopsis = "Conditional Macro Implementation" [static]

Definition at line 99 of file app_macro.c.

struct ast_datastore_info macro_ds_info

Initial value:

 {
   .type = "MACRO",
   .chan_fixup = macro_fixup,
}

Definition at line 105 of file app_macro.c.

Referenced by _macro_exec().

char* synopsis = "Macro Implementation" [static]

Definition at line 98 of file app_macro.c.


Generated on Wed Aug 18 22:33:59 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7