Thu Jul 9 13:40:45 2009

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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, }
static char * app = "Macro"
static const 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 561 of file app_macro.c.

static void __unreg_module ( void   )  [static]

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

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 549 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 497 of file app_macro.c.

References _macro_exec(), and chan.

Referenced by load_module(), and macroif_exec().

00498 {
00499    return _macro_exec(chan, data, 0);
00500 }

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

Definition at line 532 of file app_macro.c.

References MACRO_EXIT_RESULT.

Referenced by load_module().

00533 {
00534    return MACRO_EXIT_RESULT;
00535 }

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 502 of file app_macro.c.

References _macro_exec(), and chan.

Referenced by load_module().

00503 {
00504    return _macro_exec(chan, data, 1);
00505 }

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

Definition at line 507 of file app_macro.c.

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

Referenced by load_module().

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

static int unload_module ( void   )  [static]

Definition at line 537 of file app_macro.c.

References ast_unregister_application().

00538 {
00539    int res;
00540 
00541    res = ast_unregister_application(if_app);
00542    res |= ast_unregister_application(exit_app);
00543    res |= ast_unregister_application(app);
00544    res |= ast_unregister_application(exclusive_app);
00545 
00546    return res;
00547 }


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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } [static]

Definition at line 561 of file app_macro.c.

char* app = "Macro" [static]

Definition at line 93 of file app_macro.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 561 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 Thu Jul 9 13:40:45 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7