Wed Aug 7 17:15:48 2019

Asterisk developer's documentation


app_parkandannounce.c File Reference

ParkAndAnnounce application for Asterisk. More...

#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/features.h"
#include "asterisk/say.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"

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, const char *data)
static int unload_module (void)

Variables

static char * app = "ParkAndAnnounce"

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

References ast_register_application_xml, and parkandannounce_exec().

00228 {
00229    /* return ast_register_application(app, park_exec); */
00230    return ast_register_application_xml(app, parkandannounce_exec);
00231 }

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

Definition at line 92 of file app_parkandannounce.c.

References __ast_request_and_dial(), ast_channel::_state, args, ARRAY_LEN, AST_APP_ARG, ast_channel_lock, ast_channel_unlock, ast_clear_flag, AST_DECLARE_APP_ARGS, ast_exists_extension(), AST_FLAG_IN_AUTOLOOP, AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_masq_park_call(), ast_parseable_goto(), ast_party_id_copy(), ast_party_id_free(), ast_party_id_init(), ast_say_digits(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), ast_verb, ast_waitstream(), ast_channel::caller, ast_channel::context, ast_channel::exten, ast_party_caller::id, LOG_WARNING, ast_party_id::name, ast_party_id::number, outgoing_helper::parent_channel, ast_channel::priority, S_COR, ast_party_name::str, ast_party_number::str, ast_dial::timeout, ast_party_name::valid, ast_party_number::valid, and outgoing_helper::vars.

Referenced by load_module().

00093 {
00094    int res = -1;
00095    int lot, timeout = 0, dres;
00096    char *dialtech, *tmp[100], buf[13];
00097    int looptemp, i;
00098    char *s;
00099    struct ast_party_id caller_id;
00100 
00101    struct ast_channel *dchan;
00102    struct outgoing_helper oh = { 0, };
00103    int outstate;
00104    AST_DECLARE_APP_ARGS(args,
00105       AST_APP_ARG(template);
00106       AST_APP_ARG(timeout);
00107       AST_APP_ARG(dial);
00108       AST_APP_ARG(return_context);
00109    );
00110    if (ast_strlen_zero(data)) {
00111       ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce_template,timeout,dial,[return_context])\n");
00112       return -1;
00113    }
00114   
00115    s = ast_strdupa(data);
00116    AST_STANDARD_APP_ARGS(args, s);
00117 
00118    if (args.timeout)
00119       timeout = atoi(args.timeout) * 1000;
00120 
00121    if (ast_strlen_zero(args.dial)) {
00122       ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or DAHDI/g1/5551212\n");
00123       return -1;
00124    }
00125 
00126    dialtech = strsep(&args.dial, "/");
00127    ast_verb(3, "Dial Tech,String: (%s,%s)\n", dialtech, args.dial);
00128 
00129    if (!ast_strlen_zero(args.return_context)) {
00130       ast_clear_flag(chan, AST_FLAG_IN_AUTOLOOP);
00131       ast_parseable_goto(chan, args.return_context);
00132    } else {
00133       chan->priority++;
00134    }
00135 
00136    ast_verb(3, "Return Context: (%s,%s,%d) ID: %s\n", chan->context, chan->exten,
00137       chan->priority,
00138       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""));
00139    if (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority,
00140       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
00141       ast_verb(3, "Warning: Return Context Invalid, call will return to default|s\n");
00142    }
00143 
00144    /* Save the CallerID because the masquerade turns chan into a ZOMBIE. */
00145    ast_party_id_init(&caller_id);
00146    ast_channel_lock(chan);
00147    ast_party_id_copy(&caller_id, &chan->caller.id);
00148    ast_channel_unlock(chan);
00149 
00150    /* we are using masq_park here to protect * from touching the channel once we park it.  If the channel comes out of timeout
00151    before we are done announcing and the channel is messed with, Kablooeee.  So we use Masq to prevent this.  */
00152 
00153    res = ast_masq_park_call(chan, NULL, timeout, &lot);
00154    if (res) {
00155       /* Parking failed. */
00156       ast_party_id_free(&caller_id);
00157       return -1;
00158    }
00159 
00160    ast_verb(3, "Call parked in space: %d, timeout: %d, return-context: %s\n",
00161       lot, timeout, args.return_context ? args.return_context : "");
00162 
00163    /* Now place the call to the extension */
00164 
00165    snprintf(buf, sizeof(buf), "%d", lot);
00166    oh.parent_channel = chan;
00167    oh.vars = ast_variable_new("_PARKEDAT", buf, "");
00168    dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, chan, args.dial, 30000,
00169       &outstate,
00170       S_COR(caller_id.number.valid, caller_id.number.str, NULL),
00171       S_COR(caller_id.name.valid, caller_id.name.str, NULL),
00172       &oh);
00173    ast_variables_destroy(oh.vars);
00174    ast_party_id_free(&caller_id);
00175    if (dchan) {
00176       if (dchan->_state == AST_STATE_UP) {
00177          ast_verb(4, "Channel %s was answered.\n", dchan->name);
00178       } else {
00179          ast_verb(4, "Channel %s was never answered.\n", dchan->name);
00180          ast_log(LOG_WARNING, "PARK: Channel %s was never answered for the announce.\n", dchan->name);
00181          ast_hangup(dchan);
00182          return -1;
00183       }
00184    } else {
00185       ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
00186       return -1; 
00187    }
00188 
00189    ast_stopstream(dchan);
00190 
00191    /* now we have the call placed and are ready to play stuff to it */
00192 
00193    ast_verb(4, "Announce Template:%s\n", args.template);
00194 
00195    for (looptemp = 0; looptemp < ARRAY_LEN(tmp); looptemp++) {
00196       if ((tmp[looptemp] = strsep(&args.template, ":")) != NULL)
00197          continue;
00198       else
00199          break;
00200    }
00201 
00202    for (i = 0; i < looptemp; i++) {
00203       ast_verb(4, "Announce:%s\n", tmp[i]);
00204       if (!strcmp(tmp[i], "PARKED")) {
00205          ast_say_digits(dchan, lot, "", dchan->language);
00206       } else {
00207          dres = ast_streamfile(dchan, tmp[i], dchan->language);
00208          if (!dres) {
00209             dres = ast_waitstream(dchan, "");
00210          } else {
00211             ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], dchan->name);
00212          }
00213       }
00214    }
00215 
00216    ast_stopstream(dchan);  
00217    ast_hangup(dchan);
00218    
00219    return res;
00220 }

static int unload_module ( void   )  [static]

Definition at line 222 of file app_parkandannounce.c.

References ast_unregister_application().

00223 {
00224    return ast_unregister_application(app);
00225 }


Variable Documentation

char* app = "ParkAndAnnounce" [static]

Definition at line 90 of file app_parkandannounce.c.


Generated on 7 Aug 2019 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1