From d4c553c20284df6ac20e8ca8273db3adaea92897 Mon Sep 17 00:00:00 2001 From: Mark Spencer Date: Tue, 18 Jan 2005 16:40:56 +0000 Subject: Make sure we ring queues properly and know busy vs. no answer (bug #3114) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4836 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_queue.c | 73 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 27 deletions(-) diff --git a/apps/app_queue.c b/apps/app_queue.c index 4d2cd9813..b8b9f6857 100755 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -759,7 +759,7 @@ static int compare_weight(struct ast_call_queue *req_q, struct localuser *req_us -static int ring_entry(struct queue_ent *qe, struct localuser *tmp) +static int ring_entry(struct queue_ent *qe, struct localuser *tmp, int *busies) { int res; int status; @@ -773,6 +773,7 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp) if (qe->chan->cdr) ast_cdr_busy(qe->chan->cdr); tmp->stillgoing = 0; + (*busies)++; return 0; } } @@ -782,6 +783,7 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp) if (qe->chan->cdr) ast_cdr_busy(qe->chan->cdr); tmp->stillgoing = 0; + (*busies)++; return 0; } @@ -801,6 +803,7 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp) ast_cdr_busy(qe->chan->cdr); tmp->stillgoing = 0; update_dial_status(qe->parent, tmp->member, status); + (*busies)++; return 0; } else if (status != tmp->oldstatus) update_dial_status(qe->parent, tmp->member, status); @@ -841,6 +844,7 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp) ast_hangup(tmp->chan); tmp->chan = NULL; tmp->stillgoing = 0; + (*busies)++; return 0; } else { if (ast_test_flag(qe->parent, QUEUE_FLAG_EVENTWHENCALLED)) { @@ -860,10 +864,10 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp) if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", tmp->interface); } - return 0; + return 1; } -static int ring_one(struct queue_ent *qe, struct localuser *outgoing) +static int ring_one(struct queue_ent *qe, struct localuser *outgoing, int *busies) { struct localuser *cur; struct localuser *best; @@ -885,10 +889,10 @@ static int ring_one(struct queue_ent *qe, struct localuser *outgoing) /* Ring everyone who shares this best metric (for ringall) */ cur = outgoing; while(cur) { - if (cur->stillgoing && !cur->chan && (cur->metric == bestmetric)) { + if (cur->stillgoing && !cur->chan && (cur->metric <= bestmetric)) { if (option_debug) ast_log(LOG_DEBUG, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric); - ring_entry(qe, cur); + ring_entry(qe, cur, busies); } cur = cur->next; } @@ -896,7 +900,7 @@ static int ring_one(struct queue_ent *qe, struct localuser *outgoing) /* Ring just the best channel */ if (option_debug) ast_log(LOG_DEBUG, "Trying '%s' with metric %d\n", best->interface, best->metric); - ring_entry(qe, best); + ring_entry(qe, best, busies); } } } while (best && !best->chan); @@ -961,7 +965,27 @@ static int valid_exit(struct queue_ent *qe, char digit) #define AST_MAX_WATCHERS 256 -static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, struct ast_flags *flags, char *digit) +#define BUILD_STATS do { \ + o = outgoing; \ + found = -1; \ + pos = 1; \ + numlines = 0; \ + watchers[0] = in; \ + while(o) { \ + /* Keep track of important channels */ \ + if (o->stillgoing) { \ + stillgoing = 1; \ + if (o->chan) { \ + watchers[pos++] = o->chan; \ + found = 1; \ + } \ + } \ + o = o->next; \ + numlines++; \ + } \ + } while(0) + +static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, struct ast_flags *flags, char *digit, int prebusies) { char *queue = qe->parent->name; struct localuser *o; @@ -969,8 +993,9 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser int numlines; int status; int sentringing = 0; - int numbusies = 0; + int numbusies = prebusies; int numnochan = 0; + int stillgoing = 0; int orig = *to; struct ast_frame *f; struct localuser *peer = NULL; @@ -980,25 +1005,18 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser struct ast_channel *in = qe->chan; while(*to && !peer) { - o = outgoing; - found = -1; - pos = 1; - numlines = 0; - watchers[0] = in; - while(o) { - /* Keep track of important channels */ - if (o->stillgoing && o->chan) { - watchers[pos++] = o->chan; - found = 1; - } - o = o->next; - numlines++; + BUILD_STATS; + if ((found < 0) && stillgoing && !qe->parent->strategy) { + /* On "ringall" strategy we only move to the next penalty level + when *all* ringing phones are done in the current penalty level */ + ring_one(qe, outgoing, &numbusies); + BUILD_STATS; } if (found < 0) { if (numlines == (numbusies + numnochan)) { ast_log(LOG_DEBUG, "Everyone is busy at this time\n"); } else { - ast_log(LOG_NOTICE, "No one is answering queue '%s'\n", queue); + ast_log(LOG_NOTICE, "No one is answering queue '%s' (%d/%d/%d)\n", queue, numlines, numbusies, numnochan); } *to = 0; return NULL; @@ -1109,7 +1127,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser ast_hangup(o->chan); o->chan = NULL; if (qe->parent->strategy) - ring_one(qe, outgoing); + ring_one(qe, outgoing, &numbusies); numbusies++; break; case AST_CONTROL_CONGESTION: @@ -1121,7 +1139,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser ast_hangup(o->chan); o->chan = NULL; if (qe->parent->strategy) - ring_one(qe, outgoing); + ring_one(qe, outgoing, &numbusies); numbusies++; break; case AST_CONTROL_RINGING: @@ -1147,7 +1165,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser ast_hangup(o->chan); o->chan = NULL; if (qe->parent->strategy) - ring_one(qe, outgoing); + ring_one(qe, outgoing, &numbusies); } } o = o->next; @@ -1328,6 +1346,7 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri struct member *member; int res = 0, bridge = 0; int zapx = 2; + int numbusies = 0; int x=0; char *announce = NULL; char digit = 0; @@ -1421,9 +1440,9 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri to = qe->parent->timeout * 1000; else to = -1; - ring_one(qe, outgoing); + ring_one(qe, outgoing, &numbusies); ast_mutex_unlock(&qe->parent->lock); - lpeer = wait_for_answer(qe, outgoing, &to, &flags, &digit); + lpeer = wait_for_answer(qe, outgoing, &to, &flags, &digit, numbusies); ast_mutex_lock(&qe->parent->lock); if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) { store_next(qe, outgoing); -- cgit v1.2.3