mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-25 15:08:53 +00:00
Adding the general option "shared_lastcall" to queues so that a member's wrapuptime
may be used across multiple queues. (closes issue #9777, reported and patched by eliel) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@86985 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -257,6 +257,9 @@ static int autofill_default = 0;
|
|||||||
/*! \brief queues.conf [general] option */
|
/*! \brief queues.conf [general] option */
|
||||||
static int montype_default = 0;
|
static int montype_default = 0;
|
||||||
|
|
||||||
|
/*! \brief queues.conf [general] option */
|
||||||
|
static int shared_lastcall = 0;
|
||||||
|
|
||||||
/*! \brief Subscription to device state change events */
|
/*! \brief Subscription to device state change events */
|
||||||
static struct ast_event_sub *device_state_sub;
|
static struct ast_event_sub *device_state_sub;
|
||||||
|
|
||||||
@@ -300,6 +303,7 @@ struct callattempt {
|
|||||||
int metric;
|
int metric;
|
||||||
int oldstatus;
|
int oldstatus;
|
||||||
time_t lastcall;
|
time_t lastcall;
|
||||||
|
struct call_queue *lastqueue;
|
||||||
struct member *member;
|
struct member *member;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -336,6 +340,7 @@ struct member {
|
|||||||
int status; /*!< Status of queue member */
|
int status; /*!< Status of queue member */
|
||||||
int paused; /*!< Are we paused (not accepting calls)? */
|
int paused; /*!< Are we paused (not accepting calls)? */
|
||||||
time_t lastcall; /*!< When last successful call was hungup */
|
time_t lastcall; /*!< When last successful call was hungup */
|
||||||
|
struct call_queue *lastqueue; /*!< Last queue we received a call */
|
||||||
unsigned int dead:1; /*!< Used to detect members deleted in realtime */
|
unsigned int dead:1; /*!< Used to detect members deleted in realtime */
|
||||||
unsigned int delme:1; /*!< Flag to delete entry on reload */
|
unsigned int delme:1; /*!< Flag to delete entry on reload */
|
||||||
};
|
};
|
||||||
@@ -797,7 +802,7 @@ static int member_hash_fn(const void *obj, const int flags)
|
|||||||
static int member_cmp_fn(void *obj1, void *obj2, int flags)
|
static int member_cmp_fn(void *obj1, void *obj2, int flags)
|
||||||
{
|
{
|
||||||
struct member *mem1 = obj1, *mem2 = obj2;
|
struct member *mem1 = obj1, *mem2 = obj2;
|
||||||
return strcmp(mem1->interface, mem2->interface) ? 0 : CMP_MATCH;
|
return strcasecmp(mem1->interface, mem2->interface) ? 0 : CMP_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_queue(struct call_queue *q)
|
static void init_queue(struct call_queue *q)
|
||||||
@@ -1858,8 +1863,10 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
|
|||||||
char *location;
|
char *location;
|
||||||
|
|
||||||
/* on entry here, we know that tmp->chan == NULL */
|
/* on entry here, we know that tmp->chan == NULL */
|
||||||
if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) {
|
if ((tmp->lastqueue && tmp->lastqueue->wrapuptime && (time(NULL) - tmp->lastcall < tmp->lastqueue->wrapuptime)) ||
|
||||||
ast_debug(1, "Wrapuptime not yet expired for %s\n", tmp->interface);
|
(!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 (qe->chan->cdr)
|
if (qe->chan->cdr)
|
||||||
ast_cdr_busy(qe->chan->cdr);
|
ast_cdr_busy(qe->chan->cdr);
|
||||||
tmp->stillgoing = 0;
|
tmp->stillgoing = 0;
|
||||||
@@ -2492,9 +2499,31 @@ static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *r
|
|||||||
|
|
||||||
static int update_queue(struct call_queue *q, struct member *member, int callcompletedinsl)
|
static int update_queue(struct call_queue *q, struct member *member, int callcompletedinsl)
|
||||||
{
|
{
|
||||||
|
struct member *mem;
|
||||||
|
struct call_queue *qtmp;
|
||||||
|
struct ao2_iterator queue_iter;
|
||||||
|
|
||||||
|
if (shared_lastcall) {
|
||||||
|
queue_iter = ao2_iterator_init(queues, 0);
|
||||||
|
while ((qtmp = ao2_iterator_next(&queue_iter))) {
|
||||||
|
ao2_lock(qtmp);
|
||||||
|
if ((mem = ao2_find(qtmp->members, member, OBJ_POINTER))) {
|
||||||
|
time(&mem->lastcall);
|
||||||
|
mem->calls++;
|
||||||
|
mem->lastqueue = q;
|
||||||
|
ao2_ref(mem, -1);
|
||||||
|
}
|
||||||
|
ao2_unlock(qtmp);
|
||||||
|
ao2_ref(qtmp, -1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
ao2_lock(q);
|
ao2_lock(q);
|
||||||
time(&member->lastcall);
|
time(&member->lastcall);
|
||||||
member->calls++;
|
member->calls++;
|
||||||
|
member->lastqueue = q;
|
||||||
|
ao2_unlock(q);
|
||||||
|
}
|
||||||
|
ao2_lock(q);
|
||||||
q->callscompleted++;
|
q->callscompleted++;
|
||||||
if (callcompletedinsl)
|
if (callcompletedinsl)
|
||||||
q->callscompletedinsl++;
|
q->callscompletedinsl++;
|
||||||
@@ -2698,6 +2727,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
|
|||||||
tmp->member = cur;
|
tmp->member = cur;
|
||||||
tmp->oldstatus = cur->status;
|
tmp->oldstatus = cur->status;
|
||||||
tmp->lastcall = cur->lastcall;
|
tmp->lastcall = cur->lastcall;
|
||||||
|
tmp->lastqueue = cur->lastqueue;
|
||||||
ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
|
ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
|
||||||
/* Special case: If we ring everyone, go ahead and ring them, otherwise
|
/* Special case: If we ring everyone, go ahead and ring them, otherwise
|
||||||
just calculate their metric for the appropriate strategy */
|
just calculate their metric for the appropriate strategy */
|
||||||
@@ -4169,6 +4199,9 @@ static int reload_queues(int reload)
|
|||||||
update_cdr = 0;
|
update_cdr = 0;
|
||||||
if ((general_val = ast_variable_retrieve(cfg, "general", "updatecdr")))
|
if ((general_val = ast_variable_retrieve(cfg, "general", "updatecdr")))
|
||||||
update_cdr = ast_true(general_val);
|
update_cdr = ast_true(general_val);
|
||||||
|
shared_lastcall = 0;
|
||||||
|
if ((general_val = ast_variable_retrieve(cfg, "general", "shared_lastcall")))
|
||||||
|
shared_lastcall = ast_true(general_val);
|
||||||
} else { /* Define queue */
|
} else { /* Define queue */
|
||||||
/* Look for an existing one */
|
/* Look for an existing one */
|
||||||
ast_copy_string(tmpq.name, cat, sizeof(tmpq.name));
|
ast_copy_string(tmpq.name, cat, sizeof(tmpq.name));
|
||||||
|
@@ -60,6 +60,13 @@ monitor-type = MixMonitor
|
|||||||
; Queue(queuename|[options]|[optionalurl]|[announceoverride]|[timeout])
|
; Queue(queuename|[options]|[optionalurl]|[announceoverride]|[timeout])
|
||||||
; example: Queue(dave|t|||45)
|
; example: Queue(dave|t|||45)
|
||||||
|
|
||||||
|
; shared_lastcall will make the lastcall and calls received be the same in
|
||||||
|
; members logged in more than one queue.
|
||||||
|
; This is useful to make the queue respect the wrapuptime of another queue
|
||||||
|
; for a shared member
|
||||||
|
;
|
||||||
|
shared_lastcall=no
|
||||||
|
;
|
||||||
;[markq]
|
;[markq]
|
||||||
;
|
;
|
||||||
; A sample call queue
|
; A sample call queue
|
||||||
|
Reference in New Issue
Block a user