]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
(closes issue #13251)
authorSteve Murphy <murf@digium.com>
Thu, 21 Aug 2008 23:03:50 +0000 (23:03 +0000)
committerSteve Murphy <murf@digium.com>
Thu, 21 Aug 2008 23:03:50 +0000 (23:03 +0000)
Reported by: sergee
Tested by: murf

THis is a bold move for a static release fix, but I wouldn't have
made it if I didn't feel confident (at least a *bit* confident)
that it wouldn't mess everyone up.

The reasoning goes something like this:

1. We simply cannot do anything with CDR's at the current point
(in pbx.c, after the __ast_pbx_run loop). It's way too late to
have any affect on the CDRs. The CDR is already posted and gone,
and the remnants have been cleared.

2. I was very much afraid that moving the running of the 'h'
extension down into the bridge code (where it would be now
practical to do it), would result in a lot more calls to the
'h' exten, so I implemented it as another exten under another
name, but found, to my pleasant surprise, that there was a
1:1 correspondence to the running of the 'h' exten in the
pbx_run loop, and the new spot at the end of the bridge.
So, I ifdef'd out the current 'h' loop, and moved it into
the bridge code. The only difference I can see is the stuff
about the AST_PBX_KEEPALIVE, and hopefully, if this
is still an important decision point, I can replicate it
if there are complaints. To be perfectly honest,
the KEEPALIVE situation is not totally clear to me,
and how it relates to a post-bridge situation is less
clear. I suspect the users will point out everything
in total clarity if this steps on anyone's toes!

3. I temporarily swap the bridge_cdr into the channel
before running the 'h' exten, which makes it possible
for users to edit the cdr before it goes out the door.
And, of course, with the endbeforehexten config var set,
the users can also get at the billsec/duration vals.
After the h exten finishes, the cdr is swapped back
and processing continues as normal.

Please, all who deal with CDR's, please test this version
of Asterisk, and file bug reports as appropriate!

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@139347 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/pbx.c
res/res_features.c

index f4e5a150cd9106a106eb7d55b779003568dff15c..88a6567ca52fac2903b86a7ccbe224a172abb086 100644 (file)
@@ -2539,7 +2539,10 @@ static int __ast_pbx_run(struct ast_channel *c)
                ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name);
        if (res != AST_PBX_KEEPALIVE)
                ast_softhangup(c, c->hangupcause ? c->hangupcause : AST_CAUSE_NORMAL_CLEARING);
+#ifdef HANGUP_EXTEN_EXECUTION_MOVED_TO_res_features
        if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) {
+               /* end before h exten was here */
+               
                set_ext_pri(c, "h", 1);
                while(ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
                        if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
@@ -2553,6 +2556,7 @@ static int __ast_pbx_run(struct ast_channel *c)
                        c->priority++;
                }
        }
+#endif
        ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP);
 
        pbx_destroy(c->pbx);
index 75e1ccbd91daa085ae494b71d7fa817767fed53f..101ce09a0ea6cdb7bdc15a0ccf7846525cf1f78d 100644 (file)
@@ -1659,6 +1659,42 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
 
        }
    before_you_go:
+       if (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];
+               
+               if (chan->cdr && ast_opt_end_cdr_before_h_exten) {
+                       ast_cdr_end(bridge_cdr);
+               }
+               /* swap the bridge cdr and the chan cdr for a moment, and let the endbridge
+                  dialplan code operate on it */
+               swapper = chan->cdr;
+               ast_copy_string(savelastapp, bridge_cdr->lastapp, sizeof(bridge_cdr->lastapp));
+               ast_copy_string(savelastdata, bridge_cdr->lastdata, sizeof(bridge_cdr->lastdata));
+               chan->cdr = bridge_cdr;
+               ast_channel_lock(chan);
+               ast_copy_string(chan->exten, "h", sizeof(chan->exten));
+               chan->priority = 1;
+               ast_channel_unlock(chan);
+               while(ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
+                       if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num))) {
+                               /* Something bad happened, or a hangup has been requested. */
+                               if (option_debug)
+                                       ast_log(LOG_DEBUG, "Spawn h extension (%s,%s,%d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
+                               if (option_verbose > 1)
+                                       ast_verbose( VERBOSE_PREFIX_2 "Spawn h extension (%s, %s, %d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
+                               break;
+                       }
+                       chan->priority++;
+               }
+               /* swap it back */
+               chan->cdr = swapper;
+               /* protect the lastapp/lastdata against the effects of the hangup/dialplan code */
+               ast_copy_string(bridge_cdr->lastapp, savelastapp, sizeof(bridge_cdr->lastapp));
+               ast_copy_string(bridge_cdr->lastdata, savelastdata, sizeof(bridge_cdr->lastdata));
+       }
+       
        /* obey the NoCDR() wishes. */
        if (!chan->cdr || (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED))) {