[asterisk-commits] jrose: branch 12 r413196 - in /branches/12: ./ res/parking/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri May 2 10:58:38 CDT 2014


Author: jrose
Date: Fri May  2 10:58:27 2014
New Revision: 413196

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=413196
Log:
Parking: Add 'AnnounceChannel' argument to manager action 'Park'

(closes ASTERISK-23397)
Reported by: Denis
Review: https://reviewboard.asterisk.org/r/3446/

Modified:
    branches/12/CHANGES
    branches/12/res/parking/parking_bridge_features.c
    branches/12/res/parking/parking_manager.c
    branches/12/res/parking/res_parking.h

Modified: branches/12/CHANGES
URL: http://svnview.digium.com/svn/asterisk/branches/12/CHANGES?view=diff&rev=413196&r1=413195&r2=413196
==============================================================================
--- branches/12/CHANGES (original)
+++ branches/12/CHANGES Fri May  2 10:58:27 2014
@@ -39,6 +39,15 @@
      In the case of PAI, a Privacy: id header will be appended for prohibited
      calling information to communicate that the private information should
      not be relayed to untrusted parties.
+
+res_parking
+------------------
+ * Manager action 'Park' now takes an additional argument 'AnnounceChannel'
+   which can be used to announce the parked call's location to an arbitrary
+   channel in a bridge. If 'Channel' and 'TimeoutChannel' are now the two
+   parties in a one to one bridge, 'TimeoutChannel' is treated as having
+   parked 'Channel' like with the Park Call DTMF feature and will receive
+   announcements prior to being hung up.
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 12.1.0 to Asterisk 12.2.0 ------------
@@ -1413,7 +1422,6 @@
    what the script provides will be needed.
 
 ------------------------------------------------------------------------------
->>>>>>> .merge-right.r412746
 --- Functionality changes from Asterisk 10 to Asterisk 11 --------------------
 ------------------------------------------------------------------------------
 

Modified: branches/12/res/parking/parking_bridge_features.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/parking/parking_bridge_features.c?view=diff&rev=413196&r1=413195&r2=413196
==============================================================================
--- branches/12/res/parking/parking_bridge_features.c (original)
+++ branches/12/res/parking/parking_bridge_features.c Fri May  2 10:58:27 2014
@@ -50,6 +50,7 @@
 
 struct parked_subscription_data {
 	char *parkee_uuid;
+	int hangup_after:1;
 	char parker_uuid[0];
 };
 
@@ -114,7 +115,7 @@
 
 	if (message->event_type == PARKED_CALL) {
 		/* queue the saynum on the bridge channel and hangup */
-		snprintf(saynum_buf, sizeof(saynum_buf), "%u %u", 1, message->parkingspace);
+		snprintf(saynum_buf, sizeof(saynum_buf), "%u %u", data->hangup_after, message->parkingspace);
 		ast_bridge_channel_queue_playfile(bridge_channel, say_parking_space, saynum_buf, NULL);
 		wipe_subscription_datastore(bridge_channel->chan);
 	}
@@ -138,7 +139,7 @@
 	}
 }
 
-static int create_parked_subscription(struct ast_channel *chan, const char *parkee_uuid)
+int create_parked_subscription(struct ast_channel *chan, const char *parkee_uuid, int hangup_after)
 {
 	struct ast_datastore *datastore;
 	struct parked_subscription_datastore *parked_datastore;
@@ -166,6 +167,7 @@
 		return -1;
 	}
 
+	subscription_data->hangup_after = hangup_after;
 	subscription_data->parkee_uuid = subscription_data->parker_uuid + parker_uuid_size;
 	strcpy(subscription_data->parkee_uuid, parkee_uuid);
 	strcpy(subscription_data->parker_uuid, parker_uuid);
@@ -218,7 +220,7 @@
 	ast_channel_unlock(parkee);
 
 	/* We need to have the parker subscribe to the new local channel before hand. */
-	create_parked_subscription(parker, ast_channel_uniqueid(parkee_side_2));
+	create_parked_subscription(parker, ast_channel_uniqueid(parkee_side_2), 1);
 
 	ast_bridge_set_transfer_variables(parkee_side_2, ast_channel_name(parker), 0);
 
