00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "asterisk.h"
00033
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 170049 $")
00035
00036 #include "asterisk/file.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/pbx.h"
00039 #include "asterisk/module.h"
00040 #include "asterisk/features.h"
00041 #include "asterisk/say.h"
00042 #include "asterisk/lock.h"
00043 #include "asterisk/utils.h"
00044 #include "asterisk/app.h"
00045
00046 static char *app = "ParkAndAnnounce";
00047
00048 static char *synopsis = "Park and Announce";
00049
00050 static char *descrip =
00051 " ParkAndAnnounce(announce:template,timeout,dial[,return_context]):\n"
00052 "Park a call into the parkinglot and announce the call to another channel.\n"
00053 "\n"
00054 "announce template: Colon-separated list of files to announce. The word PARKED\n"
00055 " will be replaced by a say_digits of the extension in which\n"
00056 " the call is parked.\n"
00057 "timeout: Time in seconds before the call returns into the return\n"
00058 " context.\n"
00059 "dial: The app_dial style resource to call to make the\n"
00060 " announcement. Console/dsp calls the console.\n"
00061 "return_context: The goto-style label to jump the call back into after\n"
00062 " timeout. Default <priority+1>.\n"
00063 "\n"
00064 "The variable ${PARKEDAT} will contain the parking extension into which the\n"
00065 "call was placed. Use with the Local channel to allow the dialplan to make\n"
00066 "use of this information.\n";
00067
00068
00069 static int parkandannounce_exec(struct ast_channel *chan, void *data)
00070 {
00071 int res = -1;
00072 int lot, timeout = 0, dres;
00073 char *dialtech, *tmp[100], buf[13];
00074 int looptemp, i;
00075 char *s;
00076
00077 struct ast_channel *dchan;
00078 struct outgoing_helper oh = { 0, };
00079 int outstate;
00080 AST_DECLARE_APP_ARGS(args,
00081 AST_APP_ARG(template);
00082 AST_APP_ARG(timeout);
00083 AST_APP_ARG(dial);
00084 AST_APP_ARG(return_context);
00085 );
00086 if (ast_strlen_zero(data)) {
00087 ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce:template|timeout|dial|[return_context])\n");
00088 return -1;
00089 }
00090
00091 s = ast_strdupa(data);
00092 AST_STANDARD_APP_ARGS(args, s);
00093
00094 if (args.timeout)
00095 timeout = atoi(args.timeout) * 1000;
00096
00097 if (ast_strlen_zero(args.dial)) {
00098 ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or DAHDI/g1/5551212\n");
00099 return -1;
00100 }
00101
00102 dialtech = strsep(&args.dial, "/");
00103 ast_verb(3, "Dial Tech,String: (%s,%s)\n", dialtech, args.dial);
00104
00105 if (!ast_strlen_zero(args.return_context)) {
00106 ast_clear_flag(chan, AST_FLAG_IN_AUTOLOOP);
00107 ast_parseable_goto(chan, args.return_context);
00108 }
00109
00110 ast_verb(3, "Return Context: (%s,%s,%d) ID: %s\n", chan->context, chan->exten, chan->priority, chan->cid.cid_num);
00111 if (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
00112 ast_verb(3, "Warning: Return Context Invalid, call will return to default|s\n");
00113 }
00114
00115
00116
00117
00118 res = ast_masq_park_call(chan, NULL, timeout, &lot);
00119 if (res == -1)
00120 return res;
00121
00122 ast_verb(3, "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, args.return_context);
00123
00124
00125
00126 snprintf(buf, sizeof(buf), "%d", lot);
00127 oh.parent_channel = chan;
00128 oh.vars = ast_variable_new("_PARKEDAT", buf, "");
00129 dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, args.dial, 30000, &outstate, chan->cid.cid_num, chan->cid.cid_name, &oh);
00130
00131 if (dchan) {
00132 if (dchan->_state == AST_STATE_UP) {
00133 ast_verb(4, "Channel %s was answered.\n", dchan->name);
00134 } else {
00135 ast_verb(4, "Channel %s was never answered.\n", dchan->name);
00136 ast_log(LOG_WARNING, "PARK: Channel %s was never answered for the announce.\n", dchan->name);
00137 ast_hangup(dchan);
00138 return -1;
00139 }
00140 } else {
00141 ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
00142 return -1;
00143 }
00144
00145 ast_stopstream(dchan);
00146
00147
00148
00149 ast_verb(4, "Announce Template:%s\n", args.template);
00150
00151 for (looptemp = 0; looptemp < ARRAY_LEN(tmp); looptemp++) {
00152 if ((tmp[looptemp] = strsep(&args.template, ":")) != NULL)
00153 continue;
00154 else
00155 break;
00156 }
00157
00158 for (i = 0; i < looptemp; i++) {
00159 ast_verb(4, "Announce:%s\n", tmp[i]);
00160 if (!strcmp(tmp[i], "PARKED")) {
00161 ast_say_digits(dchan, lot, "", dchan->language);
00162 } else {
00163 dres = ast_streamfile(dchan, tmp[i], dchan->language);
00164 if (!dres) {
00165 dres = ast_waitstream(dchan, "");
00166 } else {
00167 ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], dchan->name);
00168 dres = 0;
00169 }
00170 }
00171 }
00172
00173 ast_stopstream(dchan);
00174 ast_hangup(dchan);
00175
00176 return res;
00177 }
00178
00179 static int unload_module(void)
00180 {
00181 return ast_unregister_application(app);
00182 }
00183
00184 static int load_module(void)
00185 {
00186
00187 return ast_register_application(app, parkandannounce_exec, synopsis, descrip);
00188 }
00189
00190 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Call Parking and Announce Application");