[svn-commits] russell: branch russell/sla_updates r54672 - /team/russell/sla_updates/apps/

svn-commits at lists.digium.com svn-commits at lists.digium.com
Thu Feb 15 10:56:35 MST 2007


Author: russell
Date: Thu Feb 15 11:56:34 2007
New Revision: 54672

URL: http://svn.digium.com/view/asterisk?view=rev&rev=54672
Log:
Handle station, and per-trunk on a station ring timeouts.

What is done here is that once the timeout is reached, the ringing station
will be hung up.  However, what I have not decided on, is exactly how to
handle the station after this.  When is it ok to dial the station again?
Is saying that "the station can not be called again until all trunks that
were ringing at the time of the timeout have stopped ringing" enough?

Tune in later for the exciting conclusion ...

Modified:
    team/russell/sla_updates/apps/app_meetme.c

Modified: team/russell/sla_updates/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/russell/sla_updates/apps/app_meetme.c?view=diff&rev=54672&r1=54671&r2=54672
==============================================================================
--- team/russell/sla_updates/apps/app_meetme.c (original)
+++ team/russell/sla_updates/apps/app_meetme.c Thu Feb 15 11:56:34 2007
@@ -3120,6 +3120,25 @@
 	return NULL;
 }
 
+static void sla_stop_ringing_trunk(struct sla_ringing_trunk *ringing_trunk)
+{
+	char buf[80];
+
+	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, 0);
+
+	free(ringing_trunk);
+}
+
+static void sla_stop_ringing_station(struct sla_ringing_station *ringing_station)
+{
+	ast_dial_join(ringing_station->station->dial);
+	ast_dial_destroy(ringing_station->station->dial);
+	ringing_station->station->dial = NULL;
+	free(ringing_station);
+}
+
 static void sla_dial_state_callback(struct ast_dial *dial)
 {
 	sla_queue_event(SLA_EVENT_DIAL_STATE);
@@ -3146,10 +3165,7 @@
 		case AST_DIAL_RESULT_TIMEOUT:
 		case AST_DIAL_RESULT_UNANSWERED:
 			AST_LIST_REMOVE_CURRENT(&sla.ringing_stations, entry);
-			ast_dial_join(ringing_station->station->dial);
-			ast_dial_destroy(ringing_station->station->dial);
-			ringing_station->station->dial = NULL;
-			free(ringing_station);
+			sla_stop_ringing_station(ringing_station);
 			break;
 		case AST_DIAL_RESULT_ANSWERED:
 			AST_LIST_REMOVE_CURRENT(&sla.ringing_stations, entry);
@@ -3321,26 +3337,15 @@
 	}
 }
 
-static void sla_stop_ringing_trunk(struct sla_ringing_trunk *ringing_trunk)
-{
-	char buf[80];
-
-	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, 0);
-
-	free(ringing_trunk);
-}
-
 /*! \brief Calculate the time until the next known event
  *  \note Called with sla.lock locked */