@@ -325,7 +327,7 @@
 	}
 
 	/* Subscribe to park messages with the other channel entering */
-	if (create_parked_subscription(bridge_channel->chan, ast_channel_uniqueid(other->chan))) {
+	if (create_parked_subscription(bridge_channel->chan, ast_channel_uniqueid(other->chan), 1)) {
 		return -1;
 	}
 

Modified: branches/12/res/parking/parking_manager.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/parking/parking_manager.c?view=diff&rev=413196&r1=413195&r2=413196
==============================================================================
--- branches/12/res/parking/parking_manager.c (original)
+++ branches/12/res/parking/parking_manager.c Fri May  2 10:58:27 2014
@@ -74,11 +74,21 @@
 				<para>Channel name to park.</para>
 			</parameter>
 			<parameter name="TimeoutChannel" required="false">
-				<para>Channel name to use when constructing the dial string that will be dialed if the parked channel times out.</para>
+				<para>Channel name to use when constructing the dial string that will be dialed if the parked channel
+				times out. If <literal>TimeoutChannel</literal> is in a two party bridge with
+				<literal>Channel</literal>, then <literal>TimeoutChannel</literal> will receive an announcement and be
+				treated as having parked <literal>Channel</literal> in the same manner as the Park Call DTMF feature.
+				</para>
+			</parameter>
+			<parameter name="AnnounceChannel" required="false">
+				<para>If specified, then this channel will receive an announcement when <literal>Channel</literal>
+				is parked if <literal>AnnounceChannel</literal> is in a state where it can receive announcements
+				(AnnounceChannel must be bridged). <literal>AnnounceChannel</literal> has no bearing on the actual
+				state of the parked call.</para>
 			</parameter>
 			<parameter name="Timeout" required="false">
 				<para>Overrides the timeout of the parking lot for this park action. Specified in milliseconds, but will be converted to
-					seconds. Use a value of 0 to nullify the timeout.
+					seconds. Use a value of 0 to disable the timeout.
 				</para>
 			</parameter>
 			<parameter name="Parkinglot" required="false">
@@ -420,17 +430,85 @@
 	return 0;
 }
 
+static void manager_park_unbridged(struct mansession *s, const struct message *m,
+		struct ast_channel *chan, const char *parkinglot, int timeout_override)
+{
+	struct ast_bridge *parking_bridge = park_common_setup(chan,
+		chan, parkinglot, NULL, 0, 0, timeout_override, 1);
+
+	if (!parking_bridge) {
+		astman_send_error(s, m, "Park action failed\n");
+		return;
+	}
+
+	if (ast_bridge_add_channel(parking_bridge, chan, NULL, 0, NULL)) {
+		astman_send_error(s, m, "Park action failed\n");
+		ao2_cleanup(parking_bridge);
+		return;
+	}
+
+	astman_send_ack(s, m, "Park successful\n");
+	ao2_cleanup(parking_bridge);
+}
+
+static void manager_park_bridged(struct mansession *s, const struct message *m,
+		struct ast_channel *chan, struct ast_channel *parker_chan,
+		const char *parkinglot, int timeout_override)
+{
+	struct ast_bridge_channel *bridge_channel;
+	char *app_data;
+
+	if (timeout_override != -1) {
+		if (ast_asprintf(&app_data, "%s,t(%d)", parkinglot, timeout_override) == -1) {
+			astman_send_error(s, m, "Park action failed\n");
+			return;
+		}
+	} else {
+		if (ast_asprintf(&app_data, "%s", parkinglot) == -1) {
+			astman_send_error(s, m, "Park action failed\n");
+			return;
+		}
+	}
+
+	ast_channel_lock(parker_chan);
+	bridge_channel = ast_channel_get_bridge_channel(parker_chan);
+	ast_channel_unlock(parker_chan);
+
+	if (!bridge_channel) {
+		ast_free(app_data);
+		astman_send_error(s, m, "Park action failed\n");
+		return;
+	}
+
+	/* Subscribe to park messages for the channel being parked */
+	if (create_parked_subscription(parker_chan, ast_channel_uniqueid(chan), 1)) {
+		ast_free(app_data);
+		astman_send_error(s, m, "Park action failed\n");
+		ao2_cleanup(bridge_channel);
+		return;
+	}
+
+	ast_bridge_channel_write_park(bridge_channel, ast_channel_uniqueid(chan),
+			ast_channel_uniqueid(parker_chan), app_data);
+
+	ast_free(app_data);
+
+	astman_send_ack(s, m, "Park successful\n");
+	ao2_cleanup(bridge_channel);
+}
+
 static int manager_park(struct mansession *s, const struct message *m)
 {
 	const char *channel = astman_get_header(m, "Channel");
 	const char *timeout_channel = S_OR(astman_get_header(m, "TimeoutChannel"), astman_get_header(m, "Channel2"));
+	const char *announce_channel = astman_get_header(m, "AnnounceChannel");
 	const char *timeout = astman_get_header(m, "Timeout");
 	const char *parkinglot = astman_get_header(m, "Parkinglot");
 	char buf[BUFSIZ];
 	int timeout_override = -1;
 
+	RAII_VAR(struct ast_channel *, parker_chan, NULL, ao2_cleanup);
 	RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup);
