[asterisk-commits] jpeeler: branch jpeeler/bug13494 r170810 - /team/jpeeler/bug13494/res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jan 23 17:20:54 CST 2009


Author: jpeeler
Date: Fri Jan 23 17:20:53 2009
New Revision: 170810

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=170810
Log:
Pull out the slot assignment functionality from park_call_full and put into park_slot_reserve, enabling one to check and see if an attempt to enter the parking lot will succeed without doing so. The idea is to call park_slot_reserve before doing any masquerades and bail out if the parking lot entry will fail while also leaving the bridge up as well.

I believe this does what I want here... the only thing I'm concerned about is if anywhere in park_call_full needs to be protected with the parkinglock.


Modified:
    team/jpeeler/bug13494/res/res_features.c

Modified: team/jpeeler/bug13494/res/res_features.c
URL: http://svn.digium.com/svn-view/asterisk/team/jpeeler/bug13494/res/res_features.c?view=diff&rev=170810&r1=170809&r2=170810
==============================================================================
--- team/jpeeler/bug13494/res/res_features.c (original)
+++ team/jpeeler/bug13494/res/res_features.c Fri Jan 23 17:20:53 2009
@@ -71,6 +71,14 @@
 
 #define AST_MAX_WATCHERS 256
 
+#define FEATURE_RETURN_HANGUP                  -1
+#define FEATURE_RETURN_SUCCESSBREAK             0
+#define FEATURE_RETURN_PASSDIGITS               21
+#define FEATURE_RETURN_STOREDIGITS              22
+#define FEATURE_RETURN_SUCCESS                  23
+#define FEATURE_RETURN_KEEPTRYING               24
+#define FEATURE_RETURN_PARKFAILED               25
+
 enum {
 	AST_FEATURE_FLAG_NEEDSDTMF = (1 << 0),
 	AST_FEATURE_FLAG_ONPEER =    (1 << 1),
@@ -302,16 +310,12 @@
 		return AST_DEVICE_INUSE;
 }
 
-static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout, const char *orig_chan_name)
-{
-	struct parkeduser *pu, *cur;
-	int i, x = -1, parking_range, parkingnum_copy;
-	struct ast_context *con;
+static int park_slot_reserve(struct ast_channel *chan)
+{
+	struct parkeduser *cur;
+	int i, x = -1, parking_range;
 	const char *parkingexten;
-	
-	/* Allocate memory for parking data */
-	if (!(pu = ast_calloc(1, sizeof(*pu)))) 
-		return -1;
+	char validparkingexten[AST_MAX_EXTENSION];
 
 	/* Lock parking lot */
 	ast_mutex_lock(&parking_lock);
@@ -327,16 +331,14 @@
 		if (sscanf(parkingexten, "%d", &x) != 1 || x < 0) {
 			ast_log(LOG_WARNING, "PARKINGEXTEN does not indicate a valid parking slot: '%s'.\n", parkingexten);
 			ast_mutex_unlock(&parking_lock);
-			free(pu);
-			return 1;	/* Continue execution if possible */
-		}
-		snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
-
-		if (ast_exists_extension(NULL, parking_con, pu->parkingexten, 1, NULL)) {
+			return -1;
+		}
+		snprintf(validparkingexten, sizeof(validparkingexten), "%d", x);
+
+		if (ast_exists_extension(NULL, parking_con, validparkingexten, 1, NULL)) {
 			ast_mutex_unlock(&parking_lock);
-			free(pu);
 			ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parking_con);
-			return 1;	/* Continue execution if possible */
+			return -1;
 		}
 	} else {
 		/* Select parking space within range */
@@ -355,15 +357,36 @@
 
 		if (!(i < parking_range)) {
 			ast_log(LOG_WARNING, "No more parking spaces\n");
-			free(pu);
 			ast_mutex_unlock(&parking_lock);
 			return -1;
 		}
 		/* Set pointer for next parking */
 		if (parkfindnext) 
 			parking_offset = x - parking_start + 1;
-		snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
-	}
+	}
+	ast_mutex_unlock(&parking_lock);
+
+	return x;
+}
+
+static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout, const char *orig_chan_name, int reserved)
+{
+	struct parkeduser *pu;
+	int x, parkingnum_copy;
+	struct ast_context *con;
+	
+	/* Allocate memory for parking data */
+	if (!(pu = ast_calloc(1, sizeof(*pu)))) 
+		return -1;
+
+	if (reserved < 0)
+		x = park_slot_reserve(chan);
+	else
+		x = reserved;
+	//if ((x = park_slot_reserve(chan)) < 0)
+	//	return FEATURE_RETURN_PASSDIGITS;
+
+	snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
 	
 	chan->appl = "Parked Call";
 	chan->data = NULL; 
@@ -452,7 +475,7 @@
 		}
 	}
 
