diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/features.c | 48 | ||||
-rw-r--r-- | main/manager.c | 15 | ||||
-rw-r--r-- | main/pbx.c | 3 |
3 files changed, 52 insertions, 14 deletions
diff --git a/main/features.c b/main/features.c index 3d94fb82c..056692671 100644 --- a/main/features.c +++ b/main/features.c @@ -975,16 +975,24 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", transferee->name); pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", transferer->name); res=finishup(transferee); - if (!transferer->cdr) { + if (!transferer->cdr) { /* this code should never get called (in a perfect world) */ transferer->cdr=ast_cdr_alloc(); - if (transferer) { + if (transferer->cdr) { ast_cdr_init(transferer->cdr, transferer); /* initilize our channel's cdr */ ast_cdr_start(transferer->cdr); } } if (transferer->cdr) { - ast_cdr_setdestchan(transferer->cdr, transferee->name); - ast_cdr_setapp(transferer->cdr, "BLINDTRANSFER",""); + struct ast_cdr *swap = transferer->cdr; + ast_log(LOG_DEBUG,"transferer=%s; transferee=%s; lastapp=%s; lastdata=%s; chan=%s; dstchan=%s\n", + transferer->name, transferee->name, transferer->cdr->lastapp, transferer->cdr->lastdata, + transferer->cdr->channel, transferer->cdr->dstchannel); + ast_log(LOG_DEBUG,"TRANSFEREE; lastapp=%s; lastdata=%s, chan=%s; dstchan=%s\n", + transferee->cdr->lastapp, transferee->cdr->lastdata, transferee->cdr->channel, transferee->cdr->dstchannel); + ast_log(LOG_DEBUG,"transferer_real_context=%s; xferto=%s\n", transferer_real_context, xferto); + /* swap cdrs-- it will save us some time & work */ + transferer->cdr = transferee->cdr; + transferee->cdr = swap; } if (!transferee->pbx) { /* Doh! Use our handy async_goto functions */ @@ -994,6 +1002,8 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p ast_log(LOG_WARNING, "Async goto failed :-(\n"); } else { /* Set the channel's new extension, since it exists, using transferer context */ + ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ + ast_log(LOG_DEBUG,"ABOUT TO AST_ASYNC_GOTO, have a pbx... set HANGUP_DONT on chan=%s\n", transferee->name); set_c_e_p(transferee, transferer_real_context, xferto, 0); } check_goto_on_transfer(transferer); @@ -2046,9 +2056,11 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast ast_cdr_answer(bridge_cdr); ast_cdr_answer(chan_cdr); /* for the sake of cli status checks */ } - ast_set_flag(chan_cdr, AST_CDR_FLAG_BRIDGED); - if (peer_cdr) { - ast_set_flag(peer_cdr, AST_CDR_FLAG_BRIDGED); + if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT)) { + ast_set_flag(chan_cdr, AST_CDR_FLAG_BRIDGED); + if (peer_cdr) { + ast_set_flag(peer_cdr, AST_CDR_FLAG_BRIDGED); + } } } for (;;) { @@ -2213,13 +2225,22 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast } before_you_go: + + if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT)) { + ast_clear_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT); /* its job is done */ + if (bridge_cdr) { + ast_cdr_discard(bridge_cdr); + /* QUESTION: should we copy bridge_cdr fields to the peer before we throw it away? */ + } + return res; /* if we shouldn't do the h-exten, we shouldn't do the bridge cdr, either! */ + } + if (config->end_bridge_callback) { config->end_bridge_callback(config->end_bridge_callback_data); } - autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP); - ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP); - if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) && ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) { + if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) && + ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) { struct ast_cdr *swapper = NULL; char savelastapp[AST_MAX_EXTENSION]; char savelastdata[AST_MAX_EXTENSION]; @@ -2228,6 +2249,8 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast int found = 0; /* set if we find at least one match */ int spawn_error = 0; + autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP); + ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP); if (bridge_cdr && ast_opt_end_cdr_before_h_exten) { ast_cdr_end(bridge_cdr); } @@ -2266,9 +2289,9 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast ast_copy_string(bridge_cdr->lastapp, savelastapp, sizeof(bridge_cdr->lastapp)); ast_copy_string(bridge_cdr->lastdata, savelastdata, sizeof(bridge_cdr->lastdata)); } + ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP); } - ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP); - + /* obey the NoCDR() wishes. -- move the DISABLED flag to the bridge CDR if it was set on the channel during the bridge... */ new_chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */ if (bridge_cdr && new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED)) @@ -2357,6 +2380,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast ast_cdr_specialized_reset(peer_cdr,0); /* nothing changed, reset the peer_cdr */ } } + return res; } diff --git a/main/manager.c b/main/manager.c index ad3fd1977..d1b34629e 100644 --- a/main/manager.c +++ b/main/manager.c @@ -1922,13 +1922,24 @@ static int action_redirect(struct mansession *s, const struct message *m) ast_channel_unlock(chan2); return 0; } + if (chan->pbx) { + ast_channel_lock(chan); + ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ + ast_channel_unlock(chan); + } res = ast_async_goto(chan, context, exten, pi); if (!res) { if (!ast_strlen_zero(name2)) { - if (chan2) + if (chan2) { + if (chan2->pbx) { + ast_channel_lock(chan2); + ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ + ast_channel_unlock(chan2); + } res = ast_async_goto(chan2, context, exten, pi); - else + } else { res = -1; + } if (!res) astman_send_ack(s, m, "Dual Redirect successful"); else diff --git a/main/pbx.c b/main/pbx.c index eb9cf7ee3..b2b3dba17 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -3844,6 +3844,9 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c, !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) { set_ext_pri(c, "h", 1); + if (c->cdr && ast_opt_end_cdr_before_h_exten) { + ast_cdr_end(c->cdr); + } while ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found, 1)) == 0) { c->priority++; } |