[asterisk-commits] branch oej/02-labarea r22164 - in
/team/oej/02-labarea: ./ apps/ cdr/ channel...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Sat Apr 22 23:51:44 MST 2006
Author: oej
Date: Sun Apr 23 01:51:43 2006
New Revision: 22164
URL: http://svn.digium.com/view/asterisk?rev=22164&view=rev
Log:
Update to trunk
Added:
team/oej/02-labarea/configs/say.conf.sample
- copied unchanged from r22128, trunk/configs/say.conf.sample
Modified:
team/oej/02-labarea/ (props changed)
team/oej/02-labarea/app.c
team/oej/02-labarea/apps/app_dial.c
team/oej/02-labarea/apps/app_directory.c
team/oej/02-labarea/apps/app_dumpchan.c
team/oej/02-labarea/apps/app_meetme.c
team/oej/02-labarea/apps/app_playback.c
team/oej/02-labarea/apps/app_queue.c
team/oej/02-labarea/apps/app_voicemail.c
team/oej/02-labarea/asterisk.c
team/oej/02-labarea/cdr.c
team/oej/02-labarea/cdr/cdr_odbc.c
team/oej/02-labarea/channel.c
team/oej/02-labarea/channels/chan_features.c
team/oej/02-labarea/channels/chan_local.c
team/oej/02-labarea/channels/chan_mgcp.c
team/oej/02-labarea/channels/chan_sip.c
team/oej/02-labarea/channels/chan_skinny.c
team/oej/02-labarea/channels/chan_zap.c
team/oej/02-labarea/cli.c
team/oej/02-labarea/contrib/scripts/safe_asterisk
team/oej/02-labarea/contrib/scripts/safe_asterisk.8
team/oej/02-labarea/enum.c
team/oej/02-labarea/file.c
team/oej/02-labarea/funcs/func_callerid.c
team/oej/02-labarea/include/asterisk/channel.h
team/oej/02-labarea/include/asterisk/file.h
team/oej/02-labarea/include/asterisk/frame.h
team/oej/02-labarea/include/asterisk/say.h
team/oej/02-labarea/include/asterisk/utils.h
team/oej/02-labarea/manager.c
team/oej/02-labarea/pbx.c
team/oej/02-labarea/res/res_adsi.c
team/oej/02-labarea/res/res_agi.c
team/oej/02-labarea/res/res_features.c
team/oej/02-labarea/res/res_musiconhold.c
team/oej/02-labarea/say.c
Propchange: team/oej/02-labarea/
------------------------------------------------------------------------------
Binary property 'branch-1.2-merged' - no diff available.
Modified: team/oej/02-labarea/app.c
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/app.c?rev=22164&r1=22163&r2=22164&view=diff
==============================================================================
--- team/oej/02-labarea/app.c (original)
+++ team/oej/02-labarea/app.c Sun Apr 23 01:51:43 2006
@@ -155,10 +155,7 @@
struct ast_dsp *sildet;
/* Play prompt if requested */
if (prompt) {
- res = ast_streamfile(c, prompt, c->language);
- if (res < 0)
- return res;
- res = ast_waitstream(c,"");
+ res = ast_stream_and_wait(c, prompt, c->language, "");
if (res < 0)
return res;
}
@@ -573,9 +570,7 @@
if (playfile) {
d = ast_play_and_wait(chan, playfile);
if (d > -1)
- d = ast_streamfile(chan, "beep",chan->language);
- if (!d)
- d = ast_waitstream(chan,"");
+ d = ast_stream_and_wait(chan, "beep", chan->language, "");
if (d < 0)
return -1;
}
@@ -749,8 +744,7 @@
}
if (outmsg > 1) {
/* Let them know recording is stopped */
- if(!ast_streamfile(chan, "auth-thankyou", chan->language))
- ast_waitstream(chan, "");
+ ast_stream_and_wait(chan, "auth-thankyou", chan->language, "");
}
if (sildet)
ast_dsp_free(sildet);
@@ -794,9 +788,7 @@
if (!beep)
d = ast_play_and_wait(chan, playfile);
if (d > -1)
- d = ast_streamfile(chan, "beep",chan->language);
- if (!d)
- d = ast_waitstream(chan,"");
+ d = ast_stream_and_wait(chan, "beep",chan->language, "");
if (d < 0)
return -1;
}
@@ -981,8 +973,7 @@
}
if (outmsg > 1) {
/* Let them know it worked */
- ast_streamfile(chan, "auth-thankyou", chan->language);
- ast_waitstream(chan, "");
+ ast_stream_and_wait(chan, "auth-thankyou", chan->language, "");
}
return res;
}
@@ -1205,16 +1196,14 @@
cmd = '3';
break;
} else {
- ast_streamfile(chan, "vm-msgsaved", chan->language);
- ast_waitstream(chan, "");
+ ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
cmd = 't';
return res;
}
case '2':
/* Review */
ast_verbose(VERBOSE_PREFIX_3 "Reviewing the recording\n");
- ast_streamfile(chan, recordfile, chan->language);
- cmd = ast_waitstream(chan, AST_DIGIT_ANY);
+ cmd = ast_stream_and_wait(chan, recordfile, chan->language, AST_DIGIT_ANY);
break;
case '3':
message_exists = 0;
@@ -1300,19 +1289,15 @@
case AST_ACTION_NOOP:
return 0;
case AST_ACTION_BACKGROUND:
- res = ast_streamfile(chan, (char *)option->adata, chan->language);
- if (!res) {
- res = ast_waitstream(chan, AST_DIGIT_ANY);
- } else {
+ res = ast_stream_and_wait(chan, (char *)option->adata, chan->language, AST_DIGIT_ANY);
+ if (res < 0) {
ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
res = 0;
}
return res;
case AST_ACTION_PLAYBACK:
- res = ast_streamfile(chan, (char *)option->adata, chan->language);
- if (!res) {
- res = ast_waitstream(chan, "");
- } else {
+ res = ast_stream_and_wait(chan, (char *)option->adata, chan->language, "");
+ if (res < 0) {
ast_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
res = 0;
}
@@ -1341,7 +1326,8 @@
c = ast_strdupa(option->adata);
if (c) {
while((n = strsep(&c, ";")))
- if ((res = ast_streamfile(chan, n, chan->language)) || (res = ast_waitstream(chan, (option->action == AST_ACTION_BACKLIST) ? AST_DIGIT_ANY : "")))
+ if ((res = ast_stream_and_wait(chan, n, chan->language,
+ (option->action == AST_ACTION_BACKLIST) ? AST_DIGIT_ANY : "")))
break;
ast_stopstream(chan);
}
Modified: team/oej/02-labarea/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/apps/app_dial.c?rev=22164&r1=22163&r2=22164&view=diff
==============================================================================
--- team/oej/02-labarea/apps/app_dial.c (original)
+++ team/oej/02-labarea/apps/app_dial.c Sun Apr 23 01:51:43 2006
@@ -154,6 +154,16 @@
" o - Specify that the CallerID that was present on the *calling* channel\n"
" be set as the CallerID on the *called* channel. This was the\n"
" behavior of Asterisk 1.0 and earlier.\n"
+" O([x]) - \"Operator Services\" mode (Zaptel channel to Zaptel channel\n"
+" only, if specified on non-Zaptel interface, it will be ignored).\n"
+" When the destination answers (presumably an operator services\n"
+" station), the originator no longer has control of their line.\n"
+" They may hang up, but the switch will not release their line\n"
+" until the destination party hangs up (the operator). Specified\n"
+" without an arg, or with 1 as an arg, the originator hanging up\n"
+" will cause the phone to ring back immediately. With a 2 specified,\n"
+" when the \"operator\" flashes the trunk, it will ring their phone\n"
+" back.\n"
" p - This option enables screening mode. This is basically Privacy mode\n"
" without memory.\n"
" P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
@@ -213,6 +223,7 @@
OPT_CALLEE_MONITOR = (1 << 21),
OPT_CALLER_MONITOR = (1 << 22),
OPT_GOTO = (1 << 23),
+ OPT_OPERMODE = (1 << 24),
} dial_exec_option_flags;
#define DIAL_STILLGOING (1 << 30)
@@ -227,6 +238,7 @@
OPT_ARG_CALLEE_MACRO,
OPT_ARG_PRIVACY,
OPT_ARG_DURATION_STOP,
+ OPT_ARG_OPERMODE,
/* note: this entry _MUST_ be the last one in the enum */
OPT_ARG_ARRAY_SIZE,
} dial_exec_option_args;
@@ -247,6 +259,7 @@
AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
+ AST_APP_OPTION_ARG('O', OPT_OPERMODE,OPT_ARG_OPERMODE),
AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
AST_APP_OPTION('p', OPT_SCREENING),
AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
@@ -334,28 +347,17 @@
}
-static char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
+static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
{
- char *context;
- char *exten;
- if (!ast_strlen_zero(chan->macrocontext))
- context = chan->macrocontext;
- else
- context = chan->context;
-
- if (!ast_strlen_zero(chan->macroexten))
- exten = chan->macroexten;
- else
- exten = chan->exten;
-
- if (ast_get_hint(NULL, 0, name, namelen, chan, context, exten))
- return name;
- else
- return "";
+ const char *context = S_OR(chan->macrocontext, chan->context);
+ const char *exten = S_OR(chan->macroexten, chan->exten);
+
+ return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
}
static void senddialevent(struct ast_channel *src, struct ast_channel *dst)
{
+ /* XXX do we need also CallerIDnum ? */
manager_event(EVENT_FLAG_CALL, "Dial",
"Source: %s\r\n"
"Destination: %s\r\n"
@@ -363,32 +365,21 @@
"CallerIDName: %s\r\n"
"SrcUniqueID: %s\r\n"
"DestUniqueID: %s\r\n",
- src->name, dst->name, src->cid.cid_num ? src->cid.cid_num : "<unknown>",
- src->cid.cid_name ? src->cid.cid_name : "<unknown>", src->uniqueid,
+ src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
+ S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
dst->uniqueid);
}
static struct ast_channel *wait_for_answer(struct ast_channel *in, struct dial_localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart, int priority_jump, int *result)
{
- struct dial_localuser *o;
- int found;
- int numlines;
int numbusy = busystart;
int numcongestion = congestionstart;
int numnochan = nochanstart;
int prestart = busystart + congestionstart + nochanstart;
- int cause;
int orig = *to;
- struct ast_frame *f;
struct ast_channel *peer = NULL;
- struct ast_channel *watchers[AST_MAX_WATCHERS];
- int pos;
- int single;
- struct ast_channel *winner;
- const char *context = NULL;
- char cidname[AST_MAX_EXTENSION];
-
- single = (outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK));
+ /* single is set if only one destination is enabled */
+ int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
if (single) {
/* Turn off hold music, etc */
@@ -399,21 +390,20 @@
while (*to && !peer) {
- o = outgoing;
- found = -1;
- pos = 1;
- numlines = prestart;
- watchers[0] = in;
- while (o) {
+ struct dial_localuser *o;
+ int pos = 0; /* how many channels do we handle */
+ int numlines = prestart;
+ struct ast_channel *winner;
+ struct ast_channel *watchers[AST_MAX_WATCHERS];
+
+ watchers[pos++] = in;
+ for (o = outgoing; o; o = o->next) {
/* Keep track of important channels */
- if (ast_test_flag(o, DIAL_STILLGOING) && o->chan) {
+ if (ast_test_flag(o, DIAL_STILLGOING) && o->chan)
watchers[pos++] = o->chan;
- found = 1;
- }
- o = o->next;
numlines++;
}
- if (found < 0) {
+ if (pos == 1) { /* only the input channel is available */
if (numlines == (numbusy + numcongestion + numnochan)) {
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
@@ -433,239 +423,224 @@
return NULL;
}
winner = ast_waitfor_n(watchers, pos, to);
- o = outgoing;
- while (o) {
- if (ast_test_flag(o, DIAL_STILLGOING) && o->chan && (o->chan->_state == AST_STATE_UP)) {
+ for (o = outgoing; o; o = o->next) {
+ struct ast_frame *f;
+ struct ast_channel *c = o->chan;
+
+ if (c == NULL)
+ continue;
+ if (ast_test_flag(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
if (!peer) {
if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
- peer = o->chan;
+ ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
+ peer = c;
ast_copy_flags(peerflags, o,
OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
DIAL_NOFORWARDHTML);
}
- } else if (o->chan && (o->chan == winner)) {
- if (!ast_strlen_zero(o->chan->call_forward)) {
- char tmpchan[256];
- char *stuff;
- char *tech;
- const char *forward_context;
-
- ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan));
- if ((stuff = strchr(tmpchan, '/'))) {
- *stuff = '\0';
- stuff++;
- tech = tmpchan;
+ continue;
+ }
+ if (c != winner)
+ continue;
+ if (!ast_strlen_zero(c->call_forward)) {
+ char tmpchan[256];
+ char *stuff;
+ char *tech;
+ int cause;
+
+ ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
+ if ((stuff = strchr(tmpchan, '/'))) {
+ *stuff++ = '\0';
+ tech = tmpchan;
+ } else {
+ const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
+ snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
+ stuff = tmpchan;
+ tech = "Local";
+ }
+ /* Before processing channel, go ahead and check for forwarding */
+ o->forwards++;
+ if (o->forwards < AST_MAX_FORWARDS) {
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
+ /* Setup parameters */
+ c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
+ if (!c)
+ ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
+ } else {
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", c->name);
+ cause = AST_CAUSE_CONGESTION;
+ c = o->chan = NULL;
+ }
+ if (!c) {
+ ast_clear_flag(o, DIAL_STILLGOING);
+ HANDLE_CAUSE(cause, in);
+ } else {
+ ast_rtp_make_compatible(c, in);
+ if (c->cid.cid_num)
+ free(c->cid.cid_num);
+ c->cid.cid_num = NULL;
+ if (c->cid.cid_name)
+ free(c->cid.cid_name);
+ c->cid.cid_name = NULL;
+
+ if (ast_test_flag(o, OPT_FORCECLID)) {
+ c->cid.cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
+ ast_string_field_set(c, accountcode, winner->accountcode);
+ c->cdrflags = winner->cdrflags;
} else {
- forward_context = pbx_builtin_getvar_helper(o->chan, "FORWARD_CONTEXT");
- snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, forward_context ? forward_context : o->chan->context);
- stuff = tmpchan;
- tech = "Local";
+ c->cid.cid_num = ast_strdup(in->cid.cid_num);
+ c->cid.cid_name = ast_strdup(in->cid.cid_name);
+ ast_string_field_set(c, accountcode, in->accountcode);
+ c->cdrflags = in->cdrflags;
}
- /* Before processing channel, go ahead and check for forwarding */
- o->forwards++;
- if (o->forwards < AST_MAX_FORWARDS) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
- /* Setup parameters */
- o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
- if (!o->chan)
- ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
+
+ if (in->cid.cid_ani) {
+ if (c->cid.cid_ani)
+ free(c->cid.cid_ani);
+ c->cid.cid_ani = ast_strdup(in->cid.cid_ani);
+ }
+ if (c->cid.cid_rdnis)
+ free(c->cid.cid_rdnis);
+ c->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
+ if (ast_call(c, tmpchan, 0)) {
+ ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
+ ast_clear_flag(o, DIAL_STILLGOING);
+ ast_hangup(c);
+ c = o->chan = NULL;
+ numnochan++;
} else {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", o->chan->name);
- cause = AST_CAUSE_CONGESTION;
- o->chan = NULL;
- }
- if (!o->chan) {
- ast_clear_flag(o, DIAL_STILLGOING);
- HANDLE_CAUSE(cause, in);
- } else {
- ast_rtp_make_compatible(o->chan, in);
- if (o->chan->cid.cid_num)
- free(o->chan->cid.cid_num);
- o->chan->cid.cid_num = NULL;
- if (o->chan->cid.cid_name)
- free(o->chan->cid.cid_name);
- o->chan->cid.cid_name = NULL;
-
- if (ast_test_flag(o, OPT_FORCECLID)) {
- char *newcid = NULL;
-
- if (!ast_strlen_zero(in->macroexten))
- newcid = in->macroexten;
- else
- newcid = in->exten;
- o->chan->cid.cid_num = strdup(newcid);
- ast_string_field_set(o->chan, accountcode, winner->accountcode);
- o->chan->cdrflags = winner->cdrflags;
- if (!o->chan->cid.cid_num)
- ast_log(LOG_WARNING, "Out of memory\n");
- } else {
- if (in->cid.cid_num) {
- o->chan->cid.cid_num = strdup(in->cid.cid_num);
- if (!o->chan->cid.cid_num)
- ast_log(LOG_WARNING, "Out of memory\n");
- }
- if (in->cid.cid_name) {
- o->chan->cid.cid_name = strdup(in->cid.cid_name);
- if (!o->chan->cid.cid_name)
- ast_log(LOG_WARNING, "Out of memory\n");
- }
- ast_string_field_set(o->chan, accountcode, in->accountcode);
- o->chan->cdrflags = in->cdrflags;
- }
-
- if (in->cid.cid_ani) {
- if (o->chan->cid.cid_ani)
- free(o->chan->cid.cid_ani);
- o->chan->cid.cid_ani = strdup(in->cid.cid_ani);
- if (!o->chan->cid.cid_ani)
- ast_log(LOG_WARNING, "Out of memory\n");
- }
- if (o->chan->cid.cid_rdnis)
- free(o->chan->cid.cid_rdnis);
- if (!ast_strlen_zero(in->macroexten))
- o->chan->cid.cid_rdnis = strdup(in->macroexten);
- else
- o->chan->cid.cid_rdnis = strdup(in->exten);
- if (ast_call(o->chan, tmpchan, 0)) {
- ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
- ast_clear_flag(o, DIAL_STILLGOING);
- ast_hangup(o->chan);
- o->chan = NULL;
- numnochan++;
- } else {
- senddialevent(in, o->chan);
- /* After calling, set callerid to extension */
- if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
- ast_set_callerid(o->chan, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
+ senddialevent(in, c);
+ /* After calling, set callerid to extension */
+ if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
+ char cidname[AST_MAX_EXTENSION];
+ ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
}
}
- /* Hangup the original channel now, in case we needed it */
- ast_hangup(winner);
- continue;
}
- f = ast_read(winner);
- if (f) {
- if (f->frametype == AST_FRAME_CONTROL) {
- switch(f->subclass) {
- case AST_CONTROL_ANSWER:
- /* This is our guy if someone answered. */
- if (!peer) {
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
- peer = o->chan;
- ast_copy_flags(peerflags, o,
- OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
- OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
- OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
- DIAL_NOFORWARDHTML);
- }
- /* If call has been answered, then the eventual hangup is likely to be normal hangup */
- in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
- o->chan->hangupcause = AST_CAUSE_NORMAL_CLEARING;
- break;
- case AST_CONTROL_BUSY:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name);
- in->hangupcause = o->chan->hangupcause;
- ast_hangup(o->chan);
- o->chan = NULL;
- ast_clear_flag(o, DIAL_STILLGOING);
- HANDLE_CAUSE(AST_CAUSE_BUSY, in);
- break;
- case AST_CONTROL_CONGESTION:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", o->chan->name);
- in->hangupcause = o->chan->hangupcause;
- ast_hangup(o->chan);
- o->chan = NULL;
- ast_clear_flag(o, DIAL_STILLGOING);
- HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
- break;
- case AST_CONTROL_RINGING:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
- if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
- ast_indicate(in, AST_CONTROL_RINGING);
- (*sentringing)++;
- }
- break;
- case AST_CONTROL_PROGRESS:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", o->chan->name,in->name);
- if (!ast_test_flag(outgoing, OPT_RINGBACK))
- ast_indicate(in, AST_CONTROL_PROGRESS);
- break;
- case AST_CONTROL_VIDUPDATE:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", o->chan->name,in->name);
- ast_indicate(in, AST_CONTROL_VIDUPDATE);
- break;
- case AST_CONTROL_PROCEEDING:
- if (option_verbose > 2)
- ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", o->chan->name,in->name);
- if (!ast_test_flag(outgoing, OPT_RINGBACK))
- ast_indicate(in, AST_CONTROL_PROCEEDING);
- break;
- case AST_CONTROL_HOLD:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", o->chan->name);
- ast_indicate(in, AST_CONTROL_HOLD);
- break;
- case AST_CONTROL_UNHOLD:
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", o->chan->name);
- ast_indicate(in, AST_CONTROL_UNHOLD);
- break;
- case AST_CONTROL_OFFHOOK:
- case AST_CONTROL_FLASH:
- /* Ignore going off hook and flash */
- break;
- case -1:
- if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", o->chan->name);
- ast_indicate(in, -1);
- (*sentringing) = 0;
- }
- break;
- default:
- if (option_debug)
- ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
- }
- } else if (single && (f->frametype == AST_FRAME_VOICE) &&
- !(ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK))) {
- if (ast_write(in, f))
- ast_log(LOG_WARNING, "Unable to forward voice frame\n");
- } else if (single && (f->frametype == AST_FRAME_IMAGE) &&
- !(ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK))) {
- if (ast_write(in, f))
- ast_log(LOG_WARNING, "Unable to forward image\n");
- } else if (single && (f->frametype == AST_FRAME_TEXT) &&
- !(ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK))) {
- if (ast_write(in, f))
- ast_log(LOG_WARNING, "Unable to send text\n");
- } else if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML))
- if(ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
- ast_log(LOG_WARNING, "Unable to send URL\n");
-
- ast_frfree(f);
- } else {
- in->hangupcause = o->chan->hangupcause;
- ast_hangup(o->chan);
- o->chan = NULL;
+ /* Hangup the original channel now, in case we needed it */
+ ast_hangup(winner);
+ continue;
+ }
+ f = ast_read(winner);
+ if (!f) {
+ in->hangupcause = c->hangupcause;
+ ast_hangup(c);
+ c = o->chan = NULL;
+ ast_clear_flag(o, DIAL_STILLGOING);
+ HANDLE_CAUSE(in->hangupcause, in);
+ continue;
+ }
+ if (f->frametype == AST_FRAME_CONTROL) {
+ switch(f->subclass) {
+ case AST_CONTROL_ANSWER:
+ /* This is our guy if someone answered. */
+ if (!peer) {
+ if (option_verbose > 2)
+ ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
+ peer = c;
+ ast_copy_flags(peerflags, o,
+ OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
+ OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
+ OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
+ DIAL_NOFORWARDHTML);
+ }
+ /* If call has been answered, then the eventual hangup is likely to be normal hangup */
+ in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
+ c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
+ break;
+ case AST_CONTROL_BUSY:
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
+ in->hangupcause = c->hangupcause;
+ ast_hangup(c);
+ c = o->chan = NULL;
+ ast_clear_flag(o, DIAL_STILLGOING);
+ HANDLE_CAUSE(AST_CAUSE_BUSY, in);
+ break;
+ case AST_CONTROL_CONGESTION:
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
+ in->hangupcause = c->hangupcause;
+ ast_hangup(c);
+ c = o->chan = NULL;
ast_clear_flag(o, DIAL_STILLGOING);
- HANDLE_CAUSE(in->hangupcause, in);
+ HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
+ break;
+ case AST_CONTROL_RINGING:
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
+ if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
+ ast_indicate(in, AST_CONTROL_RINGING);
+ (*sentringing)++;
+ }
+ break;
+ case AST_CONTROL_PROGRESS:
+ if (option_verbose > 2)
+ ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
+ if (!ast_test_flag(outgoing, OPT_RINGBACK))
+ ast_indicate(in, AST_CONTROL_PROGRESS);
+ break;
+ case AST_CONTROL_VIDUPDATE:
+ if (option_verbose > 2)
+ ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
+ ast_indicate(in, AST_CONTROL_VIDUPDATE);
+ break;
+ case AST_CONTROL_PROCEEDING:
+ if (option_verbose > 2)
+ ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
+ if (!ast_test_flag(outgoing, OPT_RINGBACK))
+ ast_indicate(in, AST_CONTROL_PROCEEDING);
+ break;
+ case AST_CONTROL_HOLD:
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
+ ast_indicate(in, AST_CONTROL_HOLD);
+ break;
+ case AST_CONTROL_UNHOLD:
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
+ ast_indicate(in, AST_CONTROL_UNHOLD);
+ break;
+ case AST_CONTROL_OFFHOOK:
+ case AST_CONTROL_FLASH:
+ /* Ignore going off hook and flash */
+ break;
+ case -1:
+ if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
+ ast_indicate(in, -1);
+ (*sentringing) = 0;
+ }
+ break;
+ default:
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
}
- }
- o = o->next;
- }
+ } else if (single) {
+ /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
+ if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
+ if (ast_write(in, f))
+ ast_log(LOG_WARNING, "Unable to forward voice frame\n");
+ } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
+ if (ast_write(in, f))
+ ast_log(LOG_WARNING, "Unable to forward image\n");
+ } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
+ if (ast_write(in, f))
+ ast_log(LOG_WARNING, "Unable to send text\n");
+ } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) {
+ if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
+ ast_log(LOG_WARNING, "Unable to send URL\n");
+ }
+ }
+ ast_frfree(f);
+ } /* end for */
if (winner == in) {
- f = ast_read(in);
+ struct ast_frame *f = ast_read(in);
#if 0
if (f && (f->frametype != AST_FRAME_VOICE))
printf("Frame type: %d, %d\n", f->frametype, f->subclass);
@@ -683,7 +658,7 @@
if (f && (f->frametype == AST_FRAME_DTMF)) {
if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
- context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
+ const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
if (onedigit_goto(in, context, (char) f->subclass, 1)) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
@@ -728,17 +703,34 @@
}
return peer;
-
+}
+
+static void replace_macro_delimiter(char *s)
+{
+ for (; *s; s++)
+ if (*s == '^')
+ *s = '|';
+}
+
+
+/* returns true if there is a valid privacy reply */
+static int valid_priv_reply(struct ast_flags *opts, int res)
+{
+ if (res < '1')
+ return 0;
+ if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
+ return 1;
+ if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
+ return 1;
+ return 0;
}
static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags)
{
int res = -1;
struct localuser *u;
- char *tech, *number, *rest, *cur;
- char privcid[256];
- char privintro[1024];
- struct dial_localuser *outgoing = NULL, *tmp;
+ char *rest, *cur;
+ struct dial_localuser *outgoing = NULL;
struct ast_channel *peer;
int to;
int numbusy = 0;
@@ -747,11 +739,8 @@
int cause;
char numsubst[AST_MAX_EXTENSION];
char cidname[AST_MAX_EXTENSION];
- char toast[80];
- char *l;
int privdb_val = 0;
unsigned int calldurationlimit = 0;
- struct ast_bridge_config config;
long timelimit = 0;
long play_warning = 0;
long warning_freq = 0;
@@ -759,18 +748,16 @@
const char *end_sound = NULL;
const char *start_sound = NULL;
char *dtmfcalled = NULL, *dtmfcalling = NULL;
- const char *var;
char status[256];
int play_to_caller = 0, play_to_callee = 0;
int sentringing = 0, moh = 0;
const char *outbound_group = NULL;
- const char *macro_result = NULL;
- char *macro_transfer_dest = NULL;
- int digit = 0, result = 0;
- time_t start_time, answer_time, end_time;
- struct ast_app *app = NULL;
-
+ int result = 0;
+ time_t start_time;
+ char privintro[1024];
+ char privcid[256];
char *parse;
+ int opermode = 0;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(peers);
AST_APP_ARG(timeout);
@@ -787,50 +774,50 @@
LOCAL_USER_ADD(u);
- if (!(parse = ast_strdupa(data))) {
- LOCAL_USER_REMOVE(u);
- return -1;
- }
-
+ if (!(parse = ast_strdupa(data)))
+ goto done;
+
AST_STANDARD_APP_ARGS(args, parse);
- if (!ast_strlen_zero(args.options)) {
- if (ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
- LOCAL_USER_REMOVE(u);
- return -1;
- }
- }
+ if (!ast_strlen_zero(args.options) &&
+ ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options))
+ goto done;
if (ast_strlen_zero(args.peers)) {
ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
- LOCAL_USER_REMOVE(u);
- return -1;
+ goto done;
+ }
+
+ if (ast_test_flag(&opts, OPT_OPERMODE)) {
+ if (ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]))
+ opermode = 1;
+ else opermode = atoi(opt_args[OPT_ARG_OPERMODE]);
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Setting operator services mode to %d.\n", opermode);
}
if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
if (!calldurationlimit) {
ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
- LOCAL_USER_REMOVE(u);
- return -1;
+ goto done;
}
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
}
if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
- parse = opt_args[OPT_ARG_SENDDTMF];
- dtmfcalled = strsep(&parse, ":");
- dtmfcalling = parse;
+ dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
+ dtmfcalled = strsep(&dtmfcalling, ":");
}
if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
char *limit_str, *warning_str, *warnfreq_str;
-
- parse = opt_args[OPT_ARG_DURATION_LIMIT];
- limit_str = strsep(&parse, ":");
- warning_str = strsep(&parse, ":");
- warnfreq_str = parse;
+ const char *var;
+
+ warnfreq_str = opt_args[OPT_ARG_DURATION_LIMIT];
+ limit_str = strsep(&warnfreq_str, ":");
+ warning_str = strsep(&warnfreq_str, ":");
timelimit = atol(limit_str);
if (warning_str)
@@ -840,8 +827,7 @@
if (!timelimit) {
ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
- LOCAL_USER_REMOVE(u);
- return -1;
+ goto done;
} else if (play_warning > timelimit) {
/* If the first warning is requested _after_ the entire call would end,
and no warning frequency is requested, then turn off the warning. If
@@ -852,6 +838,7 @@
if (!warning_freq) {
play_warning = 0;
} else {
+ /* XXX fix this!! */
while (play_warning > timelimit)
play_warning -= warning_freq;
if (play_warning < 1)
@@ -869,13 +856,13 @@
play_to_caller = 1;
var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
- warning_sound = (!ast_strlen_zero(var)) ? var : "timeleft";
+ warning_sound = S_OR(var, "timeleft");
var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
- end_sound = (!ast_strlen_zero(var)) ? var : NULL;
+ end_sound = S_OR(var, NULL); /* XXX not much of a point in doing this! */
var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
- start_sound = (!ast_strlen_zero(var)) ? var : NULL;
+ start_sound = S_OR(var, NULL); /* XXX not much of a point in doing this! */
/* undo effect of S(x) in case they are both used */
calldurationlimit = 0;
@@ -904,8 +891,7 @@
opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
char callerid[60];
-
- l = chan->cid.cid_num;
+ char *l = chan->cid.cid_num; /* XXX watch out, we are overwriting it */
if (!ast_strlen_zero(l)) {
ast_shrink_phone_number(l);
if( ast_test_flag(&opts, OPT_PRIVACY) ) {
@@ -998,26 +984,19 @@
outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP);
- cur = args.peers;
- do {
- /* Remember where to start next time */
- rest = strchr(cur, '&');
- if (rest) {
- *rest = 0;
- rest++;
- }
+ /* loop through the list of dial destinations */
+ rest = args.peers;
+ while ((cur = strsep(&rest, "&")) ) {
+ struct dial_localuser *tmp;
/* Get a technology/[device:]number pair */
- tech = cur;
- number = strchr(tech, '/');
+ char *number = cur;
+ char *tech = strsep(&number, "/");
if (!number) {
ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
goto out;
}
- *number = '\0';
- number++;
- if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
+ if (!(tmp = ast_calloc(1, sizeof(*tmp))))
goto out;
- }
if (opts.flags) {
ast_copy_flags(tmp, &opts,
OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
@@ -1033,8 +1012,7 @@
/* If we can't, just go on to the next call */
ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
HANDLE_CAUSE(cause, chan);
- cur = rest;
- if (!cur)
+ if (!rest) /* we are on the last destination */
chan->hangupcause = cause;
continue;
}
@@ -1045,8 +1023,7 @@
char *tech;
ast_copy_string(tmpchan, tmp->chan->call_forward, sizeof(tmpchan));
if ((stuff = strchr(tmpchan, '/'))) {
- *stuff = '\0';
- stuff++;
+ *stuff++ = '\0';
tech = tmpchan;
} else {
snprintf(tmpchan, sizeof(tmpchan), "%s@%s", tmp->chan->call_forward, tmp->chan->context);
@@ -1071,7 +1048,6 @@
}
if (!tmp->chan) {
HANDLE_CAUSE(cause, chan);
- cur = rest;
continue;
}
}
@@ -1085,22 +1061,18 @@
tmp->chan->appl = "AppDial";
tmp->chan->data = "(Outgoing Line)";
tmp->chan->whentohangup = 0;
+
if (tmp->chan->cid.cid_num)
free(tmp->chan->cid.cid_num);
- tmp->chan->cid.cid_num = NULL;
+ tmp->chan->cid.cid_num = ast_strdup(chan->cid.cid_num);
+
if (tmp->chan->cid.cid_name)
free(tmp->chan->cid.cid_name);
- tmp->chan->cid.cid_name = NULL;
+ tmp->chan->cid.cid_name = ast_strdup(chan->cid.cid_name);
+
if (tmp->chan->cid.cid_ani)
free(tmp->chan->cid.cid_ani);
- tmp->chan->cid.cid_ani = NULL;
-
- if (chan->cid.cid_num)
- tmp->chan->cid.cid_num = strdup(chan->cid.cid_num);
- if (chan->cid.cid_name)
- tmp->chan->cid.cid_name = strdup(chan->cid.cid_name);
- if (chan->cid.cid_ani)
- tmp->chan->cid.cid_ani = strdup(chan->cid.cid_ani);
+ tmp->chan->cid.cid_ani = ast_strdup(chan->cid.cid_ani);
/* Copy language from incoming to outgoing */
ast_string_field_set(tmp->chan, language, chan->language);
@@ -1108,8 +1080,8 @@
tmp->chan->cdrflags = chan->cdrflags;
if (ast_strlen_zero(tmp->chan->musicclass))
ast_string_field_set(tmp->chan, musicclass, chan->musicclass);
- if (chan->cid.cid_rdnis)
- tmp->chan->cid.cid_rdnis = strdup(chan->cid.cid_rdnis);
+ /* XXX don't we free previous values ? */
+ tmp->chan->cid.cid_rdnis = ast_strdup(chan->cid.cid_rdnis);
/* Pass callingpres setting */
tmp->chan->cid.cid_pres = chan->cid.cid_pres;
/* Pass type of number */
@@ -1141,7 +1113,6 @@
ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
ast_hangup(tmp->chan);
tmp->chan = NULL;
- cur = rest;
continue;
} else {
senddialevent(chan, tmp->chan);
@@ -1159,19 +1130,21 @@
/* If this line is up, don't try anybody else */
if (outgoing->chan->_state == AST_STATE_UP)
break;
- cur = rest;
- } while (cur);
+ }
- if (!ast_strlen_zero(args.timeout)) {
+ if (ast_strlen_zero(args.timeout)) {
+ to = -1;
+ } else {
to = atoi(args.timeout);
if (to > 0)
to *= 1000;
else
ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
- } else
- to = -1;
-
- if (outgoing) {
+ }
+
+ if (!outgoing) {
+ strcpy(status, "CHANUNAVAIL");
+ } else {
/* Our status will at least be NOANSWER */
strcpy(status, "NOANSWER");
if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
@@ -1181,8 +1154,7 @@
ast_indicate(chan, AST_CONTROL_RINGING);
sentringing++;
}
- } else
- strcpy(status, "CHANUNAVAIL");
+ }
time(&start_time);
peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
@@ -1190,17 +1162,16 @@
if (!peer) {
if (result) {
res = result;
- } else if (to)
- /* Musta gotten hung up */
+ } else if (to) { /* Musta gotten hung up */
res = -1;
- else
- /* Nobody answered, next please? */
+ } else { /* Nobody answered, next please? */
res = 0;
-
- goto out;
- }
- if (peer) {
- time(&answer_time);
+ }
+ /* almost done, although the 'else' block is 400 lines */
+ } else {
+ const char *number;
+ time_t end_time, answer_time = time(NULL);
+
strcpy(status, "ANSWER");
/* Ah ha! Someone answered within the desired timeframe. Of course after this
[... 4453 lines stripped ...]
More information about the asterisk-commits
mailing list