diff options
-rw-r--r-- | apps/app_dial.c | 93 | ||||
-rw-r--r-- | apps/app_queue.c | 13 | ||||
-rw-r--r-- | include/asterisk/features.h | 17 | ||||
-rw-r--r-- | include/asterisk/pbx.h | 13 | ||||
-rw-r--r-- | main/features.c | 149 |
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 { |