-static int sla_calc_timeout(struct timespec *ts)
+static int sla_process_timers(struct timespec *ts)
 {
 	struct sla_ringing_trunk *ringing_trunk;
 	struct sla_ringing_station *ringing_station;
 	unsigned int timeout = UINT_MAX;
 	struct timeval tv;
-	unsigned int trunk_stopped = 0;
+	unsigned int change_made = 0;
 
 	/* Check for ring timeouts on ringing trunks */
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
@@ -3352,7 +3357,7 @@
 		if (time_left <= 0) {
 			AST_LIST_REMOVE_CURRENT(&sla.ringing_trunks, entry);
 			sla_stop_ringing_trunk(ringing_trunk);
-			trunk_stopped = 1;
+			change_made = 1;
 			continue;
 		}
 		if (time_left < timeout)
@@ -3362,46 +3367,54 @@
 
 	/* Check for ring timeouts on ringing stations */
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
-
+		unsigned int ring_timeout = 0;
+		int time_elapsed, time_left;
+		struct sla_trunk_ref *trunk_ref;
+		/* If there are any ring timeouts specified for a specific trunk
+		 * on the station, then use the highest per-trunk ring timeout.
+		 * Otherwise, use the ring timeout set for the entire station. */
+		AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
+			AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
+				if (ringing_trunk->trunk == trunk_ref->trunk)
+					break;
+			}
+			if (!ringing_trunk || !trunk_ref->ring_timeout)
+				continue;
+			if (trunk_ref->ring_timeout > ring_timeout)
+				ring_timeout = trunk_ref->ring_timeout;
+		}
+		if (!ring_timeout && !ringing_station->station->ring_timeout)
+			continue;
+		ring_timeout = ringing_station->station->ring_timeout;
+
+		/* Finally, we actually have a ring timeout for this station. */
+		time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_station->ring_begin);
+		time_left = (ring_timeout * 1000) - time_elapsed;
+		if (time_left <= 0) {
+			AST_LIST_REMOVE_CURRENT(&sla.ringing_stations, entry);
+			sla_stop_ringing_station(ringing_station);
+			change_made = 1;
+			continue;
+		}
+		if (time_left < timeout)
+			timeout = time_left;
 	}
 	AST_LIST_TRAVERSE_SAFE_END
 
-	/* Ringing trunk removed, queue reprocessing of ringing trunks */
-	if (trunk_stopped)
+	/* queue reprocessing of ringing trunks */
+	if (change_made)
 		sla_queue_event(SLA_EVENT_RINGING_TRUNK);
 
 	if (timeout == UINT_MAX)
 		return 0;
-	
-	tv = ast_samp2tv(timeout, 1000);
-	ts->tv_sec = tv.tv_sec;
-	ts->tv_nsec = tv.tv_usec * 1000;
+
+	if (ts) {
+		tv = ast_samp2tv(timeout, 1000);
+		ts->tv_sec = tv.tv_sec;
+		ts->tv_nsec = tv.tv_usec * 1000;
+	}
 
 	return 1;
-}
-
-static void sla_check_timeout(void)
-{
-	struct sla_ringing_trunk *ringing_trunk;
-	unsigned int trunk_stopped = 0;
-
-	AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_trunks, ringing_trunk, entry) {
-		int time_left, time_elapsed;
-		if (!ringing_trunk->trunk->ring_timeout)
-			continue;
-		time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
-		time_left = (ringing_trunk->trunk->ring_timeout * 1000) - time_elapsed;
-		if (time_left <= 0) {
-			AST_LIST_REMOVE_CURRENT(&sla.ringing_trunks, entry);
-			sla_stop_ringing_trunk(ringing_trunk);
-			trunk_stopped = 1;
-		}
-	}
-	AST_LIST_TRAVERSE_SAFE_END
-
-	/* Ringing trunk removed, queue reprocessing of ringing trunks */
-	if (trunk_stopped)
-		sla_queue_event(SLA_EVENT_RINGING_TRUNK);
 }
 
 static void *sla_thread(void *data)
@@ -3417,7 +3430,7 @@
 		unsigned int have_timeout = 0;
 
 		if (AST_LIST_EMPTY(&sla.event_q)) {
-			if ((have_timeout = sla_calc_timeout(&ts)))
+			if ((have_timeout = sla_process_timers(&ts)))
 				ast_cond_timedwait(&sla.cond, &sla.lock, &ts);
 			else
 				ast_cond_wait(&sla.cond, &sla.lock);
@@ -3427,7 +3440,7 @@
 		}
 
 		if (have_timeout)
-			sla_check_timeout();
+			sla_process_timers(NULL);
 
 		while ((event = AST_LIST_REMOVE_HEAD(&sla.event_q, entry))) {
 			ast_mutex_unlock(&sla.lock);



More information about the svn-commits mailing list