[asterisk-commits] rmudgett: branch 10 r348465 - in /branches/10: ./ main/channel.c main/features.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Dec 16 17:56:54 CST 2011
Author: rmudgett
Date: Fri Dec 16 17:56:50 2011
New Revision: 348465
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=348465
Log:
Clean-up on isle five for __ast_request_and_dial() and ast_call_forward().
* Add locking when a channel inherits variables and datastores in
__ast_request_and_dial() and ast_call_forward(). Note: The involved
channels are not active so there was minimal potential for problems.
* Remove calls to ast_set_callerid() in __ast_request_and_dial() and
ast_call_forward() because the set information is for the wrong direction.
* Don't use C++ keywords for variable names in ast_call_forward().
* Run the redirecting interception macro if defined when forwarding a call
in ast_call_forward(). Note: Currently will never execute because the
only callers that supply a calling channel supply a hungup or zombie
channel.
* Make feature_request_and_dial() put the transferee into autoservice when
it calls ast_call_forward() in case a redirection interception macro is
run. Note: Currently will never happen because the caller channel (Party
B) is always hungup at this time.
* Make feature_request_and_dial() ignore the AST_CONTROL_PROCEEDING frame
to silence a log message.
........
Merged revisions 348464 from http://svn.asterisk.org/svn/asterisk/branches/1.8
Modified:
branches/10/ (props changed)
branches/10/main/channel.c
branches/10/main/features.c
Propchange: branches/10/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.
Modified: branches/10/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/main/channel.c?view=diff&rev=348465&r1=348464&r2=348465
==============================================================================
--- branches/10/main/channel.c (original)
+++ branches/10/main/channel.c Fri Dec 16 17:56:50 2011
@@ -5389,11 +5389,47 @@
}
}
+/*!
+ * \internal
+ * \brief Helper function to inherit info from parent channel.
+ *
+ * \param new_chan Channel inheriting information.
+ * \param parent Channel new_chan inherits information.
+ * \param orig Channel being replaced by the call forward channel.
+ *
+ * \return Nothing
+ */
+static void call_forward_inherit(struct ast_channel *new_chan, struct ast_channel *parent, struct ast_channel *orig)
+{
+ if (!ast_test_flag(parent, AST_FLAG_ZOMBIE) && !ast_check_hangup(parent)) {
+ struct ast_party_redirecting redirecting;
+
+ /*
+ * The parent is not a ZOMBIE or hungup so update it with the
+ * original channel's redirecting information.
+ */
+ ast_party_redirecting_init(&redirecting);
+ ast_channel_lock(orig);
+ ast_party_redirecting_copy(&redirecting, &orig->redirecting);
+ ast_channel_unlock(orig);
+ if (ast_channel_redirecting_macro(orig, parent, &redirecting, 1, 0)) {
+ ast_channel_update_redirecting(parent, &redirecting, NULL);
+ }
+ ast_party_redirecting_free(&redirecting);
+ }
+
+ /* Safely inherit variables and datastores from the parent channel. */
+ ast_channel_lock_both(parent, new_chan);
+ ast_channel_inherit_variables(parent, new_chan);
+ ast_channel_datastore_inherit(parent, new_chan);
+ ast_channel_unlock(new_chan);
+ ast_channel_unlock(parent);
+}
+
struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_channel *orig, int *timeout, struct ast_format_cap *cap, struct outgoing_helper *oh, int *outstate)
{
char tmpchan[256];
- struct ast_channel *new = NULL;
- struct ast_party_redirecting *apr = &orig->redirecting;
+ struct ast_channel *new_chan = NULL;
char *data, *type;
int cause = 0;
int res;
@@ -5412,64 +5448,52 @@
data = tmpchan;
type = "Local";
}
- if (!(new = ast_request(type, cap, orig, data, &cause))) {
+ if (!(new_chan = ast_request(type, cap, orig, data, &cause))) {
ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
handle_cause(cause, outstate);
ast_hangup(orig);
return NULL;
}
- ast_channel_set_redirecting(new, apr, NULL);
-
/* Copy/inherit important information into new channel */
if (oh) {
if (oh->vars) {
- ast_set_variables(new, oh->vars);
- }
- if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
- ast_set_callerid(new, oh->cid_num, oh->cid_name, oh->cid_num);
+ ast_set_variables(new_chan, oh->vars);
}
if (oh->parent_channel) {
- ast_channel_update_redirecting(oh->parent_channel, apr, NULL);
- ast_channel_inherit_variables(oh->parent_channel, new);
- ast_channel_datastore_inherit(oh->parent_channel, new);
+ call_forward_inherit(new_chan, oh->parent_channel, orig);
}
if (oh->account) {
- ast_channel_lock(new);
- ast_cdr_setaccount(new, oh->account);
- ast_channel_unlock(new);
+ ast_channel_lock(new_chan);
+ ast_cdr_setaccount(new_chan, oh->account);
+ ast_channel_unlock(new_chan);
}
} else if (caller) { /* no outgoing helper so use caller if avaliable */
- ast_channel_update_redirecting(caller, apr, NULL);
- ast_channel_inherit_variables(caller, new);
- ast_channel_datastore_inherit(caller, new);
- }
-
- ast_channel_lock(orig);
- while (ast_channel_trylock(new)) {
- CHANNEL_DEADLOCK_AVOIDANCE(orig);
- }
- ast_copy_flags(new->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED);
- ast_string_field_set(new, accountcode, orig->accountcode);
- ast_party_caller_copy(&new->caller, &orig->caller);
- ast_party_connected_line_copy(&new->connected, &orig->connected);
- ast_channel_unlock(new);
+ call_forward_inherit(new_chan, caller, orig);
+ }
+
+ ast_channel_lock_both(orig, new_chan);
+ ast_copy_flags(new_chan->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED);
+ ast_string_field_set(new_chan, accountcode, orig->accountcode);
+ ast_party_connected_line_copy(&new_chan->connected, &orig->connected);
+ ast_party_redirecting_copy(&new_chan->redirecting, &orig->redirecting);
+ ast_channel_unlock(new_chan);
ast_channel_unlock(orig);
/* call new channel */
- res = ast_call(new, data, 0);
+ res = ast_call(new_chan, data, 0);
if (timeout) {
*timeout = res;
}
if (res) {
ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data);
ast_hangup(orig);
- ast_hangup(new);
+ ast_hangup(new_chan);
return NULL;
}
ast_hangup(orig);
- return new;
+ return new_chan;
}
struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
@@ -5494,14 +5518,24 @@
}
if (oh) {
- if (oh->vars)
+ if (oh->vars) {
ast_set_variables(chan, oh->vars);
- /* XXX why is this necessary, for the parent_channel perhaps ? */
- if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
- ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
+ }
+ if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
+ /*
+ * Use the oh values instead of the function parameters for the
+ * outgoing CallerID.
+ */
+ cid_num = oh->cid_num;
+ cid_name = oh->cid_name;
+ }
if (oh->parent_channel) {
+ /* Safely inherit variables and datastores from the parent channel. */
+ ast_channel_lock_both(oh->parent_channel, chan);
ast_channel_inherit_variables(oh->parent_channel, chan);
ast_channel_datastore_inherit(oh->parent_channel, chan);
+ ast_channel_unlock(oh->parent_channel);
+ ast_channel_unlock(chan);
}
if (oh->account) {
ast_channel_lock(chan);
@@ -5510,7 +5544,6 @@
}
}
- ast_set_callerid(chan, cid_num, cid_name, cid_num);
ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
ast_party_connected_line_set_init(&connected, &chan->connected);
if (cid_num) {
Modified: branches/10/main/features.c
URL: http://svnview.digium.com/svn/asterisk/branches/10/main/features.c?view=diff&rev=348465&r1=348464&r2=348465
==============================================================================
--- branches/10/main/features.c (original)
+++ branches/10/main/features.c Fri Dec 16 17:56:50 2011
@@ -3538,7 +3538,9 @@
} else if (chan == active_channel) {
if (!ast_strlen_zero(chan->call_forward)) {
state = 0;
+ ast_autoservice_start(transferee);
chan = ast_call_forward(caller, chan, NULL, tmp_cap, NULL, &state);
+ ast_autoservice_stop(transferee);
if (!chan) {
break;
}
@@ -3613,7 +3615,9 @@
}
ast_autoservice_stop(transferee);
}
- } else if (f->subclass.integer != -1 && f->subclass.integer != AST_CONTROL_PROGRESS) {
+ } else if (f->subclass.integer != -1
+ && f->subclass.integer != AST_CONTROL_PROGRESS
+ && f->subclass.integer != AST_CONTROL_PROCEEDING) {
ast_log(LOG_NOTICE, "Don't know what to do about control frame: %d\n", f->subclass.integer);
}
/* else who cares */
More information about the asterisk-commits
mailing list