From 623d0656ccfab8f793c3a758c3d8451bfad14256 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Tue, 22 Oct 2013 00:13:53 +0000 Subject: [PATCH] chan_dahdi: Fix unable to get index warning when transferring an analog call. Transferring an analog call using flashhooks generated an unable to get index WARNING message when the transfer is completed. * Removed unnecessary analog subchannel shell games when transferring a call using flashhooks. Thanks to Tzafrir Cohen for mentioning this in a comment on issue ASTERISK-22720. git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@401378 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/sig_analog.c | 52 +++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/channels/sig_analog.c b/channels/sig_analog.c index 6d11a3d73e..4ef4bb9872 100644 --- a/channels/sig_analog.c +++ b/channels/sig_analog.c @@ -679,13 +679,11 @@ static int analog_is_dialing(struct analog_pvt *p, enum analog_sub index) * \param p Analog private structure. * \param inthreeway TRUE if the 3-way call is conferenced. * - * \note - * On entry these locks are held: real-call, private, 3-way call. + * \note On entry these locks are held: real-call, private, 3-way call. + * \note On exit these locks are held: real-call, private. * - * \retval 1 Transfer successful. 3-way call is unlocked and subchannel is unalloced. - * Swapped real and 3-way subchannel. - * \retval 0 Transfer successful. 3-way call is unlocked and subchannel is unalloced. - * \retval -1 on error. Caller must unlock 3-way call. + * \retval 0 on success. + * \retval -1 on error. */ static int analog_attempt_transfer(struct analog_pvt *p, int inthreeway) { @@ -693,6 +691,7 @@ static int analog_attempt_transfer(struct analog_pvt *p, int inthreeway) struct ast_channel *owner_3way; struct ast_channel *bridge_real; struct ast_channel *bridge_3way; + int ret = 0; owner_real = p->subs[ANALOG_SUB_REAL].owner; owner_3way = p->subs[ANALOG_SUB_THREEWAY].owner; @@ -720,15 +719,8 @@ static int analog_attempt_transfer(struct analog_pvt *p, int inthreeway) bridge_3way, &owner_3way->connected, !inthreeway)) { ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", bridge_3way->name, owner_real->name); - return -1; + ret = -1; } - - /* Three-way is now the REAL */ - analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL); - ast_channel_unlock(owner_3way); - analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); - /* Tell the caller not to hangup */ - return 1; } else if (bridge_real) { /* Try transferring the other way. */ ast_verb(3, "TRANSFERRING %s to %s\n", owner_real->name, owner_3way->name); @@ -746,18 +738,19 @@ static int analog_attempt_transfer(struct analog_pvt *p, int inthreeway) !inthreeway, bridge_real, &owner_real->connected, 0)) { ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", bridge_real->name, owner_3way->name); - return -1; + ret = -1; } - - /* Orphan the channel after releasing the lock */ - ast_channel_unlock(owner_3way); - analog_unalloc_sub(p, ANALOG_SUB_THREEWAY); - return 0; } else { ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n", owner_real->name, owner_3way->name); - return -1; + ret = -1; } + + if (ret) { + ast_softhangup_nolock(owner_3way, AST_SOFTHANGUP_DEV); + } + ast_channel_unlock(owner_3way); + return ret; } static int analog_update_conf(struct analog_pvt *p) @@ -2881,16 +2874,13 @@ static struct ast_frame *__analog_handle_event(struct analog_pvt *p, struct ast_ analog_set_new_owner(p, NULL); /* Ring the phone */ analog_ring(p); - } else { - res = analog_attempt_transfer(p, inthreeway); - if (res < 0) { - /* Transfer attempt failed. */ - ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV); - ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner); - } else if (res) { - /* Don't actually hang up at this point */ - break; - } + } else if (!analog_attempt_transfer(p, inthreeway)) { + /* + * Transfer successful. Don't actually hang up at this point. + * Let our channel legs of the calls die off as the transfer + * percolates through the core. + */ + break; } } else { ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);