[asterisk-commits] russell: branch russell/sla_updates r57010 - /team/russell/sla_updates/apps/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Feb 27 14:48:56 MST 2007


Author: russell
Date: Tue Feb 27 15:48:56 2007
New Revision: 57010

URL: http://svn.digium.com/view/asterisk?view=rev&rev=57010
Log:
Add functional support for station ring delays

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=57010&r1=57009&r2=57010
==============================================================================
--- team/russell/sla_updates/apps/app_meetme.c (original)
+++ team/russell/sla_updates/apps/app_meetme.c Tue Feb 27 15:48:56 2007
@@ -3059,7 +3059,7 @@
 	return station;
 }
 
-static struct sla_trunk_ref *sla_find_trunk_ref(const struct sla_station *station,
+static struct sla_trunk_ref *sla_find_trunk_ref_byname(const struct sla_station *station,
 	const char *name)
 {
 	struct sla_trunk_ref *trunk_ref = NULL;
@@ -3432,6 +3432,60 @@
 	return 0;
 }
 
+/*! \brief Check to see if a station is in use
+ */
+static int sla_check_inuse_station(const struct sla_station *station)
+{
+	struct sla_trunk_ref *trunk_ref;
+
+	AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
+		if (trunk_ref->chan)
+			return 1;
+	}
+
+	return 0;
+}
+
+static struct sla_trunk_ref *sla_find_trunk_ref(const struct sla_station *station,
+	const struct sla_trunk *trunk)
+{
+	struct sla_trunk_ref *trunk_ref = NULL;
+
+	AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
+		if (trunk_ref->trunk == trunk)
+			break;
+	}
+
+	return trunk_ref;
+}
+
+/*! \brief Calculate the ring delay for a given ringing trunk on a station
+ * \param station the station
+ * \param trunk the trunk.  If NULL, the highest priority ringing trunk will be used
+ * \return the delay in seconds or UINT_MAX if there is no delay
+ */
+static int sla_check_station_delay(struct sla_station *station, 
+	struct sla_ringing_trunk *ringing_trunk)
+{
+	struct sla_trunk_ref *trunk_ref;
+	unsigned int delay = UINT_MAX;
+
+	if (!ringing_trunk)
+		ringing_trunk = sla_choose_ringing_trunk(station, 0);
+
+	if (!(trunk_ref = sla_find_trunk_ref(station, ringing_trunk->trunk)))
+		return delay;
+
+	/* If this station has a ring delay specific to the highest priority
+	 * ringing trunk, use that.  Otherwise, use the ring delay specified
+	 * globally for the station. */
+	delay = trunk_ref->ring_delay;
+	if (!delay)
+		delay = station->ring_delay;
+
+	return delay;
+}
+
 /*! \brief Ring stations based on current set of ringing trunks
  * \note Assumes that sla.lock is locked
  */
