Index: main/features.c
===================================================================
--- main/features.c	(revision 289621)
+++ main/features.c	(working copy)
@@ -299,6 +299,9 @@
 #define DEFAULT_ATXFER_DROP_CALL 0
 #define DEFAULT_ATXFER_LOOP_DELAY 10000
 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
+#define DEFAULT_COMEBACK_CONTEXT "parkedcallstimeout"
+#define DEFAULT_COMEBACK_TO_ORIGIN 1
+#define DEFAULT_COMEBACK_DIAL_TIME 30
 
 #define AST_MAX_WATCHERS 256
 #define MAX_DIAL_FEATURE_OPTIONS 30
@@ -351,6 +354,7 @@
 	char parkext[AST_MAX_EXTENSION];				/*!< Parkingextension */
 	char parking_con[AST_MAX_EXTENSION];		/*!< Context for which parking is made accessible */
 	char parking_con_dial[AST_MAX_EXTENSION];	/*!< Context for dialback for parking (KLUDGE) */
+	char comebackcontext[AST_MAX_EXTENSION];	/*!< Context for timeout return when comebacktoorigin=no */
 	int parking_start;				/*!< First available extension for parking */
 	int parking_stop;				/*!< Last available extension for parking */
 	int parking_offset;
@@ -362,6 +366,8 @@
 	int parkedcallreparking;                        /*!< Enable DTMF based parking on bridge when picking up parked calls */
 	int parkedcallhangup;                           /*!< Enable DTMF based hangup on a bridge when pickup up parked calls */
 	int parkedcallrecording;                        /*!< Enable DTMF based recording on a bridge when picking up parked calls */
+	int comebacktoorigin;				/*!< Configures the behavior of call parking when the parked call times out */
+	int comebackdialtime;				/*!< Time in seconds do dial the device that parked a timedout parked call */
 	unsigned short the_mark:1;                      /*!< Used during reloads, that which bears the_mark shall be deleted! */
 	AST_LIST_HEAD(parkinglot_parklist, parkeduser) parkings; /*!< List of active parkings in this parkinglot */
 };
@@ -384,7 +390,6 @@
 
 static int transferdigittimeout;
 static int featuredigittimeout;
-static int comebacktoorigin = 1;
 
 static int atxfernoanswertimeout;
 static unsigned int atxferdropcall;
@@ -3676,6 +3681,7 @@
 	struct parkeduser *pu;
 	int res = 0;
 	char parkingslot[AST_MAX_EXTENSION];
+	char comebackdialtime[AST_MAX_EXTENSION];
 
 	/* Lock parking list */
 	AST_LIST_LOCK(&curlot->parkings);
@@ -3731,24 +3737,32 @@
 
 					if (dialfeatures) {
 						char buf[MAX_DIAL_FEATURE_OPTIONS] = {0,};
-						snprintf(returnexten, sizeof(returnexten), "%s,30,%s", peername, callback_dialoptions(&(dialfeatures->features_callee), &(dialfeatures->features_caller), buf, sizeof(buf)));
+						snprintf(returnexten, sizeof(returnexten), "%s,%d,%s", peername, pu->parkinglot->comebackdialtime, callback_dialoptions(&(dialfeatures->features_callee), &(dialfeatures->features_caller), buf, sizeof(buf)));
 					} else { /* Existing default */
 						ast_log(LOG_NOTICE, "Dial features not found on %s, using default!\n", chan->name);
-						snprintf(returnexten, sizeof(returnexten), "%s,30,t", peername);
+						snprintf(returnexten, sizeof(returnexten), "%s,%d,t", peername, pu->parkinglot->comebackdialtime);
 					}
 
