[svn-commits] mvanbaak: branch group/multiparking r104046 - in /team/group/multiparking: ch...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Sat Feb 23 05:26:22 CST 2008


Author: mvanbaak
Date: Sat Feb 23 05:26:20 2008
New Revision: 104046

URL: http://svn.digium.com/view/asterisk?view=rev&rev=104046
Log:
work done so far

Modified:
    team/group/multiparking/channels/chan_iax2.c
    team/group/multiparking/configs/features.conf.sample
    team/group/multiparking/main/features.c

Modified: team/group/multiparking/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/channels/chan_iax2.c?view=diff&rev=104046&r1=104045&r2=104046
==============================================================================
--- team/group/multiparking/channels/chan_iax2.c (original)
+++ team/group/multiparking/channels/chan_iax2.c Sat Feb 23 05:26:20 2008
@@ -2432,7 +2432,7 @@
 		ast_cli(a->fd, "  * Name       : %s\n", peer->name);
 		ast_cli(a->fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
 		ast_cli(a->fd, "  Context      : %s\n", peer->context);
-		ast_cli(a->fd, "  Parking lot  : %s\n", peer->parkinglot);
+ 		ast_cli(a->fd, "  Parking lot  : %s\n", peer->parkinglot);
 		ast_cli(a->fd, "  Mailbox      : %s\n", peer->mailbox);
 		ast_cli(a->fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
 		ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));

Modified: team/group/multiparking/configs/features.conf.sample
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/configs/features.conf.sample?view=diff&rev=104046&r1=104045&r2=104046
==============================================================================
--- team/group/multiparking/configs/features.conf.sample (original)
+++ team/group/multiparking/configs/features.conf.sample Sat Feb 23 05:26:20 2008
@@ -47,6 +47,7 @@
 ; They can not be used while the remote party is ringing or in progress. If you require this feature you can use
 ; chan_local in combination with Answer to accomplish it.
 
+
 [featuremap]
 ;blindxfer => #1		; Blind transfer  (default is #)
 ;disconnect => *0		; Disconnect  (default is *)
@@ -88,6 +89,7 @@
 ;                   channel waits for the feature to complete. If left blank,
 ;                   no music will be played.
 ;
+
 ;
 ; IMPORTANT NOTE: The applicationmap is not intended to be used for all Asterisk
 ;   applications. When applications are used in extensions.conf, they are executed
@@ -109,7 +111,6 @@
 ;unpauseMonitor => #3,self/callee,UnPauseMonitor   ;Allow the callee to unpause monitoring
 ;                                                  ;on their channel
 ;
-
 ;*** Define another parking lot
 ;
 ; You can set parkinglot with the CHANNEL dialplan function
@@ -124,15 +125,7 @@
 ;   Groups are groupings of features defined in [applicationmap]
 ;   that can have their own key mappings.
 ;
-;   Groups are defined as a configuration section,
-;   and can be set as part of DYNAMIC_FEATURES in
-;   the same way that a normal feature can... 
-;	etc:	
-;
-;	  Set(DYNAMIC_FEATURES=myGroupName);
-;
 ; example:
 ; [myGroupName]        ; defines the group named myGroupName
 ; testfeature => #9    ; associates testfeature with the group and the keycode #9
 ; pauseMonitor         ; associates pauseMonitor with the group and the keycode
-;                      ; defined in [applicationmap]

Modified: team/group/multiparking/main/features.c
URL: http://svn.digium.com/view/asterisk/team/group/multiparking/main/features.c?view=diff&rev=104046&r1=104045&r2=104046
==============================================================================
--- team/group/multiparking/main/features.c (original)
+++ team/group/multiparking/main/features.c Sat Feb 23 05:26:20 2008
@@ -53,11 +53,13 @@
 #include "asterisk/devicestate.h"
 #include "asterisk/monitor.h"
 #include "asterisk/audiohook.h"
