[asterisk-commits] branch bweschke/findme_followme r9498 - /team/bweschke/findme_followme/apps/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Fri Feb 10 23:53:30 MST 2006


Author: bweschke
Date: Sat Feb 11 00:53:28 2006
New Revision: 9498

URL: http://svn.digium.com/view/asterisk?rev=9498&view=rev
Log:
 Committing latest changes (forked dialing IS actually functional with this!) to fix svnmerge conflicts

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=9498&r1=9497&r2=9498&view=diff
==============================================================================
--- team/bweschke/findme_followme/apps/app_followme.c (original)
+++ team/bweschke/findme_followme/apps/app_followme.c Sat Feb 11 00:53:28 2006
@@ -3,7 +3,7 @@
  *
  * A full-featured Find-Me/Follow-Me Application
  * 
- * Copyright (C) 2005, BJ Weschke
+ * Copyright (C) 2005-2006, BJ Weschke
  *
  * BJ Weschke <bweschke at btwtech.com>
  *
@@ -57,7 +57,7 @@
 
 struct number {
 	char number[512];	/* Phone Number and/or Extension */
-	unsigned int timeout;		/* Dial Timeout, if used. */
+	long timeout;		/* Dial Timeout, if used. */
 	struct number *next;		/* Next Number record */
 };
 
@@ -88,12 +88,15 @@
 	struct ast_channel *ochan;
 	int state;
 	char dialarg[256];
+	char yn[10];
+	int ynidx; 
+	int digts;
 	struct findme_user *next;	
 };
 
 struct thread_args targs;
 struct ast_bridge_config config;
-int res, ret = 0;
+int res, ret = 0, ynlongest = 0;
 char toast[80];
 time_t start_time, answer_time, end_time;
 
@@ -330,7 +333,7 @@
 	ast_mutex_unlock(&fmlock);
 }
 
-static void clear_calling_tree(struct findme_user *headuser) 
+static void clear_calling_tree(struct findme_user *headuser,int wholetree) 
 {
 	struct findme_user *tmpuser = NULL;
 	struct ast_channel *outbound = NULL;
@@ -338,7 +341,7 @@
 	tmpuser = headuser;
 	
 	while (tmpuser) {		
-		if (tmpuser->ochan) {
+		if (tmpuser->ochan && tmpuser->state >= 0) {
 			outbound = tmpuser->ochan;
 			if (!outbound->cdr) {
 				outbound->cdr = ast_cdr_alloc();
@@ -359,11 +362,16 @@
 				ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
 			ast_hangup(tmpuser->ochan);
 		}
-		tmpuser = tmpuser->next;
-	}
-}
-
-static struct ast_channel *wait_for_winner(struct findme_user *headuser, struct number *nm, struct ast_channel *caller)
+		if (wholetree)
+			tmpuser = tmpuser->next;
+		else
+			tmpuser = NULL;
+	}
+}
+
+
+
+static struct ast_channel *wait_for_winner(struct findme_user *headuser, struct number *nm, struct ast_channel *caller, char *namerecloc, int *status)
 {
 
 		struct ast_channel *watchers[256];
@@ -375,27 +383,82 @@
 		int dg;
 		struct findme_user *fmuser = NULL;
 		struct findme_user *tmpuser = NULL;
+		int *to = malloc(sizeof(int));
+		int livechannels = 0;
+		int tmpto;
+		long totalwait = 0;
 
 		/* ------------ wait_for_winner_channel start --------------- */ 
 		
 		if (headuser->ochan)
 		{
-			pos = 1;
-			watchers[0] = caller;
-			
-			dg = 0;	
-			
-			tmpuser = headuser;
-			
-			while (tmpuser) {
-				watchers[pos++] = tmpuser->ochan;
-				tmpuser = tmpuser->next;
+			if (!caller) {
+				ast_log(LOG_NOTICE, "Original caller hungup. Cleanup.\n");
+				clear_calling_tree(headuser,1);
+				return 0;
 			}
 			ctstatus = 0;
-						
+			totalwait = nm->timeout * 1000;
 			while (!ctstatus) {
-				winner = ast_waitfor_n(watchers, pos, (nm->timeout*1000));
-
+				*to = 1000;
+				pos = 1;
+				livechannels = 0;
+				watchers[0] = caller;
+			
+				dg = 0;	
+				winner = NULL;	
+				tmpuser = headuser;
+				while (tmpuser) {
+					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");
+							tmpuser->state = 1;
+							tmpuser->digts = 0;
+							if (!ast_streamfile(tmpuser->ochan, "call-from", tmpuser->ochan->language)) {
+								ast_sched_runq(tmpuser->ochan->sched);
+							}
+							
+						}
+						if (tmpuser->ochan->stream) {
+							ast_sched_runq(tmpuser->ochan->sched);
+							tmpto = ast_sched_wait(tmpuser->ochan->sched);
+							if (tmpto > 0 && tmpto < *to)
+								*to = tmpto;
+							else if (tmpto < 0) {
+								ast_stopstream(tmpuser->ochan);
+								if (tmpuser->state == 1) {
+									ast_log(LOG_NOTICE, "Playback of the file appears to be done.\n");
+									if (!ast_streamfile(tmpuser->ochan, namerecloc, tmpuser->ochan->language)) {
+										tmpuser->state = 2;
+									}
+								} else if (tmpuser->state == 2) {
+									ast_log(LOG_NOTICE, "Playback of name file appears to be done.\n");
+									memset(tmpuser->yn, 0, sizeof(tmpuser->yn));
+									tmpuser->ynidx = 0;
+									tmpuser->digts = 0;
+									if (!ast_streamfile(tmpuser->ochan, "press-1-to-be-connected-or", tmpuser->ochan->language)) {
+										tmpuser->state = 3;
+										
+									} 
+								} else if (tmpuser->state == 3) {
+									ast_log(LOG_NOTICE, "Playback of the next step file appears to be done.\n");
+								}
+							}
+						}
+						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. %d\n", totalwait);
+					clear_calling_tree(headuser,1);
+					return 0;
+				}
 				if (winner) {
 					/* Need to find out which channel this is */
 					dg = 0;
@@ -415,7 +478,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);
+									clear_calling_tree(headuser,1);
 									ctstatus = -1;
 								}
 								break;
@@ -428,8 +491,10 @@
 								caller->hangupcause = AST_CAUSE_NORMAL_CLEARING;
 								if (dg > 0) {
 									if (!ast_streamfile(winner, "call-from", winner->language)) {
+										ast_sched_runq(winner->sched);
+										tmpuser->state = 1;
+									}
 									
-									}
 								}
 								break;
 							case AST_CONTROL_BUSY:
@@ -475,13 +540,68 @@
 							default:
 								ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
 							}
