Wed Oct 28 15:48:07 2009

Asterisk developer's documentation


app_macro.c File Reference

Dial plan macro Implementation. More...

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/options.h"
#include "asterisk/config.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"

Include dependency graph for app_macro.c:

Go to the source code of this file.

Defines

#define MACRO_EXIT_RESULT   1024
#define MAX_ARGS   80

Functions

char * description (void)
 Provides a description of the module.
static struct ast_extenfind_matching_priority (struct ast_context *c, const char *exten, int priority, const char *callerid)
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
static int macro_exec (struct ast_channel *chan, void *data)
static int macro_exit_exec (struct ast_channel *chan, void *data)
static int macroif_exec (struct ast_channel *chan, void *data)
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.

Variables

static char * app = "Macro"
static char * descrip
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"
 LOCAL_USER_DECL
 STANDARD_LOCAL_USER
static char * synopsis = "Macro Implementation"
static char * tdesc = "Extension Macros"


Detailed Description

Dial plan macro Implementation.

Definition in file app_macro.c.


Define Documentation

#define MACRO_EXIT_RESULT   1024

Definition at line 49 of file app_macro.c.

Referenced by macro_exec(), and macro_exit_exec().

#define MAX_ARGS   80

Definition at line 46 of file app_macro.c.

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


Function Documentation

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 525 of file app_macro.c.

00526 {
00527    return tdesc;
00528 }

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

Definition at line 101 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 find_matching_endwhile(), find_matching_priority(), and macro_exec().

00102 {
00103    struct ast_exten *e;
00104    struct ast_include *i;
00105    struct ast_context *c2;
00106 
00107    for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) {
00108       if (ast_extension_match(ast_get_extension_name(e), exten)) {
00109          int needmatch = ast_get_extension_matchcid(e);
00110          if ((needmatch && ast_extension_match(ast_get_extension_cidmatch(e), callerid)) ||
00111             (!needmatch)) {
00112             /* This is the matching extension we want */
00113             struct ast_exten *p;
00114             for (p=ast_walk_extension_priorities(e, NULL); p; p=ast_walk_extension_priorities(e, p)) {
00115                if (priority != ast_get_extension_priority(p))
00116                   continue;
00117                return p;
00118             }
00119          }
00120       }
00121    }
00122 
00123    /* No match; run through includes */
00124    for (i=ast_walk_context_includes(c, NULL); i; i=ast_walk_context_includes(c, i)) {
00125       for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) {
00126          if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) {
00127             e = find_matching_priority(c2, exten, priority, callerid);
00128             if (e)
00129                return e;
00130          }
00131       }
00132    }
00133    return NULL;
00134 }

char* key ( void   ) 

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;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 537 of file app_macro.c.

References ASTERISK_GPL_KEY.

00538 {
00539    return ASTERISK_GPL_KEY;
00540 }

int load_module ( void   ) 

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.
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.

Returns:
int Always 0.
TE STUFF END

Definition at line 514 of file app_macro.c.

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

00515 {
00516    int res;
00517 
00518    res = ast_register_application(exit_app, macro_exit_exec, exit_synopsis, exit_descrip);
00519    res |= ast_register_application(if_app, macroif_exec, if_synopsis, if_descrip);
00520    res |= ast_register_application(app, macro_exec, synopsis, descrip);
00521 
00522    return res;
00523 }

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

Definition at line 136 of file app_macro.c.

