[svn-commits] rmudgett: branch rmudgett/hangup_handlers r369177 - /team/rmudgett/hangup_han...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Jun 20 18:37:29 CDT 2012


Author: rmudgett
Date: Wed Jun 20 18:37:24 2012
New Revision: 369177

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=369177
Log:
Commit current hangup handler work.

* Made ast_hangup() call ast_pbx_hangup_handler_run() instead of checking
all locations where ast_hangup() is called to see if should run hangup
handlers.

* Fix bridge_exec() to not allow the after-bridge code to run the h-exten
because the dialplan normally needs to keep running.

* Made ast_do_masquerade() not drop the original original's physical side
so the hangup handlers could access any channel driver statistics.

* Made ast_do_masquerade() call ast_hangup() on pre-zombied clonechan.
This restarts the ast_hangup() that was deferred because of the
masquerade.

Needs more testing and bridge peer calling hangup handlers where needed.

Modified:
    team/rmudgett/hangup_handlers/main/autoservice.c
    team/rmudgett/hangup_handlers/main/channel.c
    team/rmudgett/hangup_handlers/main/features.c

Modified: team/rmudgett/hangup_handlers/main/autoservice.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/hangup_handlers/main/autoservice.c?view=diff&rev=369177&r1=369176&r2=369177
==============================================================================
--- team/rmudgett/hangup_handlers/main/autoservice.c (original)
+++ team/rmudgett/hangup_handlers/main/autoservice.c Wed Jun 20 18:37:24 2012
@@ -308,7 +308,6 @@
 	if (chan) {
 		ast_autoservice_start(chan);
 	}
-	ast_pbx_hangup_handler_run(peer);
 	ast_hangup(peer);
 	if (chan) {
 		ast_autoservice_stop(chan);

Modified: team/rmudgett/hangup_handlers/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/hangup_handlers/main/channel.c?view=diff&rev=369177&r1=369176&r2=369177
==============================================================================
--- team/rmudgett/hangup_handlers/main/channel.c (original)
+++ team/rmudgett/hangup_handlers/main/channel.c Wed Jun 20 18:37:24 2012
@@ -2614,7 +2614,6 @@
 int ast_hangup(struct ast_channel *chan)
 {
 	char extra_str[64]; /* used for cel logging below */
-	int was_zombie;
 
 	ast_autoservice_stop(chan);
 
@@ -2647,11 +2646,10 @@
 	}
 
 	/* Mark as a zombie so a masquerade cannot be setup on this channel. */
-	if (!(was_zombie = ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE))) {
-		ast_set_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE);
-	}
+	ast_set_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE);
 
 	ast_channel_unlock(chan);
+	ast_pbx_hangup_handler_run(chan);
 	ao2_unlink(channels, chan);
 	ast_channel_lock(chan);
 
@@ -2690,14 +2688,10 @@
 			(long) pthread_self(), ast_channel_name(chan), (long)ast_channel_blocker(chan), ast_channel_blockproc(chan));
 		ast_assert(ast_test_flag(ast_channel_flags(chan), AST_FLAG_BLOCKING) == 0);
 	}