-						}		
+						} 
+						if (tmpuser && tmpuser->state == 3 && f->frametype == AST_FRAME_DTMF) {
+							if (winner->stream)
+								ast_stopstream(winner);
+							if (!tmpuser->digts)
+								tmpuser->digts = totalwait;
+							ast_log(LOG_NOTICE, "DTMF received: %c\n",(char) f->subclass);
+							tmpuser->yn[tmpuser->ynidx] = (char) f->subclass;
+							tmpuser->ynidx++;
+							ast_log(LOG_NOTICE, "DTMF string: %s\n", tmpuser->yn);
+							if (tmpuser->ynidx >= ynlongest) {
+								ast_log(LOG_NOTICE, "reached longest possible match\n");
+								if (!strcmp(tmpuser->yn, takecall)) {
+									ast_log(LOG_NOTICE, "Match to take the call!\n");
+									return tmpuser->ochan;	
+								}
+								if (!strcmp(tmpuser->yn, nextindp)) {
+									ast_log(LOG_NOTICE, "Next in dial plan step requested.\n");
+									status = 1;
+									return 0;
+								}	
+								if (!strcmp(tmpuser->yn, nextinfmfm)) {
+									ast_log(LOG_NOTICE, "Next in find me/follow me step requested.\n");
+									status = 2;
+									return 0;
+								}	
+								if (!strcmp(tmpuser->yn, blindxferexten)) {
+									ast_log(LOG_NOTICE, "Blind Transfer requested.\n");
+									status = 3;
+									return 0;
+								}	
+								if (!strcmp(tmpuser->yn, atxferexten)) {
+									ast_log(LOG_NOTICE, "Attended Transfer requested.\n");
+									status = 4;
+									return 0;
+								}	
+
+							}
+						}
+						
 						ast_frfree(f);
+					} else {
+						if (winner) {
+
+							ast_log(LOG_NOTICE, "we didn't get a frame. hanging up. dg is %d\n",dg);					      
+							if (!dg) {
+								clear_calling_tree(headuser,1);
+								return 0;
+							} else {
+								tmpuser->state = -1;
+							 	ast_hangup(winner);  
+								livechannels--;
+								ast_log(LOG_NOTICE, "live channels left %d\n", livechannels);
+								if (!livechannels) {
+									ast_log(LOG_NOTICE, "no live channels left. exiting.\n");
+									return 0;
+								}
+							}
+						}
 					}					
