[asterisk-commits] russell: trunk r58475 - in /trunk: ./ apps/app_meetme.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Mar 8 13:56:57 MST 2007


Author: russell
Date: Thu Mar  8 14:56:57 2007
New Revision: 58475

URL: http://svn.digium.com/view/asterisk?view=rev&rev=58475
Log:
Merged revisions 58474 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r58474 | russell | 2007-03-08 14:54:56 -0600 (Thu, 08 Mar 2007) | 3 lines

Refactor hold handling a bit so that it does not require keeping the call up
when a call is put on hold.

........

Modified:
    trunk/   (props changed)
    trunk/apps/app_meetme.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: trunk/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_meetme.c?view=diff&rev=58475&r1=58474&r2=58475
==============================================================================
--- trunk/apps/app_meetme.c (original)
+++ trunk/apps/app_meetme.c Thu Mar  8 14:56:57 2007
@@ -65,6 +65,7 @@
 #include "asterisk/astobj.h"
 #include "asterisk/devicestate.h"
 #include "asterisk/dial.h"
+#include "asterisk/causes.h"
 
 #include "enter.h"
 #include "leave.h"
@@ -360,6 +361,7 @@
 	SLA_TRUNK_STATE_RINGING,
 	SLA_TRUNK_STATE_UP,
 	SLA_TRUNK_STATE_ONHOLD,
+	SLA_TRUNK_STATE_ONHOLD_BYME,
 };
 
 enum sla_hold_access {
@@ -448,8 +450,6 @@
 enum sla_event_type {
 	/*! A station has put the call on hold */
 	SLA_EVENT_HOLD,
-	/*! A station has taken the call off of hold */
-	SLA_EVENT_UNHOLD,
 	/*! The state of a dial has changed */
 	SLA_EVENT_DIAL_STATE,
 	/*! The state of a ringing trunk has changed */
@@ -1062,6 +1062,7 @@
 	S(SLA_TRUNK_STATE_RINGING)
 	S(SLA_TRUNK_STATE_UP)
 	S(SLA_TRUNK_STATE_ONHOLD)
+	S(SLA_TRUNK_STATE_ONHOLD_BYME)
 	}
 	return "Uknown State";
 #undef S
@@ -1271,7 +1272,7 @@
 }
 
 /*! \brief Queue a SLA event from the conference */
-static void sla_queue_event_conf(enum sla_event_type type, const struct ast_channel *chan,
+static void sla_queue_event_conf(enum sla_event_type type, struct ast_channel *chan,
 	struct ast_conference *conf)
 {
 	struct sla_station *station;
@@ -1300,6 +1301,9 @@
 		ast_log(LOG_DEBUG, "Trunk not found for event!\n");
 		return;
 	}
+
+	ast_softhangup(chan, AST_CAUSE_NORMAL);
+	trunk_ref->chan = NULL;
 
 	sla_queue_event_full(type, trunk_ref, station, 1);
 }
@@ -2101,8 +2105,6 @@
 					case AST_CONTROL_HOLD:
 						sla_queue_event_conf(SLA_EVENT_HOLD, chan, conf);
 						break;
-					case AST_CONTROL_UNHOLD:
-						sla_queue_event_conf(SLA_EVENT_UNHOLD, chan, conf);
 					default:
 						break;
 					}
@@ -3104,7 +3106,8 @@
 	return station;
 }
 
