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" |
ParkAndAnnounce application for Asterisk.
Definition in file app_parkandannounce.c.
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 }
char* app = "ParkAndAnnounce" [static] |
Definition at line 90 of file app_parkandannounce.c.