aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/app_dial.c93
-rw-r--r--apps/app_queue.c13
-rw-r--r--include/asterisk/features.h17
-rw-r--r--include/asterisk/pbx.h13
-rw-r--r--main/features.c149
5 files changed, 164 insertions, 121 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c
index a3dba3c50..deaa82429 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -1,7 +1,7 @@
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) 1999 - 2006, Digium, Inc.
+ * Copyright (C) 1999 - 2008, Digium, Inc.
*
* Mark Spencer <markster@digium.com>
*
@@ -111,7 +111,8 @@ static char *descrip =
" DTMF string is sent to the called party, and the 'calling' DTMF\n"
" string is sent to the calling party. Both parameters can be used\n"
" alone.\n"
-" e - execute the 'h' extension for peer after the call ends\n"
+" e - execute the 'h' extension for peer after the call ends. This\n"
+" operation will not be performed if the peer was parked\n"
" f - Force the callerid of the *calling* channel to be set as the\n"
" extension associated with the channel using a dialplan 'hint'.\n"
" For example, some PSTNs do not allow CallerID to be set to anything\n"
@@ -1793,16 +1794,17 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
struct ast_app *theapp;
const char *gosub_result;
char *gosub_args, *gosub_argstart;
+ int res9 = -1;
- res = ast_autoservice_start(chan);
- if (res) {
+ res9 = ast_autoservice_start(chan);
+ if (res9) {
ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
- res = -1;
+ res9 = -1;
}
theapp = pbx_findapp("Gosub");
- if (theapp && !res) {
+ if (theapp && !res9) {
replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
/* Set where we came from */
@@ -1820,50 +1822,50 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
}
if (gosub_args) {
- res = pbx_exec(peer, theapp, gosub_args);
+ res9 = pbx_exec(peer, theapp, gosub_args);
ast_pbx_run(peer);
ast_free(gosub_args);
if (option_debug)
- ast_log(LOG_DEBUG, "Gosub exited with status %d\n", res);
+ ast_log(LOG_DEBUG, "Gosub exited with status %d\n", res9);
} else
ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
- res = 0;
- } else if (!res) {
+ res9 = 0;
+ } else if (!res9) {
ast_log(LOG_ERROR, "Could not find application Gosub\n");
- res = -1;
+ res9 = -1;
}
if (ast_autoservice_stop(chan) < 0) {
ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
- res = -1;
+ res9 = -1;
}
ast_channel_lock(peer);
- if (!res && (gosub_result = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
+ if (!res9 && (gosub_result = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
char *gosub_transfer_dest;
if (!strcasecmp(gosub_result, "BUSY")) {
ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
ast_set_flag64(peerflags, OPT_GO_ON);
- res = -1;
+ res9 = -1;
} else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
ast_set_flag64(peerflags, OPT_GO_ON);
- res = -1;
+ res9 = -1;
} else if (!strcasecmp(gosub_result, "CONTINUE")) {
/* hangup peer and keep chan alive assuming the macro has changed
the context / exten / priority or perhaps
the next priority in the current exten is desired.
*/
ast_set_flag64(peerflags, OPT_GO_ON);
- res = -1;
+ res9 = -1;
} else if (!strcasecmp(gosub_result, "ABORT")) {
/* Hangup both ends unless the caller has the g flag */
- res = -1;
+ res9 = -1;
} else if (!strncasecmp(gosub_result, "GOTO:", 5) && (gosub_transfer_dest = ast_strdupa(gosub_result + 5))) {
- res = -1;
+ res9 = -1;
/* perform a transfer to a new extension */
if (strchr(gosub_transfer_dest, '^')) { /* context^exten^priority*/
replace_macro_delimiter(gosub_transfer_dest);
@@ -1952,32 +1954,34 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
- if (ast_test_flag64(&opts, OPT_PEER_H)) {
+ if (res != AST_PBX_NO_HANGUP_PEER_PARKED && ast_test_flag64(&opts, OPT_PEER_H)) {
ast_log(LOG_NOTICE, "PEER context: %s; PEER exten: %s; PEER priority: %d\n",
peer->context, peer->exten, peer->priority);
}
+ if (res != AST_PBX_NO_HANGUP_PEER_PARKED)
+ strcpy(peer->context, chan->context);
- strcpy(peer->context, chan->context);
-
- if (ast_test_flag64(&opts, OPT_PEER_H) && ast_exists_extension(peer, peer->context, "h", 1, peer->cid.cid_num)) {
+ if (res != AST_PBX_NO_HANGUP_PEER_PARKED && ast_test_flag64(&opts, OPT_PEER_H) && ast_exists_extension(peer, peer->context, "h", 1, peer->cid.cid_num)) {
int autoloopflag;
int found;
+ int res9;
+
strcpy(peer->exten, "h");
peer->priority = 1;
autoloopflag = ast_test_flag(peer, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
ast_set_flag(peer, AST_FLAG_IN_AUTOLOOP);
- while ((res = ast_spawn_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num, &found, 1)) == 0)
+ while ((res9 = ast_spawn_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num, &found, 1)) == 0)
peer->priority++;
- if (found && res) {
+ if (found && res9) {
/* Something bad happened, or a hangup has been requested. */
ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
}
ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP); /* set it back the way it was */
}
- if (res != AST_PBX_NO_HANGUP_PEER) {
+ if (res != AST_PBX_NO_HANGUP_PEER && res != AST_PBX_NO_HANGUP_PEER_PARKED) {
if (!ast_check_hangup(peer) && ast_test_flag64(&opts, OPT_CALLEE_GO_ON) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GO_ON])) {
replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GO_ON]);
ast_parseable_goto(peer, opt_args[OPT_ARG_CALLEE_GO_ON]);
@@ -1990,23 +1994,28 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
}
}
out:
- if (moh) {
- moh = 0;
- ast_moh_stop(chan);
- } else if (sentringing) {
- sentringing = 0;
- ast_indicate(chan, -1);
- }
- ast_channel_early_bridge(chan, NULL);
- hanguptree(outgoing, NULL, 0); /* In this case, there's no answer anywhere */
- pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
- senddialendevent(chan, pa.status);
- ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
-
- if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_KEEPALIVE) && (res != AST_PBX_INCOMPLETE)) {
- if (calldurationlimit)
- memset(&chan->whentohangup, 0, sizeof(chan->whentohangup));
- res = 0;
+ /* cleaning up chan is not a good idea here if AST_PBX_KEEPALIVE
+ is returned; chan will get the love it needs from another
+ thread */
+ if (res != AST_PBX_KEEPALIVE) {
+ if (moh) {
+ moh = 0;
+ ast_moh_stop(chan);
+ } else if (sentringing) {
+ sentringing = 0;
+ ast_indicate(chan, -1);
+ }
+ ast_channel_early_bridge(chan, NULL);
+ hanguptree(outgoing, NULL, 0); /* In this case, there's no answer anywhere */
+ pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
+ senddialendevent(chan, pa.status);
+ ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
+
+ if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_KEEPALIVE) && (res != AST_PBX_INCOMPLETE)) {
+ if (calldurationlimit)
+ memset(&chan->whentohangup, 0, sizeof(chan->whentohangup));
+ res = 0;
+ }
}
done:
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 030dab001..d9df46fb8 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -3757,21 +3757,24 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
/* If the queue member did an attended transfer, then the TRANSFER already was logged in the queue_log
* when the masquerade occurred. These other "ending" queue_log messages are unnecessary
*/
- if (!attended_transfer_occurred(qe->chan)) {
+ if (bridge != AST_PBX_KEEPALIVE && !attended_transfer_occurred(qe->chan)) {
struct ast_datastore *transfer_ds;
if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) {
ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "TRANSFER", "%s|%s|%ld|%ld|%d",
qe->chan->exten, qe->chan->context, (long) (callstart - qe->start),
(long) (time(NULL) - callstart), qe->opos);
- send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), TRANSFER);
+ if (bridge != AST_PBX_NO_HANGUP_PEER && bridge != AST_PBX_NO_HANGUP_PEER_PARKED)
+ send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), TRANSFER);
} else if (ast_check_hangup(qe->chan)) {
ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "COMPLETECALLER", "%ld|%ld|%d",
(long) (callstart - qe->start), (long) (time(NULL) - callstart), qe->opos);
- send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), CALLER);
+ if (bridge != AST_PBX_NO_HANGUP_PEER && bridge != AST_PBX_NO_HANGUP_PEER_PARKED)
+ send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), CALLER);
} else {
ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "COMPLETEAGENT", "%ld|%ld|%d",
(long) (callstart - qe->start), (long) (time(NULL) - callstart), qe->opos);
- send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), AGENT);
+ if (bridge != AST_PBX_NO_HANGUP_PEER && bridge != AST_PBX_NO_HANGUP_PEER_PARKED)
+ send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), AGENT);
}
ast_channel_lock(qe->chan);
transfer_ds = ast_channel_datastore_find(qe->chan, &queue_transfer_info, NULL);
@@ -3783,7 +3786,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
update_queue(qe->parent, member, callcompletedinsl);
}
- if (bridge != AST_PBX_NO_HANGUP_PEER)
+ if (bridge != AST_PBX_NO_HANGUP_PEER && bridge != AST_PBX_NO_HANGUP_PEER_PARKED)
ast_hangup(peer);
res = bridge ? bridge : 1;
ao2_ref(member, -1);
diff --git a/include/asterisk/features.h b/include/asterisk/features.h
index 723373f94..20b26c3a8 100644
--- a/include/asterisk/features.h
+++ b/include/asterisk/features.h
@@ -61,14 +61,15 @@ struct ast_call_feature {
};
-#define AST_FEATURE_RETURN_HANGUP -1
-#define AST_FEATURE_RETURN_SUCCESSBREAK 0
-#define AST_FEATURE_RETURN_PBX_KEEPALIVE AST_PBX_KEEPALIVE
-#define AST_FEATURE_RETURN_NO_HANGUP_PEER AST_PBX_NO_HANGUP_PEER
-#define AST_FEATURE_RETURN_PASSDIGITS 21
-#define AST_FEATURE_RETURN_STOREDIGITS 22
-#define AST_FEATURE_RETURN_SUCCESS 23
-#define AST_FEATURE_RETURN_KEEPTRYING 24
+#define AST_FEATURE_RETURN_HANGUP -1
+#define AST_FEATURE_RETURN_SUCCESSBREAK 0
+#define AST_FEATURE_RETURN_PBX_KEEPALIVE AST_PBX_KEEPALIVE
+#define AST_FEATURE_RETURN_NO_HANGUP_PEER AST_PBX_NO_HANGUP_PEER
+#define AST_FEATURE_RETURN_NO_HANGUP_PEER_PARKED AST_PBX_NO_HANGUP_PEER_PARKED
+#define AST_FEATURE_RETURN_PASSDIGITS 21
+#define AST_FEATURE_RETURN_STOREDIGITS 22
+#define AST_FEATURE_RETURN_SUCCESS 23
+#define AST_FEATURE_RETURN_KEEPTRYING 24
/*!
diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h
index b4bec238e..d2d95acca 100644
--- a/include/asterisk/pbx.h
+++ b/include/asterisk/pbx.h
@@ -37,12 +37,13 @@ extern "C" {
#define AST_PBX_REPLACE 1
/*! \brief Special return values from applications to the PBX { */
-#define AST_PBX_HANGUP -1 /*!< Jump to the 'h' exten */
-#define AST_PBX_OK 0 /*!< No errors */
-#define AST_PBX_ERROR 1 /*!< Jump to the 'e' exten */
-#define AST_PBX_KEEPALIVE 10 /*!< Destroy the thread, but don't hang up the channel */
-#define AST_PBX_NO_HANGUP_PEER 11
-#define AST_PBX_INCOMPLETE 12 /*!< Return to PBX matching, allowing more digits for the extension */
+#define AST_PBX_HANGUP -1 /*!< Jump to the 'h' exten */
+#define AST_PBX_OK 0 /*!< No errors */
+#define AST_PBX_ERROR 1 /*!< Jump to the 'e' exten */
+#define AST_PBX_KEEPALIVE 10 /*!< Destroy the thread, but don't hang up the channel */
+#define AST_PBX_NO_HANGUP_PEER 11 /*!< The peer has been involved in a transfer */
+#define AST_PBX_INCOMPLETE 12 /*!< Return to PBX matching, allowing more digits for the extension */
+#define AST_PBX_NO_HANGUP_PEER_PARKED 13 /*!< Don't touch the peer channel - it was sent to the parking lot and might be gone by now */
/*! } */
#define PRIORITY_HINT -1 /*!< Special Priority for a hint */
diff --git a/main/features.c b/main/features.c
index c5e6d9201..ef07b23db 100644
--- a/main/features.c
+++ b/main/features.c
@@ -777,7 +777,7 @@ static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer,
res = ast_park_call(parkee, parker, 0, NULL);
if (!res) {
if (sense == FEATURE_SENSE_CHAN) {
- res = AST_PBX_NO_HANGUP_PEER;
+ res = AST_PBX_NO_HANGUP_PEER_PARKED;
} else {
res = AST_PBX_KEEPALIVE;
}
@@ -1127,7 +1127,7 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p
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;
+ return (transferer == peer) ? AST_PBX_KEEPALIVE : AST_PBX_NO_HANGUP_PEER_PARKED;
} else {
ast_log(LOG_WARNING, "Unable to park call %s\n", transferee->name);
}
@@ -1730,6 +1730,8 @@ static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer,
}
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)
return AST_FEATURE_RETURN_SUCCESSBREAK;
@@ -2377,10 +2379,12 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
}
before_you_go:
- new_chan_cdr = pick_unlocked_cdr(chan->cdr); /* the proper chan cdr, if there are forked cdrs */
- new_peer_cdr = pick_unlocked_cdr(peer->cdr); /* the proper chan cdr, if there are forked cdrs */
- if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) && ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) {
+ /* run the hangup exten on the chan object IFF it was NOT involved in a parking situation
+ * if it were, then chan belongs to a different thread now, and might have been hung up long
+ * ago.
+ */
+ 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)) {
struct ast_cdr *swapper;
char savelastapp[AST_MAX_EXTENSION];
char savelastdata[AST_MAX_EXTENSION];
@@ -2424,39 +2428,57 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
ast_copy_string(bridge_cdr->lastdata, savelastdata, sizeof(bridge_cdr->lastdata));
}
- /* obey the NoCDR() wishes. */
- 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))
- ast_set_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED); /* DISABLED is viral-- it will propagate across a bridge */
- if (!new_chan_cdr || (new_chan_cdr && !ast_test_flag(new_chan_cdr, AST_CDR_FLAG_POST_DISABLED))) {
- struct ast_channel *chan_ptr = NULL;
-
- ast_cdr_end(bridge_cdr);
-
- ast_cdr_detach(bridge_cdr);
-
- /* do a specialized reset on the beginning channel
- CDR's, if they still exist, so as not to mess up
- issues in future bridges;
-
- Here are the rules of the game:
- 1. The chan and peer channel pointers will not change
- during the life of the bridge.
- 2. But, in transfers, the channel names will change.
- between the time the bridge is started, and the
- time the channel ends.
- Usually, when a channel changes names, it will
- also change CDR pointers.
- 3. Usually, only one of the two channels (chan or peer)
- will change names.
- 4. Usually, if a channel changes names during a bridge,
- it is because of a transfer. Usually, in these situations,
- it is normal to see 2 bridges running simultaneously, and
- it is not unusual to see the two channels that change
- swapped between bridges.
- 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.
- */
+ /* 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 (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 */
+ ast_cdr_end(bridge_cdr);
+ ast_cdr_detach(bridge_cdr);
+
+ /* do a specialized reset on the beginning channel
+ CDR's, if they still exist, so as not to mess up
+ issues in future bridges;
+
+ Here are the rules of the game:
+ 1. The chan and peer channel pointers will not change
+ during the life of the bridge.
+ 2. But, in transfers, the channel names will change.
+ between the time the bridge is started, and the
+ time the channel ends.
+ Usually, when a channel changes names, it will
+ also change CDR pointers.
+ 3. Usually, only one of the two channels (chan or peer)
+ will change names.
+ 4. Usually, if a channel changes names during a bridge,
+ it is because of a transfer. Usually, in these situations,
+ it is normal to see 2 bridges running simultaneously, and
+ it is not unusual to see the two channels that change
+ swapped between bridges.
+ 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) {
+ struct ast_channel *chan_ptr = NULL;
if (strcasecmp(orig_channame, chan->name) != 0) {
/* old channel */
@@ -2479,28 +2501,35 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
} else {
ast_cdr_specialized_reset(chan_cdr,0); /* nothing changed, reset the chan_cdr */
}
- if (strcasecmp(orig_peername, peer->name) != 0) {
- /* old channel */
- chan_ptr = ast_get_channel_by_name_locked(orig_peername);
- if (chan_ptr) {
- if (!ast_bridged_channel(chan_ptr)) {
- struct ast_cdr *cur;
- for (cur = chan_ptr->cdr; cur; cur = cur->next) {
+ }
+
+ 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))
+ ast_set_flag(new_peer_cdr, AST_CDR_FLAG_POST_DISABLED); /* DISABLED is viral-- it will propagate across a bridge */
+ if (strcasecmp(orig_peername, peer->name) != 0) {
+ /* old channel */
+ chan_ptr = ast_get_channel_by_name_locked(orig_peername);
+ if (chan_ptr) {
+ if (!ast_bridged_channel(chan_ptr)) {
+ struct ast_cdr *cur;
+ for (cur = chan_ptr->cdr; cur; cur = cur->next) {
if (cur == peer_cdr) {
- break;
- }
- }
- if (cur)
- ast_cdr_specialized_reset(peer_cdr,0);
- }
- ast_channel_unlock(chan_ptr);
- }
- /* new channel */
- ast_cdr_specialized_reset(new_peer_cdr,0);
- } else {
- ast_cdr_specialized_reset(peer_cdr,0); /* nothing changed, reset the peer_cdr */
- }
- }
+ break;
+ }
+ }
+ if (cur)
+ ast_cdr_specialized_reset(peer_cdr,0);
+ }
+ ast_channel_unlock(chan_ptr);
+ }
+ /* new channel */
+ ast_cdr_specialized_reset(new_peer_cdr,0);
+ } else {
+ ast_cdr_specialized_reset(peer_cdr,0); /* nothing changed, reset the peer_cdr */
+ }
+ }
return res;
}
@@ -2955,7 +2984,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)
+ if (res != AST_PBX_NO_HANGUP_PEER && res != AST_PBX_NO_HANGUP_PEER_PARKED)
ast_hangup(peer);
return res;
} else {