-				} else {
-					if (option_verbose > 2)
-							ast_verbose(VERBOSE_PREFIX_3 "%s timeout on the dialing channel %s\n", caller->name, winner->name);
-				}
+					
+				} 
 			}
 		/*	
 			if (tpargs->status == -50)
@@ -714,19 +834,22 @@
 				struct number *nm;
 				struct ast_channel *outbound = NULL;
 				struct ast_channel *caller;
+				struct ast_channel *winner = NULL;
 				char dialarg[512];
-				int ynidx = 0, ynlongest = 0, passed = 0, attempts = 0;
+				int ynidx = 0, passed = 0, attempts = 0;
 				char yn[5];
 				int d = 0,dg;
 				char *rest, *number;
 				struct findme_user *tmpuser = NULL;
 			        struct findme_user *fmuser = NULL;
 			        struct findme_user *headuser = NULL;
+				int status;
+					
 	
 				tpargs = (struct thread_args *)args;
 				
 				if (!tpargs->chan) {
-					pthread_exit(0);
+					return;
 				}
 
 				/* We're going to figure out what the longest possible string of digits to collect is */
@@ -752,6 +875,7 @@
 				time(&start_time);
 
 				number = ast_strdupa(nm->number);
+				ast_log(LOG_NOTICE, "examining %s\n", number);
 				do {
 					rest = strchr(number, '&');
 					if (rest) {
@@ -767,7 +891,7 @@
 					tmpuser = malloc(sizeof(struct findme_user));
 					if (!tmpuser) {
 						ast_log(LOG_WARNING, "Out of memory!\n");
-						pthread_exit(0);
+						return;
 					}
 					memset(tmpuser, 0, sizeof(struct findme_user));
 					
@@ -775,7 +899,7 @@
 					if (outbound) {
 						ast_set_callerid(outbound, caller->cid.cid_num, caller->cid.cid_name, caller->cid.cid_num);
 						ast_channel_inherit_variables(tpargs->chan, outbound);
-						
+						ast_log(LOG_NOTICE, "calling %s\n", dialarg);
 						if (!ast_call(outbound,dialarg,0)) {
 							tmpuser->ochan = outbound;
 							tmpuser->state = 0;
@@ -817,14 +941,34 @@
 				} while (number);
 				
 				headuser = fmuser;
-				
+			
+				status = 0;	
 				if (headuser->ochan)
-					wait_for_winner(headuser, nm, caller);
-				
+					winner = wait_for_winner(headuser, nm, caller, tpargs->namerecloc, &status);
+		
+					
+				fmuser = headuser;
+				while (fmuser) {
+					headuser = fmuser->next;
+					if (fmuser->ochan != winner)
+						clear_calling_tree(fmuser, 0);
+					free(fmuser);
+					fmuser = headuser;
+				}
+				fmuser = NULL;
+				tmpuser = NULL;
+				headuser = NULL;	
 				nm = nm->next;
-				}
-				tpargs->status = 1;
-				pthread_exit(0);
+				if (winner)
+					break;
+				}
+				if (!winner) {
+					tpargs->status = 1;
+				} else {
+					tpargs->status = 100;
+					tpargs->outbound = winner;
+				}
+				return;
 		
 }
 
@@ -890,19 +1034,6 @@
 				if (!ast_streamfile(chan, "pls-hold-while-try", chan->language)) {
 				} else
 				goto outrun;
-
-				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));
-
-				
-				pthread_attr_init(&tattr);
-				pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
-				ast_pthread_create(&finderthread, &tattr, findmethread, &targs);
- 				
-
 				if (ast_waitstream(chan, "") < 0)
 				goto outrun;
 				nm = f->numbers;
@@ -915,21 +1046,22 @@
 					 nm = nm->next;
 				}
 
+
+				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));
+
+				/*
 				
-				
-				while (finderthread)
-				{
-					res = ast_safe_sleep(chan, 250);
-				
-					if ((res < 0) || (targs.status > 0))
-					{
-						ast_log(LOG_DEBUG, "original caller appears to have hungup early. killing off dialing thread.\n");
-						if (res < 0)
-							targs.status = -50;
-						finderthread = 0;
-					}
-					
-				}
+				pthread_attr_init(&tattr);
+				pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
+				ast_pthread_create(&finderthread, &tattr, findmethread, &targs);
+ 				*/
+
+				findmethread(&targs);			
+	
 				unlink(namerecloc);	
 				if (targs.status != 100)
 				{
@@ -938,6 +1070,7 @@
 				}
 				else
 				{
+							
 							caller = chan;
 							outbound = targs.outbound;
 							/* Bridge the two channels. */



More information about the asterisk-commits mailing list