[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