[asterisk-commits] branch oej/multiparking - r7685 in /team/oej/multiparking: ./ res/res_features.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sat Dec 31 03:30:35 CST 2005


Author: oej
Date: Sat Dec 31 03:30:33 2005
New Revision: 7685

URL: http://svn.digium.com/view/asterisk?rev=7685&view=rev
Log:
Update

Modified:
    team/oej/multiparking/   (props changed)
    team/oej/multiparking/res/res_features.c

Propchange: team/oej/multiparking/
            ('svnmerge-integrated' removed)

Modified: team/oej/multiparking/res/res_features.c
URL: http://svn.digium.com/view/asterisk/team/oej/multiparking/res/res_features.c?rev=7685&r1=7684&r2=7685&view=diff
==============================================================================
--- team/oej/multiparking/res/res_features.c (original)
+++ team/oej/multiparking/res/res_features.c Sat Dec 31 03:30:33 2005
@@ -87,6 +87,7 @@
 #define DEFAULT_PARK_TIME 45000
 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
 #define DEFAULT_FEATURE_DIGIT_TIMEOUT 500
+#define DEFAULT_PARKINGLOT "default"
 
 #define AST_MAX_WATCHERS 256
 
@@ -106,25 +107,30 @@
 static char xfersound[256];
 static char xferfailsound[256];
 
-/* Structure for parking lots in a linked list. */
-/* You set parkinglot by setting channel var PARKINGLOT for now */
-/* Maybe a channel setting later */
+/*! \brief Structure for parking lots in a linked list. 
+ * You set parkinglot by setting channel var PARKINGLOT for now
+ * Maybe a channel setting later */
 struct ast_parkinglot {
-	char name[AST_MAX_EXTENSION];
-	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) */
-	int parking_start;				/* First available extension for parking */
-	int parking_stop;				/* Last available extension for parking */
+	char name[AST_MAX_EXTENSION];			/*!< Name for this lot (used in other configs) */
+	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) */
+	int parking_start;				/*!< First available extension for parking */
+	int parking_stop;				/*!< Last available extension for parking */
 	int parking_offset;
 	int parkfindnext;
+	static int parkingtime;				/*!< Default parking time */
 	struct parkeduser *occupiedlots;
-	struct ast_parkinglot *next;		/* Kevin will hate me */
+	AST_LIST_ENTRY(ast_parkinglot) list;		/*!< List entry */
 };
 
-struct ast_parkinglot default_parkinglot = { "default", "parkedcalls", "park-dial", 701, 750, 0, 0, NULL, NULL};
-
-struct ast_parkinglot extra_parkinglot = { "edvina", "edvinapark", "edvina-dial", 501, 550, 0, 0, NULL, NULL };
-struct ast_parkinglot *parkinglots = &default_parkinglot;
+static AST_LIST_HEAD_STATIC(parkinglots, ast_parkinglot);
+
+struct ast_parkinglot *default_parkinglot;
+
+//struct ast_parkinglot default_parkinglot = { "default", "parkedcalls", "park-dial", 701, 750, 0, 0, NULL, NULL};
+
+//struct ast_parkinglot extra_parkinglot = { "edvina", "edvinapark", "edvina-dial", 501, 550, 0, 0, NULL, NULL };
+// struct ast_parkinglot *parkinglots = &default_parkinglot;
 
 static int adsipark = 0;
 
@@ -158,6 +164,7 @@
 static struct ast_app *monitor_app=NULL;
 static int monitor_ok=1;
 
+/*! \brief Structure to handle one parked user */ 
 struct parkeduser {
 	struct ast_channel *chan;
 	struct timeval start;
@@ -175,6 +182,7 @@
 };
 
 
+/*!  Lock for parking */
 AST_MUTEX_DEFINE_STATIC(parking_lock);
 
 static pthread_t parking_thread;
@@ -182,6 +190,7 @@
 STANDARD_LOCAL_USER;
 
 LOCAL_USER_DECL;
+
 
 char *ast_parking_ext(void)
 {
@@ -199,10 +208,12 @@
 	struct ast_channel *chan;
 	struct ast_channel *peer;
 };
+
 /* Forward declarations */
 int ast_park_call_full(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout, struct ast_parkinglot *parkinglot);
 struct ast_parkinglot *find_parkinglot(char *name);
 
