[asterisk-commits] jrose: trunk r393704 - in /trunk: ./ bridges/ include/asterisk/ main/ res/par...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jul 4 13:47:03 CDT 2013


Author: jrose
Date: Thu Jul  4 13:46:56 2013
New Revision: 393704

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=393704
Log:
res_parking: Replace Parker snapshots with ParkerDialString

This process also involved a large amount of rework regarding how to redial
the Parker when a channel leaves a parking lot due to timeout. An attended
transfer channel variable has been added to attended transfers to extensions
that will eventually park (but haven't at the time of transfer) as well.
This resolves one of the two BUGBUG comments remaining in res_parking.

(issues ASTERISK-21877)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2638/

Modified:
    trunk/CHANGES
    trunk/UPGRADE.txt
    trunk/bridges/bridge_builtin_features.c
    trunk/include/asterisk/channel.h
    trunk/include/asterisk/parking.h
    trunk/main/bridging.c
    trunk/main/cel.c
    trunk/main/channel.c
    trunk/main/features.c
    trunk/main/parking.c
    trunk/res/parking/parking_applications.c
    trunk/res/parking/parking_bridge.c
    trunk/res/parking/parking_bridge_features.c
    trunk/res/parking/parking_controller.c
    trunk/res/parking/parking_manager.c
    trunk/res/parking/parking_ui.c
    trunk/res/parking/res_parking.h

Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Thu Jul  4 13:46:56 2013
@@ -136,6 +136,10 @@
    feature on the bridge peer in a multi-party bridge will execute it on all
    peers of the activating channel.
 
+ * A channel variable ATTENDEDTRANSFER is now set which indicates which channel
+   was responsible for an attended transfer in a similar fashion to
+   BLINDTRANSFER.
+
 AMI (Asterisk Manager Interface)
 ------------------
  * The SIPshowpeer action will now include a 'SubscribeContext' field for a peer
@@ -176,12 +180,24 @@
 
  * The AMI events 'ParkedCall', 'ParkedCallTimeOut', 'ParkedCallGiveUp', and
    'UnParkedCall' have changed significantly in the new res_parking module.
-   First, channel snapshot data is included for both the parker and the parkee
-   in lieu of the "From" and "Channel" fields. They follow standard channel
-   snapshot format but each field is suffixed with 'Parker' or 'Parkee'
-   depending on which side it applies to. The 'Exten' field is replaced with
-   'ParkingSpace' since the registration of extensions as for parking spaces
-   is no longer mandatory.
+
+   The 'Channel' and 'From' headers are gone. For the channel that was parked
+   or is coming out of parking, a 'Parkee' channel snapshot is issued and it
+   has a number of fields associated with it. The old 'Channel' header relayed
+   the same data as the new 'ParkeeChannel' header.
+
+   The 'From' field was ambiguous and changed meaning depending on the event.
+   for most of these, it was the name of the channel that parked the call
+   (the 'Parker'). There is no longer a header that provides this channel name,
+   however the 'ParkerDialString' will contain a dialstring to redial the
+   device that parked the call.
+
+   On UnParkedCall events, the 'From' header would instead represent the
+   channel responsible for retrieving the parkee. It receives a channel
+   snapshot labeled 'Retriever'. The 'from' field is is replaced with
+   'RetrieverChannel'.
+
+   Lastly, the 'Exten' field has been replaced with 'ParkingSpace'.
 
  * The AMI event 'Parkinglot' (response to 'Parkinglots' command) in a similar
    fashion has changed the field names 'StartExten' and 'StopExten' to

Modified: trunk/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/trunk/UPGRADE.txt?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/UPGRADE.txt (original)
+++ trunk/UPGRADE.txt Thu Jul  4 13:46:56 2013
@@ -75,6 +75,22 @@
    - Channels no longer swap Uniqueid's as a result of the masquerade.
    - Instead of a shell game of renames, there's now a single rename, appending
      <ZOMBIE> to the name of the original channel.
+ - The AMI events 'ParkedCall', 'ParkedCallTimeOut', 'ParkedCallGiveUp', and
+   'UnParkedCall' have changed significantly in the new res_parking module.
+   - The 'Channel' and 'From' headers are gone. For the channel that was parked
+     or is coming out of parking, a 'Parkee' channel snapshot is issued and it
+     has a number of fields associated with it. The old 'Channel' header relayed
+     the same data as the new 'ParkeeChannel' header.
+   - The 'From' field was ambiguous and changed meaning depending on the event.
+     for most of these, it was the name of the channel that parked the call
+     (the 'Parker'). There is no longer a header that provides this channel name,
+     however the 'ParkerDialString' will contain a dialstring to redial the
+     device that parked the call.
+   - On UnParkedCall events, the 'From' header would instead represent the
+     channel responsible for retrieving the parkee. It receives a channel
+     snapshot labeled 'Retriever'. The 'from' field is is replaced with
+     'RetrieverChannel'.
+   - Lastly, the 'Exten' field has been replaced with 'ParkingSpace'.
 
 CEL:
  - The Uniqueid field for a channel is now a stable identifier, and will not

Modified: trunk/bridges/bridge_builtin_features.c
URL: http://svnview.digium.com/svn/asterisk/trunk/bridges/bridge_builtin_features.c?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/bridges/bridge_builtin_features.c (original)
+++ trunk/bridges/bridge_builtin_features.c Thu Jul  4 13:46:56 2013
@@ -139,6 +139,9 @@
 
 	/* Who is transferring the call. */
 	pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", ast_channel_name(caller));
+
+	/* To work as an analog to BLINDTRANSFER */
+	pbx_builtin_setvar_helper(chan, "ATTENDEDTRANSFER", ast_channel_name(caller));
 
 	/* Before we actually dial out let's inherit appropriate information. */
 	copy_caller_data(chan, caller);

Modified: trunk/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/channel.h?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/include/asterisk/channel.h (original)
+++ trunk/include/asterisk/channel.h Thu Jul  4 13:46:56 2013
@@ -4375,5 +4375,13 @@
 */
 const char *ast_channel_oldest_linkedid(const char *a, const char *b);
 
+/*!
+ * \brief Removes the trailing identifiers from a channel name string
+ * \since 12.0.0
+ *
+ * \param channel_name string that you wish to turn into a dial string.
+ *                     This string will be edited in place.
+ */
+void ast_channel_name_to_dial_string(char *channel_name);
 
 #endif /* _ASTERISK_CHANNEL_H */

Modified: trunk/include/asterisk/parking.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/parking.h?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/include/asterisk/parking.h (original)
+++ trunk/include/asterisk/parking.h Thu Jul  4 13:46:56 2013
@@ -45,14 +45,14 @@
  */
 struct ast_parked_call_payload {
 	struct ast_channel_snapshot *parkee;             /*!< Snapshot of the channel that is parked */
-	struct ast_channel_snapshot *parker;             /*!< Snapshot of the channel that parked the call */
-	struct ast_channel_snapshot *retriever;          /*!< Snapshot of the channel that retrieved the call */
+	struct ast_channel_snapshot *retriever;          /*!< Snapshot of the channel that retrieved the call (may be NULL) */
 	enum ast_parked_call_event_type event_type;      /*!< Reason for issuing the parked call message */
 	long unsigned int timeout;                       /*!< Time remaining before the call times out (seconds ) */
 	long unsigned int duration;                      /*!< How long the parkee has been parked (seconds) */
 	unsigned int parkingspace;                       /*!< Which Parking Space the parkee occupies */
 	AST_DECLARE_STRING_FIELDS(
 		AST_STRING_FIELD(parkinglot);                /*!< Name of the parking lot used to park the parkee */
+		AST_STRING_FIELD(parker_dial_string);          /*!< The device string used for call control on parking timeout */
 	);
 };
 
@@ -64,7 +64,7 @@
  *
  * \param event_type What kind of parked call event is happening
  * \param parkee_snapshot channel snapshot of the parkee
- * \param parker_snapshot channel snapshot of the parker
+ * \param parker_dial_string dialstring used when the call times out
  * \param retriever_snapshot channel snapshot of the retriever (NULL allowed)
  * \param parkinglot name of the parking lot where the parked call is parked
  * \param parkingspace what numerical parking space the parked call is parked in
@@ -75,7 +75,7 @@
  * \retval reference to a newly created parked call payload
  */
 struct ast_parked_call_payload *ast_parked_call_payload_create(enum ast_parked_call_event_type event_type,
-		struct ast_channel_snapshot *parkee_snapshot, struct ast_channel_snapshot *parker_snapshot,
+		struct ast_channel_snapshot *parkee_snapshot, const char *parker_dial_string,
 		struct ast_channel_snapshot *retriever_snapshot, const char *parkinglot,
 		unsigned int parkingspace, unsigned long int timeout, unsigned long int duration);
 

Modified: trunk/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/bridging.c?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/main/bridging.c (original)
+++ trunk/main/bridging.c Thu Jul  4 13:46:56 2013
@@ -719,8 +719,9 @@
 		bridge_channel_pull(swap);
 	}
 