+					snprintf(comebackdialtime, sizeof(comebackdialtime), "%d", pu->parkinglot->comebackdialtime);
+					pbx_builtin_setvar_helper(chan, "COMEBACKDIALTIME", comebackdialtime);
+
+					pbx_builtin_setvar_helper(chan, "PARKER", peername);
+
+					snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
+					pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parkingslot);
+					
 					ast_add_extension2(con, 1, peername_flat, 1, NULL, NULL, "Dial", ast_strdup(returnexten), ast_free_ptr, registrar);
 				}
 				if (pu->options_specified == 1) {
 					/* Park() was called with overriding return arguments, respect those arguments */
 					set_c_e_p(chan, pu->context, pu->exten, pu->priority);
 				} else {
-					if (comebacktoorigin) {
+					if (pu->parkinglot->comebacktoorigin) {
 						set_c_e_p(chan, pu->parkinglot->parking_con_dial, peername_flat, 1);
 					} else {
 						snprintf(parkingslot, sizeof(parkingslot), "%d", pu->parkingnum);
 						pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parkingslot);
-						set_c_e_p(chan, "parkedcallstimeout", peername_flat, 1);
+						set_c_e_p(chan, pu->parkinglot->comebackcontext, peername_flat, 1);
 					}
 				}
 			} else {
@@ -4310,6 +4324,16 @@
 
 	ast_debug(1, "Building parking lot %s\n", name);
 
+	/* Copy some settings from the default parking lot */
+	/* They will only get updated if they are explicitly defined in the per-parkinglot config */
+	/* If not they get the default setting from the config file */
+	if (var) {
+		ast_copy_string(parkinglot->comebackcontext, default_parkinglot->comebackcontext, sizeof(parkinglot->mohclass));
+		parkinglot->comebacktoorigin = default_parkinglot->comebacktoorigin;
+		parkinglot->comebackdialtime = default_parkinglot->comebackdialtime;
+		ast_copy_string(parkinglot->mohclass, default_parkinglot->mohclass, sizeof(parkinglot->mohclass));
+	}
+
 	/* Do some config stuff */
 	while(confvar) {
 		if (!strcasecmp(confvar->name, "context")) {
@@ -4332,6 +4356,9 @@
 			}
 		} else if (!strcasecmp(confvar->name, "findslot")) {
 			parkinglot->parkfindnext = (!strcasecmp(confvar->value, "next"));
+		} else if (!strcasecmp(confvar->name, "parkedmusicclass")) {
+			ast_log(LOG_DEBUG, "Setting parking lot %s %s to %s\n", name, confvar->name, confvar->value);
+			ast_copy_string(parkinglot->mohclass, confvar->value, sizeof(parkinglot->mohclass));
 		} else if (!strcasecmp(confvar->name, "parkedcalltransfers")) {
 			ast_log(LOG_DEBUG, "Setting parking lot %s %s to %s\n", name, confvar->name, confvar->value);
 			if (!strcasecmp(confvar->value, "both")) {
@@ -4368,6 +4395,18 @@
 			} else if (!strcasecmp(confvar->value, "callee")) {
 				parkinglot->parkedcallrecording = AST_FEATURE_FLAG_BYCALLEE;
 			}
+		} else if (!strcasecmp(confvar->name, "comebackcontext")) {
+			ast_log(LOG_DEBUG, "Setting parking lot %s %s to %s\n", name, confvar->name, confvar->value);
+			ast_copy_string(parkinglot->comebackcontext, confvar->value, sizeof(parkinglot->comebackcontext));
+		} else if (!strcasecmp(confvar->name, "comebacktoorigin")) {
+			ast_log(LOG_DEBUG, "Setting parking lot %s %s to %s\n", name, confvar->name, confvar->value);
+			parkinglot->comebacktoorigin = ast_true(confvar->value);
+		} else if (!strcasecmp(confvar->name, "comebackdialtime")) {
+			ast_log(LOG_DEBUG, "Setting parking lot %s %s to %s\n", name, confvar->name, confvar->value);
+			if ((sscanf(confvar->value, "%30d", &parkinglot->comebackdialtime) != 1) || (parkinglot->comebackdialtime < 1)) {
+				ast_log(LOG_WARNING, "%s is not a valid comebackdialtime\n", confvar->value);
+				parkinglot->parkingtime = DEFAULT_COMEBACK_DIAL_TIME;
+			}
 		}
 		confvar = confvar->next;
 	}
@@ -4384,6 +4423,9 @@
 		ast_copy_string(parkinglot->parking_con, "parkedcalls", sizeof(parkinglot->parking_con));
 		ast_copy_string(parkinglot->parking_con_dial, "park-dial", sizeof(parkinglot->parking_con_dial));
 		ast_copy_string(parkinglot->mohclass, "default", sizeof(parkinglot->mohclass));