-static int sla_check_station_hold_access(const struct sla_trunk *trunk)
+static int sla_check_station_hold_access(const struct sla_trunk *trunk,
+	const struct sla_station *station)
 {
 	struct sla_station_ref *station_ref;
 	struct sla_trunk_ref *trunk_ref;
@@ -3112,9 +3115,9 @@
 	/* For each station that has this call on hold, check for private hold. */
 	AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
 		AST_LIST_TRAVERSE(&station_ref->station->trunks, trunk_ref, entry) {
-			if (trunk_ref->trunk != trunk)
+			if (trunk_ref->trunk != trunk || station_ref->station == station)
 				continue;
-			if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD && trunk_ref->chan &&
+			if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD_BYME &&
 				station_ref->station->hold_access == SLA_HOLD_PRIVATE)
 				return 1;
 			return 0;
@@ -3143,8 +3146,9 @@
 		if ( (trunk_ref->trunk->barge_disabled 
 			&& trunk_ref->state != SLA_TRUNK_STATE_IDLE) ||
 			(trunk_ref->trunk->hold_stations 
-			&& trunk_ref->trunk->hold_access == SLA_HOLD_PRIVATE) ||
-			sla_check_station_hold_access(trunk_ref->trunk) )
+			&& trunk_ref->trunk->hold_access == SLA_HOLD_PRIVATE
+			&& trunk_ref->state != SLA_TRUNK_STATE_ONHOLD_BYME) ||
+			sla_check_station_hold_access(trunk_ref->trunk, station) )
 			trunk_ref = NULL;
 
 		break;
@@ -3179,14 +3183,15 @@
 }
 
 static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk_state state, 
-	enum sla_which_trunk_refs inactive_only)
+	enum sla_which_trunk_refs inactive_only, const struct sla_trunk_ref *exclude)
 {
 	struct sla_station *station;
 	struct sla_trunk_ref *trunk_ref;
 
 	AST_LIST_TRAVERSE(&sla_stations, station, entry) {
 		AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
-			if (trunk_ref->trunk != trunk || (inactive_only ? trunk_ref->chan : 0))
+			if (trunk_ref->trunk != trunk || (inactive_only ? trunk_ref->chan : 0)
+				|| trunk_ref == exclude)
 				continue;
 			trunk_ref->state = state;
 			ast_device_state_changed("SLA:%s_%s", station->name, trunk->name);
@@ -3232,10 +3237,11 @@
 		conf = NULL;
 	}
 	trunk_ref->chan = NULL;
-	if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->active_stations)) {
+	if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->active_stations) &&
+		!trunk_ref->trunk->hold_stations) {
 		strncat(conf_name, "|K", sizeof(conf_name) - strlen(conf_name) - 1);
 		admin_exec(NULL, conf_name);
-		sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS);
+		sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
 	}
 
 	ast_dial_join(station->dial);
@@ -3252,7 +3258,7 @@
 
 	snprintf(buf, sizeof(buf), "SLA_%s|K", ringing_trunk->trunk->name);
 	admin_exec(NULL, buf);
