[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