+		ast_copy_string(parkinglot->comebackcontext, DEFAULT_COMEBACK_CONTEXT, sizeof(parkinglot->comebackcontext));
+		parkinglot->comebacktoorigin = DEFAULT_COMEBACK_TO_ORIGIN;
+		parkinglot->comebackdialtime = DEFAULT_COMEBACK_DIAL_TIME;
 	}
 
 	/* Check for errors */
@@ -4392,6 +4434,17 @@
 		error = 1;
 	}
 
+	/* Make sure parking_con_dial is set so autocreated extensions don't get added to a NULL context*/
+	if (ast_strlen_zero(parkinglot->parking_con_dial)) {
+		ast_copy_string(parkinglot->parking_con_dial, "park-dial", sizeof(parkinglot->parking_con_dial));
+	}
+
+	/* Make sure the comebackdialtime didn't get set to 0 */
+	if (parkinglot->comebackdialtime == 0) {
+		ast_log(LOG_DEBUG, "Setting parking lot %s comebackdialtime to default\n", name);
+		parkinglot->comebackdialtime = DEFAULT_COMEBACK_DIAL_TIME;
+	}
+
 	/* Create context */
 	if (!error && !(con = ast_context_find_or_create(NULL, NULL, parkinglot->parking_con, registrar))) {
 		ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parkinglot->parking_con);
@@ -4478,7 +4531,6 @@
 	pickupsound[0] = '\0';
 	pickupfailsound[0] = '\0';
 	adsipark = 0;
-	comebacktoorigin = 1;
 	parkeddynamic = 0;
 
 	default_parkinglot->parkaddhints = 0;
@@ -4551,6 +4603,12 @@
 				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, "comebackdialtime")) {
+			ast_log(LOG_DEBUG, "Setting default parking lot %s to %s\n", var->name, var->value);
+			if ((sscanf(var->value, "%30d", &default_parkinglot->comebackdialtime) != 1) || (default_parkinglot->comebackdialtime < 1)) {
+				ast_log(LOG_WARNING, "%s is not a valid comebackdialtime\n", var->value);
+				default_parkinglot->parkingtime = DEFAULT_COMEBACK_DIAL_TIME;
+			}
 		} else if (!strcasecmp(var->name, "parkeddynamic")) {
 			parkeddynamic = ast_true(var->value);
 		} else if (!strcasecmp(var->name, "adsipark")) {
@@ -4605,8 +4663,13 @@
 		} else if (!strcasecmp(var->name, "pickupfailsound")) {
 			ast_copy_string(pickupfailsound, var->value, sizeof(pickupfailsound));
 		} else if (!strcasecmp(var->name, "comebacktoorigin")) {
-			comebacktoorigin = ast_true(var->value);
+			ast_log(LOG_DEBUG, "Setting default parking lot %s to %s\n", var->name, var->value);
+			default_parkinglot->comebacktoorigin = ast_true(var->value);
+		} else if (!strcasecmp(var->name, "comebackcontext")) {
+			ast_log(LOG_DEBUG, "Setting default parking lot %s to %s\n", var->name, var->value);
+			ast_copy_string(default_parkinglot->comebackcontext, var->value, sizeof(default_parkinglot->comebackcontext));
 		} else if (!strcasecmp(var->name, "parkedmusicclass")) {
+			ast_log(LOG_DEBUG, "Setting default parking lot %s to %s\n", var->name, var->value);
 			ast_copy_string(default_parkinglot->mohclass, var->value, sizeof(default_parkinglot->mohclass));
 		}
 	}
@@ -4846,6 +4909,9 @@
 		ast_cli(a->fd,"%-22s:      %s\n", "Parking context", curlot->parking_con);
 		ast_cli(a->fd,"%-22s:      %d-%d\n", "Parked call extensions", curlot->parking_start, curlot->parking_stop);
 		ast_cli(a->fd,"%-22s:      %d\n", "Parkingtime", curlot->parkingtime);
+		ast_cli(a->fd,"%-22s:      %s\n", "Comeback to origin", (curlot->comebacktoorigin ? "yes" : "no"));
+		ast_cli(a->fd,"%-22s:      %s%s\n", "Comeback context", curlot->comebackcontext, (curlot->comebacktoorigin ? " (comebacktoorigin=yes, not used)" : ""));
+		ast_cli(a->fd,"%-22s:      %d\n", "Comeback dial time", curlot->comebackdialtime);
 		ast_cli(a->fd,"%-22s:      %s\n", "MusicOnHold class", curlot->mohclass);
 		ast_cli(a->fd,"\n");
 		ao2_ref(curlot, -1);