-	if (!was_zombie) {
-		ast_debug(1, "Hanging up channel '%s'\n", ast_channel_name(chan));
-
-		if (ast_channel_tech(chan)->hangup) {
-			ast_channel_tech(chan)->hangup(chan);
-		}
-	} else {
-		ast_debug(1, "Hanging up zombie '%s'\n", ast_channel_name(chan));
+
+	ast_debug(1, "Hanging up channel '%s'\n", ast_channel_name(chan));
+	if (ast_channel_tech(chan)->hangup) {
+		ast_channel_tech(chan)->hangup(chan);
 	}
 
 	ast_channel_unlock(chan);
@@ -6899,19 +6893,6 @@
 	 * container lock.
 	 */
 	ast_channel_unlock(original);
-
-	/* Disconnect the original original's physical side */
-	if (ast_channel_tech(clonechan)->hangup && ast_channel_tech(clonechan)->hangup(clonechan)) {
-		ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
-	} else {
-		/*
-		 * We just hung up the original original's physical side of the
-		 * channel.  Set the new zombie to use the kill channel driver
-		 * for safety.
-		 */
-		ast_channel_tech_set(clonechan, &ast_kill_tech);
-	}
-
 	ast_channel_unlock(clonechan);
 
 	/*
@@ -6959,32 +6940,17 @@
 		ast_datastore_free(xfer_ds);
 	}
 
-	if (clone_was_zombie) {
-		ast_channel_lock(clonechan);
-		ast_debug(1, "Destroying channel clone '%s'\n", ast_channel_name(clonechan));
-		ast_manager_event(clonechan, EVENT_FLAG_CALL, "Hangup",
-			"Channel: %s\r\n"
-			"Uniqueid: %s\r\n"
-			"Cause: %d\r\n"
-			"Cause-txt: %s\r\n",
-			ast_channel_name(clonechan),
-			ast_channel_uniqueid(clonechan),
-			ast_channel_hangupcause(clonechan),
-			ast_cause2str(ast_channel_hangupcause(clonechan))
-			);
-		ast_channel_unlock(clonechan);
-
-		/*
-		 * Drop the system reference to destroy the channel since it is
-		 * already unlinked.
-		 */
-		ast_channel_unref(clonechan);
-	} else {
+	if (!clone_was_zombie) {
 		ao2_link(channels, clonechan);
 	}
-
 	ao2_link(channels, original);
 	ao2_unlock(channels);
+
+	if (clone_was_zombie) {
+		/* Restart the ast_hangup() that was deferred because of this masquerade. */
+		ast_debug(1, "Destroying channel clone '%s'\n", ast_channel_name(clonechan));
+		ast_hangup(clonechan);
+	}
 
 	/* Release our held safety references. */
 	ast_channel_unref(original);

Modified: team/rmudgett/hangup_handlers/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/hangup_handlers/main/features.c?view=diff&rev=369177&r1=369176&r2=369177
==============================================================================
--- team/rmudgett/hangup_handlers/main/features.c (original)
+++ team/rmudgett/hangup_handlers/main/features.c Wed Jun 20 18:37:24 2012
@@ -1038,7 +1038,6 @@
 	ast_do_masquerade(xferchan);
 	if (ast_pbx_start(xferchan)) {
 		/* Failed to start PBX. */
-		ast_pbx_hangup_handler_run(xferchan);
 		ast_hangup(xferchan);
 	}
 }
@@ -1087,17 +1086,13 @@
 			ast_log(LOG_VERBOSE, "putting chan %s into PBX again\n", ast_channel_name(tobj->chan));
 			if (ast_pbx_start(tobj->chan)) {
 				ast_log(LOG_WARNING, "FAILED continuing PBX on chan %s\n", ast_channel_name(tobj->chan));
-				ast_pbx_hangup_handler_run(tobj->chan);
 				ast_hangup(tobj->chan);
 			}
 		} else {
-			ast_pbx_hangup_handler_run(tobj->chan);
 			ast_hangup(tobj->chan);
 		}
 	} else {
-		ast_pbx_hangup_handler_run(tobj->chan);
 		ast_hangup(tobj->chan);
-		ast_pbx_hangup_handler_run(tobj->peer);
 		ast_hangup(tobj->peer);
 	}
 