+/*! If GOTO_ON_BLINDXFR is set, transferer in a blind transfer will be sent there. */
 static void check_goto_on_transfer(struct ast_channel *chan) 
 {
 	struct ast_channel *xferchan;
@@ -313,7 +324,8 @@
 		parkinglot = &default_parkinglot;
 	parkinglotname = pbx_builtin_getvar_helper(chan, "PARKINGLOT");
 	if (parkinglotname) {
-		ast_log(LOG_DEBUG, "---------**--------- Found chanvar Parkinglot: %s\n", parkinglotname);
+		if (option_debug)
+			ast_log(LOG_DEBUG, "---------**--------- Found chanvar Parkinglot: %s\n", parkinglotname);
 		parkinglot = find_parkinglot(parkinglotname);	
 	}
 	ast_log(LOG_DEBUG, "---------**--------- Parkinglot: %s\n", parkinglot->name);
@@ -1699,17 +1711,21 @@
 /*--- find_parkinglot: Find parkinglot by name */
 struct ast_parkinglot *find_parkinglot(char *name)
 {
-	struct ast_parkinglot *parkinglot = &default_parkinglot;
-
-	while(parkinglot) {
+	struct ast_parkinglot *parkinglot = NULL;
+	
+	if (ast_strlen_zero(name))
+		return NULL;
+
+	AST_LIST_TRAVERSE(&parkinglots, parkinglot, list) {
 		if (!strcasecmp(parkinglot->name, name)) {
-			ast_log(LOG_DEBUG, "---------**--------- Found Parkinglot: %s\n", parkinglot->name);
-			return parkinglot;
-		}
-		parkinglot = parkinglot->next;
-	}
+			if (option_debug)
+				ast_log(LOG_DEBUG, "---------**--------- Found Parkinglot: %s\n", parkinglot->name);
+			return(parkinglot);
+		}
+	}
+
 	/* We did not find a parking lot */
-	return &default_parkinglot;
+	return parkinglot;
 }
 
 /*--- park_call_exec: Park a call */
@@ -1719,8 +1735,7 @@
 	   lot context eventually */
 	int res=0;
 	struct localuser *u;
-	char *parkinglotname;
-	struct ast_parkinglot *parkinglot = &default_parkinglot;
+	char *parkinglotname = DEFAULT_PARKINGLOT;
 
 	LOCAL_USER_ADD(u);
 	parkinglotname = pbx_builtin_getvar_helper(chan, "PARKINGLOT");
@@ -2051,19 +2066,117 @@
 	return res;
 }
 
