summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2013-07-13 23:28:23 +0000
committerMatthew Jordan <mjordan@digium.com>2013-07-13 23:28:23 +0000
commit70decd0abe9da563bbbfac94a0d488d9e25010ac (patch)
tree180ea22dc3294201e61b7ee946f1e6553aa636c8 /main
parentc3c031569312fe85fb8e7f3c61c5140aadc2904a (diff)
Fix FRACK message from external redirects; handle outbound channels better
This patch does the following: * It simplifies the Dial handling in CDRs. As a rule, the caller in a dial relationship is always the Party A. There was some logic present in the handling of the dial message that could, conceivably, pick the caller as Party A for the beginning of the dial and the peer as Party A for the end of the dial. This shouldn't have happened if the code in the bridging framework was doing its job; however, that was broken and it led to the FRACK. As it is, this code was overly ocmplex and not needed: the caller, if present, should always be Party A. Period. * It properly checks to see if a channel will continue on in the dialplan. ast_check_hangup - much like cake at the end - is a lie. It will tell you that you are hungup when you are not. Do not believe it. I would make this function tell the truth, but I'm nervous that we've been depending on it sitting on its throne of lies for far too long, and it would probably break lots of things. So I'm just checking the "internal" soft hangup flags, like everyone else. (closes issue ASTERISK-22060) Reported by: Mark Michelson (issue ASTERISK-21831) Reported by: Matt Jordan git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@394290 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/bridging.c3
-rw-r--r--main/cdr.c63
2 files changed, 23 insertions, 43 deletions
diff --git a/main/bridging.c b/main/bridging.c
index 7738bd30d..07c04a160 100644
--- a/main/bridging.c
+++ b/main/bridging.c
@@ -707,7 +707,8 @@ static void bridge_channel_pull(struct ast_bridge_channel *bridge_channel)
* outgoing channel, clear the outgoing flag.
*/
if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_OUTGOING)
- && (!ast_check_hangup(bridge_channel->chan))) {
+ && (ast_channel_softhangup_internal_flag(bridge_channel->chan) &
+ (AST_SOFTHANGUP_ASYNCGOTO | AST_SOFTHANGUP_UNBRIDGE))) {
ast_clear_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_OUTGOING);
}
diff --git a/main/cdr.c b/main/cdr.c
index 5fdd60c22..7791440a0 100644
--- a/main/cdr.c
+++ b/main/cdr.c
@@ -918,8 +918,15 @@ static int snapshot_cep_changed(struct ast_channel_snapshot *old_snapshot,
if (strcmp(new_snapshot->context, old_snapshot->context)
|| strcmp(new_snapshot->exten, old_snapshot->exten)
- || new_snapshot->priority != old_snapshot->priority
- || strcmp(new_snapshot->appl, old_snapshot->appl)) {
+ || new_snapshot->priority != old_snapshot->priority) {
+ return 1;
+ }
+
+ /* When Party A is originated to an application and the application exits, the stack
+ * will attempt to clear the application and restore the dummy originate application
+ * of "AppDialX". Ignore application changes to AppDialX as a result.
+ */
+ if (strcmp(new_snapshot->appl, old_snapshot->appl) && strncasecmp(new_snapshot->appl, "appdial", 7)) {
return 1;
}
@@ -1784,15 +1791,10 @@ static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_ch
static void handle_dial_message(void *data, struct stasis_subscription *sub, struct stasis_topic *topic, struct stasis_message *message)
{
RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);
- RAII_VAR(struct cdr_object *, cdr_caller, NULL, ao2_cleanup);
- RAII_VAR(struct cdr_object *, cdr_peer, NULL, ao2_cleanup);
struct cdr_object *cdr;
struct ast_multi_channel_blob *payload = stasis_message_data(message);
struct ast_channel_snapshot *caller;
struct ast_channel_snapshot *peer;
- struct ast_channel_snapshot *party_a_snapshot;
- struct ast_channel_snapshot *party_b_snapshot;
- struct cdr_object_snapshot *party_a;
struct cdr_object *it_cdr;
struct ast_json *dial_status_blob;
const char *dial_status = NULL;
@@ -1817,32 +1819,9 @@ static void handle_dial_message(void *data, struct stasis_subscription *sub, str
/* Figure out who is running this show */
if (caller) {
- cdr_caller = ao2_find(active_cdrs_by_channel, caller->name, OBJ_KEY);
- }
- if (peer) {
- cdr_peer = ao2_find(active_cdrs_by_channel, peer->name, OBJ_KEY);
- }
- if (cdr_caller && cdr_peer) {
- party_a = cdr_object_pick_party_a(&cdr_caller->last->party_a, &cdr_peer->last->party_a);
- if (!strcmp(party_a->snapshot->name, cdr_caller->last->party_a.snapshot->name)) {
- cdr = cdr_caller;
- party_a_snapshot = caller;
- party_b_snapshot = peer;
- } else {
- cdr = cdr_peer;
- party_a_snapshot = peer;
- party_b_snapshot = caller;
- }
- } else if (cdr_caller) {
- cdr = cdr_caller;
- party_a_snapshot = caller;
- party_b_snapshot = NULL;
- } else if (cdr_peer) {
- cdr = cdr_peer;
- party_a_snapshot = NULL;
- party_b_snapshot = peer;
+ cdr = ao2_find(active_cdrs_by_channel, caller->name, OBJ_KEY);
} else {
- return;
+ cdr = ao2_find(active_cdrs_by_channel, peer->name, OBJ_KEY);
}
ao2_lock(cdr);
@@ -1853,22 +1832,22 @@ static void handle_dial_message(void *data, struct stasis_subscription *sub, str
}
CDR_DEBUG(mod_cfg, "%p - Processing Dial Begin message for channel %s, peer %s\n",
cdr,
- party_a_snapshot ? party_a_snapshot->name : "(none)",
- party_b_snapshot ? party_b_snapshot->name : "(none)");
+ caller ? caller->name : "(none)",
+ peer ? peer->name : "(none)");
res &= it_cdr->fn_table->process_dial_begin(it_cdr,
- party_a_snapshot,
- party_b_snapshot);
+ caller,
+ peer);
} else {
if (!it_cdr->fn_table->process_dial_end) {
continue;
}
CDR_DEBUG(mod_cfg, "%p - Processing Dial End message for channel %s, peer %s\n",
cdr,
- party_a_snapshot ? party_a_snapshot->name : "(none)",
- party_b_snapshot ? party_b_snapshot->name : "(none)");
+ caller ? caller->name : "(none)",
+ peer ? peer->name : "(none)");
it_cdr->fn_table->process_dial_end(it_cdr,
- party_a_snapshot,
- party_b_snapshot,
+ caller,
+ peer,
dial_status);
}
}
@@ -1882,8 +1861,8 @@ static void handle_dial_message(void *data, struct stasis_subscription *sub, str
return;
}
new_cdr->fn_table->process_dial_begin(new_cdr,
- party_a_snapshot,
- party_b_snapshot);
+ caller,
+ peer);
}
ao2_unlock(cdr);
}