[asterisk-commits] dvossel: trunk r247248 - in /trunk: ./ configs/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Feb 17 12:29:55 CST 2010


Author: dvossel
Date: Wed Feb 17 12:29:48 2010
New Revision: 247248

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=247248
Log:
addition of dynamic parkinglots feature

This feature allows for parkinglots to be created dynamically within
the dialplan.  Thanks to all who were involved with getting this patch
written and tested!

(closes issue #15135)
Reported by: IgorG
Patches:
      features.dynamic_park.v3.diff uploaded by IgorG (license 20)
      2009090400_dynamicpark.diff.txt uploaded by mvanbaak (license 7)
      dynamic_parkinglot.diff uploaded by dvossel (license 671)
Tested by: eliel, IgorG, acunningham, mvanbaak, zktech

Review: https://reviewboard.asterisk.org/r/352/

Modified:
    trunk/CHANGES
    trunk/configs/features.conf.sample
    trunk/main/features.c

Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=247248&r1=247247&r2=247248
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Wed Feb 17 12:29:48 2010
@@ -197,6 +197,15 @@
  * Added DYNAMIC_FEATURENAME which holds the last triggered dynamic feature.
  * Added DYNAMIC_PEERNAME which holds the unique channel name on the other side
    and is set when a dynamic feature is triggered.
+ * Added PARKINGLOT which can be used with parkeddynamic feature.conf option
+   to dynamically create a new parking lot matching the value this varible is
+   set to.
+ * Added PARKINGDYNAMIC which represents the template parkinglot defined in
+   features.conf that should be the base for dynamic parkinglots.
+ * Added PARKINGDYNCONTEXT which tells what context a newly created dynamic
+   parkinglot should have.
+ * Added PARKINGDYNPOS which holds what parking positions a dynamic parkinglot
+   should have.
 
 Queue changes
 -------------
@@ -396,6 +405,8 @@
  * jabber.conf supports a new option auth_policy that toggles auto user registration.
  * A new lockconfdir option has been added to asterisk.conf to protect the
    configuration directory (/etc/asterisk by default) during reloads.
+ * The parkeddynamic option has been added to features.conf to enable the creation
+   of dynamic parkinglots.
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 1.6.1 to Asterisk 1.6.2  -------------

Modified: trunk/configs/features.conf.sample
URL: http://svnview.digium.com/svn/asterisk/trunk/configs/features.conf.sample?view=diff&rev=247248&r1=247247&r2=247248
==============================================================================
--- trunk/configs/features.conf.sample (original)
+++ trunk/configs/features.conf.sample Wed Feb 17 12:29:48 2010
@@ -27,6 +27,7 @@
                                 ; one of: callee, caller, both, no (default is no)
 ;parkedcallrecording = caller   ; Enables or disables DTMF based one-touch recording when picking up a parked call.
                                 ; one of: callee, caller, both, no (default is no)
+;parkeddynamic = yes            ; Enables dynamically created parkinglots. (default is no)
 ;adsipark = yes			; if you want ADSI parking announcements
 ;findslot => next		; Continue to the 'next' free parking space.
 				; Defaults to 'first' available

Modified: trunk/main/features.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/features.c?view=diff&rev=247248&r1=247247&r2=247248
==============================================================================
--- trunk/main/features.c (original)
+++ trunk/main/features.c Wed Feb 17 12:29:48 2010
@@ -212,6 +212,14 @@
 			<para>If you set the <variable>PARKINGEXTEN</variable> variable to an extension in your
 			parking context, Park() will park the call on that extension, unless
 			it already exists. In that case, execution will continue at next priority.</para>
+			<para>If you set the <variable>PARKINGLOT</variable> variable, Park() will park the call
+			in that parkinglot.</para>
+			<para>If you set the <variable>PARKINGDYNAMIC</variable> variable, this parkinglot from features.conf
+			will be used as template for the newly created dynamic lot.</para>
+			<para>If you set the <variable>PARKINGDYNCONTEXT</variable> variable the newly created dynamic
+			parking lot will use this context.</para>
+			<para>If you set the <variable>PARKINGDYNPOS</variable> variable the newly created dynamic parkinglot
+			will use those parking postitions.</para>
 		</description>
 		<see-also>
 			<ref type="application">ParkAndAnnounce</ref>
@@ -356,6 +364,7 @@
 
 static char courtesytone[256];                             /*!< Courtesy tone */
 static int parkedplay = 0;                                 /*!< Who to play the courtesy tone to */
+static int parkeddynamic = 0;                              /*!< Enable creation of parkinglots dynamically */
 static char xfersound[256];                                /*!< Call transfer sound */
 static char xferfailsound[256];                            /*!< Call transfer failure sound */
 static char pickupsound[256];                              /*!< Pickup sound */
@@ -426,7 +435,8 @@
 static void parkinglot_destroy(void *obj);
 int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds, int *fs, int *max);
 struct ast_parkinglot *find_parkinglot(const char *name);
-
+static struct ast_parkinglot *create_parkinglot(const char *name);
+static struct ast_parkinglot *copy_parkinglot(const char *name, const struct ast_parkinglot *parkinglot);
 
 const char *ast_parking_ext(void)
 {
@@ -679,23 +689,67 @@
 	struct parkeduser *pu;
 };
 
