aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormurf <murf@f38db490-d61c-443f-a65b-d21fe96a405b>2008-09-12 05:03:09 +0000
committermurf <murf@f38db490-d61c-443f-a65b-d21fe96a405b>2008-09-12 05:03:09 +0000
commit89d5bf8e0550eea985e6110ddce5a21923c4a1a6 (patch)
tree4968f0c80cb18b79d4fa63517eac08b9acad433d
parent472c195d49dfaa6a9738fff0ab25023e37797b9a (diff)
Merged revisions 142676 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ................ r142676 | murf | 2008-09-11 22:50:48 -0600 (Thu, 11 Sep 2008) | 40 lines Merged revisions 142675 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r142675 | murf | 2008-09-11 22:29:34 -0600 (Thu, 11 Sep 2008) | 29 lines Tested by: sergee, murf, chris-mac, andrew, KNK This is a "second attempt" to restore the previous "endbeforeh" behavior in 1.4 and up. In order to capture information concerning all the legs of transfers in all their infinite combinations, I was forced to this particular solution by a chain of logical necessities, the first being that I was not allowed to rewrite the CDR mechanism from the ground up! This change basically leaves the original machinery alone, which allows IVR and local channel type situations to generate CDR's as normal, but a channel flag can be set to suppress the normal running of the h exten. That flag would be set by the code that runs the h exten from the ast_bridge_call routine, to prevent the h exten from being run twice. Also, a flag in the ast_bridge_config struct passed into ast_bridge_call can be used to suppress the running of the h exten in that routine. This would happen, for instance, if you use the 'g' option in the Dial app. Running this routine 'early' allows not only the CDR() func to be used in the h extension for reading CDR variables, but also allows them to be modified before the CDR is posted to the backends. While I dearly hope that this patch overcomes all problems, and introduces no new problems, reality suggests that surely someone will have problems. In this case, please re-open 13251 (or 13289), and we'll see if we can't fix any remaining issues. ** trunk note: some code to suppress the h exten being run from app_queue was added; for the 'continue' option available only in trunk/1.6.x. ........ ................ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.1@142678 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--apps/app_dial.c2
-rw-r--r--apps/app_queue.c3
-rw-r--r--include/asterisk/channel.h5
-rw-r--r--main/features.c44
-rw-r--r--main/pbx.c4
5 files changed, 56 insertions, 2 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c
index 439fafa11..919963538 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -1905,6 +1905,8 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMIXMON);
if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMIXMON);
+ if (ast_test_flag64(peerflags, OPT_GO_ON))
+ ast_set_flag(&(config.features_caller), AST_FEATURE_NO_H_EXTEN);
if (moh) {
moh = 0;
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 86a51bd11..59f28abd3 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -3260,6 +3260,9 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
case 'W':
ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMON);
break;
+ case 'c':
+ ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_NO_H_EXTEN);
+ break;
case 'd':
nondataquality = 0;
break;
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 95bc7c08b..e7317961e 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -552,6 +552,10 @@ enum {
/*! This flag indicates that on a masquerade, an active stream should not
* be carried over */
AST_FLAG_MASQ_NOSTREAM = (1 << 16),
+ /*! This flag indicates that the hangup exten was run when the bridge terminated,
+ * a message aimed at preventing a subsequent hangup exten being run at the pbx_run
+ * level */
+ AST_FLAG_BRIDGE_HANGUP_RUN = (1 << 17),
};
/*! \brief ast_bridge_config flags */
@@ -563,6 +567,7 @@ enum {
AST_FEATURE_AUTOMON = (1 << 4),
AST_FEATURE_PARKCALL = (1 << 5),
AST_FEATURE_AUTOMIXMON = (1 << 6),
+ AST_FEATURE_NO_H_EXTEN = (1 << 7),
};
/*! \brief bridge configuration */
diff --git a/main/features.c b/main/features.c
index d5d317404..c8ce6ccde 100644
--- a/main/features.c
+++ b/main/features.c
@@ -2351,6 +2351,50 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
}
before_you_go:
+ 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;
+ char savelastapp[AST_MAX_EXTENSION];
+ char savelastdata[AST_MAX_EXTENSION];
+ char save_exten[AST_MAX_EXTENSION];
+ int save_prio;
+ int found = 0; /* set if we find at least one match */
+
+ 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));
+ ast_channel_lock(chan);
+ chan->cdr = bridge_cdr;
+ ast_copy_string(save_exten, chan->exten, sizeof(save_exten));
+ save_prio = chan->priority;
+ ast_copy_string(chan->exten, "h", sizeof(chan->exten));
+ chan->priority = 1;
+ ast_channel_unlock(chan);
+ while ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &found, 1)) == 0) {
+ chan->priority++;
+ }
+ if (found && res)
+ {
+ /* Something bad happened, or a hangup has been requested. */
+ ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
+ ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", chan->context, chan->exten, chan->priority, chan->name);
+ }
+ /* swap it back */
+ ast_channel_lock(chan);
+ ast_copy_string(chan->exten, save_exten, sizeof(chan->exten));
+ chan->priority = save_prio;
+ chan->cdr = swapper;
+ ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN);
+ ast_channel_unlock(chan);
+ /* 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 && ast_test_flag(chan_cdr, AST_CDR_FLAG_POST_DISABLED) && peer_cdr && !ast_test_flag(peer_cdr, AST_CDR_FLAG_POST_DISABLED))
ast_set_flag(peer_cdr, AST_CDR_FLAG_POST_DISABLED); /* DISABLED is viral-- it will propagate across a bridge */
diff --git a/main/pbx.c b/main/pbx.c
index 504c7fb08..b084d57d1 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -3880,7 +3880,7 @@ 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);
- if ((res != AST_PBX_KEEPALIVE) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) {
+ if ((res != AST_PBX_KEEPALIVE) && !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);
while ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found, 1)) == 0) {
c->priority++;
@@ -3892,7 +3892,7 @@ static int __ast_pbx_run(struct ast_channel *c)
}
}
ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP);
-
+ ast_clear_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */
pbx_destroy(c->pbx);
c->pbx = NULL;
if (res != AST_PBX_KEEPALIVE)