-	RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
 
 	if (ast_strlen_zero(channel)) {
 		astman_send_error(s, m, "Channel not specified");
@@ -461,17 +539,37 @@
 	}
 	ast_channel_unlock(chan);
 
-	if (!(parking_bridge = park_common_setup(chan, chan, parkinglot, NULL, 0, 0, timeout_override, 0))) {
-		astman_send_error(s, m, "Park action failed\n");
+	parker_chan = ast_channel_bridge_peer(chan);
+	if (!parker_chan || strcmp(ast_channel_name(parker_chan), timeout_channel)) {
+		if (!ast_strlen_zero(announce_channel)) {
+			struct ast_channel *announce_chan = ast_channel_get_by_name(announce_channel);
+			if (!announce_channel) {
+				astman_send_error(s, m, "AnnounceChannel does not exist");
+				return 0;
+			}
+
+			create_parked_subscription(announce_chan, ast_channel_uniqueid(chan), 0);
+			ast_channel_cleanup(announce_chan);
+		}
+
+		manager_park_unbridged(s, m, chan, parkinglot, timeout_override);
 		return 0;
 	}
 
-	if (ast_bridge_add_channel(parking_bridge, chan, NULL, 0, NULL)) {
-		astman_send_error(s, m, "Park action failed\n");
-		return 0;
-	}
-
-	astman_send_ack(s, m, "Park successful\n");
+	if (!ast_strlen_zero(announce_channel) && strcmp(announce_channel, timeout_channel)) {
+		/* When using an announce_channel in bridge mode, only add the announce channel if it isn't
+		 * the same as the timeout channel (which will play announcements anyway) */
+		struct ast_channel *announce_chan = ast_channel_get_by_name(announce_channel);
+		if (!announce_channel) {
+			astman_send_error(s, m, "AnnounceChannel does not exist");
+			return 0;
+		}
+
+		create_parked_subscription(announce_chan, ast_channel_uniqueid(chan), 0);
+		ast_channel_cleanup(announce_chan);
+	}
+
+	manager_park_bridged(s, m, chan, parker_chan, parkinglot, timeout_override);
 	return 0;
 }
 

Modified: branches/12/res/parking/res_parking.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/parking/res_parking.h?view=diff&rev=413196&r1=413195&r2=413196
==============================================================================
--- branches/12/res/parking/res_parking.h (original)
+++ branches/12/res/parking/res_parking.h Fri May  2 10:58:27 2014
@@ -386,6 +386,19 @@
 void publish_parked_call(struct parked_user *pu, enum ast_parked_call_event_type event_type);
 
 /*!
+ * \since 12.3.0
+ * \brief Create a parking announcement subscription
+ *
+ * \param chan Channel that will receive the announcement
+ * \param parkee_uuid Unique ID of the channel being parked
+ * \param hangup_after if non-zero, have the channel hangup after hearing the announcement
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int create_parked_subscription(struct ast_channel *chan, const char *parkee_uuid, int hangup_after);
+
+/*!
  * \since 12.0.0
  * \brief Setup a parked call on a parking bridge without needing to parse appdata
  *




More information about the asterisk-commits mailing list