-static struct parkeduser *park_space_reserve(struct ast_channel *chan,
- struct ast_channel *peer, struct ast_park_call_args *args)
+static struct parkeduser *park_space_reserve(struct ast_channel *chan, struct ast_channel *peer, struct ast_park_call_args *args)
 {
 	struct parkeduser *pu;
 	int i, parking_space = -1, parking_range;
 	const char *parkinglotname = NULL;
 	const char *parkingexten;
 	struct ast_parkinglot *parkinglot = NULL;
-	
+
 	if (peer)
 		parkinglotname = findparkinglotname(peer);
 
 	if (parkinglotname) {
-		if (option_debug)
-			ast_log(LOG_DEBUG, "Found chanvar Parkinglot: %s\n", parkinglotname);
-		parkinglot = find_parkinglot(parkinglotname);	
-	}
+		ast_debug(1, "Found chanvar Parkinglot: %s\n", parkinglotname);
+		parkinglot = find_parkinglot(parkinglotname);
+
+	}
+
+	/* Dynamically create parkinglot */
+	if (!parkinglot && parkeddynamic && !ast_strlen_zero(parkinglotname)) {
+		const char *dyn_context, *dyn_range;
+		const char *parkinglotname_copy = NULL;
+		struct ast_parkinglot *parkinglot_copy = NULL;
+		int dyn_start, dyn_end;
+
+		ast_channel_lock(chan);
+		parkinglotname_copy = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNAMIC"), ""));
+		dyn_context = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNCONTEXT"), ""));
+		dyn_range = ast_strdupa(S_OR(pbx_builtin_getvar_helper(chan, "PARKINGDYNPOS"), ""));
+		ast_channel_unlock(chan);
+
+		if (!ast_strlen_zero(parkinglotname_copy)) {
+			parkinglot_copy = find_parkinglot(parkinglotname_copy);
+		}
+		if (!parkinglot_copy) {
+			parkinglot_copy = parkinglot_addref(default_parkinglot);
+			ast_debug(1, "Using default parking lot for copy\n");
+		}
+		if (!(parkinglot = copy_parkinglot(parkinglotname, parkinglot_copy))) {
+			ast_log(LOG_ERROR, "Could not build dynamic parking lot!\n");
+		} else {
+			if (!ast_strlen_zero(dyn_context)) {
+				ast_copy_string(parkinglot->parking_con, dyn_context, sizeof(parkinglot->parking_con));
+			}
+			if (!ast_strlen_zero(dyn_range)) {
+				if (sscanf(dyn_range, "%30d-%30d", &dyn_start, &dyn_end) != 2) {
+					ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers\n");
+				} else {
+					parkinglot->parking_start = dyn_start;
+					parkinglot->parking_stop = dyn_end;
+				}
+			}
+			ao2_link(parkinglots, parkinglot);
+		}
+
+		if (parkinglot_copy) {
+			/* unref our tempory copy */
+			parkinglot_unref(parkinglot_copy);
+			parkinglot_copy = NULL;
+		}
+	}
+
 	if (!parkinglot) {
 		parkinglot = parkinglot_addref(default_parkinglot);
 	}
@@ -3508,6 +3562,27 @@
 	return parkinglot;
 }
 
+/*! \brief Copy parkinglot and store it with new name */
+struct ast_parkinglot *copy_parkinglot(const char *name, const struct ast_parkinglot *parkinglot) {
+	struct ast_parkinglot *copylot;
+
+	if (ast_strlen_zero(name)) { /* No name specified */
+		return NULL;
+	}
+	if (find_parkinglot(name)) { /* Parkinglot with that name allready exists */
+		return NULL;
+	}
+
+	copylot = create_parkinglot(name);
+	ast_debug(1, "Building parking lot %s\n", name);
+
+	memcpy(copylot, parkinglot, sizeof(struct ast_parkinglot));
+	ast_copy_string(copylot->name, name, sizeof(copylot->name));
+	AST_LIST_HEAD_INIT(&copylot->parkings);
+
+	return copylot;
+}
+
 AST_APP_OPTIONS(park_call_options, BEGIN_OPTIONS
 	AST_APP_OPTION('r', AST_PARK_OPT_RINGING),
 	AST_APP_OPTION('R', AST_PARK_OPT_RANDOMIZE),
@@ -3792,7 +3867,7 @@
 }
 
 /*! \brief Allocate parking lot structure */
-static struct ast_parkinglot *create_parkinglot(char *name)
+static struct ast_parkinglot *create_parkinglot(const char *name)
 {
 	struct ast_parkinglot *newlot = (struct ast_parkinglot *) NULL;
 
@@ -3842,9 +3917,8 @@
 
 	ao2_lock(parkinglot);
 
-	if (option_debug)
-		ast_log(LOG_DEBUG, "Building parking lot %s\n", name);
-	
+	ast_debug(1, "Building parking lot %s\n", name);
+
 	/* Do some config stuff */
 	while(confvar) {
 		if (!strcasecmp(confvar->name, "context")) {
@@ -4027,6 +4101,7 @@
 	pickupfailsound[0] = '\0';
 	adsipark = 0;
 	comebacktoorigin = 1;
+	parkeddynamic = 0;
 
 	default_parkinglot->parkaddhints = 0;
 	default_parkinglot->parkedcalltransfers = 0;
@@ -4098,6 +4173,8 @@
 				default_parkinglot->parkedcallrecording = AST_FEATURE_FLAG_BYCALLER;
 			else if (!strcasecmp(var->value, "callee"))
 				default_parkinglot->parkedcallrecording = AST_FEATURE_FLAG_BYCALLEE;
+		} else if (!strcasecmp(var->name, "parkeddynamic")) {
+			parkeddynamic = ast_true(var->value);
 		} else if (!strcasecmp(var->name, "adsipark")) {
 			adsipark = ast_true(var->value);
 		} else if (!strcasecmp(var->name, "transferdigittimeout")) {




More information about the asterisk-commits mailing list