+#include "asterisk/astobj.h"
 
 #define DEFAULT_PARK_TIME 45000
 #define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000
 #define DEFAULT_FEATURE_DIGIT_TIMEOUT 500
 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000
+#define DEFAULT_PARKINGLOT "default"			/*!< Default parking lot */
 #define DEFAULT_ATXFER_DROP_CALL 0
 #define DEFAULT_ATXFER_LOOP_DELAY 10000
 #define DEFAULT_ATXFER_CALLBACK_RETRIES 2
@@ -97,26 +99,37 @@
 static int parkedcalltransfers = 0;                        /*!< Enable DTMF based transfers on bridge when picking up parked calls */
 static int parkedcallreparking = 0;                        /*!< Enable DTMF based parking on bridge when picking up parked calls */
 static int parkingtime = DEFAULT_PARK_TIME;                /*!< No more than 45 seconds parked before you do something with them */
-static char parking_con[AST_MAX_EXTENSION];                /*!< Context for which parking is made accessible */
-static char parking_con_dial[AST_MAX_EXTENSION];           /*!< Context for dialback for parking (KLUDGE) */
-static char parking_ext[AST_MAX_EXTENSION];                /*!< Extension you type to park the call */
 static char pickup_ext[AST_MAX_EXTENSION];                 /*!< Call pickup extension */
 static char parkmohclass[MAX_MUSICCLASS];                  /*!< Music class used for parking */
-static int parking_start;                                  /*!< First available extension for parking */
-static int parking_stop;                                   /*!< Last available extension for parking */
-
+
+/*! \brief Structure for parking lots in a linked list. */
+struct ast_parkinglot {
+	ASTOBJ_COMPONENTS(struct ast_parkinglot);	/*!< various object stuff, including ->name */
+	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 parking_ext[AST_MAX_EXTENSION];                /*!< Extension you type to park the call */
+	int parking_start;				/*!< First available extension for parking */
+	int parking_stop;				/*!< Last available extension for parking */
+	int parking_offset;
+	int parkfindnext;
+	int parkingtime;				/*!< Default parking time */
+	struct parkeduser *occupiedlots;
+};
+
+struct ast_parkinglot_list {
+	ASTOBJ_CONTAINER_COMPONENTS(struct ast_parkinglot);
+} parkinglots;
+ 
 static char courtesytone[256];                             /*!< Courtesy tone */
 static int parkedplay = 0;                                 /*!< Who to play the courtesy tone to */
 static char xfersound[256];                                /*!< Call transfer sound */
 static char xferfailsound[256];                            /*!< Call transfer failure sound */
 
-static int parking_offset;
-static int parkfindnext;
-
 static int adsipark;
 
 static int transferdigittimeout;
 static int featuredigittimeout;
+struct ast_parkinglot *default_parkinglot;
 static int comebacktoorigin = 1;
 
 static int atxfernoanswertimeout;
@@ -172,10 +185,18 @@
 	int notquiteyet;
 	char peername[1024];
 	unsigned char moh_trys;
-	AST_LIST_ENTRY(parkeduser) list;
+	struct ast_parkinglot *parkinglot;
+//	AST_LIST_ENTRY(parkeduser) list;
 };
 
-static AST_LIST_HEAD_STATIC(parkinglot, parkeduser);
+//static AST_LIST_HEAD_STATIC(parkinglot, parkeduser);
+/* Forward declarations */
+static struct ast_parkinglot *parkinglot_addref(struct ast_parkinglot *parkinglot);
+static void parkinglot_unref(struct ast_parkinglot *parkinglot);
+static void parkinglot_destroy(struct ast_parkinglot *ruin);
+int manage_parkinglot(struct ast_parkinglot *curlot, fd_set *rfds, fd_set *efds, fd_set *nrfds, fd_set *nefds);
+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(const char *name);
 
 static pthread_t parking_thread;
 
@@ -353,6 +374,23 @@
 	return ast_adsi_print(chan, message, justify, 1);
 }
 