@@ -3444,8 +3498,14 @@
 	 * trunks, is ringing. */
 	AST_LIST_TRAVERSE(&sla.ringing_trunks, ringing_trunk, entry) {
 		AST_LIST_TRAVERSE(&ringing_trunk->trunk->stations, station_ref, entry) {
+			unsigned int delay;
+
 			/* Is this station already ringing? */
 			if (sla_check_ringing_station(station_ref->station))
+				continue;
+
+			/* Is this station already in a call? */
+			if (sla_check_inuse_station(station_ref->station))
 				continue;
 
 			/* Did we fail to dial this station earlier?  If so, has it been
@@ -3458,9 +3518,10 @@
 			if (sla_check_timed_out_station(ringing_trunk, station_ref->station))
 				continue;
 
-			/* Check for a ring delay.  First, see if there is a ring delay set
-			 * globally for the station.  If not, check to see if there is a ring
-			 * delay for the highest priority ringing trunk for this station. */
+			/* Check for a ring delay in progress */
+			delay = sla_check_station_delay(station_ref->station, ringing_trunk);
+			if (delay != UINT_MAX && delay > 0)
+				continue;
 
 			/* It is time to make this station begin to ring.  Do it! */
 			sla_ring_station(ringing_trunk, station_ref->station);
@@ -3469,16 +3530,11 @@
 	/* Now, all of the stations that should be ringing, are ringing. */
 }
 
-static void sla_handle_ringing_trunk_event(void)
+static void sla_hangup_stations(void)
 {
 	struct sla_trunk_ref *trunk_ref;
 	struct sla_ringing_station *ringing_station;
 
-	ast_mutex_lock(&sla.lock);
-	sla_ring_stations();
-	ast_mutex_unlock(&sla.lock);
-
-	/* Find stations that shouldn't be ringing anymore. */
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&sla.ringing_stations, ringing_station, entry) {
 		AST_LIST_TRAVERSE(&ringing_station->station->trunks, trunk_ref, entry) {
 			struct sla_ringing_trunk *ringing_trunk;
@@ -3500,6 +3556,16 @@
 		}
 	}
 	AST_LIST_TRAVERSE_SAFE_END
+}
+
+static void sla_handle_ringing_trunk_event(void)
+{
+	ast_mutex_lock(&sla.lock);
+	sla_ring_stations();
+	ast_mutex_unlock(&sla.lock);
+
+	/* Find stations that shouldn't be ringing anymore. */
+	sla_hangup_stations();
 }
 
 static void sla_handle_hold_event(struct sla_event *event)
@@ -3621,6 +3687,52 @@
 	return res;
 }
 
+/*! \brief Calculate the ring delay for a station
+ * \note Assumes sla.lock is locked
+ */
+static int sla_calc_station_delays(unsigned int *timeout)
+{
+	struct sla_station *station;
+	int res = 0;
+
+	AST_LIST_TRAVERSE(&sla_stations, station, entry) {
+		struct sla_ringing_trunk *ringing_trunk;
+		unsigned int delay;
+		int time_left, time_elapsed;
+
+		/* Ignore stations already ringing */
+		if (sla_check_ringing_station(station))
+			continue;
+
+		/* Ignore stations already on a call */
+		if (sla_check_inuse_station(station))
+			continue;
+
+		/* Ignore stations that don't have one of their trunks ringing */
+		if (!(ringing_trunk = sla_choose_ringing_trunk(station, 0)))
+			continue;
+
+		if ((delay = sla_check_station_delay(station, ringing_trunk)) == UINT_MAX)
+			continue;
+
+		time_elapsed = ast_tvdiff_ms(ast_tvnow(), ringing_trunk->ring_begin);
+		time_left = (delay * 1000) - time_elapsed;
+
+		/* If there is no time left, then the station needs to be answered.
+		 * Return non-zero so that an event will be queued up an event to 
+		 * make that happen. */
+		if (time_left <= 0) {
+			res = 1;
+			continue;
+		}
+
+		if (time_left < *timeout)
+			*timeout = time_left;
+	}
+
+	return res;
+}
+
 /*! \brief Calculate the time until the next known event
  *  \note Called with sla.lock locked */
 static int sla_process_timers(struct timespec *ts)
@@ -3638,7 +3750,8 @@
 		change_made = 1;
 
 	/* Check for station ring delays */
-	/* XXX */
+	if (sla_calc_station_delays(&timeout))
+		change_made = 1;
 
 	/* queue reprocessing of ringing trunks */
 	if (change_made)
@@ -3863,7 +3976,7 @@
 
 	AST_RWLIST_RDLOCK(&sla_trunks);
 	if (!ast_strlen_zero(trunk_name))
-		trunk_ref = sla_find_trunk_ref(station, trunk_name);
+		trunk_ref = sla_find_trunk_ref_byname(station, trunk_name);
 	else
 		trunk_ref = sla_choose_idle_trunk(station);
 	AST_RWLIST_UNLOCK(&sla_trunks);



More information about the asterisk-commits mailing list