References ast_channel::_softhangup, app2, ast_context_find(), ast_exists_extension(), AST_FLAG_IN_AUTOLOOP, ast_get_context_name(), ast_get_extension_app(), ast_get_extension_app_data(), ast_lock_context(), ast_lock_contexts(), ast_log(), AST_MAX_CONTEXT, AST_PBX_KEEPALIVE, ast_set2_flag, ast_set_flag, AST_SOFTHANGUP_ASYNCGOTO, ast_spawn_extension(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_unlock_context(), ast_unlock_contexts(), ast_verbose(), ast_walk_contexts(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, find_matching_priority(), free, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_DEBUG, LOG_ERROR, LOG_WARNING, MACRO_EXIT_RESULT, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::macropriority, MAX_ARGS, ast_channel::name, offset, option_debug, option_verbose, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_checkcondition(), pbx_substitute_variables_helper(), ast_channel::priority, s, strdup, strsep(), and VERBOSE_PREFIX_2.

Referenced by load_module(), and macroif_exec().

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

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

Definition at line 496 of file app_macro.c.

References MACRO_EXIT_RESULT.

Referenced by load_module().

00497 {
00498    return MACRO_EXIT_RESULT;
00499 }

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

Definition at line 462 of file app_macro.c.

References ast_log(), ast_strdupa, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_ERROR, LOG_WARNING, macro_exec(), and pbx_checkcondition().

Referenced by load_module().

00463 {
00464    char *expr = NULL, *label_a = NULL, *label_b = NULL;
00465    int res = 0;
00466    struct localuser *u;
00467 
00468    LOCAL_USER_ADD(u);
00469 
00470    expr = ast_strdupa(data);
00471    if (!expr) {
00472       ast_log(LOG_ERROR, "Out of Memory!\n");
00473       LOCAL_USER_REMOVE(u);
00474       return -1;
00475    }
00476 
00477    if ((label_a = strchr(expr, '?'))) {
00478       *label_a = '\0';
00479       label_a++;
00480       if ((label_b = strchr(label_a, ':'))) {
00481          *label_b = '\0';
00482          label_b++;
00483       }
00484       if (pbx_checkcondition(expr))
00485          res = macro_exec(chan, label_a);
00486       else if (label_b) 
00487          res = macro_exec(chan, label_b);
00488    } else
00489       ast_log(LOG_WARNING, "Invalid Syntax.\n");
00490 
00491    LOCAL_USER_REMOVE(u);
00492 
00493    return res;
00494 }

int unload_module ( void   ) 

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).

Returns:
Zero on success, or non-zero on error.

Definition at line 501 of file app_macro.c.

References ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS.

00502 {
00503    int res;
00504 
00505    res = ast_unregister_application(if_app);
00506    res |= ast_unregister_application(exit_app);
00507    res |= ast_unregister_application(app);
00508 
00509    STANDARD_HANGUP_LOCALUSERS;
00510 
00511    return res;
00512 }

int usecount ( void   ) 

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.

Returns:
The module's usecount.

Definition at line 530 of file app_macro.c.

References STANDARD_USECOUNT.

00531 {
00532    int res;
00533    STANDARD_USECOUNT(res);
00534    return res;
00535 }


Variable Documentation

char* app = "Macro" [static]

Definition at line 89 of file app_macro.c.

char* descrip [static]

Definition at line 53 of file app_macro.c.

char* exit_app = "MacroExit" [static]

Definition at line 91 of file app_macro.c.

char* exit_descrip [static]

Definition at line 82 of file app_macro.c.

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

Definition at line 95 of file app_macro.c.

char* if_app = "MacroIf" [static]

Definition at line 90 of file app_macro.c.

char* if_descrip [static]

Initial value:

"  MacroIf(<expr>?macroname_a[|arg1][:macroname_b[|arg1]])\n"
"Executes macro defined in <macroname_a> if <expr> is true\n"
"(otherwise <macroname_b> if provided)\n"
"Arguments and return values as in application macro()\n"

Definition at line 76 of file app_macro.c.

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

Definition at line 94 of file app_macro.c.

Definition at line 99 of file app_macro.c.

Definition at line 97 of file app_macro.c.

char* synopsis = "Macro Implementation" [static]

Definition at line 93 of file app_macro.c.

char* tdesc = "Extension Macros" [static]

Definition at line 51 of file app_macro.c.


Generated on Wed Oct 28 15:48:07 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6