[svn-commits] jrose: branch jrose/bridge_projects r381253 - in /team/jrose/bridge_projects:...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Feb 11 16:48:51 CST 2013


Author: jrose
Date: Mon Feb 11 16:48:47 2013
New Revision: 381253

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=381253
Log:
bridge construction: Interval Hooks continued

Support LIMIT_CONNECT_FILE variable. Add a sequence number to interval hooks.
Interpret 'timeleft' value for sound files within the interval hook rather than
at the consumer level.

Modified:
    team/jrose/bridge_projects/include/asterisk/bridging_features.h
    team/jrose/bridge_projects/main/bridging.c
    team/jrose/bridge_projects/main/features.c

Modified: team/jrose/bridge_projects/include/asterisk/bridging_features.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/bridging_features.h?view=diff&rev=381253&r1=381252&r2=381253
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/bridging_features.h (original)
+++ team/jrose/bridge_projects/include/asterisk/bridging_features.h Mon Feb 11 16:48:47 2013
@@ -142,6 +142,8 @@
 	ast_bridge_features_hook_pvt_destructor destructor;
 	/*! Unique data that was passed into us */
 	void *hook_pvt;
+	/*! Sequence number for the hook if it is an interval hook */
+	unsigned int seqno;
 	/*! Linked list information */
 	AST_LIST_ENTRY(ast_bridge_features_hook) entry;
 	/*! Heap index for interval hooks */
@@ -170,6 +172,8 @@
 	void *talker_pvt_data;
 	/*! Feature flags that are enabled */
 	struct ast_flags feature_flags;
+	/*! Used to assign the sequence number to the next interval hook added. */
+	unsigned int interval_sequence;
 	/*! Bit to indicate that the feature_flags and hook list is setup */
 	unsigned int usable:1;
 	/*! Bit to indicate whether the channel/bridge is muted or not */
@@ -216,6 +220,10 @@
 	char duration_sound[256];
 	/*! Sound file to play when the warning time is reached (if empty, then the remaining time will be played) */
 	char warning_sound[256];
