[svn-commits] branch oej/metermaids-trunk r36014 - /team/oej/metermaids-trunk/res/

svn-commits at lists.digium.com svn-commits at lists.digium.com
Mon Jun 26 02:26:01 MST 2006


Author: oej
Date: Mon Jun 26 04:26:00 2006
New Revision: 36014

URL: http://svn.digium.com/view/asterisk?rev=36014&view=rev
Log:
Add support for parking on named extension. 

Modified:
    team/oej/metermaids-trunk/res/res_features.c

Modified: team/oej/metermaids-trunk/res/res_features.c
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids-trunk/res/res_features.c?rev=36014&r1=36013&r2=36014&view=diff
==============================================================================
--- team/oej/metermaids-trunk/res/res_features.c (original)
+++ team/oej/metermaids-trunk/res/res_features.c Mon Jun 26 04:26:00 2006
@@ -122,7 +122,11 @@
 "transfer to know the parking space). This application is always\n"
 "registered internally and does not need to be explicitly added\n"
 "into the dialplan, although you should include the 'parkedcalls'\n"
-"context.\n";
+"context (or the context specified in features.conf).\n\n"
+"If you set the PARKINGEXTEN variable to an extension in your\n"
+"parking context, park() will park the call on that extension, unless\n"
+"it already exists. In that case, execution will continue at next\n"
+"priority.\n" ;
 
 static struct ast_app *monitor_app = NULL;
 static int monitor_ok = 1;
@@ -131,6 +135,7 @@
 	struct ast_channel *chan;                   /*!< Parking channel */
 	struct timeval start;                       /*!< Time the parking started */
 	int parkingnum;                             /*!< Parking lot */
+	char parkingexten[AST_MAX_EXTENSION];       /*!< If set beforehand, parking extension used for this call */
 	char context[AST_MAX_CONTEXT];              /*!< Where to go if our parking time expires */
 	char exten[AST_MAX_EXTENSION];
 	int priority;
@@ -305,40 +310,56 @@
 int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
 {
 	struct parkeduser *pu, *cur;
-	int i,x,parking_range;
-	char exten[AST_MAX_EXTENSION];
+	int i, x = -1, parking_range;
 	struct ast_context *con;
+	const char *parkingexten;
 	
+	/* Allocate memory for parking data */
 	if (!(pu = ast_calloc(1, sizeof(*pu)))) 
 		return -1;
 
+	/* Lock parking lot */
 	ast_mutex_lock(&parking_lock);
-	parking_range = parking_stop - parking_start+1;
-	for (i = 0; i < parking_range; i++) {
-		x = (i + parking_offset) % parking_range + parking_start;
-		cur = parkinglot;
-		while(cur) {
-			if (cur->parkingnum == x) 
+	/* Check for channel variable PARKINGEXTEN */
+	parkingexten = pbx_builtin_getvar_helper(chan, "PARKINGEXTEN");
+	if (!ast_strlen_zero(parkingexten)) {
+		if (ast_exists_extension(NULL, parking_con, parkingexten, 1, NULL)) {
+			ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parking_con);
+			return 0;	/* Continue execution if possible */
+		}
+		ast_copy_string(pu->parkingexten, parkingexten, sizeof(pu->parkingexten));
+	} else {
+		/* Select parking space within range */
+		parking_range = parking_stop - parking_start+1;
+		for (i = 0; i < parking_range; i++) {
+			x = (i + parking_offset) % parking_range + parking_start;
+			cur = parkinglot;
+			while(cur) {
+				if (cur->parkingnum == x) 
+					break;
+				cur = cur->next;
+			}
+			if (!cur)
 				break;
-			cur = cur->next;
-		}
-		if (!cur)
-			break;
-	}
-
-	if (!(i < parking_range)) {
-		ast_log(LOG_WARNING, "No more parking spaces\n");
-		free(pu);
-		ast_mutex_unlock(&parking_lock);
-		return -1;
-	}
-	if (parkfindnext) 
-		parking_offset = x - parking_start + 1;
+		}
+
+		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;
+	}
+	
 	chan->appl = "Parked Call";
 	chan->data = NULL; 
 
 	pu->chan = chan;
