Thu Oct 8 21:57:32 2009

Asterisk developer's documentation


app_parkandannounce.c File Reference

ParkAndAnnounce application for Asterisk. More...

#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.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 "asterisk/utils.h"

Include dependency graph for app_parkandannounce.c:

Go to the source code of this file.

Functions

 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Call Parking and Announce Application")
static int load_module (void)
static int parkandannounce_exec (struct ast_channel *chan, void *data)
static int unload_module (void)

Variables

static char * app = "ParkAndAnnounce"
static char * descrip
static char * synopsis = "Park and Announce"


Detailed Description

ParkAndAnnounce application for Asterisk.

Author:
Ben Miller <bgmiller@dccinc.com>
  • With TONS of help from Mark!

Definition in file app_parkandannounce.c.


Function Documentation

AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY  ,
"Call Parking and Announce Application"   
)

static int load_module ( void   )  [static]

Definition at line 254 of file app_parkandannounce.c.

References ast_register_application(), and parkandannounce_exec().

00255 {
00256    /* return ast_register_application(app, park_exec); */
00257    return ast_register_application(app, parkandannounce_exec, synopsis, descrip);
00258 }

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

Definition at line 77 of file app_parkandannounce.c.

References __ast_request_and_dial(), ast_channel::_state, ARRAY_LEN, ast_exists_extension(), AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_masq_park_call(), ast_module_user_add, ast_module_user_remove, ast_say_digits(), AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_variable_new(), ast_verbose(), ast_waitstream(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, context, ast_channel::exten, exten, LOG_WARNING, option_verbose, outgoing_helper::parent_channel, ast_channel::priority, s, strsep(), outgoing_helper::vars, VERBOSE_PREFIX_3, and VERBOSE_PREFIX_4.

Referenced by load_module().

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

static int unload_module ( void   )  [static]

Definition at line 243 of file app_parkandannounce.c.

References ast_module_user_hangup_all, and ast_unregister_application().

00244 {
00245    int res;
00246 
00247    res = ast_unregister_application(app);
00248 
00249    ast_module_user_hangup_all();
00250 
00251    return res;
00252 }


Variable Documentation

char* app = "ParkAndAnnounce" [static]

Definition at line 54 of file app_parkandannounce.c.

char* descrip [static]

Definition at line 58 of file app_parkandannounce.c.

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

Definition at line 56 of file app_parkandannounce.c.


Generated on Thu Oct 8 21:57:32 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.8