Index: configs/features.conf.sample
===================================================================
--- configs/features.conf.sample	(revision 289621)
+++ configs/features.conf.sample	(working copy)
@@ -14,30 +14,45 @@
 
 ;comebacktoorigin = yes         ; Setting this option configures the behavior of call parking when the
                                 ; parked call times out (See the parkingtime option).  The default value is 'yes'.
+				; This is a per-parking lot option.
                                 ;
                                 ; 'yes' - When the parked call times out, attempt to send the call back to the peer
                                 ;         that parked this call.  This is done by saving off the name of the channel
-                                ;         that parked the call.
+                                ;         that parked the call.  The call will return to the context 'park-dial' and
+				;         an extension created based on the name of the channel that originally parked
+				;         the call.  This extension will be created automatically to do a Dial() to the
+				;         device that originally parked the call for comebacktodialtime seconds. If the
+				;         call is not answered, the call will proceed to 'park-dial,t,1'.
                                 ;
                                 ; 'no'  - This option is useful for performing custom dialplan functionality prior to
                                 ;         sending the call back to the extension that initially parked the call, or to
                                 ;         an entirely different destination.
                                 ;
                                 ;         When the parked call times out, send it back to the dialplan.  The location
-                                ;         will be the 'parkedcallstimeout' context.  The extension will be built from
+                                ;         will be defined by the comebackcontext option.  The extension will be built from
                                 ;         the saved channel name that parked the call.  For example, if a SIP peer named
                                 ;         '0004F2040001' parked this call, the extension will be 'SIP_0004F2040001'.
                                 ;         (Note that an underscore is used here because the '/' character has a special
                                 ;         meaning in extension names for CallerID matching.)  If this extension does not
                                 ;         exist, the call will be sent to the 's' extension, instead.  Finally, if the 's'
-                                ;         extension of 'parkedcallstimeout' does not exist, the call will fall back to the
-                                ;         's' extension of the 'default' context.
-                                ;
-                                ;         Additionally, in this example an extension of 'SIP_0004F2040001' will be
-                                ;         created in the 'park-dial' context.  This extension will be set up to do a
-                                ;         Dial() to 'SIP/0004F2040001'.
-                                ;
+                                ;         extension does not exist, the call will fall back to the 's' extension of the
+				;         'default' context.
+				;
+				; The channel variable PARKER is set to the name of the device that parked the call.
+				; The channel variable PARKINGSLOT is set to the slot number the call was parked on.
+				;
 
+;comebackdialtime = 30		; When a parked call times out, this is the number of seconds to dial the device that
+				; originally parked the call.  It is also available as a channel variable COMEBACKDIALTIME
+				; after a parked call has timed out.
+				; The default value is 30 seconds.
+				; This is a per-parking lot option.
+
+;comebackcontext = parkedcallstimeout
+				; The context a timed out call will return to if comebcktoorigin=no.
+				; The default value is 'parkedcallstimeout'.
+				; This is a per-parking lot option.
+
 ;courtesytone = beep		; Sound file to play to the parked caller
 				; when someone dials a parked call
 				; or the Touch Monitor is activated/deactivated.
@@ -58,6 +73,7 @@
 ;parkedmusicclass=default	; This is the MOH class to use for the parked channel
 				; as long as the class is not set on the channel directly
 				; using Set(CHANNEL(musicclass)=whatever) in the dialplan
+				; This is a per-parking lot options.
 
 ;transferdigittimeout => 3	; Number of seconds to wait between digits when transferring a call
 				; (default is 3 seconds)
@@ -88,6 +104,10 @@
 ;parkext => 799
 ;parkpos => 800-850
 ;findslot => next
+;comebacktoorigin = no
+;comebackdialtime = 90
+;comebackcontext = edvinapark-timeout		; Make sure you create the context!
+;parkedmusicclass = edvina
 
 ; Note that the DTMF features listed below only work when two channels have answered and are bridged together.
 ; They can not be used while the remote party is ringing or in progress. If you require this feature you can use