-	/* Clear any BLINDTRANSFER since the transfer has completed. */
+	/* Clear any BLINDTRANSFER and ATTENDEDTRANSFER since the transfer has completed. */
 	pbx_builtin_setvar_helper(bridge_channel->chan, "BLINDTRANSFER", NULL);
+	pbx_builtin_setvar_helper(bridge_channel->chan, "ATTENDEDTRANSFER", NULL);
 
 	bridge->reconfigured = 1;
 	return 0;

Modified: trunk/main/cel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/cel.c?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/main/cel.c (original)
+++ trunk/main/cel.c Thu Jul  4 13:46:56 2013
@@ -1333,7 +1333,7 @@
 	case PARKED_CALL:
 		report_event_snapshot(parked_payload->parkee, AST_CEL_PARK_START, NULL,
 			parked_payload->parkinglot,
-			S_COR(parked_payload->parker, parked_payload->parker->name, NULL));
+			parked_payload->parker_dial_string);
 		break;
 	case PARKED_CALL_TIMEOUT:
 		report_event_snapshot(parked_payload->parkee, AST_CEL_PARK_END, NULL, "ParkedCallTimeOut", NULL);

Modified: trunk/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/channel.c?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Thu Jul  4 13:46:56 2013
@@ -6562,6 +6562,17 @@
 	}
 	else {
 		return (atime < btime) ? a : b;
+	}
+}
+
+void ast_channel_name_to_dial_string(char *channel_name)
+{
+	char *dash;
+
+	/* Truncate after the dash */
+	dash = strrchr(channel_name, '-');
+	if (dash) {
+		*dash = '\0';
 	}
 }
 