-	/* Start music on hold */
+	
+	/* Start music on hold if we have two different channels */
 	if (chan != peer) {
 		ast_indicate(pu->chan, AST_CONTROL_HOLD);	/* Indicate to peer that we're on hold */
 		ast_moh_start(pu->chan, NULL);
@@ -348,6 +369,7 @@
 	pu->parkingtime = (timeout > 0) ? timeout : parkingtime;
 	if (extout)
 		*extout = x;
+
 	if (peer) 
 		ast_copy_string(pu->peername, peer->name, sizeof(pu->peername));
 
@@ -358,6 +380,7 @@
 	pu->priority = chan->macropriority ? chan->macropriority : chan->priority;
 	pu->next = parkinglot;
 	parkinglot = pu;
+
 	/* If parking a channel directly, don't quiet yet get parking running on it */
 	if (peer == chan) 
 		pu->notquiteyet = 1;
@@ -365,23 +388,25 @@
 	/* Wake up the (presumably select()ing) thread */
 	pthread_kill(parking_thread, SIGURG);
 	if (option_verbose > 1) 
-		ast_verbose(VERBOSE_PREFIX_2 "Parked %s on %d. Will timeout back to extension [%s] %s, %d in %d seconds\n", pu->chan->name, pu->parkingnum, pu->context, pu->exten, pu->priority, (pu->parkingtime/1000));
-
+		ast_verbose(VERBOSE_PREFIX_2 "Parked %s on %d@%s. Will timeout back to extension [%s] %s, %d in %d seconds\n", pu->chan->name, pu->parkingnum, parking_con, pu->context, pu->exten, pu->priority, (pu->parkingtime/1000));
+
+	if (pu->parkingnum != -1)
+		snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
 	manager_event(EVENT_FLAG_CALL, "ParkedCall",
-		"Exten: %d\r\n"
+		"Exten: %s\r\n"
 		"Channel: %s\r\n"
 		"From: %s\r\n"
 		"Timeout: %ld\r\n"
 		"CallerID: %s\r\n"
 		"CallerIDName: %s\r\n",
-		pu->parkingnum, pu->chan->name, peer ? peer->name : "",
+		pu->parkingexten, pu->chan->name, peer ? peer->name : "",
 		(long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
 		S_OR(pu->chan->cid.cid_num, "<unknown>"),
 		S_OR(pu->chan->cid.cid_name, "<unknown>")
 		);
 
 	if (peer && adsipark && adsi_available(peer)) {
-		adsi_announce_park(peer, pu->parkingnum);
+		adsi_announce_park(peer, pu->parkingnum);	/* Only supports parking numbers */
 		adsi_unload_session(peer);
 	}
 
@@ -391,12 +416,11 @@
 	if (!con)	/* Still no context? Bad */
 		ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
 	else {		/* Add extension to context */
-		snprintf(exten, sizeof(exten), "%d", x);
-		if (!ast_add_extension2(con, 1, exten, 1, NULL, NULL, parkedcall, strdup(exten), FREE, registrar))
+		if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, strdup(exten), FREE, registrar))
 			notify_metermaids(exten, parking_con);
 	}
 	/* Tell the peer channel the number of the parking space */
-	if (peer) 
+	if (peer && !pu->parkingnum == -1) 
 		ast_say_digits(peer, pu->parkingnum, "", peer->language);
 	if (pu->notquiteyet) {
 		/* Wake up parking thread if we're really done */
@@ -449,7 +473,7 @@
 #define FEATURE_SENSE_CHAN	(1 << 0)
 #define FEATURE_SENSE_PEER	(1 << 1)
 
-/*
+/*! \brief
  * set caller and callee according to the direction
  */
 static void set_peers(struct ast_channel **caller, struct ast_channel **callee,
@@ -464,6 +488,7 @@
 	}
 }
 
+/*! \brief support routing for one touch call parking */
 static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense)
 {
 	struct ast_channel *parker;
@@ -508,7 +533,7 @@
 	}
 
 	if (!monitor_app && !(monitor_app = pbx_findapp("Monitor"))) {
-		monitor_ok=0;
+		monitor_ok = 0;
 		ast_log(LOG_ERROR,"Cannot record the call. The monitor application is disabled.\n");
 		return -1;
 	}
@@ -596,6 +621,7 @@
         return res;
 }
 
+/*! \brief Find the context for the transfer */
 static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee)
 {
         const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT");
@@ -882,6 +908,7 @@
 	free(feature);
 }
 
+/*! \brief Remove all features in the list */
 static void ast_unregister_features(void)
 {
 	struct ast_call_feature *feature;
@@ -1449,14 +1476,15 @@
 	return res;
 }
 