+/*! \brief Allocate parking lot structure */
+static struct ast_parkinglot *create_parkinglot(char *name)
+{
+	struct ast_parkinglot *newlot = (struct ast_parkinglot *) NULL;
+
+	if (!name)
+		return NULL;
+
+	newlot = malloc(sizeof(struct ast_parkinglot));
+	if (!newlot)
+		return NULL;
+	ast_copy_string(newlot->name, name, sizeof(newlot->name));
+
+	return newlot;
+}
+
+static void destroy_parkinglot(ast_parkinglot *ruin)
+{
+	struct ast_context *con;
+	con = ast_context_find(ruin->parking_con);
+	if (con)
+		ast_context_destroy(con, registrar);
+	free(ruin);
+}
+
+/*! \brief Build parkinglot from configuration and chain it in */
+static int build_parking_lot(char *name, struct ast_variable *var)
+{
+	struct ast_parkinglot *parkinglot;
+	struct ast_context *con = NULL;
+
+	struct ast_variable *confvar = var;
+	int error = 0;
+
+	/* Check if parkinglot with this name already exists */
+	/* OEJ */
+	parkinglot = create_parkinglot(name);
+	if (!parkinglot)
+		return;
+	
+	/* Do some config stuff */
+	while(confvar) {
+		if (!strcasecmp(confvar->name, "context")) {
+			ast_copy_string(parkinglot->parking_con, confvar->value, sizeof(parkinglot->parking_con));
+		} else if (!strcasecmp(confvar->name, "parkingtime")) {
+			if ((sscanf(confvar->value, "%d", &parkingtime) != 1) || (parkingtime < 1)) {
+				ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", confvar->value);
+				parkingtime = DEFAULT_PARK_TIME;
+			} else
+				parkingtime = parkingtime * 1000;
+		} else if (!strcasecmp(confvar->name, "parkpos")) {
+			if (sscanf(confvar->value, "%d-%d", &start, &end) != 2) {
+				ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers at line %d of parking.conf\n", confvar->lineno);
+				error = 1;
+			} else {
+				parkinglot->parking_start = start;
+				parkinglot->parking_stop = end;
+			}
+		} else if (!strcasecmp(confvar->name, "findslot")) {
+			parkinglot->parkfindnext = (!strcasecmp(confvar->value, "next"));
+		}
+		confvar = confvar->next;
+	}
+	/* Check for errors */
+	if (ast_strlen_zero(parkinglot->parking_con)) {
+		ast_log(LOG_WARNING, "Parking lot %s lacks context\n", name);
+		error = 1;
+	}
+
+	/* Create context */
+	if (!error && !(con = ast_context_find(parkinglot->parking_con))) {
+		if (!(con = ast_context_create(NULL, parkinglot->parking_con, registrar))) {
+			ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", cur->parking_con);
+			error = 1;
+		}
+	}
+
+	/* Add a parking extension into the context */
+	if (ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, strdup(""), FREE, registrar) == -1)
+		error = 1;
+
+	if (error) {
+		ast_log(LOG_WARNING, "Parking %s not open for business. Configuration error.\n", name);
+		destroy_parkinglot(parkinglot);
+		return -1;
+	}
+
+	/* Move it into the list */
+	AST_LIST_INSERT_TAIL(&parkinglots, parkinglot, list);
+	return 0;
+	
+}
+
+/*! \brief Load configuration file */
 static int load_config(void) 
 {
 	int start = 0, end = 0;
 	struct ast_context *con = NULL;
 	struct ast_config *cfg = NULL;
 	struct ast_variable *var = NULL;
-	struct ast_parkinglot *cur = &default_parkinglot;
+
+	if (!default_parkinglot) {
+		default_parkinglot = build_parkinglot(DEFAULT_PARKINGLOT);
+		AST_LIST_INSERT_TAIL(&parkinglots, parkinglot, list);
+	}
 	
 	transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
 	featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
-	
-	// OEJ Make sure we remove old unused parking lots
-	// When reloading and resetting defaults as in res_features.c 
+
+	AST_LIST_HEAD_INIT(&parkinglots);
+	
 	strcpy(xfersound, "beep");
 	strcpy(xferfailsound, "pbx-invalid");
 	courtesytone[0] = '\0';	/* No default setting */
@@ -2080,7 +2193,7 @@
 			if (!strcasecmp(var->name, "parkext")) {
 				ast_copy_string(parking_ext, var->value, sizeof(parking_ext));
 			} else if (!strcasecmp(var->name, "context")) {
-				ast_copy_string(cur->parking_con, var->value, sizeof(cur->parking_con));
+				ast_copy_string(default_parkinglot->parking_con, var->value, sizeof(default_parkinglot->parking_con));
 			} else if (!strcasecmp(var->name, "parkingtime")) {
 				if ((sscanf(var->value, "%d", &parkingtime) != 1) || (parkingtime < 1)) {
 					ast_log(LOG_WARNING, "%s is not a valid parkingtime\n", var->value);
@@ -2091,11 +2204,11 @@
 				if (sscanf(var->value, "%d-%d", &start, &end) != 2) {
 					ast_log(LOG_WARNING, "Format for parking positions is a-b, where a and b are numbers at line %d of parking.conf\n", var->lineno);
 				} else {
-					cur->parking_start = start;
-					cur->parking_stop = end;
+					default_parkinglot->parking_start = start;
+					default_parkinglot->parking_stop = end;
 				}
 			} else if (!strcasecmp(var->name, "findslot")) {
-				cur->parkfindnext = (!strcasecmp(var->value, "next"));
+				default_parkinglot->parkfindnext = (!strcasecmp(var->value, "next"));
 			} else if (!strcasecmp(var->name, "adsipark")) {
 				adsipark = ast_true(var->value);
 			} else if (!strcasecmp(var->name, "transferdigittimeout")) {
@@ -2200,13 +2313,14 @@
 			var = var->next;
 		}	 
 	}
+	/* Now, find parking lot definitions */
 	ast_config_destroy(cfg);
 
 	
 	if (con)
 		ast_context_remove_extension2(con, ast_parking_ext(), 1, registrar);
 	
-	if (!(con = ast_context_find(cur->parking_con))) {
+	if (!(con = ast_context_find(default_parkinglot->parking_con))) {
 		if (!(con = ast_context_create(NULL, cur->parking_con, registrar))) {
 			ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", cur->parking_con);
 			return -1;
@@ -2216,6 +2330,18 @@
 }
 
 int reload(void) {
+
+	/* Release parking lot list */
+	if (!AST_LIST_EMPTY(&parkinglots) ) {
+		struct ast_parkinglot *park;
+		AST_LIST_LOCK(&parkinglots);
+		while ((park = AST_LIST_REMOVE_HEAD(&parkinglots, list))) {
+			destroy_parkinglot(park);
+		}
+		AST_LIST_UNLOCK(&parkinglots);
+	}
+
+	/* Reload configuration */
 	return load_config();
 }
 
@@ -2236,7 +2362,6 @@
 	if (!res) {
 		ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls" );
 	}
-	default_parkinglot.next = &extra_parkinglot;	/* Just for testing */
 	return res;
 }
 



More information about the asterisk-commits mailing list