Modified: trunk/main/features.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/features.c?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/main/features.c (original)
+++ trunk/main/features.c Thu Jul  4 13:46:56 2013
@@ -282,46 +282,6 @@
 			<para>Bridge together two channels already in the PBX.</para>
 		</description>
 	</manager>
-	<managerEvent language="en_US" name="ParkedCallTimeOut">
-		<managerEventInstance class="EVENT_FLAG_CALL">
-			<synopsis>Raised when a parked call times out.</synopsis>
-			<syntax>
-				<parameter name="Exten">
-					<para>The parking lot extension.</para>
-				</parameter>
-				<parameter name="Channel"/>
-				<parameter name="Parkinglot">
-					<para>The name of the parking lot.</para>
-				</parameter>
-				<parameter name="CallerIDNum"/>
-				<parameter name="CallerIDName"/>
-				<parameter name="ConnectedLineNum"/>
-				<parameter name="ConnectedLineName"/>
-				<parameter name="UniqueID"/>
-			</syntax>
-			<see-also>
-				<ref type="managerEvent">ParkedCall</ref>
-			</see-also>
-		</managerEventInstance>
-	</managerEvent>
-	<managerEvent language="en_US" name="ParkedCallGiveUp">
-		<managerEventInstance class="EVENT_FLAG_CALL">
-			<synopsis>Raised when a parked call hangs up while in the parking lot.</synopsis>
-			<syntax>
-				<xi:include xpointer="xpointer(/docs/managerEvent[@name='ParkedCallTimeOut']/managerEventInstance/syntax/parameter[@name='Exten'])" />
-				<parameter name="Channel"/>
-				<xi:include xpointer="xpointer(/docs/managerEvent[@name='ParkedCallTimeOut']/managerEventInstance/syntax/parameter[@name='Parkinglot'])" />
-				<parameter name="CallerIDNum"/>
-				<parameter name="CallerIDName"/>
-				<parameter name="ConnectedLineNum"/>
-				<parameter name="ConnectedLineName"/>
-				<parameter name="UniqueID"/>
-			</syntax>
-			<see-also>
-				<ref type="managerEvent">ParkedCall</ref>
-			</see-also>
-		</managerEventInstance>
-	</managerEvent>
 	<managerEvent language="en_US" name="Pickup">
 		<managerEventInstance class="EVENT_FLAG_CALL">
 			<synopsis>Raised when a call pickup occurs.</synopsis>

Modified: trunk/main/parking.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/parking.c?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/main/parking.c (original)
+++ trunk/main/parking.c Thu Jul  4 13:46:56 2013
@@ -79,13 +79,12 @@
 	struct ast_parked_call_payload *park_obj = obj;
 
 	ao2_cleanup(park_obj->parkee);
-	ao2_cleanup(park_obj->parker);
 	ao2_cleanup(park_obj->retriever);
 	ast_string_field_free_memory(park_obj);
 }
 
 struct ast_parked_call_payload *ast_parked_call_payload_create(enum ast_parked_call_event_type event_type,
-		struct ast_channel_snapshot *parkee_snapshot, struct ast_channel_snapshot *parker_snapshot,
+		struct ast_channel_snapshot *parkee_snapshot, const char *parker_dial_string,
 		struct ast_channel_snapshot *retriever_snapshot, const char *parkinglot,
 		unsigned int parkingspace, unsigned long int timeout,
 		unsigned long int duration)
@@ -106,11 +105,6 @@
 	ao2_ref(parkee_snapshot, +1);
 	payload->parkee = parkee_snapshot;
 
-	if (parker_snapshot) {
-		ao2_ref(parker_snapshot, +1);
-		payload->parker = parker_snapshot;
-	}
-
 	if (retriever_snapshot) {
 		ao2_ref(retriever_snapshot, +1);
 		payload->retriever = retriever_snapshot;
@@ -118,6 +112,10 @@
 
 	if (parkinglot) {
 		ast_string_field_set(payload, parkinglot, parkinglot);
+	}
+
+	if (parker_dial_string) {
+		ast_string_field_set(payload, parker_dial_string, parker_dial_string);
 	}
 
 	payload->parkingspace = parkingspace;

Modified: trunk/res/parking/parking_applications.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/parking/parking_applications.c?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/res/parking/parking_applications.c (original)
+++ trunk/res/parking/parking_applications.c Thu Jul  4 13:46:56 2013
@@ -284,12 +284,22 @@
 	return 0;
 }
 
