diff options
Diffstat (limited to 'main/features.c')
-rw-r--r-- | main/features.c | 94 |
1 files changed, 32 insertions, 62 deletions
diff --git a/main/features.c b/main/features.c index 184196b8f..e243e2c55 100644 --- a/main/features.c +++ b/main/features.c @@ -832,29 +832,22 @@ static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, int res = 0; set_peers(&parker, &parkee, peer, chan, sense); - /* Setup the exten/priority to be s/1 since we don't know - where this call should return */ - strcpy(chan->exten, "s"); - chan->priority = 1; + /* we used to set chan's exten and priority to "s" and 1 + here, but this generates (in some cases) an invalid + extension, and if "s" exists, could errantly + cause execution of extensions you don't expect. It + makes more sense to let nature take its course + when chan finishes, and let the pbx do its thing + and hang up when the park is over. + */ if (chan->_state != AST_STATE_UP) res = ast_answer(chan); if (!res) res = ast_safe_sleep(chan, 1000); - if (!res) { - if (sense == FEATURE_SENSE_CHAN) { - res = ast_park_call(parkee, parker, 0, NULL); - if (!res) { - if (sense == FEATURE_SENSE_CHAN) { - res = AST_PBX_NO_HANGUP_PEER_PARKED; - } else { - res = AST_PBX_KEEPALIVE; - } - } - } else if (sense == FEATURE_SENSE_PEER) { - masq_park_call_announce(parkee, parker, 0, NULL); - res = 0; /* PBX should hangup zombie channel */ - } + if (!res) { /* one direction used to call park_call.... */ + masq_park_call_announce(parkee, parker, 0, NULL); + res = 0; /* PBX should hangup zombie channel */ } return res; @@ -1191,12 +1184,12 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p res = finishup(transferee); if (res) res = -1; - else if (!ast_park_call(transferee, transferer, 0, NULL)) { /* success */ + else if (!masq_park_call_announce(transferee, transferer, 0, NULL)) { /* success */ /* We return non-zero, but tell the PBX not to hang the channel when the thread dies -- We have to be careful now though. We are responsible for hanging up the channel, else it will never be hung up! */ - return (transferer == peer) ? AST_PBX_KEEPALIVE : AST_PBX_NO_HANGUP_PEER_PARKED; + return 0; } else { ast_log(LOG_WARNING, "Unable to park call %s\n", transferee->name); } @@ -1747,7 +1740,7 @@ struct ast_call_feature *ast_find_call_feature(const char *name) * \param chan,peer,config,code,sense,data * * Find a feature, determine which channel activated - * \retval AST_FEATURE_RETURN_PBX_KEEPALIVE,AST_FEATURE_RETURN_NO_HANGUP_PEER + * \retval AST_FEATURE_RETURN_NO_HANGUP_PEER * \retval -1 error. * \retval -2 when an application cannot be found. */ @@ -1802,20 +1795,9 @@ static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, ast_autoservice_stop(idle); - if (res == AST_PBX_KEEPALIVE) { - /* do not hangup peer if feature is to be activated on it */ - if ((ast_test_flag(feature, AST_FEATURE_FLAG_ONPEER) && sense == FEATURE_SENSE_CHAN) || (ast_test_flag(feature, AST_FEATURE_FLAG_ONSELF) && sense == FEATURE_SENSE_PEER)) - return AST_FEATURE_RETURN_NO_HANGUP_PEER; - else - return AST_FEATURE_RETURN_PBX_KEEPALIVE; - } - else if (res == AST_PBX_NO_HANGUP_PEER) - return AST_FEATURE_RETURN_NO_HANGUP_PEER; - else if (res == AST_PBX_NO_HANGUP_PEER_PARKED) - return AST_FEATURE_RETURN_NO_HANGUP_PEER_PARKED; - else if (res) + if (res) { return AST_FEATURE_RETURN_SUCCESSBREAK; - + } return AST_FEATURE_RETURN_SUCCESS; /*! \todo XXX should probably return res */ } @@ -2472,7 +2454,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast } before_you_go: - if (res != AST_PBX_KEEPALIVE && config->end_bridge_callback) { + if (config->end_bridge_callback) { config->end_bridge_callback(config->end_bridge_callback_data); } @@ -2482,7 +2464,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast */ autoloopflag = ast_test_flag(chan, AST_FLAG_IN_AUTOLOOP); ast_set_flag(chan, AST_FLAG_IN_AUTOLOOP); - if (res != AST_PBX_KEEPALIVE && !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]; @@ -2533,11 +2515,9 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast 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... */ - if (res != AST_PBX_KEEPALIVE) { - 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)) - ast_set_flag(bridge_cdr, AST_CDR_FLAG_POST_DISABLED); - } + 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)) + ast_set_flag(bridge_cdr, AST_CDR_FLAG_POST_DISABLED); /* we can post the bridge CDR at this point */ if (bridge_cdr) { @@ -2567,23 +2547,9 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast 5. After a bridge occurs, we have 2 or 3 channels' CDRs to attend to; if the chan or peer changed names, we have the before and after attached CDR's. - 6. Parking has to be accounted for in the code: - a. Parking will cause ast_bridge_call to return - either AST_PBX_NO_HANGUP_PEER or AST_PBX_NO_HANGUP_PEER_PARKED; - in the latter case, peer is (most likely) a bad - pointer, you can no longer deref it. If it does still - exist, it is under another's thread control, and - could be destroyed at any time. - b. The same applies to AST_PBX_KEEPALIVE, in which - case, the chan ptr cannot be used, as another thread - owns it and may have destroyed the channel. - c. In the former case, you need to check peer to see if it - still exists before you deref it, and obtain a lock. - d. In neither case should you do an ast_hangup(peer). - e. Do not overwrite the result code from ast_bridge_call. */ - if (res != AST_PBX_KEEPALIVE && new_chan_cdr) { + if (new_chan_cdr) { struct ast_channel *chan_ptr = NULL; if (strcasecmp(orig_channame, chan->name) != 0) { @@ -2609,7 +2575,7 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast } } - if (res != AST_PBX_NO_HANGUP_PEER_PARKED) { /* if the peer was involved in a park, don't even touch it; it's probably gone */ + { struct ast_channel *chan_ptr = NULL; new_peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */ if (new_chan_cdr && ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED) && new_peer_cdr && !ast_test_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED)) @@ -2956,14 +2922,19 @@ static int park_call_exec(struct ast_channel *chan, void *data) ast_app_parse_options(park_call_options, &flags, NULL, app_args.options); args.flags = flags.flags; - res = ast_park_call_full(chan, chan, &args); + res = ast_park_call_full(chan, chan, &args); /* In experiments, using the masq_park_call + func here yielded no difference with + current implementation. I saw no advantage + in calling it instead. + */ /* Continue on in the dialplan */ if (res == 1) { ast_copy_string(chan->exten, orig_exten, sizeof(chan->exten)); chan->priority = orig_priority; res = 0; - } else if (!res) - res = AST_PBX_KEEPALIVE; + } else if (!res) { + res = 1; + } } return res; @@ -3088,8 +3059,7 @@ static int park_exec_full(struct ast_channel *chan, void *data, struct ast_parki ast_cdr_setdestchan(chan->cdr, peer->name); /* Simulate the PBX hanging up */ - if (res != AST_PBX_NO_HANGUP_PEER && res != AST_PBX_NO_HANGUP_PEER_PARKED) - ast_hangup(peer); + ast_hangup(peer); return res; } else { /*! \todo XXX Play a message XXX */ |