@@ -1126,9 +1121,7 @@
 	if (ast_pthread_create(&thread, &attr, bridge_call_thread, data)) {
 		/* Failed to create thread. Ditch the reference to callid. */
 		ast_callid_unref(data->callid);
-		ast_pbx_hangup_handler_run(data->chan);
 		ast_hangup(data->chan);
-		ast_pbx_hangup_handler_run(data->peer);
 		ast_hangup(data->peer);
 		ast_log(LOG_ERROR, "Failed to create bridge_call_thread.\n");
 		return;
@@ -2790,7 +2783,6 @@
 			|| (ast_waitfordigit(newchan, 100) < 0)
 			|| ast_check_hangup(transferee)
 			|| ast_check_hangup(newchan)) {
-			ast_pbx_hangup_handler_run(newchan);
 			ast_hangup(newchan);
 			ast_party_connected_line_free(&connected_line);
 			return -1;
@@ -2905,7 +2897,6 @@
 		 */
 		ast_debug(1, "Everyone is hungup.\n");
 		if (newchan) {
-			ast_pbx_hangup_handler_run(newchan);
 			ast_hangup(newchan);
 		}
 		ast_party_connected_line_free(&connected_line);
@@ -2946,9 +2937,7 @@
 	ast_clear_flag(ast_channel_flags(newchan), AST_FLAGS_ALL);
 	tobj = ast_calloc(1, sizeof(*tobj));
 	if (!tobj) {
-		ast_pbx_hangup_handler_run(xferchan);
 		ast_hangup(xferchan);
-		ast_pbx_hangup_handler_run(newchan);
 		ast_hangup(newchan);
 		ast_party_connected_line_free(&connected_line);
 		return -1;
@@ -5003,7 +4992,6 @@
 			ast_log(LOG_WARNING,
 				"Unable to restart the PBX for user on '%s', hanging them up...\n",
 				ast_channel_name(pu->chan));
-			ast_pbx_hangup_handler_run(chan);
 			ast_hangup(chan);
 		}
 
@@ -5058,7 +5046,6 @@
 
 				/* There's a problem, hang them up */
 				ast_verb(2, "%s got tired of being parked\n", ast_channel_name(chan));
-				ast_pbx_hangup_handler_run(chan);
 				ast_hangup(chan);
 
 				/* And take them out of the parking lot */
@@ -7212,7 +7199,6 @@
 	if (!chanb) {
 		snprintf(buf, sizeof(buf), "Channel2 does not exists: %s", channelb);
 		astman_send_error(s, m, buf);
-		ast_pbx_hangup_handler_run(tmpchana);
 		ast_hangup(tmpchana);
 		return 0;
 	}
@@ -7225,7 +7211,6 @@
 	if (!(tmpchanb = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
 		NULL, NULL, ast_channel_linkedid(chanb), 0, "Bridge/%s", ast_channel_name(chanb)))) {
 		astman_send_error(s, m, "Unable to create temporary channels!");
-		ast_pbx_hangup_handler_run(tmpchana);
 		ast_hangup(tmpchana);
 		chanb = ast_channel_unref(chanb);
 		return 0;
@@ -7234,7 +7219,6 @@
 	if (do_bridge_masquerade(chanb, tmpchanb)) {
 		snprintf(buf, sizeof(buf), "Unable to masquerade channel %s!", channelb);
 		astman_send_error(s, m, buf);
-		ast_pbx_hangup_handler_run(tmpchana);
 		ast_hangup(tmpchana);
 		ast_hangup(tmpchanb);
 		chanb = ast_channel_unref(chanb);
@@ -7247,9 +7231,7 @@
 	if (ast_channel_make_compatible(tmpchana, tmpchanb)) {
 		ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for manager bridge\n", ast_channel_name(tmpchana), ast_channel_name(tmpchanb));
 		astman_send_error(s, m, "Could not make channels compatible for manager bridge");
-		ast_pbx_hangup_handler_run(tmpchana);
 		ast_hangup(tmpchana);
-		ast_pbx_hangup_handler_run(tmpchanb);
 		ast_hangup(tmpchanb);
 		return 0;
 	}
@@ -7258,9 +7240,7 @@
 	if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
 		ast_log(LOG_WARNING, "Unable to spawn a new bridge thread on %s and %s: %s\n", ast_channel_name(tmpchana), ast_channel_name(tmpchanb), strerror(errno));
 		astman_send_error(s, m, "Unable to spawn a new bridge thread");
-		ast_pbx_hangup_handler_run(tmpchana);
 		ast_hangup(tmpchana);
-		ast_pbx_hangup_handler_run(tmpchanb);
 		ast_hangup(tmpchanb);
 		return 0;
 	}
@@ -7893,6 +7873,7 @@
 	struct ast_bridge_config bconfig = { { 0, }, };
 	char *opt_args[OPT_ARG_ARRAY_SIZE];
 	struct timeval calldurationlimit = { 0, };
+	int res;
 
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(dest_chan);
@@ -8035,6 +8016,11 @@
 	if (ast_test_flag(&opts, OPT_CALLER_PARK))
 		ast_set_flag(&(bconfig.features_caller), AST_FEATURE_PARKCALL);
 
+	/*
+	 * Don't let the after-bridge code run the h-exten.  We want to
+	 * continue in the dialplan if we did not hangup.
+	 */
+	ast_set_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_HANGUP_DONT);
 	ast_bridge_call(chan, final_dest_chan, &bconfig);
 
 	/* The bridge has ended, set BRIDGERESULT to SUCCESS. */
@@ -8089,7 +8075,13 @@
 	ast_free((char *) bconfig.end_sound);
 	ast_free((char *) bconfig.start_sound);
 
-	return 0;
+	/* Continue in the dialplan if we did not hangup. */
+	ast_channel_lock(chan);
+	ast_check_hangup(chan);
+	res = (ast_channel_softhangup_internal_flag(chan) & ~AST_SOFTHANGUP_ASYNCGOTO)
+		? -1 : 0;
+	ast_channel_unlock(chan);
+	return res;
 }
 
 #if defined(TEST_FRAMEWORK)




More information about the svn-commits mailing list