-	ast_mutex_unlock(&parking_lock);
+	//ast_mutex_unlock(&parking_lock);
 	/* Wake up the (presumably select()ing) thread */
 	pthread_kill(parking_thread, SIGURG);
 
@@ -481,14 +504,18 @@
 	after these channels too */
 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
 {
-	return park_call_full(chan, peer, timeout, extout, NULL);
+	return park_call_full(chan, peer, timeout, extout, NULL, -1);
 }
 
 static int masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout, int play_announcement, const char *orig_chan_name)
 {
 	struct ast_channel *chan;
 	struct ast_frame *f;
+	int x;
 	int park_status;
+
+	if ((x = park_slot_reserve(rchan)) < 0)
+		return FEATURE_RETURN_PARKFAILED;
 
 	/* Make a new, fake channel that we'll use to masquerade in the real one */
 	if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->amaflags, "Parked/%s",rchan->name))) {
@@ -517,7 +544,7 @@
 		orig_chan_name = ast_strdupa(chan->name);
 	}
 
-	park_status = park_call_full(chan, peer, timeout, extout, orig_chan_name);
+	park_status = park_call_full(chan, peer, timeout, extout, orig_chan_name, x);
 	if (park_status == 1) {
 		/* would be nice to play: "invalid parking extension" */
 		ast_hangup(chan);
@@ -536,12 +563,6 @@
 {
 	return masq_park_call(rchan, peer, timeout, extout, 1, orig_chan_name);
 }
-#define FEATURE_RETURN_HANGUP                  -1
-#define FEATURE_RETURN_SUCCESSBREAK             0
-#define FEATURE_RETURN_PASSDIGITS               21
-#define FEATURE_RETURN_STOREDIGITS              22
-#define FEATURE_RETURN_SUCCESS                  23
-#define FEATURE_RETURN_KEEPTRYING               24
 
 #define FEATURE_SENSE_CHAN	(1 << 0)
 #define FEATURE_SENSE_PEER	(1 << 1)
@@ -588,8 +609,8 @@
 		res = ast_safe_sleep(chan, 1000);
 
 	if (!res) { /* one direction used to call park_call.... */
-		masq_park_call_announce(parkee, parker, 0, NULL, orig_chan_name);
-		res = 0; /* PBX should hangup zombie channel */
+		res = masq_park_call_announce(parkee, parker, 0, NULL, orig_chan_name);
+		/* PBX should hangup zombie channel if a masquerade actually occurred (res=0) */
 	}
 
 	ast_module_user_remove(u);
@@ -1171,7 +1192,11 @@
 		    !ast_strlen_zero(builtin_features[x].exten)) {
 			/* Feature is up for consideration */
 			if (!strcmp(builtin_features[x].exten, code)) {
+				if (option_debug > 2) {
+					ast_log(LOG_DEBUG, "Feature detected: fname=%s sname=%s exten=%s\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
+				}
 				res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
+ast_log(LOG_DEBUG, "jpeeler: res = %d\n", res);
 				feature_detected = 1;
 				break;
 			} else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {




More information about the asterisk-commits mailing list