-static void park_common_datastore_destroy(void *data)
-{
-	struct park_common_datastore *datastore = data;
+void park_common_datastore_free(struct park_common_datastore *datastore)
+{
+	if (!datastore) {
+		return;
+	}
+
 	ast_free(datastore->parker_uuid);
+	ast_free(datastore->parker_dial_string);
 	ast_free(datastore->comeback_override);
 	ast_free(datastore);
+}
+
+static void park_common_datastore_destroy(void *data)
+{
+	struct park_common_datastore *datastore = data;
+	park_common_datastore_free(datastore);
 }
 
 static const struct ast_datastore_info park_common_info = {
@@ -314,6 +324,9 @@
 {
 	struct ast_datastore *datastore = NULL;
 	struct park_common_datastore *park_datastore;
+	const char *attended_transfer;
+	const char *blind_transfer;
+	char *parker_dial_string = NULL;
 
 	wipe_park_common_datastore(parkee);
 
@@ -326,7 +339,27 @@
 		return -1;
 	}
 
-	park_datastore->parker_uuid = ast_strdup(parker_uuid);
+	if (parker_uuid) {
+		park_datastore->parker_uuid = ast_strdup(parker_uuid);
+	}
+
+	ast_channel_lock(parkee);
+
+	attended_transfer = pbx_builtin_getvar_helper(parkee, "ATTENDEDTRANSFER");
+	blind_transfer = pbx_builtin_getvar_helper(parkee, "BLINDTRANSFER");
+
+	if (attended_transfer || blind_transfer) {
+		parker_dial_string = ast_strdupa(S_OR(attended_transfer, blind_transfer));
+	}
+
+	ast_channel_unlock(parkee);
+
+	if (!ast_strlen_zero(parker_dial_string)) {
+		ast_channel_name_to_dial_string(parker_dial_string);
+		ast_verb(5, "Setting dial string to %s from %s value", parker_dial_string, attended_transfer ? "ATTENDEDTRANSFER" : "BLINDTRANSFER");
+		park_datastore->parker_dial_string = ast_strdup(parker_dial_string);
+	}
+
 	park_datastore->randomize = randomize;
 	park_datastore->time_limit = time_limit;
 	park_datastore->silence_announce = silence_announce;
@@ -344,16 +377,15 @@
 	return 0;
 }
 
-void get_park_common_datastore_data(struct ast_channel *parkee, char **parker_uuid, char **comeback_override,
-		int *randomize, int *time_limit, int *silence_announce)
+struct park_common_datastore *get_park_common_datastore_copy(struct ast_channel *parkee)
 {
 	struct ast_datastore *datastore;
 	struct park_common_datastore *data;
-
-	ast_channel_lock(parkee);
+	struct park_common_datastore *data_copy;
+
+	SCOPED_CHANNELLOCK(lock, parkee);
 	if (!(datastore = ast_channel_datastore_find(parkee, &park_common_info, NULL))) {
-		ast_channel_unlock(parkee);
-		return;
+		return NULL;
 	}
 
 	data = datastore->data;
@@ -363,16 +395,37 @@
 		ast_assert(0);
 	}
 
-	*parker_uuid = ast_strdup(data->parker_uuid);
-	*randomize = data->randomize;
-	*time_limit = data->time_limit;
-	*silence_announce = data->silence_announce;
+	data_copy = ast_calloc(1, sizeof(*data_copy));
+	if (!data_copy) {
+		return NULL;
+	}
+
+	if (!(data_copy->parker_uuid = ast_strdup(data->parker_uuid))) {
+		park_common_datastore_free(data_copy);
+		return NULL;
+	}
+
+	data_copy->randomize = data->randomize;
+	data_copy->time_limit = data->time_limit;
+	data_copy->silence_announce = data->silence_announce;
 
 	if (data->comeback_override) {
-		*comeback_override = ast_strdup(data->comeback_override);
-	}
-
-	ast_channel_unlock(parkee);
+		data_copy->comeback_override = ast_strdup(data->comeback_override);
+		if (!data_copy->comeback_override) {
+			park_common_datastore_free(data_copy);
+			return NULL;
+		}
+	}
+
+	if (data->parker_dial_string) {
+		data_copy->parker_dial_string = ast_strdup(data->parker_dial_string);
+		if (!data_copy->parker_dial_string) {
+			park_common_datastore_free(data_copy);
+			return NULL;
+		}
+	}
+
+	return data_copy;
 }
 
 struct ast_bridge *park_common_setup(struct ast_channel *parkee, struct ast_channel *parker,
@@ -381,6 +434,10 @@
 {
 	struct ast_bridge *parking_bridge;
 	RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
+
+	if (!parker) {
+		parker = parkee;
+	}
 
 	/* If the name of the parking lot isn't specified in the arguments, find it based on the channel. */
 	if (ast_strlen_zero(lot_name)) {
@@ -433,18 +490,6 @@
 
 }
 
-/* XXX BUGBUG - determining the parker when transferred to deep park priority
- *     Currently all parking by the park application is treated as calls parking themselves.
- *     However, it's possible for calls to be transferred here when the Park application is
- *     set after the first priority of an extension. In that case, there used to be a variable
- *     (BLINDTRANSFER) set indicating which channel placed that call here.
- *
- *     If BLINDTRANSFER is set, this channel name will need to be referenced in Park events
- *     generated by stasis. Ideally we would get a whole channel snapshot and use that for the
- *     parker, but that would likely require applying the channel snapshot to a channel datastore
- *     on all transfers. Alternatively just the name of the parking channel could be applied along
- *     with an indication that it's dead.
- */
 int park_app_exec(struct ast_channel *chan, const char *data)
 {
 	RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
@@ -452,7 +497,7 @@
 	struct ast_bridge_features chan_features;
 	int res;
 	int silence_announcements = 0;
-	const char *blind_transfer;
+	const char *transferer;
 
 	/* Answer the channel if needed */
 	if (ast_channel_state(chan) != AST_STATE_UP) {
@@ -460,14 +505,15 @@
 	}
 
 	ast_channel_lock(chan);
-	if ((blind_transfer = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER"))) {
-		blind_transfer = ast_strdupa(blind_transfer);
-	}
+	if (!(transferer = pbx_builtin_getvar_helper(chan, "ATTENDEDTRANSFER"))) {
+		transferer = pbx_builtin_getvar_helper(chan, "BLINDTRANSFER");
+	}
+	transferer = ast_strdupa(S_OR(transferer, ""));
 	ast_channel_unlock(chan);
 
 	/* Handle the common parking setup stuff */
-	if (!(parking_bridge = park_application_setup(chan, chan, data, &silence_announcements))) {
-		if (!silence_announcements && !blind_transfer) {
+	if (!(parking_bridge = park_application_setup(chan, NULL, data, &silence_announcements))) {
+		if (!silence_announcements && !transferer) {
 			ast_stream_and_wait(chan, "pbx-parkingfailed", "");
 		}
 		return 0;
@@ -767,7 +813,7 @@
 	}
 
 	/* Handle the common parking setup stuff */
-	if (!(parking_bridge = park_application_setup(chan, chan, data, &silence_announcements))) {
+	if (!(parking_bridge = park_application_setup(chan, NULL, data, &silence_announcements))) {
 		return 0;
 	}
 

Modified: trunk/res/parking/parking_bridge.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/parking/parking_bridge.c?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/res/parking/parking_bridge.c (original)
+++ trunk/res/parking/parking_bridge.c Thu Jul  4 13:46:56 2013
@@ -66,8 +66,23 @@
 	struct parked_user *pu = obj;
 
 	ao2_cleanup(pu->lot);
-	ao2_cleanup(pu->parker);
 	ao2_cleanup(pu->retriever);
+	ast_free(pu->parker_dial_string);
+}
+
+/* Only call this on a parked user that hasn't had its parker_dial_string set already */
+static int parked_user_set_parker_dial_string(struct parked_user *pu, struct ast_channel *parker)
+{
+	char *dial_string = ast_strdupa(ast_channel_name(parker));
+
+	ast_channel_name_to_dial_string(dial_string);
+	pu->parker_dial_string = ast_strdup(dial_string);
+
+	if (!pu->parker_dial_string) {
+		return -1;
+	}
+
+	return 0;
 }
 
 /*!
@@ -78,6 +93,7 @@
  * \param lot The parking lot we are assigning the user to
  * \param parkee The channel being parked
  * \param parker The channel performing the park operation (may be the same channel)
+ * \param parker_dial_string Takes priority over parker for setting the parker dial string if included
  * \param use_random_space if true, prioritize using a random parking space instead
  *        of ${PARKINGEXTEN} and/or automatic assignment from the parking lot
  * \param time_limit If using a custom timeout, this should be supplied so that the
@@ -89,7 +105,7 @@
  *
  * \note ao2_cleanup this reference when you are done using it or you'll cause leaks.
  */
-static struct parked_user *generate_parked_user(struct parking_lot *lot, struct ast_channel *chan, struct ast_channel *parker, int use_random_space, int time_limit)
+static struct parked_user *generate_parked_user(struct parking_lot *lot, struct ast_channel *chan, struct ast_channel *parker, const char *parker_dial_string, int use_random_space, int time_limit)
 {
 	struct parked_user *new_parked_user;
 	int preferred_space = -1; /* Initialize to use parking lot defaults */
@@ -105,10 +121,6 @@
 	if (!new_parked_user) {
 		return NULL;
 	}
-
-	ast_channel_lock(chan);
-	ast_copy_string(new_parked_user->blindtransfer, S_OR(pbx_builtin_getvar_helper(chan, "BLINDTRANSFER"), ""), AST_CHANNEL_NAME);
-	ast_channel_unlock(chan);
 
 	if (use_random_space) {
 		preferred_space = ast_random() % (lot->cfg->parking_stop - lot->cfg->parking_start + 1);
@@ -150,8 +162,18 @@
 
 	new_parked_user->start = ast_tvnow();
 	new_parked_user->time_limit = (time_limit >= 0) ? time_limit : lot->cfg->parkingtime;
-	new_parked_user->parker = ast_channel_snapshot_create(parker);
-	if (!new_parked_user->parker) {
+
+	if (parker_dial_string) {
+		new_parked_user->parker_dial_string = ast_strdup(parker_dial_string);
+	} else {
+		if (parked_user_set_parker_dial_string(new_parked_user, parker)) {
+			ao2_ref(new_parked_user, -1);
+			ao2_unlock(lot);
+			return NULL;
+		}
+	}
+
+	if (!new_parked_user->parker_dial_string) {
 		ao2_ref(new_parked_user, -1);
 		ao2_unlock(lot);
 		return NULL;
@@ -183,13 +205,9 @@
 static int bridge_parking_push(struct ast_bridge_parking *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
 {
 	struct parked_user *pu;
-	int randomize = 0;
-	int time_limit = -1;
-	int silence = 0;
 	const char *blind_transfer;
-	RAII_VAR(struct ast_channel *, parker, NULL, ao2_cleanup);
-	RAII_VAR(char *, parker_uuid, NULL, ast_free);
-	RAII_VAR(char *, comeback_override, NULL, ast_free);
+	RAII_VAR(struct ast_channel *, parker, NULL, ao2_cleanup); /* XXX replace with ast_channel_cleanup when available */
+	RAII_VAR(struct park_common_datastore *, park_datastore, NULL, park_common_datastore_free);
 
 	ast_bridge_base_v_table.push(&self->base, bridge_channel, swap);
 
@@ -231,11 +249,14 @@
 		return 0;
 	}
 
-	get_park_common_datastore_data(bridge_channel->chan, &parker_uuid, &comeback_override, &randomize, &time_limit, &silence);
-	parker = ast_channel_get_by_name(parker_uuid);
+	if (!(park_datastore = get_park_common_datastore_copy(bridge_channel->chan))) {
+		/* There was either a failure to apply the datastore when performing park common setup or else we had alloc failures while cloning. Abort. */
+		return -1;
+	}
+	parker = ast_channel_get_by_name(park_datastore->parker_uuid);
 
 	/* If the parker and the parkee are the same channel pointer, then the channel entered using
-	 * the park application. It's possible the the blindtransfer channel is still alive (particularly
+	 * the park application. It's possible that the channel that transferred it is still alive (particularly
 	 * when a multichannel bridge is parked), so try to get the real parker if possible. */
 	ast_channel_lock(bridge_channel->chan);
 	blind_transfer = S_OR(pbx_builtin_getvar_helper(bridge_channel->chan, "BLINDTRANSFER"),
@@ -253,19 +274,17 @@
 		}
 	}
 
-	if (!parker) {
-		return -1;
-	}
-
-	pu = generate_parked_user(self->lot, bridge_channel->chan, parker, randomize, time_limit);
+	pu = generate_parked_user(self->lot, bridge_channel->chan, parker,
+		park_datastore->parker_dial_string, park_datastore->randomize, park_datastore->time_limit);
+
 	if (!pu) {
 		publish_parked_call_failure(bridge_channel->chan);
 		return -1;
 	}
 
 	/* If a comeback_override was provided, set it for the parked user's comeback string. */
-	if (comeback_override) {
-		strncpy(pu->comeback, comeback_override, sizeof(pu->comeback));
+	if (park_datastore->comeback_override) {
+		strncpy(pu->comeback, park_datastore->comeback_override, sizeof(pu->comeback));
 		pu->comeback[sizeof(pu->comeback) - 1] = '\0';
 	}
 
@@ -273,7 +292,7 @@
 	publish_parked_call(pu, PARKED_CALL);
 
 	/* If the parkee and the parker are the same and silence_announce isn't set, play the announcement to the parkee */
-	if (!strcmp(blind_transfer, ast_channel_name(bridge_channel->chan)) && !silence) {
+	if (!strcmp(blind_transfer, ast_channel_name(bridge_channel->chan)) && !park_datastore->silence_announce) {
 		char saynum_buf[16];
 		snprintf(saynum_buf, sizeof(saynum_buf), "%u %u", 0, pu->parking_space);
 		ast_bridge_channel_queue_playfile(bridge_channel, say_parking_space, saynum_buf, NULL);

Modified: trunk/res/parking/parking_bridge_features.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/parking/parking_bridge_features.c?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/res/parking/parking_bridge_features.c (original)
+++ trunk/res/parking/parking_bridge_features.c Thu Jul  4 13:46:56 2013
@@ -367,23 +367,6 @@
 	ao2_ref(user, -1);
 }
 
-/*!
- * \brief Removes the identification information from a channel name string
- * \since 12.0
- *
- * \param channel name string that you wish to turn into a dial string. This will be edited in place.
- */
-static void channel_name_to_dial_string(char *peername)
-{
-	char *dash;
-
-	/* Truncate after the dash */
-	dash = strrchr(peername, '-');
-	if (dash) {
-		*dash = '\0';
-	}
-}
-
 /*! \internal
  * \brief Interval hook. Pulls a parked call from the parking bridge after the timeout is passed and sets the resolution to timeout.
  *
@@ -396,8 +379,8 @@
 	struct parked_user *user = hook_pvt;
 	struct ast_channel *chan = user->chan;
 	struct ast_context *park_dial_context;
-	char *peername;
-	char *peername_flat;
+	const char *dial_string;
+	char *dial_string_flat;
 	char parking_space[AST_MAX_EXTENSION];
 
 	char returnexten[AST_MAX_EXTENSION];
@@ -426,14 +409,12 @@
 	pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parking_space); /* Deprecated version of PARKING_SPACE */
 	pbx_builtin_setvar_helper(chan, "PARKEDLOT", user->lot->name);
 
-	peername = ast_strdupa(S_OR(user->blindtransfer, user->parker->name));
-	channel_name_to_dial_string(peername);
-
-	peername_flat = ast_strdupa(user->parker->name);
-	flatten_peername(peername_flat);
-
-	pbx_builtin_setvar_helper(chan, "PARKER", peername);
-	pbx_builtin_setvar_helper(chan, "PARKER_FLAT", peername_flat);
+	dial_string = user->parker_dial_string;
+	dial_string_flat = ast_strdupa(dial_string);
+	flatten_dial_string(dial_string_flat);
+
+	pbx_builtin_setvar_helper(chan, "PARKER", dial_string);
+	pbx_builtin_setvar_helper(chan, "PARKER_FLAT", dial_string_flat);
 
 	/* Dialplan generation for park-dial extensions */
 
@@ -462,26 +443,26 @@
 		ast_assert(0);
 	}
 
-	snprintf(returnexten, sizeof(returnexten), "%s,%u", peername,
+	snprintf(returnexten, sizeof(returnexten), "%s,%u", dial_string,
 		user->lot->cfg->comebackdialtime);
 
 	duplicate_returnexten = ast_strdup(returnexten);
 
 	if (!duplicate_returnexten) {
 		ast_log(LOG_ERROR, "Failed to create parking redial parker extension %s@%s - Dial(%s)\n",
-			peername_flat, PARK_DIAL_CONTEXT, returnexten);
+			dial_string_flat, PARK_DIAL_CONTEXT, returnexten);
 	}
 
 	/* If an extension already exists here because we registered it for another parked call timing out, then we may overwrite it. */
-	if ((existing_exten = pbx_find_extension(NULL, NULL, &pbx_finder, PARK_DIAL_CONTEXT, peername_flat, 1, NULL, NULL, E_MATCH)) &&
+	if ((existing_exten = pbx_find_extension(NULL, NULL, &pbx_finder, PARK_DIAL_CONTEXT, dial_string_flat, 1, NULL, NULL, E_MATCH)) &&
 	    (strcmp(ast_get_extension_registrar(existing_exten), BASE_REGISTRAR))) {
 		ast_debug(3, "An extension for '%s@%s' was already registered by another registrar '%s'\n",
-			peername_flat, PARK_DIAL_CONTEXT, ast_get_extension_registrar(existing_exten));
-	} else if (ast_add_extension2_nolock(park_dial_context, 1, peername_flat, 1, NULL, NULL,
+			dial_string_flat, PARK_DIAL_CONTEXT, ast_get_extension_registrar(existing_exten));
+	} else if (ast_add_extension2_nolock(park_dial_context, 1, dial_string_flat, 1, NULL, NULL,
 			"Dial", duplicate_returnexten, ast_free_ptr, BASE_REGISTRAR)) {
 			ast_free(duplicate_returnexten);
 		ast_log(LOG_ERROR, "Failed to create parking redial parker extension %s@%s - Dial(%s)\n",
-			peername_flat, PARK_DIAL_CONTEXT, returnexten);
+			dial_string_flat, PARK_DIAL_CONTEXT, returnexten);
 	}
 
 	if (ast_unlock_context(park_dial_context)) {

Modified: trunk/res/parking/parking_controller.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/parking/parking_controller.c?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/res/parking/parking_controller.c (original)
+++ trunk/res/parking/parking_controller.c Thu Jul  4 13:46:56 2013
@@ -220,22 +220,14 @@
 	return;
 }
 
-void flatten_peername(char *peername)
+void flatten_dial_string(char *dialstring)
 {
 	int i;
-	char *dash;
-
-	/* Truncate after the dash */
-	dash = strrchr(peername, '-');
-	if (dash) {
-		*dash = '\0';
-	}
-
-	/* Replace slashes with underscores since slashes are reserved characters for extension matching */
-	for (i = 0; peername[i]; i++) {
-		if (peername[i] == '/') {
+
+	for (i = 0; dialstring[i]; i++) {
+		if (dialstring[i] == '/') {
 			/* The underscore is the flattest character of all. */
-			peername[i] = '_';
+			dialstring[i] = '_';
 		}
 	}
 }
@@ -243,39 +235,37 @@
 int comeback_goto(struct parked_user *pu, struct parking_lot *lot)
 {
 	struct ast_channel *chan = pu->chan;
-	char *peername;
-
-	peername = ast_strdupa(S_OR(pu->blindtransfer, pu->parker->name));
+	char *peername_flat = ast_strdupa(pu->parker_dial_string);
 
 	/* Flatten the peername so that it can be used for performing the timeout PBX operations */
-	flatten_peername(peername);
+	flatten_dial_string(peername_flat);
 
 	if (lot->cfg->comebacktoorigin) {
-		if (ast_exists_extension(chan, PARK_DIAL_CONTEXT, peername, 1, NULL)) {
-			ast_async_goto(chan, PARK_DIAL_CONTEXT, peername, 1);
+		if (ast_exists_extension(chan, PARK_DIAL_CONTEXT, peername_flat, 1, NULL)) {
+			ast_async_goto(chan, PARK_DIAL_CONTEXT, peername_flat, 1);
 			return 0;
 		} else {
 			ast_log(LOG_ERROR, "Can not start %s at %s,%s,1 because extension does not exist. Terminating call.\n",
-				ast_channel_name(chan), PARK_DIAL_CONTEXT, peername);
+				ast_channel_name(chan), PARK_DIAL_CONTEXT, peername_flat);
 			return -1;
 		}
 	}
 
-	if (ast_exists_extension(chan, lot->cfg->comebackcontext, peername, 1, NULL)) {
-		ast_async_goto(chan, lot->cfg->comebackcontext, peername, 1);
+	if (ast_exists_extension(chan, lot->cfg->comebackcontext, peername_flat, 1, NULL)) {
+		ast_async_goto(chan, lot->cfg->comebackcontext, peername_flat, 1);
 		return 0;
 	}
 
 	if (ast_exists_extension(chan, lot->cfg->comebackcontext, "s", 1, NULL)) {
 		ast_verb(2, "Could not start %s at %s,%s,1. Using 's@%s' instead.\n", ast_channel_name(chan),
-			lot->cfg->comebackcontext, peername, lot->cfg->comebackcontext);
+			lot->cfg->comebackcontext, peername_flat, lot->cfg->comebackcontext);
 		ast_async_goto(chan, lot->cfg->comebackcontext, "s", 1);
 		return 0;
 	}
 
 	ast_verb(2, "Can not start %s at %s,%s,1 and exten 's@%s' does not exist. Using 's at default'\n",
 		ast_channel_name(chan),
-		lot->cfg->comebackcontext, peername, lot->cfg->comebackcontext);
+		lot->cfg->comebackcontext, peername_flat, lot->cfg->comebackcontext);
 	ast_async_goto(chan, "default", "s", 1);
 
 	return 0;

Modified: trunk/res/parking/parking_manager.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/parking/parking_manager.c?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/res/parking/parking_manager.c (original)
+++ trunk/res/parking/parking_manager.c Thu Jul  4 13:46:56 2013
@@ -134,43 +134,8 @@
 				</parameter>
 				<parameter name="ParkeeUniqueid">
 				</parameter>
-				<parameter name="ParkerChannel">
-				</parameter>
-				<parameter name="ParkerChannelState">
-				<para>A numeric code for the channel's current state, related to ChannelStateDesc</para>
-				</parameter>
-				<parameter name="ParkerChannelStateDesc">
-					<enumlist>
-						<enum name="Down"/>
-						<enum name="Rsrvd"/>
-						<enum name="OffHook"/>
-						<enum name="Dialing"/>
-						<enum name="Ring"/>
-						<enum name="Ringing"/>
-						<enum name="Up"/>
-						<enum name="Busy"/>
-						<enum name="Dialing Offhook"/>
-						<enum name="Pre-ring"/>
-						<enum name="Unknown"/>
-					</enumlist>
-				</parameter>
-				<parameter name="ParkerCallerIDNum">
-				</parameter>
-				<parameter name="ParkerCallerIDName">
-				</parameter>
-				<parameter name="ParkerConnectedLineNum">
-				</parameter>
-				<parameter name="ParkerConnectedLineName">
-				</parameter>
-				<parameter name="ParkerAccountCode">
-				</parameter>
-				<parameter name="ParkerContext">
-				</parameter>
-				<parameter name="ParkerExten">
-				</parameter>
-				<parameter name="ParkerPriority">
-				</parameter>
-				<parameter name="ParkerUniqueid">
+				<parameter name="ParkerDialString">
+					<para>Dial String that can be used to call back the parker on ParkingTimeout.</para>
 				</parameter>
 				<parameter name="Parkinglot">
 					<para>Name of the parking lot that the parkee is parked in</para>
@@ -276,10 +241,6 @@
 	struct timeval now = ast_tvnow();
 	const char *lot_name = pu->lot->name;
 
-	if (!pu->parker) {
-		return NULL;
-	}
-
 	parkee_snapshot = ast_channel_snapshot_create(pu->chan);
 
 	if (!parkee_snapshot) {
@@ -289,7 +250,7 @@
 	timeout = pu->start.tv_sec + (long) pu->time_limit - now.tv_sec;
 	duration = now.tv_sec - pu->start.tv_sec;
 
-	return ast_parked_call_payload_create(event_type, parkee_snapshot, pu->parker, pu->retriever, lot_name, pu->parking_space, timeout, duration);
+	return ast_parked_call_payload_create(event_type, parkee_snapshot, pu->parker_dial_string, pu->retriever, lot_name, pu->parking_space, timeout, duration);
 
 }
 
@@ -298,7 +259,6 @@
 {
 	struct ast_str *out = ast_str_create(1024);
 	RAII_VAR(struct ast_str *, parkee_string, NULL, ast_free);
-	RAII_VAR(struct ast_str *, parker_string, NULL, ast_free);
 	RAII_VAR(struct ast_str *, retriever_string, NULL, ast_free);
 
 	if (!out) {
@@ -307,26 +267,22 @@
 
 	parkee_string = ast_manager_build_channel_state_string_prefix(payload->parkee, "Parkee");
 
-	if (payload->parker) {
-		parker_string = ast_manager_build_channel_state_string_prefix(payload->parker, "Parker");
-	}
-
 	if (payload->retriever) {
 		retriever_string = ast_manager_build_channel_state_string_prefix(payload->retriever, "Retriever");
 	}
 
 	ast_str_set(&out, 0,
 		"%s" /* parkee channel state */
-		"%s" /* parker channel state */
 		"%s" /* retriever channel state (when available) */
+		"ParkerDialString: %s\r\n"
 		"Parkinglot: %s\r\n"
 		"ParkingSpace: %u\r\n"
 		"ParkingTimeout: %lu\r\n"
 		"ParkingDuration: %lu\r\n",
 
 		ast_str_buffer(parkee_string),
-		parker_string ? ast_str_buffer(parker_string) : "",
 		retriever_string ? ast_str_buffer(retriever_string) : "",
+		payload->parker_dial_string,
 		payload->parkinglot,
 		payload->parkingspace,
 		payload->timeout,

Modified: trunk/res/parking/parking_ui.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/parking/parking_ui.c?view=diff&rev=393704&r1=393703&r2=393704
==============================================================================
--- trunk/res/parking/parking_ui.c (original)
+++ trunk/res/parking/parking_ui.c Thu Jul  4 13:46:56 2013
@@ -40,9 +40,9 @@
 
 static void display_parked_call(struct parked_user *user, int fd)
 {
-	ast_cli(fd, "  Space: %d\n", user->parking_space);
-	ast_cli(fd, "  Channel: %s\n", ast_channel_name(user->chan));
-	ast_cli(fd, "  Parker: %s\n", user->parker ? user->parker->name : "<unknown>");
+	ast_cli(fd, "  Space               :  %d\n", user->parking_space);
+	ast_cli(fd, "  Channel             :  %s\n", ast_channel_name(user->chan));
+	ast_cli(fd, "  Parker Dial String  :  %s\n", user->parker_dial_string);
 	ast_cli(fd, "\n");
 }
 

Modified: trunk/res/parking/res_parking.h

[... 87 lines stripped ...]



More information about the asterisk-commits mailing list