[asterisk-commits] rmudgett: branch 1.8 r359344 - in /branches/1.8: apps/app_dial.c main/channel.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Mar 14 12:17:09 CDT 2012
Author: rmudgett
Date: Wed Mar 14 12:17:03 2012
New Revision: 359344
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=359344
Log:
Fix Dial m and r options and forked calls generating warnings for voice frames.
When connected line support was added, the wait_for_answer() variable
single changed its meaning slightly. Unfortunately, the places where
single was used did not necessarily get updated to reflect that change.
Also audio/video frames were sent to all forked calls when the endpoints
were never made compatible.
* Don't pass audio/video media frames when the channels have not been made
compatible.
* Added handling of AST_CONTROL_SRCCHANGE to app_dial.c.
* Fixed app_dial.c passing on AST_CONTROL_HOLD because that frame can also
pass a requested MOH class.
(closes issue ASTERISK-16901)
Reported by: Chris Gentle
(closes issue ASTERISK-17541)
Reported by: clint
Review: https://reviewboard.asterisk.org/r/1805/
Modified:
branches/1.8/apps/app_dial.c
branches/1.8/main/channel.c
Modified: branches/1.8/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/apps/app_dial.c?view=diff&rev=359344&r1=359343&r2=359344
==============================================================================
--- branches/1.8/apps/app_dial.c (original)
+++ branches/1.8/apps/app_dial.c Wed Mar 14 12:17:03 2012
@@ -823,13 +823,21 @@
/*!
* helper function for wait_for_answer()
*
+ * \param o Outgoing call channel list.
+ * \param num Incoming call channel cause accumulation
+ * \param peerflags Dial option flags
+ * \param single_caller_bored From wait_for_answer: single && !caller_entertained
+ * \param to Remaining call timeout time.
+ * \param forced_clid OPT_FORCECLID caller id to send
+ * \param stored_clid Caller id representing the called party if needed
+ *
* XXX this code is highly suspicious, as it essentially overwrites
* the outgoing channel without properly deleting it.
*
- * \todo eventually this function should be intergrated into and replaced by ast_call_forward()
+ * \todo eventually this function should be intergrated into and replaced by ast_call_forward()
*/
static void do_forward(struct chanlist *o,
- struct cause_args *num, struct ast_flags64 *peerflags, int single, int *to,
+ struct cause_args *num, struct ast_flags64 *peerflags, int single_caller_bored, int *to,
struct ast_party_id *forced_clid, struct ast_party_id *stored_clid)
{
char tmpchan[256];
@@ -871,8 +879,9 @@
/* Setup parameters */
c = o->chan = ast_request(tech, in->nativeformats, in, stuff, &cause);
if (c) {
- if (single)
+ if (single_caller_bored) {
ast_channel_make_compatible(o->chan, in);
+ }
ast_channel_inherit_variables(in, o->chan);
ast_channel_datastore_inherit(in, o->chan);
/* When a call is forwarded, we don't want to track new interfaces
@@ -893,7 +902,7 @@
} else {
struct ast_party_redirecting redirecting;
- if (single && CAN_EARLY_BRIDGE(peerflags, c, in)) {
+ if (single_caller_bored && CAN_EARLY_BRIDGE(peerflags, c, in)) {
ast_rtp_instance_early_bridge_make_compatible(c, in);
}
@@ -986,7 +995,7 @@
/* Hangup the original channel now, in case we needed it */
ast_hangup(original);
}
- if (single) {
+ if (single_caller_bored) {
ast_indicate(in, -1);
}
}
@@ -1015,6 +1024,8 @@
struct ast_channel *peer = NULL;
/* single is set if only one destination is enabled */
int single = outgoing && !outgoing->next;
+ int caller_entertained = outgoing
+ && ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
#ifdef HAVE_EPOLL
struct chanlist *epollo;
#endif
@@ -1028,7 +1039,7 @@
ast_party_connected_line_init(&connected_caller);
if (single) {
/* Turn off hold music, etc */
- if (!ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK)) {
+ if (!caller_entertained) {
ast_deactivate_generator(in);
/* If we are calling a single channel, and not providing ringback or music, */
/* then, make them compatible for in-band tone purpose */
@@ -1152,7 +1163,8 @@
}
ast_frfree(f);
}
- do_forward(o, &num, peerflags, single, to, forced_clid, stored_clid);
+ do_forward(o, &num, peerflags, single && !caller_entertained, to,
+ forced_clid, stored_clid);
continue;
}
f = ast_read(winner);
@@ -1167,7 +1179,8 @@
handle_cause(in->hangupcause, &num);
continue;
}
- if (f->frametype == AST_FRAME_CONTROL) {
+ switch (f->frametype) {
+ case AST_FRAME_CONTROL:
switch (f->subclass.integer) {
case AST_CONTROL_ANSWER:
/* This is our guy if someone answered. */
@@ -1263,8 +1276,10 @@
if (ignore_cc || cc_frame_received || num_ringing == numlines) {
ast_verb(3, "%s is ringing\n", c->name);
/* Setup early media if appropriate */
- if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
+ if (single && !caller_entertained
+ && CAN_EARLY_BRIDGE(peerflags, in, c)) {
ast_channel_early_bridge(in, c);
+ }
if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK) && ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
ast_indicate(in, AST_CONTROL_RINGING);
pa->sentringing++;
@@ -1274,8 +1289,10 @@
case AST_CONTROL_PROGRESS:
ast_verb(3, "%s is making progress passing it to %s\n", c->name, in->name);
/* Setup early media if appropriate */
- if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
+ if (single && !caller_entertained
+ && CAN_EARLY_BRIDGE(peerflags, in, c)) {
ast_channel_early_bridge(in, c);
+ }
if (!ast_test_flag64(outgoing, OPT_RINGBACK)) {
if (single || (!single && !pa->sentringing)) {
ast_indicate(in, AST_CONTROL_PROGRESS);
@@ -1289,12 +1306,14 @@
}
break;
case AST_CONTROL_VIDUPDATE:
- ast_verb(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_SRCUPDATE:
- ast_verb(3, "%s requested a source update, passing it to %s\n", c->name, in->name);
- ast_indicate(in, AST_CONTROL_SRCUPDATE);
+ case AST_CONTROL_SRCCHANGE:
+ if (!single || caller_entertained) {
+ break;
+ }
+ ast_verb(3, "%s requested media update control %d, passing it to %s\n",
+ c->name, f->subclass.integer, in->name);
+ ast_indicate(in, f->subclass.integer);
break;
case AST_CONTROL_CONNECTED_LINE:
if (ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
@@ -1337,16 +1356,20 @@
break;
case AST_CONTROL_PROCEEDING:
ast_verb(3, "%s is proceeding passing it to %s\n", c->name, in->name);
- if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
+ if (single && !caller_entertained
+ && CAN_EARLY_BRIDGE(peerflags, in, c)) {
ast_channel_early_bridge(in, c);
+ }
if (!ast_test_flag64(outgoing, OPT_RINGBACK))
ast_indicate(in, AST_CONTROL_PROCEEDING);
break;
case AST_CONTROL_HOLD:
+ /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
ast_verb(3, "Call on %s placed on hold\n", c->name);
- ast_indicate(in, AST_CONTROL_HOLD);
+ ast_indicate_data(in, AST_CONTROL_HOLD, f->data.ptr, f->datalen);
break;
case AST_CONTROL_UNHOLD:
+ /* XXX this should be saved like AST_CONTROL_CONNECTED_LINE for !single || caller_entertained */
ast_verb(3, "Call on %s left from hold\n", c->name);
ast_indicate(in, AST_CONTROL_UNHOLD);
break;
@@ -1361,7 +1384,7 @@
}
break;
case -1:
- if (!ast_test_flag64(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
+ if (single && !caller_entertained) {
ast_verb(3, "%s stopped sounds\n", c->name);
ast_indicate(in, -1);
pa->sentringing = 0;
@@ -1369,26 +1392,29 @@
break;
default:
ast_debug(1, "Dunno what to do with control type %d\n", f->subclass.integer);
- }
- } else if (single) {
- switch (f->frametype) {
- case AST_FRAME_VOICE:
- case AST_FRAME_IMAGE:
- case AST_FRAME_TEXT:
- if (!ast_test_flag64(outgoing, OPT_RINGBACK | OPT_MUSICBACK) && ast_write(in, f)) {
- ast_log(LOG_WARNING, "Unable to write frametype: %d\n",
- f->frametype);
- }
- break;
- case AST_FRAME_HTML:
- if (!ast_test_flag64(outgoing, DIAL_NOFORWARDHTML)
- && ast_channel_sendhtml(in, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
- ast_log(LOG_WARNING, "Unable to send URL\n");
- }
- break;
- default:
break;
}
+ break;
+ case AST_FRAME_VOICE:
+ case AST_FRAME_IMAGE:
+ if (caller_entertained) {
+ break;
+ }
+ /* Fall through */
+ case AST_FRAME_TEXT:
+ if (single && ast_write(in, f)) {
+ ast_log(LOG_WARNING, "Unable to write frametype: %d\n",
+ f->frametype);
+ }
+ break;
+ case AST_FRAME_HTML:
+ if (single && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML)
+ && ast_channel_sendhtml(in, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
+ ast_log(LOG_WARNING, "Unable to send URL\n");
+ }
+ break;
+ default:
+ break;
}
ast_frfree(f);
} /* end for */
@@ -1469,6 +1495,15 @@
break;
case AST_FRAME_VOICE:
case AST_FRAME_IMAGE:
+ if (!single || caller_entertained) {
+ /*
+ * We are calling multiple parties or caller is being
+ * entertained and has thus not been made compatible.
+ * No need to check any other called parties.
+ */
+ goto skip_frame;
+ }
+ /* Fall through */
case AST_FRAME_TEXT:
case AST_FRAME_DTMF_BEGIN:
case AST_FRAME_DTMF_END:
@@ -1480,12 +1515,27 @@
case AST_FRAME_CONTROL:
switch (f->subclass.integer) {
case AST_CONTROL_HOLD:
+ ast_verb(3, "Call on %s placed on hold\n", o->chan->name);
+ ast_indicate_data(o->chan, AST_CONTROL_HOLD, f->data.ptr, f->datalen);
+ break;
case AST_CONTROL_UNHOLD:
+ ast_verb(3, "Call on %s left from hold\n", o->chan->name);
+ ast_indicate(o->chan, AST_CONTROL_UNHOLD);
+ break;
case AST_CONTROL_VIDUPDATE:
case AST_CONTROL_SRCUPDATE:
- ast_verb(3, "%s requested special control %d, passing it to %s\n",
+ case AST_CONTROL_SRCCHANGE:
+ if (!single || caller_entertained) {
+ /*
+ * We are calling multiple parties or caller is being
+ * entertained and has thus not been made compatible.
+ * No need to check any other called parties.
+ */
+ goto skip_frame;
+ }
+ ast_verb(3, "%s requested media update control %d, passing it to %s\n",
in->name, f->subclass.integer, o->chan->name);
- ast_indicate_data(o->chan, f->subclass.integer, f->data.ptr, f->datalen);
+ ast_indicate(o->chan, f->subclass.integer);
break;
case AST_CONTROL_CONNECTED_LINE:
if (ast_channel_connected_line_macro(in, o->chan, f, 0, 1)) {
@@ -1498,13 +1548,16 @@
}
break;
default:
- break;
+ /* We are not going to do anything with this frame. */
+ goto skip_frame;
}
break;
default:
- break;
+ /* We are not going to do anything with this frame. */
+ goto skip_frame;
}
}
+skip_frame:;
ast_frfree(f);
}
if (!*to)
Modified: branches/1.8/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/main/channel.c?view=diff&rev=359344&r1=359343&r2=359344
==============================================================================
--- branches/1.8/main/channel.c (original)
+++ branches/1.8/main/channel.c Wed Mar 14 12:17:03 2012
@@ -4914,14 +4914,18 @@
if (fr->subclass.codec == chan->rawwriteformat) {
f = fr;
} else {
- /* XXX Something is not right we are not compatible with this frame bad things can happen
- * problems range from no/one-way audio to unexplained line hangups as a last resort try adjust the format
- * ideally we do not want to do this and this indicates a deeper problem for now we log these events to
- * eliminate user impact and help identify the problem areas
- * JIRA issues related to this :-
- * ASTERISK-14384, ASTERISK-17502, ASTERISK-17541, ASTERISK-18063, ASTERISK-18325, ASTERISK-18422*/
if ((!(fr->subclass.codec & chan->nativeformats)) && (chan->writeformat != fr->subclass.codec)) {
char nf[512];
+
+ /*
+ * XXX Something is not right. We are not compatible with this
+ * frame. Bad things can happen. Problems range from no audio,
+ * one-way audio, to unexplained line hangups. As a last resort
+ * try to adjust the format. Ideally, we do not want to do this
+ * because it indicates a deeper problem. For now, we log these
+ * events to reduce user impact and help identify the problem
+ * areas.
+ */
ast_log(LOG_WARNING, "Codec mismatch on channel %s setting write format to %s from %s native formats %s\n",
chan->name, ast_getformatname(fr->subclass.codec), ast_getformatname(chan->writeformat),
ast_getformatname_multiple(nf, sizeof(nf), chan->nativeformats & AST_FORMAT_AUDIO_MASK));
More information about the asterisk-commits
mailing list