+/*! \brief Find parking lot name from channel */
+static const char *findparkinglotname(struct ast_channel *chan)
+{
+	const char *temp, *parkinglot = NULL;
+
+	/* Check if the channel has a parking lot */
+	if (!ast_strlen_zero(chan->parkinglot))
+		parkinglot = chan->parkinglot;
+
+	/* Channel variables override everything */
+
+	if ((temp  = pbx_builtin_getvar_helper(chan, "PARKINGLOT")))
+		return temp;
+
+	return parkinglot;
+}
+
 /*! \brief Notify metermaids that we've changed an extension */
 static void notify_metermaids(const char *exten, char *context, enum ast_device_state state)
 {
@@ -383,36 +421,57 @@
 }
 
 /* Park a call */
-static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout, char *orig_chan_name)
+static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout, char *orig_chan_name, struct ast_parkinglot *parkinglot)
 {
 	struct parkeduser *pu, *cur;
 	int i, x = -1, parking_range;
 	struct ast_context *con;
+	const char *parkinglotname;
 	const char *parkingexten;
 	
+	parkinglotname = findparkinglotname(peer);
+
+	if (parkinglotname) {
+		if (option_debug)
+			ast_log(LOG_DEBUG, "Found chanvar Parkinglot: %s\n", parkinglotname);
+		parkinglot = find_parkinglot(parkinglotname);	
+	}
+	if (!parkinglot)
+		parkinglot = default_parkinglot;
+
+	parkinglot_addref(parkinglot);
+	if (option_debug)
+		ast_log(LOG_DEBUG, "Parkinglot: %s\n", parkinglot->name);
+
 	/* Allocate memory for parking data */
-	if (!(pu = ast_calloc(1, sizeof(*pu)))) 
+	if (!(pu = ast_calloc(1, sizeof(*pu)))) {
+		parkinglot_unref(parkinglot);
 		return -1;
+	}
+
+	ASTOBJ_WRLOCK(parkinglot);
 
 	/* Lock parking lot */
-	AST_LIST_LOCK(&parkinglot);
+	//AST_LIST_LOCK(&parkinglot);
 	/* 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_LIST_UNLOCK(&parkinglot);
+		if (ast_exists_extension(NULL, parkinglot->parking_con, parkingexten, 1, NULL)) {
+			//AST_LIST_UNLOCK(&parkinglot);
+			parkinglot_unref(parkinglot);
 			ast_free(pu);
-			ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parking_con);
+			ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parkinglot->parking_con);
 			return 1;	/* Continue execution if possible */
 		}
 		ast_copy_string(pu->parkingexten, parkingexten, sizeof(pu->parkingexten));
 		x = atoi(parkingexten);
 	} else {
 		/* Select parking space within range */
-		parking_range = parking_stop - parking_start+1;
+		parking_range = parkinglot->parking_stop - parkinglot->parking_start+1;
 		for (i = 0; i < parking_range; i++) {
-			x = (i + parking_offset) % parking_range + parking_start;
-			AST_LIST_TRAVERSE(&parkinglot, cur, list) {
+			x = (i + parkinglot->parking_offset) % parking_range + parkinglot->parking_start;
+			cur = parkinglot->occupiedlots;
+			while (cur) {
 				if (cur->parkingnum == x)
 					break;
 			}
@@ -421,14 +480,15 @@
 		}
 
 		if (!(i < parking_range)) {
-			ast_log(LOG_WARNING, "No more parking spaces\n");
+			ast_log(LOG_WARNING, "No more parking spaces in parking lot \"%s\"\n", parkinglot->name);
 			ast_free(pu);
-			AST_LIST_UNLOCK(&parkinglot);
+			parkinglot_unref(parkinglot);
+			ASTOBJ_UNLOCK(parkinglot);
 			return -1;
 		}
 		/* Set pointer for next parking */
-		if (parkfindnext) 
-			parking_offset = x - parking_start + 1;
+		if (parkinglot->parkfindnext) 
+			parkinglot->parking_offset = x - parkinglot->parking_start + 1;
 	}
 	
 	chan->appl = "Parked Call";
@@ -445,6 +505,7 @@
 	
 	pu->start = ast_tvnow();
 	pu->parkingnum = x;
+	pu->parkinglot = parkinglot;
 	pu->parkingtime = (timeout > 0) ? timeout : parkingtime;
 	if (extout)
 		*extout = x;
@@ -457,7 +518,9 @@
 	ast_copy_string(pu->context, S_OR(chan->macrocontext, chan->context), sizeof(pu->context));
 	ast_copy_string(pu->exten, S_OR(chan->macroexten, chan->exten), sizeof(pu->exten));
 	pu->priority = chan->macropriority ? chan->macropriority : chan->priority;
-	AST_LIST_INSERT_TAIL(&parkinglot, pu, list);
+	pu->next = parkinglot->occupiedlots;
+	parkinglot->occupiedlots = pu;
+	ASTOBJ_UNLOCK(parkinglot);
 
 	/* If parking a channel directly, don't quiet yet get parking running on it */
 	if (peer == chan) 
@@ -465,18 +528,19 @@
 	AST_LIST_UNLOCK(&parkinglot);
 	/* Wake up the (presumably select()ing) thread */
 	pthread_kill(parking_thread, SIGURG);
-	ast_verb(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));
+	ast_verb(2, "Parked %s on %d (lot %s). Will timeout back to extension [%s] %s, %d in %d seconds\n", pu->chan->name, pu->parkingnum, parkinglot->name, 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: %s\r\n"
 		"Channel: %s\r\n"
+		"Parkinglot: %s\r\n"
 		"From: %s\r\n"
 		"Timeout: %ld\r\n"
 		"CallerIDNum: %s\r\n"
 		"CallerIDName: %s\r\n",
-		pu->parkingexten, pu->chan->name, peer ? peer->name : "",
+		pu->parkingexten, pu->chan->name, pu->parkinglot->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>")
@@ -487,11 +551,11 @@
 		ast_adsi_unload_session(peer);
 	}
 
