[svn-commits] branch bweschke/findme_followme r31808 - /team/bweschke/findme_followme/apps/

svn-commits at lists.digium.com svn-commits at lists.digium.com
Sat Jun 3 11:29:57 MST 2006


Author: bweschke
Date: Sat Jun  3 13:29:57 2006
New Revision: 31808

URL: http://svn.digium.com/view/asterisk?rev=31808&view=rev
Log:
 List macro conversion "complete"... sans compiler errors having been eliminated.


Modified:
    team/bweschke/findme_followme/apps/app_followme.c

Modified: team/bweschke/findme_followme/apps/app_followme.c
URL: http://svn.digium.com/view/asterisk/team/bweschke/findme_followme/apps/app_followme.c?rev=31808&r1=31807&r2=31808&view=diff
==============================================================================
--- team/bweschke/findme_followme/apps/app_followme.c (original)
+++ team/bweschke/findme_followme/apps/app_followme.c Sat Jun  3 13:29:57 2006
@@ -86,9 +86,10 @@
 	AST_LIST_ENTRY(ast_call_followme) entry;           /*!< Next Follow-Me record */
 };
 
-struct thread_args {
+struct fm_args {
 	struct ast_channel *chan;
-	struct number *numbers;
+	char *mohclass;
+	AST_LIST_HEAD_NOLOCK(numbers, number) numbers;
 	int status;
 	char context[AST_MAX_CONTEXT];
 	char namerecloc[AST_MAX_CONTEXT];
@@ -105,8 +106,6 @@
 	AST_LIST_ENTRY(findme_user) entry;	
 };
 
-static struct thread_args targs;
-static struct ast_bridge_config config;
 static int ynlongest = 0;
 static char toast[80];
 static time_t start_time, answer_time, end_time;
@@ -118,6 +117,7 @@
 static char takecall[20] = "1", nextindp[20] = "2", nextinfmfm[20] = "", blindxferexten[20] = "", atxferexten[20] = "";
 
 static AST_LIST_HEAD_STATIC(followmes, ast_call_followme);
+static AST_LIST_HEAD_NOLOCK(findme_user_listptr, findme_user);
 
 static void free_numbers(struct ast_call_followme *f)
 {
@@ -249,7 +249,7 @@
 		/* Define a new profile */
 		/* Look for an existing one */
 		AST_LIST_TRAVERSE(&followmes, f, entry) {
-			if (!strcmp(f->name, cat))
+			if (!strcasecmp(f->name, cat))
 				break;
 		}
 		if (option_debug > 2)
@@ -306,43 +306,46 @@
 	return 1;
 }
 
-static void clear_calling_tree(struct findme_user *headuser,int wholetree) 
+static void clear_caller(struct findme_user *tmpuser)
+{
+	struct ast_channel *outbound = NULL;
+	
+	if (tmpuser && tmpuser->ochan && tmpuser->state >= 0) {
+		outbound = tmpuser->ochan;
+		if (!outbound->cdr) {
+			outbound->cdr = ast_cdr_alloc();
+			if (outbound->cdr)
+				ast_cdr_init(outbound->cdr, outbound);
+		}
+		if (outbound->cdr) {
+			char tmp[256];
+			snprintf(tmp, 256, "%s/%s", "Local", tmpuser->dialarg);
+			ast_cdr_setapp(outbound->cdr,"FollowMe",tmp);
+			ast_cdr_update(outbound);
+			ast_cdr_start(outbound->cdr);
+			ast_cdr_end(outbound->cdr);
+			/* If the cause wasn't handled properly */
+			if (ast_cdr_disposition(outbound->cdr,outbound->hangupcause))
+				ast_cdr_failed(outbound->cdr);
+		} else
+			ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
+		ast_hangup(tmpuser->ochan);
+	}
+
+}
+
+static void clear_calling_tree(findme_user_listptr findme_user_list) 
 {
 	struct findme_user *tmpuser = NULL;
-	struct ast_channel *outbound = NULL;
-	
-	tmpuser = headuser;
-	
-	while (tmpuser) {		
-		if (tmpuser->ochan && tmpuser->state >= 0) {
-			outbound = tmpuser->ochan;
-			if (!outbound->cdr) {
-				outbound->cdr = ast_cdr_alloc();
-				if (outbound->cdr)
-					ast_cdr_init(outbound->cdr, outbound);
-			}
-			if (outbound->cdr) {
-				char tmp[256];
-				snprintf(tmp, 256, "%s/%s", "Local", tmpuser->dialarg);
-				ast_cdr_setapp(outbound->cdr,"FollowMe",tmp);
-				ast_cdr_update(outbound);
-				ast_cdr_start(outbound->cdr);
-				ast_cdr_end(outbound->cdr);
-				/* If the cause wasn't handled properly */
-				if (ast_cdr_disposition(outbound->cdr,outbound->hangupcause))
-					ast_cdr_failed(outbound->cdr);
-			} else
-				ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
-			ast_hangup(tmpuser->ochan);
-		}
-		if (!wholetree)
-			break;
-	}
-}
-
-
-
-static struct ast_channel *wait_for_winner(struct findme_user *headuser, struct number *nm, struct ast_channel *caller, char *namerecloc, int *status) 
+	
+	AST_LIST_TRAVERSE(&findme_user_list, tmpuser, entry) 		
+		clear_caller(tmpuser);
+	
+}
+
+
+
+static struct ast_channel *wait_for_winner(findme_user_listptr findme_user_list, struct number *nm, struct ast_channel *caller, char *namerecloc, int *status) 
 {
 	struct ast_channel *watchers[256];
 	int pos;
@@ -363,11 +366,11 @@
 	callfromname = ast_strdupa("call-from");
 	pressbuttonname = ast_strdupa("press-1-to-be-connected-or");	
 
-	if (headuser->ochan)
+	if (!AST_LIST_EMPTY(&findme_user_list))
 	{
 		if (!caller) {
 			ast_log(LOG_NOTICE, "Original caller hungup. Cleanup.\n");
-			clear_calling_tree(headuser,1);
+			clear_calling_tree(findme_user_list);
 			free(to);
 			return 0;
 		}
@@ -381,8 +384,7 @@
 		
 			dg = 0;	
 			winner = NULL;	
-			tmpuser = headuser;
-			while (tmpuser) {
+			AST_LIST_TRAVERSE(&findme_user_list, tmpuser, entry) {
 				if (tmpuser->state >= 0 && tmpuser->ochan) {
 					if (tmpuser->digts && (tmpuser->digts - totalwait) > featuredigittimeout) {
 						ast_log(LOG_NOTICE, "We've been waiting for digits longer than we should have.\n");
@@ -432,15 +434,15 @@
 					watchers[pos++] = tmpuser->ochan;
 					livechannels++;
 				}
-				tmpuser = tmpuser->next;
 			}
+
 			tmpto = *to;
 			winner = ast_waitfor_n(watchers, pos, to);
 			tmpto -= *to;
 			totalwait -= tmpto;
 			if (totalwait <= 0) {
 				ast_log(LOG_NOTICE, "We've hit our timeout for this step. Drop everyone and move on to the next one. %ld\n", totalwait);
-				clear_calling_tree(headuser,1);
+				clear_calling_tree(findme_user_list);
 				free(to);
 				return 0;
 			}
@@ -449,9 +451,9 @@
 				dg = 0;
 				while ((winner != watchers[dg]) && (dg < 256))
 					dg++;
-				tmpuser = headuser;
-				while ((tmpuser) && (tmpuser->ochan != winner)) {
-					tmpuser = tmpuser->next;
+				AST_LIST_TRAVERSE(&findme_user_list, tmpuser, entry) {
+					if (tmpuser->ochan == winner)
+						break;
 				}
 				f = ast_read(winner);
 				if (f) {
@@ -463,7 +465,7 @@
 							if (dg == 0) {
 								if (option_verbose > 2)
 									ast_verbose( VERBOSE_PREFIX_3 "The calling channel hungup. Need to drop everyone else.\n");
-								clear_calling_tree(headuser,1);
+								clear_calling_tree(findme_user_list);
 								ctstatus = -1;
 							}
 							break;
@@ -581,7 +583,7 @@
 
 						ast_log(LOG_NOTICE, "we didn't get a frame. hanging up. dg is %d\n",dg);					      
 						if (!dg) {
-							clear_calling_tree(headuser,1);
+							clear_calling_tree(findme_user_list);
 							free(to);
 							return 0;
 						} else {
@@ -614,7 +616,7 @@
 
 static void findmeexec(void *args)
 {
-	struct thread_args *tpargs;
+	struct fm_args *tpargs;
 	struct number *nm;
 	struct ast_channel *outbound = NULL;
 	struct ast_channel *caller;
@@ -625,10 +627,12 @@
 	struct findme_user *tmpuser = NULL;
 	struct findme_user *fmuser = NULL;
 	struct findme_user *headuser = NULL;
+	struct findme_user_listptr findme_user_list;
 	int status;
-					
-
-	tpargs = (struct thread_args *)args;
+	
+	AST_LIST_HEAD_INIT_NOLOCK(&findme_user_list);
+
+	tpargs = (struct fm_args *)args;
 			
 	if (!tpargs->chan) 
 		return;
@@ -649,10 +653,9 @@
 
 
 	caller = tpargs->chan;
-	nm = tpargs->numbers;
-	while (nm) {
+	AST_LIST_TRAVERSE(&tpargs.numbers, nm, entry) {
 		if (option_debug > 2)	
-			ast_log(LOG_DEBUG, "sleeping now inside the thread. Number %s timeout %ld\n",nm->number,nm->timeout);
+			ast_log(LOG_DEBUG, "Number %s timeout %ld\n",nm->number,nm->timeout);
 		time(&start_time);
 
 		number = ast_strdupa(nm->number);
@@ -684,8 +687,7 @@
 					tmpuser->ochan = outbound;
 					tmpuser->state = 0;
 					ast_copy_string(tmpuser->dialarg, dialarg, sizeof(dialarg));
-					tmpuser->next = fmuser;
-					fmuser = tmpuser;
+					AST_LIST_INSERT_TAIL(&findme_user_list, tmpuser, entry);
 				} else { 
 					ast_log(LOG_NOTICE, "couldn't reach at this number.\n"); 
 					if (outbound) {
@@ -717,31 +719,27 @@
 			number = rest;
 		} while (number);
 				
-		headuser = fmuser;
-			
 		status = 0;	
-		if (headuser->ochan)
+		if (!AST_LIST_EMPTY(&findme_user_list))
 			winner = wait_for_winner(headuser, nm, caller, tpargs->namerecloc, &status);
 		
 					
-		fmuser = headuser;
-		while (fmuser) {
-			headuser = fmuser->next;
+		AST_LIST_TRAVERSE_SAFE_BEGIN(&findme_user_list, fmuser, entry) {
 			if (fmuser->ochan != winner)
-				clear_calling_tree(fmuser, 0);
+				clear_caller(fmuser);
+			AST_LIST_REMOVE_CURRENT(&findme_user_list, entry);
 			free(fmuser);
-			fmuser = headuser;
 		}
+		AST_LIST_TRAVERSE_SAFE_END
 		fmuser = NULL;
 		tmpuser = NULL;
 		headuser = NULL;	
-		nm = nm->next;
 		if (winner)
 			break;
 	}
-	if (!winner) {
+	if (!winner) 
 		tpargs->status = 1;
-	} else {
+	else {
 		tpargs->status = 100;
 		tpargs->outbound = winner;
 	}
@@ -751,13 +749,14 @@
 
 static int app_exec(struct ast_channel *chan, void *data)
 {
+	struct fm_args targs;
+	struct ast_bridge_config config;
 	struct ast_call_followme *f;
-	struct number *nm;
+	struct number *nm, *newnm;
 	int res = 0;
 	struct localuser *u;
 	char *argstr;
 	char namerecloc[255];
-	char dbgetval[50];
 	int duration = 0;
 	struct ast_channel *caller;
 	struct ast_channel *outbound;
@@ -781,28 +780,39 @@
 	AST_STANDARD_APP_ARGS(args, argstr);
 
 	if (!ast_strlen_zero(args.followmeid) && (option_debug > 2)) 
-		ast_log(LOG_DEBUG, "Follow me ID value is : %s\n", args.followmeid);
-	
-
-			f = followmes;
-			while(f) {
-				if (!strcmp(f->name, args.followmeid) && (f->active))
+	
+			AST_LIST_LOCK(&followmes);
+			AST_LIST_TRAVERSE(&followmes, f, entry) {
+				if (!strcasecmp(f->name, args.followmeid) && (f->active))
 					break;
-				f = f->next;
 			}
+			AST_LIST_UNLOCK(&followmes);
+
 			if (option_debug > 2)
 				ast_log(LOG_DEBUG, "New profile %s.\n", args.followmeid);
 			if (!f)
 			{ 
-				ast_log(LOG_WARNING, "Profile not found.");
+				ast_log(LOG_WARNING, "Profile requested, %s, not found in the configuration.", args.followmeid);
 				res = -1;
 			}
 			else
 			{
-
-				if (ast_db_get("FollowMe", args.followmeid, (void *)&dbgetval, 49))
-				{
-					
+	
+				/* XXX TODO: Reinsert the db check value to see whether or not follow-me is on or off */
+
+				/* Lock the profile lock and copy out everything we need to run with before unlocking it again */
+				ast_mutex_lock(&f->lock);
+				targs.mohclass = ast_strdupa(f->moh);
+				ast_copy_string(targs.context, f->context, sizeof(targs.context));
+				/* Copy the numbers we're going to use into another list in case the master list should get modified 
+				   (and locked) while we're trying to do a follow-me */
+				AST_LIST_HEAD_INIT_NOLOCK(&targs.numbers);
+				AST_LIST_TRAVERSE(&f->numbers, nm, entry) {
+					newnm = create_followme_number(nm->number, nm->timeout);
+					AST_LIST_INSERT_TAIL(&targs.numbers, newnm, entry);
+				}
+				ast_mutex_unlock(&f->lock);
+
 				snprintf(namerecloc,sizeof(namerecloc),"%s/followme.%s",ast_config_AST_SPOOL_DIR,chan->uniqueid);
 				duration = 5;
 				if (ast_play_and_record(chan, "vm-rec-name", namerecloc, 5, "sln", &duration, 128, 0, NULL) < 0)
@@ -811,25 +821,24 @@
 					goto outrun;
 				if (ast_waitstream(chan, "") < 0)
 					goto outrun;
-				nm = f->numbers;
-				if (!strcmp(f->moh, ""))
+				if (!strcmp(targs.mohclass, ""))
 					ast_moh_start(chan, NULL);
 				else
-					ast_moh_start(chan, f->moh);
-				while (nm) {
-					 	if (option_debug > 2)
-							ast_log(LOG_DEBUG, "Number %s, timeout %ld\n", nm->number, nm->timeout);
-					 nm = nm->next;
-				}
+					ast_moh_start(chan, targs.mohclass);
 
 
 				targs.status = 0;
 				targs.chan = chan;
-				targs.numbers = f->numbers;
+
 				ast_copy_string(targs.namerecloc, namerecloc, sizeof(targs.namerecloc));
-				ast_copy_string(targs.context, f->context, sizeof(targs.context));
-
-				findmeexec(&targs);			
+
+				findmeexec(&targs);		
+				
+				AST_LIST_TRAVERSE_SAFE_BEGIN(&targs.numbers, nm, entry)	{
+					AST_LIST_REMOVE_CURRENT(&targs.numbers, entry);
+					free(nm);
+				}
+				AST_LIST_TRAVERSE_SAFE_END
 	
 				unlink(namerecloc);	
 				if (targs.status != 100)
@@ -873,14 +882,6 @@
 				}
 				
 			}
-			else
-			{
-				ast_log(LOG_NOTICE, "DB Key found for this profile. Therefore, followme is disabled.\n");
-			}
-
-
-	
-			}
 	outrun:
 	
 	LOCAL_USER_REMOVE(u);
@@ -889,16 +890,14 @@
 
 static int unload_module(void *mod)
 {
-	struct ast_call_followme *f, *prior;
+	struct ast_call_followme *f;
 	/* Free Memory. Yeah! I'm free! */
-	f = followmes;
-	while(f) {
-		f->active = 0;
-		prior = f;
-		f = f->next;
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&followmes, f, entry) {
 		free_numbers(f);
-		free(prior);
-	}
+		AST_LIST_REMOVE_CURRENT(&followmes, entry);
+		free(f);
+	}
+	AST_LIST_TRAVERSE_SAFE_END
 	STANDARD_HANGUP_LOCALUSERS;
 	return ast_unregister_application(app);
 }



More information about the svn-commits mailing list