-static void post_manager_event(const char *s, int num, struct ast_channel *chan)
+static void post_manager_event(const char *s, char *parkingexten, struct ast_channel *chan)
 {
 	manager_event(EVENT_FLAG_CALL, s,
-		"Exten: %d\r\n"
+		"Exten: %s\r\n"
 		"Channel: %s\r\n"
 		"CallerID: %s\r\n"
 		"CallerIDName: %s\r\n\r\n",
-		num, chan->name,
+		parkingexten, 
+		chan->name,
 		S_OR(chan->cid.cid_num, "<unknown>"),
 		S_OR(chan->cid.cid_name, "<unknown>")
 		);
@@ -1481,7 +1509,7 @@
 		pl = NULL;
 		pu = parkinglot;
 		/* navigate the list with prev-cur pointers to support removals */
-		while(pu) {
+		while (pu) {
 			struct ast_channel *chan = pu->chan;	/* shorthand */
 			int tms;        /* timeout for this item */
 			int x;          /* fd index in channel */
@@ -1506,9 +1534,8 @@
 					con = ast_context_find(parking_con_dial);
 					if (!con) {
 						con = ast_context_create(NULL, parking_con_dial, registrar);
-						if (!con) {
+						if (!con)
 							ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", parking_con_dial);
-						}
 					}
 					if (con) {
 						char returnexten[AST_MAX_EXTENSION];
@@ -1522,7 +1549,7 @@
 					set_c_e_p(chan, pu->context, pu->exten, pu->priority);
 				}
 
-				post_manager_event("ParkedCallTimeOut", pu->parkingnum, chan);
+				post_manager_event("ParkedCallTimeOut", pu->parkingexten, chan);
 
 				if (option_verbose > 1) 
 					ast_verbose(VERBOSE_PREFIX_2 "Timeout for %s parked on %d. Returning to %s,%s,%d\n", chan->name, pu->parkingnum, chan->context, chan->exten, chan->priority);
@@ -1540,9 +1567,7 @@
 				pu = pu->next;
 				con = ast_context_find(parking_con);
 				if (con) {
-					char exten[AST_MAX_EXTENSION];
-					snprintf(exten, sizeof(exten), "%d", pt->parkingnum);
-					if (ast_context_remove_extension2(con, exten, 1, NULL))
+					if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL))
 						ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
 					else
 						notify_metermaids(exten, parking_con);
@@ -1561,12 +1586,13 @@
 					else
 						ast_clear_flag(chan, AST_FLAG_EXCEPTION);
 					chan->fdno = x;
+
 					/* See if they need servicing */
 					f = ast_read(chan);
 					if (!f || (f->frametype == AST_FRAME_CONTROL && f->subclass ==  AST_CONTROL_HANGUP)) {
 						if (f)
 							ast_frfree(f);
-						post_manager_event("ParkedCallGiveUp", pu->parkingnum, chan);
+						post_manager_event("ParkedCallGiveUp", pu->parkingexten, chan);
 
 						/* There's a problem, hang them up*/
 						if (option_verbose > 1) 
@@ -1581,9 +1607,7 @@
 						pu = pu->next;
 						con = ast_context_find(parking_con);
 						if (con) {
-							char exten[AST_MAX_EXTENSION];
-							snprintf(exten, sizeof(exten), "%d", pt->parkingnum);
-							if (ast_context_remove_extension2(con, exten, 1, NULL))
+							if (ast_context_remove_extension2(con, pt->parkingexten, 1, NULL))
 								ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
 						else
 							notify_metermaids(exten, parking_con);
@@ -1634,6 +1658,7 @@
 	return NULL;	/* Never reached */
 }
 
+/*! \brief Park a call */
 static int park_call_exec(struct ast_channel *chan, void *data)
 {
 	/* Data is unused at the moment but could contain a parking
@@ -1645,10 +1670,13 @@
 	   where this call should return */
 	strcpy(chan->exten, "s");
 	chan->priority = 1;
+	/* Answer if call is not up */
 	if (chan->_state != AST_STATE_UP)
 		res = ast_answer(chan);
+	/* Sleep to allow VoIP streams to settle down */
 	if (!res)
 		res = ast_safe_sleep(chan, 1000);
+	/* Park the call */
 	if (!res)
 		res = ast_park_call(chan, chan, 0, NULL);
 	LOCAL_USER_REMOVE(u);
@@ -1657,6 +1685,7 @@
 	return res;
 }
 
+/*! \brief Pickup parked call */
 static int park_exec(struct ast_channel *chan, void *data)
 {
 	int res=0;
@@ -1668,7 +1697,7 @@
 	struct ast_bridge_config config;
 
 	if (!data) {
-		ast_log(LOG_WARNING, "Park requires an argument (extension number)\n");
+		ast_log(LOG_WARNING, "Parkedcall requires an argument (extension number)\n");
 		return -1;
 	}
 	LOCAL_USER_ADD(u);
@@ -1844,8 +1873,8 @@
 	ast_mutex_lock(&parking_lock);
 
 	for (cur = parkinglot; cur; cur = cur->next) {
-		ast_cli(fd, "%4d %25s (%-15s %-12s %-4d) %6lds\n"
-			,cur->parkingnum, cur->chan->name, cur->context, cur->exten
+		ast_cli(fd, "%-10.10s %25s (%-15s %-12s %-4d) %6lds\n"
+			,cur->parkingexten, cur->chan->name, cur->context, cur->exten
 			,cur->priority, cur->start.tv_sec + (cur->parkingtime/1000) - time(NULL));
 
 		numparked++;



More information about the svn-commits mailing list