diff options
author | Matthew Jordan <mjordan@digium.com> | 2012-10-29 21:02:20 +0000 |
---|---|---|
committer | Matthew Jordan <mjordan@digium.com> | 2012-10-29 21:02:20 +0000 |
commit | 1eb14dbff8bb10caba4e7bd6ebb284056d328821 (patch) | |
tree | f3f7d7b5d6e5a6b2158dc3ec208619e59d1fdd0d /apps/app_queue.c | |
parent | 8d65c777c845c4854f9a57cf51d89caf1ad35d2c (diff) |
Ensure that CDRs for a caller in a Queue that is not answered is NO ANSWER.
When a caller enters a queue and no queue member answers the call, the current
behaviour can be a little odd depending on the paused status of the queue
members. If any queue member is paused, but not all, the CDR disposition
will be BUSY. If all queue members are paused, then the CDR disposition is
based instead on the disposition of the call prior to entering the Queue.
This patch modifies the behaviour in the following ways:
* If no queue members are paused, the CDR disposition is whatever the
disposition was prior to going into Queue. If the call was answered this
will be ANSWERED; otherwise, it is NO ANSWER.
* If some queue members are pused, the CDR result is NO ANSWER. (This is a
change in behaviour, as the result would previously have been BUSY)
* If all queue members are paused, the CDR result is whatever the result was
prior to going into Queue. This is the same as the behaviour prior to this
patch.
* If the caller hangs up, times out, or presses '*' with the 'h' option, the
CDR disposition is again not set and is dependent on whether or not the
caller was Answered prior to entering Queue.
This patch was based on one provided by Thomas Arimont, but has been modified
to accomodate findings by the reviewers.
Review: https://reviewboard.asterisk.org/r/2064/
(closes issue AST-906)
Reported by: Thomas Arimont
(closes issue ASTERISK-17776)
Reported by: Attila Megyeri
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@375416 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps/app_queue.c')
-rw-r--r-- | apps/app_queue.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c index f7ea7f3d3..a6ec76616 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -3520,10 +3520,8 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies /* on entry here, we know that tmp->chan == NULL */ if (tmp->member->paused) { ast_debug(1, "%s paused, can't receive call\n", tmp->interface); - if (ast_channel_cdr(qe->chan)) { - ast_cdr_busy(ast_channel_cdr(qe->chan)); - } tmp->stillgoing = 0; + (*busies)++; return 0; } @@ -3531,9 +3529,6 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies (!tmp->lastqueue && qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime))) { ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n", (tmp->lastqueue ? tmp->lastqueue->name : qe->parent->name), tmp->interface); - if (ast_channel_cdr(qe->chan)) { - ast_cdr_busy(ast_channel_cdr(qe->chan)); - } tmp->stillgoing = 0; (*busies)++; return 0; @@ -3550,19 +3545,14 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies } if ((tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) { ast_debug(1, "%s in use, can't receive call\n", tmp->interface); - if (ast_channel_cdr(qe->chan)) { - ast_cdr_busy(ast_channel_cdr(qe->chan)); - } tmp->stillgoing = 0; + (*busies)++; return 0; } } if (use_weight && compare_weight(qe->parent,tmp->member)) { ast_debug(1, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface); - if (ast_channel_cdr(qe->chan)) { - ast_cdr_busy(ast_channel_cdr(qe->chan)); - } tmp->stillgoing = 0; (*busies)++; return 0; @@ -4077,7 +4067,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte } } #endif - + while (*to && !peer) { int numlines, retry, pos = 1; struct ast_channel *watchers[AST_MAX_WATCHERS]; @@ -4115,8 +4105,14 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte if (pos == 1 /* not found */) { if (numlines == (numbusies + numnochan)) { ast_debug(1, "Everyone is busy at this time\n"); + if (ast_channel_cdr(in) && ast_channel_state(in) != AST_STATE_UP) { + ast_cdr_busy(ast_channel_cdr(in)); + } } else { ast_debug(3, "No one is answering queue '%s' (%d numlines / %d busies / %d failed channels)\n", queue, numlines, numbusies, numnochan); + if (ast_channel_cdr(in) && ast_channel_state(in) != AST_STATE_UP) { + ast_cdr_failed(ast_channel_cdr(in)); + } } *to = 0; return NULL; @@ -4358,7 +4354,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte case AST_CONTROL_CONGESTION: ast_verb(3, "%s is circuit-busy\n", ochan_name); if (ast_channel_cdr(in)) { - ast_cdr_busy(ast_channel_cdr(in)); + ast_cdr_failed(ast_channel_cdr(in)); } endtime = (long) time(NULL); endtime -= starttime; @@ -4491,6 +4487,9 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer); *to = 0; ast_frfree(f); + if (ast_channel_cdr(in) && ast_channel_state(in) != AST_STATE_UP) { + ast_cdr_noanswer(ast_channel_cdr(in)); + } return NULL; } if ((f->frametype == AST_FRAME_DTMF) && valid_exit(qe, f->subclass.integer)) { @@ -4498,6 +4497,9 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte *to = 0; *digit = f->subclass.integer; ast_frfree(f); + if (ast_channel_cdr(in) && ast_channel_state(in) != AST_STATE_UP) { + ast_cdr_noanswer(ast_channel_cdr(in)); + } return NULL; } @@ -4541,6 +4543,12 @@ skip_frame:; rna(orig, qe, o->interface, o->member->membername, 1); } } + + if (ast_channel_cdr(in) + && ast_channel_state(in) != AST_STATE_UP + && (!*to || ast_check_hangup(in))) { + ast_cdr_noanswer(ast_channel_cdr(in)); + } } #ifdef HAVE_EPOLL |