+	/*! Sound file to play when the call is first entered (if empty, then the remaining time will be played) */
+	char connect_sound[256];
+	/*! Time when the bridge will be terminated by the limits feature */
+	struct timeval quitting_time;
 };
 
 /*!

Modified: team/jrose/bridge_projects/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/bridging.c?view=diff&rev=381253&r1=381252&r2=381253
==============================================================================
--- team/jrose/bridge_projects/main/bridging.c (original)
+++ team/jrose/bridge_projects/main/bridging.c Mon Feb 11 16:48:47 2013
@@ -1096,6 +1096,8 @@
 		hook->interval_trip_time = ast_tvadd(start, ast_samp2tv(hook->interval - execution_time, 1000));
 
 		ast_debug(1, "Sticking hook '%p' in heap on '%p'\n", hook, bridge_channel->features);
+
+		hook->seqno = ast_atomic_fetchadd_int((int *)&bridge_channel->features->interval_sequence, +1);
 		ast_heap_push(bridge_channel->features->interval_hooks, hook);
 	}
 }
@@ -1967,6 +1969,7 @@
 	ast_debug(1, "Putting interval hook '%p' in the interval hooks heap on features '%p'\n",
 		hook, features);
 	hook->interval_trip_time = ast_tvadd(ast_tvnow(), ast_samp2tv(hook->interval, 1000));
+	hook->seqno = ast_atomic_fetchadd_int((int *)&features->interval_sequence, +1);
 	ast_heap_push(features->interval_hooks, hook);
 	features->usable = 1;
 
@@ -2034,21 +2037,71 @@
 	return -1;
 }
 
-static int bridge_features_warning_sound_callback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
+static void limits_interval_playback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_bridge_features_limits *limits, char *file)
+{
+	if (!strcasecmp(file, "timeleft")) {
+
+		unsigned int remaining = 0;
+		remaining = ast_tvdiff_ms(limits->quitting_time, ast_tvnow()) / 1000;
+
+		if (remaining > 0) {
+			unsigned int min;
+			unsigned int sec;
+
+			if ((remaining / 60) > 1) {
+				min = remaining / 60;
+				sec = remaining % 60;
+			} else {
+				min = 0;
+				sec = remaining;
+			}
+
+			ast_stream_and_wait(bridge_channel->chan, "vm-youhave", AST_DIGIT_NONE);
+			if (min) {
+				ast_say_number(bridge_channel->chan, min, AST_DIGIT_NONE,
+					ast_channel_language(bridge_channel->chan), NULL);
+				ast_stream_and_wait(bridge_channel->chan, "queue-minutes", AST_DIGIT_NONE);
+			}
+			if (sec) {
+				ast_say_number(bridge_channel->chan, sec, AST_DIGIT_NONE,
+					ast_channel_language(bridge_channel->chan), NULL);
+				ast_stream_and_wait(bridge_channel->chan, "queue-seconds", AST_DIGIT_NONE);
+			}
+
+			/* It may be necessary to resume music on hold after we finish playing the announcment. */
+			if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_MOH)) {
+				ast_moh_start(bridge_channel->chan, NULL, NULL);
+			}
+		}
+
+	} else {
+		if (bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT) {
+			ast_debug(1, "Skipping warning, the channel state is already set to leave bridge.\n");
+			return;
+		}
+
+		ast_stream_and_wait(bridge_channel->chan, file, AST_DIGIT_NONE);
+
+		/* It may be necessary to resume music on hold after we play the sound file. */
+		if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_MOH)) {
+			ast_moh_start(bridge_channel->chan, NULL, NULL);
+		}
+
+	}
+}
+
+static int bridge_features_connect_callback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 {
 	struct ast_bridge_features_limits *limits = hook_pvt;
-
-	if (bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT) {
-		ast_debug(1, "Skipping warning, the channel state is already set to leave bridge.\n");
-		return -1;
-	}
-
-	ast_stream_and_wait(bridge_channel->chan, limits->warning_sound, AST_DIGIT_NONE);
-
-	/* It may be necessary to resume music on hold after we play the sound file. */
-	if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_MOH)) {
-		ast_moh_start(bridge_channel->chan, NULL, NULL);
-	}
+	limits_interval_playback(bridge, bridge_channel, limits, limits->connect_sound);
+	return -1;
+}
+
+static int bridge_features_warning_callback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
+{
+	struct ast_bridge_features_limits *limits = hook_pvt;
+
+	limits_interval_playback(bridge, bridge_channel, limits, limits->warning_sound);
 
 	if (limits->frequency) {
 		ast_bridge_features_interval_update(bridge_channel, limits->frequency);
@@ -2057,65 +2110,6 @@
 	return !limits->frequency ? -1 : 0;
 }
 
-static int bridge_features_warning_time_left_callback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
-{
-	struct ast_bridge_features_limits *limits = hook_pvt;
-	struct ast_bridge_features_hook *interval_hook;
-	unsigned int remaining = 0;
-	int heap_traversal_index;
-	int heap_size;
-
-	if (bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT) {
-		ast_debug(1, "Skipping warning, the channel state is already set to leave bridge.\n");
-		return -1;
-	}
-
-	heap_size = ast_heap_size(bridge_channel->features->interval_hooks);
-	for (heap_traversal_index = 0; heap_traversal_index < heap_size; heap_traversal_index++) {
-		interval_hook = ast_heap_peek(bridge_channel->features->interval_hooks, heap_traversal_index + 1);
-		if (interval_hook->callback == bridge_features_duration_callback) {
-			remaining = ast_tvdiff_ms(interval_hook->interval_trip_time, ast_tvnow()) / 1000;
-			break;
-		}
-	}
-
-	if (remaining > 0) {
-		unsigned int min;
-		unsigned int sec;
-
-		if ((remaining / 60) > 1) {
-			min = remaining / 60;
-			sec = remaining % 60;
-		} else {
-			min = 0;
-			sec = remaining;
-		}
-
-		ast_stream_and_wait(bridge_channel->chan, "vm-youhave", AST_DIGIT_NONE);
-		if (min) {
-			ast_say_number(bridge_channel->chan, min, AST_DIGIT_NONE,
-				ast_channel_language(bridge_channel->chan), NULL);
-			ast_stream_and_wait(bridge_channel->chan, "queue-minutes", AST_DIGIT_NONE);
-		}
-		if (sec) {
-			ast_say_number(bridge_channel->chan, sec, AST_DIGIT_NONE,
-				ast_channel_language(bridge_channel->chan), NULL);
-			ast_stream_and_wait(bridge_channel->chan, "queue-seconds", AST_DIGIT_NONE);
-		}
-
-		/* It may be necessary to resume music on hold after we finish playing the announcment. */
-		if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_MOH)) {
-			ast_moh_start(bridge_channel->chan, NULL, NULL);
-		}
-	}
-
-	if (limits->frequency) {
-		ast_bridge_features_interval_update(bridge_channel, limits->frequency);
-	}
-
-	return !limits->frequency ? -1 : 0;
-}
-
 void ast_bridge_features_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits)
 {
 	if (!limits->duration) {
@@ -2125,11 +2119,15 @@
 	ast_bridge_features_interval_hook(features, limits->duration, 0,
 		bridge_features_duration_callback, limits, NULL);
 
+	limits->quitting_time = ast_tvadd(ast_tvnow(), ast_samp2tv(limits->duration, 1000));
+
+	if (!ast_strlen_zero(limits->connect_sound)) {
+		ast_bridge_features_interval_hook(features, 1, 1, bridge_features_connect_callback, limits, NULL);
+	}
+
 	if (limits->warning && limits->warning < limits->duration) {
 		ast_bridge_features_interval_hook(features, limits->warning, 1,
-			!ast_strlen_zero(limits->warning_sound)
-				? bridge_features_warning_sound_callback
-				: bridge_features_warning_time_left_callback,
+			bridge_features_warning_callback,
 			limits, NULL);
 	}
 }
@@ -2144,8 +2142,17 @@
 {
 	struct ast_bridge_features_hook *hook_a = a;
 	struct ast_bridge_features_hook *hook_b = b;
-
-	return ast_tvcmp(hook_b->interval_trip_time, hook_a->interval_trip_time);
+	int tvcmp_res = ast_tvcmp(hook_b->interval_trip_time, hook_a->interval_trip_time);
+
+	if (tvcmp_res) {
+		return tvcmp_res;
+	}
+
+	if (hook_b->seqno < hook_a->seqno) {
+		return -1;
+	}
+
+	return 1;
 }
 
 int ast_bridge_features_init(struct ast_bridge_features *features)

Modified: team/jrose/bridge_projects/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/features.c?view=diff&rev=381253&r1=381252&r2=381253
==============================================================================
--- team/jrose/bridge_projects/main/features.c (original)
+++ team/jrose/bridge_projects/main/features.c Mon Feb 11 16:48:47 2013
@@ -4367,11 +4367,18 @@
 
 static void bridge_config_set_limits_warning_values(struct ast_bridge_config *config, struct ast_bridge_features_limits *limits)
 {
-	ast_copy_string(limits->duration_sound, config->end_sound, sizeof(limits->duration_sound));
-
-/* BUGBUG 'timeleft' is a hard-coded value that is set when the argument isn't provided. This should probably be changed. */
-	if (strcmp("timeleft", config->warning_sound)) {
+	if (config->end_sound) {
+		ast_copy_string(limits->duration_sound, config->end_sound, sizeof(limits->duration_sound));
+	}
+
+	if (config->warning_sound) {
 		ast_copy_string(limits->warning_sound, config->warning_sound, sizeof(limits->warning_sound));
+	}
+
+	if (config->start_sound) {
+		ast_copy_string(limits->connect_sound, config->start_sound, sizeof(limits->connect_sound));
+	} else {
+		ast_copy_string(limits->connect_sound, "timeleft", sizeof(limits->connect_sound));
 	}
 
 	limits->frequency = config->warning_freq;




More information about the svn-commits mailing list