--- manager.c 2004-05-18 16:28:54.000000000 -0400 +++ manager.c.merged 2004-05-18 17:09:24.000000000 -0400 @@ -445,6 +445,33 @@ return 0; } +static struct ast_channel *get_chan_by_name(char *name) { + struct ast_channel *chan; + + chan=ast_channel_walk(NULL); + while (chan) { + if (!strcasecmp(name, chan->name)) + break; + chan = ast_channel_walk(chan); + } + + // If the channel is not found, it's OK to return NULL. + + return chan; +} + +static void set_dual_xfer_flag(char *name, int value) { + struct ast_channel *chan; + + chan=get_chan_by_name(name); + if (chan) { + chan->used_by_dual_xfer=value; + } + + // If the channel is not found, that's OK. +} + + static int action_redirect(struct mansession *s, struct message *m) { char *name = astman_get_header(m, "Channel"); @@ -454,6 +481,20 @@ char *priority = astman_get_header(m, "Priority"); int pi = 0; int res; + int is_dual_redirect=0; + char scratch_name[256]; + struct ast_channel *scratch_chan; + + if ((strlen(name))&&(strlen(name2))) { + is_dual_redirect=1; + + // Mark these channels so they won't be hungup no matter what, + // until we're finished with them + + set_dual_xfer_flag(name,1); + set_dual_xfer_flag(name2,1); + } + if (!name || !strlen(name)) { astman_send_error(s, m, "Channel not specified"); return 0; @@ -474,6 +515,34 @@ astman_send_ack(s, m, "Redirect successful"); } else astman_send_error(s, m, "Redirect failed"); + + // Now clear the 'used_by_dual_xfer' flag from any channels that might have been involved here + // Some of these may not exist, which is OK. Some may have the same names as before but be in + // a different place in memory, so it's good that we look them up by name. + // Also send an actual hangup to any of the AsyncGoto channels still around + + if (is_dual_redirect) { + // put the original 2 channels back to normal + set_dual_xfer_flag(name,0); + set_dual_xfer_flag(name2,0); + + sprintf(scratch_name,"AsyncGoto/%s",name); + set_dual_xfer_flag(scratch_name,0); // eligible to be hung up + scratch_chan=get_chan_by_name(scratch_name); + + if (scratch_chan != NULL) { + ast_hangup(scratch_chan); // actually hang it up + } + + sprintf(scratch_name,"AsyncGoto/%s",name2); + set_dual_xfer_flag(scratch_name,0); // eligible to be hung up + scratch_chan=get_chan_by_name(scratch_name); + + if (scratch_chan != NULL) { + ast_hangup(scratch_chan); // actually hang it up + } + } // end dual redirect logic + return 0; }