-	con = ast_context_find(parking_con);
+	con = ast_context_find(parkinglot->parking_con);
 	if (!con) 
-		con = ast_context_create(NULL, parking_con, registrar);
+		con = ast_context_create(NULL, parkinglot->parking_con, registrar);
 	if (!con)	/* Still no context? Bad */
-		ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
+		ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parkinglot->parking_con);
 	/* Tell the peer channel the number of the parking space */
 	if (peer && ((pu->parkingnum != -1 && ast_strlen_zero(orig_chan_name)) || !strcasecmp(peer->name, orig_chan_name))) { /* Only say number if it's a number and the channel hasn't been masqueraded away */
 		/* Make sure we don't start saying digits to the channel being parked */
@@ -501,7 +565,7 @@
 	}
 	if (con) {
 		if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar))
-			notify_metermaids(pu->parkingexten, parking_con, AST_DEVICE_INUSE);
+			notify_metermaids(pu->parkingexten, parkinglot->parking_con, AST_DEVICE_INUSE);
 	}
 	if (pu->notquiteyet) {
 		/* Wake up parking thread if we're really done */
@@ -2164,10 +2228,12 @@
 	manager_event(EVENT_FLAG_CALL, s,
 		"Exten: %s\r\n"
 		"Channel: %s\r\n"
+		"Parkinglot: %s\r\n"
 		"CallerIDNum: %s\r\n"
 		"CallerIDName: %s\r\n\r\n",
 		pu->parkingexten, 
 		pu->chan->name,
+		pu->parkinglot->name,
 		S_OR(pu->chan->cid.cid_num, "<unknown>"),
 		S_OR(pu->chan->cid.cid_name, "<unknown>")
 		);




More information about the svn-commits mailing list