Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:10 2009

## Asterisk developer's documentation

# app_parkandannounce.c File Reference

ParkAndAnnounce application for Asterisk. 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/features.h"`
`#include "asterisk/options.h"`
`#include "asterisk/say.h"`
`#include "asterisk/lock.h"`

Include dependency graph for app_parkandannounce.c:

Go to the source code of this file.

## Functions

char * | description (void)
| Provides a description of the module.
char * | key ()
| Returns the ASTERISK_GPL_KEY.
int | load_module (void)
| Initialize the module.
static int | parkandannounce_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 = "ParkAndAnnounce"
static char * | descrip
| LOCAL_USER_DECL
| STANDARD_LOCAL_USER
static char * | synopsis = "Park and Announce"
static char * | tdesc = "Call Parking and Announce Application"

## Detailed Description

ParkAndAnnounce application for Asterisk.

Definition in file app_parkandannounce.c.

## Function Documentation

char* description | ( | void |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 266 of file app_parkandannounce.c.

    00267 {
    00268    return tdesc;
    00269 }

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 278 of file app_parkandannounce.c.

References ASTERISK_GPL_KEY.

    00279 {
    00280    return ASTERISK_GPL_KEY;
    00281 }

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 260 of file app_parkandannounce.c.

References ast_register_application(), and parkandannounce_exec().

    00261 {
    00262    /* return ast_register_application(app, park_exec); */
    00263    return ast_register_application(app, parkandannounce_exec, synopsis, descrip);
    00264 }

static int parkandannounce_exec | ( | struct ast_channel * | chan,
|  | void * | data |
| ) |  |  | `[static]`

Definition at line 70 of file app_parkandannounce.c.

References __ast_request_and_dial(), ast_channel::_state, ast_exists_extension(), AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_masq_park_call(), ast_say_digits(), AST_STATE_UP, ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitstream(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, context, ast_channel::exten, exten, free, ast_channel::language, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_WARNING, malloc, ast_channel::name, option_verbose, outgoing_helper::parent_channel, ast_channel::priority, s, strsep(), VERBOSE_PREFIX_3, and VERBOSE_PREFIX_4.

Referenced by load_module().

    00071 {
    00072    int res=0;
    00073    char *return_context;
    00074    int l, lot, timeout = 0, dres;
    00075    char *working, *context, *exten, *priority, *dial, *dialtech, *dialstr;
    00076    char *template, *tpl_working, *tpl_current;
    00077    char *tmp[100];
    00078    int looptemp=0,i=0;
    00079    char *s,*orig_s;
    00080
    00081    struct ast_channel *dchan;
    00082    struct outgoing_helper oh;
    00083    int outstate;
    00084
    00085    struct localuser *u;
    00086
    00087    if (ast_strlen_zero(data)) {
    00088       ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce:template|timeout|dial|[return_context])\n");
    00089       return -1;
    00090    }
    00091
    00092    LOCAL_USER_ADD(u);
    00093
    00094    l=strlen(data)+2;
    00095    orig_s=malloc(l);
    00096    if(!orig_s) {
    00097       ast_log(LOG_WARNING, "Out of memory\n");
    00098       LOCAL_USER_REMOVE(u);
    00099       return -1;
    00100    }
    00101    s=orig_s;
    00102    strncpy(s,data,l);
    00103
    00104    template=strsep(&s,"|");
    00105    if(! template) {
    00106       ast_log(LOG_WARNING, "PARK: An announce template must be defined\n");
    00107       free(orig_s);
    00108       LOCAL_USER_REMOVE(u);
    00109       return -1;
    00110    }
    00111
    00112    if(s) {
    00113       timeout = atoi(strsep(&s, "|"));
    00114       timeout *= 1000;
    00115    }
    00116    dial=strsep(&s, "|");
    00117    if(!dial) {
    00118       ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or Zap/g1/5551212\n");
    00119       free(orig_s);
    00120       LOCAL_USER_REMOVE(u);
    00121       return -1;
    00122    } else {
    00123       dialtech=strsep(&dial, "/");
    00124       dialstr=dial;
    00125       ast_verbose( VERBOSE_PREFIX_3 "Dial Tech,String: (%s,%s)\n", dialtech,dialstr);
    00126    }
    00127
    00128    return_context = s;
    00129
    00130    if(return_context != NULL) {
    00131       /* set the return context. Code borrowed from the Goto builtin */
    00132
    00133       working = return_context;
    00134       context = strsep(&working, "|");
    00135       exten = strsep(&working, "|");
    00136       if(!exten) {
    00137          /* Only a priority in this one */
    00138          priority = context;
    00139          exten = NULL;
    00140          context = NULL;
    00141       } else {
    00142          priority = strsep(&working, "|");
    00143          if(!priority) {
    00144             /* Only an extension and priority in this one */
    00145             priority = exten;
    00146             exten = context;
    00147             context = NULL;
    00148       }
    00149    }
    00150    if(atoi(priority) < 0) {
    00151       ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority);
    00152       free(orig_s);
    00153       LOCAL_USER_REMOVE(u);
    00154       return -1;
    00155    }
    00156    /* At this point we have a priority and maybe an extension and a context */
    00157    chan->priority = atoi(priority);
    00158    if(exten && strcasecmp(exten, "BYEXTENSION"))
    00159       strncpy(chan->exten, exten, sizeof(chan->exten)-1);
    00160    if(context)
    00161       strncpy(chan->context, context, sizeof(chan->context)-1);
    00162    } else {  /* increment the priority by default*/
    00163       chan->priority++;
    00164    }
    00165
    00166    if(option_verbose > 2) {
    00167       ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num);
    00168       if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
    00169          ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n");
    00170       }
    00171    }
    00172
    00173    /* we are using masq_park here to protect * from touching the channel once we park it.  If the channel comes out of timeout
    00174    before we are done announcing and the channel is messed with, Kablooeee.  So we use Masq to prevent this.  */
    00175
    00176    ast_masq_park_call(chan, NULL, timeout, &lot);
    00177
    00178    res=-1;
    00179
    00180    ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context);
    00181
    00182    /* Now place the call to the extention */
    00183
    00184    memset(&oh, 0, sizeof(oh));
    00185    oh.parent_channel = chan;
    00186    dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, dialstr,30000, &outstate, chan->cid.cid_num, chan->cid.cid_name, &oh);
    00187
    00188    if(dchan) {
    00189       if(dchan->_state == AST_STATE_UP) {
    00190          if(option_verbose > 3)
    00191             ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", dchan->name);
    00192       } else {
    00193          if(option_verbose > 3)
    00194             ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", dchan->name);
    00195                ast_log(LOG_WARNING, "PARK: Channel %s was never answered for the announce.\n", dchan->name);
    00196          ast_hangup(dchan);
    00197          free(orig_s);
    00198          LOCAL_USER_REMOVE(u);
    00199          return -1;
    00200       }
    00201    } else {
    00202       ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
    00203       free(orig_s);
    00204       LOCAL_USER_REMOVE(u);
    00205       return -1;
    00206    }
    00207
    00208    ast_stopstream(dchan);
    00209
    00210    /* now we have the call placed and are ready to play stuff to it */
    00211
    00212    ast_verbose(VERBOSE_PREFIX_4 "Announce Template:%s\n", template);
    00213
    00214    tpl_working = template;
    00215    tpl_current=strsep(&tpl_working, ":");
    00216
    00217    while(tpl_current && looptemp < sizeof(tmp)) {
    00218       tmp[looptemp]=tpl_current;
    00219       looptemp++;
    00220       tpl_current=strsep(&tpl_working,":");
    00221    }
    00222
    00223    for(i=0; i<looptemp; i++) {
    00224       ast_verbose(VERBOSE_PREFIX_4 "Announce:%s\n", tmp[i]);
    00225       if(!strcmp(tmp[i], "PARKED")) {
    00226          ast_say_digits(dchan, lot, "", dchan->language);
    00227       } else {
    00228          dres = ast_streamfile(dchan, tmp[i], dchan->language);
    00229          if(!dres) {
    00230             dres = ast_waitstream(dchan, "");
    00231          } else {
    00232             ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], dchan->name);
    00233             dres = 0;
    00234          }
    00235       }
    00236    }
    00237
    00238    ast_stopstream(dchan);
    00239    ast_hangup(dchan);
    00240    free(orig_s);
    00241
    00242    LOCAL_USER_REMOVE(u);
    00243
    00244    return res;
    00245 }

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 249 of file app_parkandannounce.c.

References ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS.

    00250 {
    00251    int res;
    00252
    00253    res = ast_unregister_application(app);
    00254
    00255    STANDARD_HANGUP_LOCALUSERS;
    00256
    00257    return res;
    00258 }

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 271 of file app_parkandannounce.c.

References STANDARD_USECOUNT.

    00272 {
    00273    int res;
    00274    STANDARD_USECOUNT(res);
    00275    return res;
    00276 }

## Variable Documentation

char* app = "ParkAndAnnounce"`[static]`

Definition at line 52 of file app_parkandannounce.c.

char* descrip`[static]`

Definition at line 56 of file app_parkandannounce.c.

LOCAL_USER_DECL

Definition at line 68 of file app_parkandannounce.c.

STANDARD_LOCAL_USER

Definition at line 66 of file app_parkandannounce.c.

char* synopsis = "Park and Announce"`[static]`

Definition at line 54 of file app_parkandannounce.c.

char* tdesc = "Call Parking and Announce Application"`[static]`

Definition at line 50 of file app_parkandannounce.c.