-	sla_change_trunk_state(ringing_trunk->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS);
+	sla_change_trunk_state(ringing_trunk->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
 
 	while ((station_ref = AST_LIST_REMOVE_HEAD(&ringing_trunk->timed_out_stations, entry)))
 		free(station_ref);
@@ -3396,7 +3402,7 @@
 			s_trunk_ref->chan = ast_dial_answered(ringing_station->station->dial);
 			/* Actually answer the trunk */
 			ast_answer(ringing_trunk->trunk->chan);
-			sla_change_trunk_state(ringing_trunk->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS);
+			sla_change_trunk_state(ringing_trunk->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
 			/* Now, start a thread that will connect this station to the trunk.  The rest of
 			 * the code here sets up the thread and ensures that it is able to save the arguments
 			 * before they are no longer valid since they are allocated on the stack. */
@@ -3663,21 +3669,11 @@
 static void sla_handle_hold_event(struct sla_event *event)
 {
 	ast_atomic_fetchadd_int((int *) &event->trunk_ref->trunk->hold_stations, 1);
-	event->trunk_ref->state = SLA_TRUNK_STATE_ONHOLD;
+	event->trunk_ref->state = SLA_TRUNK_STATE_ONHOLD_BYME;
 	ast_device_state_changed("SLA:%s_%s", 
 		event->station->name, event->trunk_ref->trunk->name);
-	sla_change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_ONHOLD, INACTIVE_TRUNK_REFS);	
-}
-
-static void sla_handle_unhold_event(struct sla_event *event)
-{
-	if (ast_atomic_dec_and_test((int *) &event->trunk_ref->trunk->hold_stations) == 1)
-		sla_change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS);
-	else {
-		event->trunk_ref->state = SLA_TRUNK_STATE_UP;
-		ast_device_state_changed("SLA:%s_%s",
-			event->station->name, event->trunk_ref->trunk->name);
-	}
+	sla_change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_ONHOLD, 
+		INACTIVE_TRUNK_REFS, event->trunk_ref);
 }
 
 /*! \brief Process trunk ring timeouts
@@ -3901,9 +3897,6 @@
 			switch (event->type) {
 			case SLA_EVENT_HOLD:
 				sla_handle_hold_event(event);
-				break;
-			case SLA_EVENT_UNHOLD:
-				sla_handle_unhold_event(event);				
 				break;
 			case SLA_EVENT_DIAL_STATE:
 				sla_handle_dial_state_event();
@@ -4076,9 +4069,9 @@
 	}
 
 	AST_RWLIST_RDLOCK(&sla_trunks);
-	if (!ast_strlen_zero(trunk_name))
+	if (!ast_strlen_zero(trunk_name)) {
 		trunk_ref = sla_find_trunk_ref_byname(station, trunk_name);
-	else
+	} else
 		trunk_ref = sla_choose_idle_trunk(station);
 	AST_RWLIST_UNLOCK(&sla_trunks);
 
@@ -4091,6 +4084,15 @@
 		}
 		pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
 		return 0;
+	}
+
+	if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD_BYME) {
+		if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->hold_stations) == 1)
+			sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
+		else {
+			trunk_ref->state = SLA_TRUNK_STATE_UP;
+			ast_device_state_changed("SLA:%s_%s", station->name, trunk_ref->trunk->name);
+		}
 	}
 
 	trunk_ref->chan = chan;
@@ -4106,7 +4108,7 @@
 			.cond_lock = &cond_lock,
 			.cond = &cond,
 		};
-		sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS);
+		sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
 		/* Create a thread to dial the trunk and dump it into the conference.
 		 * However, we want to wait until the trunk has been dialed and the
 		 * conference is created before continuing on here. */
@@ -4126,7 +4128,7 @@
 		if (!trunk_ref->trunk->chan) {
 			ast_log(LOG_DEBUG, "Trunk didn't get created. chan: %lx\n", (long) trunk_ref->trunk->chan);
 			pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
-			sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS);
+			sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
 			trunk_ref->chan = NULL;
 			return 0;
 		}
@@ -4148,7 +4150,7 @@
 	if (res == 1) {	
 		strncat(conf_name, "|K", sizeof(conf_name) - strlen(conf_name) - 1);
 		admin_exec(NULL, conf_name);
-		sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS);
+		sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
 	}
 	
 	pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "SUCCESS");
@@ -4178,7 +4180,7 @@
 	ringing_trunk->trunk = trunk;
 	ringing_trunk->ring_begin = ast_tvnow();
 
-	sla_change_trunk_state(trunk, SLA_TRUNK_STATE_RINGING, 0);
+	sla_change_trunk_state(trunk, SLA_TRUNK_STATE_RINGING, ALL_TRUNK_REFS, NULL);
 
 	ast_mutex_lock(&sla.lock);
 	AST_LIST_INSERT_HEAD(&sla.ringing_trunks, ringing_trunk, entry);
@@ -4290,6 +4292,7 @@
 			res = AST_DEVICE_INUSE;
 			break;
 		case SLA_TRUNK_STATE_ONHOLD:
+		case SLA_TRUNK_STATE_ONHOLD_BYME:
 			res = AST_DEVICE_ONHOLD;
 			break;
 		}



More information about the asterisk-commits mailing list