mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-06 12:36:58 +00:00
Fix formatting etc in queues (bug #3159)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4640 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -115,7 +115,8 @@ static char *descrip =
|
|||||||
" 'd' -- data-quality (modem) call (minimum delay).\n"
|
" 'd' -- data-quality (modem) call (minimum delay).\n"
|
||||||
" 'h' -- allow callee to hang up by hitting *.\n"
|
" 'h' -- allow callee to hang up by hitting *.\n"
|
||||||
" 'H' -- allow caller to hang up by hitting *.\n"
|
" 'H' -- allow caller to hang up by hitting *.\n"
|
||||||
" 'n' -- no retries on the timeout; will exit this application and go to the next step.\n"
|
" 'n' -- no retries on the timeout; will exit this application and \n"
|
||||||
|
" go to the next step.\n"
|
||||||
" 'r' -- ring instead of playing MOH\n"
|
" 'r' -- ring instead of playing MOH\n"
|
||||||
" In addition to transferring the call, a call may be parked and then picked\n"
|
" In addition to transferring the call, a call may be parked and then picked\n"
|
||||||
"up by another user.\n"
|
"up by another user.\n"
|
||||||
@@ -169,7 +170,7 @@ static int queue_persistent_members = 0;
|
|||||||
#define QUEUE_FLAG_REPORTHOLDTIME (1 << 12) /* Should we report caller hold time to answering member? */
|
#define QUEUE_FLAG_REPORTHOLDTIME (1 << 12) /* Should we report caller hold time to answering member? */
|
||||||
#define QUEUE_FLAG_WRAPPED (1 << 13) /* Round Robin - wrapped around? */
|
#define QUEUE_FLAG_WRAPPED (1 << 13) /* Round Robin - wrapped around? */
|
||||||
|
|
||||||
/* We define a customer "local user" structure because we
|
/* We define a custom "local user" structure because we
|
||||||
use it not only for keeping track of what is in use but
|
use it not only for keeping track of what is in use but
|
||||||
also for keeping track of who we're dialing. */
|
also for keeping track of who we're dialing. */
|
||||||
|
|
||||||
@@ -229,7 +230,7 @@ struct ast_call_queue {
|
|||||||
int callscompleted; /* Number of queue calls completed */
|
int callscompleted; /* Number of queue calls completed */
|
||||||
int callsabandoned; /* Number of queue calls abandoned */
|
int callsabandoned; /* Number of queue calls abandoned */
|
||||||
int servicelevel; /* seconds setting for servicelevel*/
|
int servicelevel; /* seconds setting for servicelevel*/
|
||||||
int callscompletedinsl; /* Number of queue calls answererd with servicelevel*/
|
int callscompletedinsl; /* Number of queue calls answered with servicelevel*/
|
||||||
char monfmt[8]; /* Format to use when recording calls */
|
char monfmt[8]; /* Format to use when recording calls */
|
||||||
char sound_next[80]; /* Sound file: "Your call is now first in line" (def. queue-youarenext) */
|
char sound_next[80]; /* Sound file: "Your call is now first in line" (def. queue-youarenext) */
|
||||||
char sound_thereare[80]; /* Sound file: "There are currently" (def. queue-thereare) */
|
char sound_thereare[80]; /* Sound file: "There are currently" (def. queue-thereare) */
|
||||||
@@ -249,7 +250,6 @@ struct ast_call_queue {
|
|||||||
int timeout; /* How long to wait for an answer */
|
int timeout; /* How long to wait for an answer */
|
||||||
|
|
||||||
/* Queue strategy things */
|
/* Queue strategy things */
|
||||||
|
|
||||||
int rrpos; /* Round Robin - position */
|
int rrpos; /* Round Robin - position */
|
||||||
int memberdelay; /* Seconds to delay connecting member to caller */
|
int memberdelay; /* Seconds to delay connecting member to caller */
|
||||||
|
|
||||||
@@ -261,6 +261,7 @@ struct ast_call_queue {
|
|||||||
static struct ast_call_queue *queues = NULL;
|
static struct ast_call_queue *queues = NULL;
|
||||||
AST_MUTEX_DEFINE_STATIC(qlock);
|
AST_MUTEX_DEFINE_STATIC(qlock);
|
||||||
|
|
||||||
|
|
||||||
static char *int2strat(int strategy)
|
static char *int2strat(int strategy)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
@@ -333,6 +334,7 @@ static void *changethread(void *data)
|
|||||||
struct statechange *sc = data;
|
struct statechange *sc = data;
|
||||||
struct member *cur;
|
struct member *cur;
|
||||||
char *loc;
|
char *loc;
|
||||||
|
|
||||||
loc = strchr(sc->dev, '/');
|
loc = strchr(sc->dev, '/');
|
||||||
if (loc) {
|
if (loc) {
|
||||||
*loc = '\0';
|
*loc = '\0';
|
||||||
@@ -369,6 +371,7 @@ static void *changethread(void *data)
|
|||||||
ast_mutex_unlock(&q->lock);
|
ast_mutex_unlock(&q->lock);
|
||||||
}
|
}
|
||||||
ast_mutex_unlock(&qlock);
|
ast_mutex_unlock(&qlock);
|
||||||
|
if (option_debug)
|
||||||
ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d'\n", sc->dev, loc, sc->state);
|
ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d'\n", sc->dev, loc, sc->state);
|
||||||
free(sc);
|
free(sc);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -381,6 +384,7 @@ static int statechange_queue(const char *dev, int state, void *ign)
|
|||||||
struct statechange *sc;
|
struct statechange *sc;
|
||||||
pthread_t t;
|
pthread_t t;
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
|
|
||||||
sc = malloc(sizeof(struct statechange) + strlen(dev) + 1);
|
sc = malloc(sizeof(struct statechange) + strlen(dev) + 1);
|
||||||
if (sc) {
|
if (sc) {
|
||||||
sc->state = state;
|
sc->state = state;
|
||||||
@@ -716,6 +720,7 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
|
|||||||
char *location;
|
char *location;
|
||||||
|
|
||||||
if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) {
|
if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) {
|
||||||
|
if (option_debug)
|
||||||
ast_log(LOG_DEBUG, "Wrapuptime not yet expired for %s\n", tmp->interface);
|
ast_log(LOG_DEBUG, "Wrapuptime not yet expired for %s\n", tmp->interface);
|
||||||
if (qe->chan->cdr)
|
if (qe->chan->cdr)
|
||||||
ast_cdr_busy(qe->chan->cdr);
|
ast_cdr_busy(qe->chan->cdr);
|
||||||
@@ -733,7 +738,7 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
|
|||||||
tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status);
|
tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status);
|
||||||
if (!tmp->chan) { /* If we can't, just go on to the next call */
|
if (!tmp->chan) { /* If we can't, just go on to the next call */
|
||||||
#if 0
|
#if 0
|
||||||
ast_log(LOG_NOTICE, "Unable to create channel of type '%s'\n", cur->tech);
|
ast_log(LOG_NOTICE, "Unable to create channel of type '%s' for Queue\n", cur->tech);
|
||||||
#endif
|
#endif
|
||||||
if (qe->chan->cdr)
|
if (qe->chan->cdr)
|
||||||
ast_cdr_busy(qe->chan->cdr);
|
ast_cdr_busy(qe->chan->cdr);
|
||||||
@@ -819,6 +824,7 @@ static int ring_one(struct queue_ent *qe, struct localuser *outgoing)
|
|||||||
cur = outgoing;
|
cur = outgoing;
|
||||||
while(cur) {
|
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);
|
ast_log(LOG_DEBUG, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric);
|
||||||
ring_entry(qe, cur);
|
ring_entry(qe, cur);
|
||||||
}
|
}
|
||||||
@@ -858,6 +864,7 @@ static int store_next(struct queue_ent *qe, struct localuser *outgoing)
|
|||||||
}
|
}
|
||||||
if (best) {
|
if (best) {
|
||||||
/* Ring just the best channel */
|
/* Ring just the best channel */
|
||||||
|
if (option_debug)
|
||||||
ast_log(LOG_DEBUG, "Next is '%s' with metric %d\n", best->interface, best->metric);
|
ast_log(LOG_DEBUG, "Next is '%s' with metric %d\n", best->interface, best->metric);
|
||||||
qe->parent->rrpos = best->metric % 1000;
|
qe->parent->rrpos = best->metric % 1000;
|
||||||
} else {
|
} else {
|
||||||
@@ -1490,8 +1497,10 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
|
|||||||
if(bridge != AST_PBX_NO_HANGUP_PEER)
|
if(bridge != AST_PBX_NO_HANGUP_PEER)
|
||||||
ast_hangup(peer);
|
ast_hangup(peer);
|
||||||
update_queue(qe->parent, member);
|
update_queue(qe->parent, member);
|
||||||
if( bridge == 0 ) res=1; /* JDG: bridge successfull, leave app_queue */
|
if (bridge == 0)
|
||||||
else res = bridge; /* bridge error, stay in the queue */
|
res = 1; /* JDG: bridge successfull, leave app_queue */
|
||||||
|
else
|
||||||
|
res = bridge; /* bridge error, stay in the queue */
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
hanguptree(outgoing, NULL);
|
hanguptree(outgoing, NULL);
|
||||||
@@ -1735,7 +1744,7 @@ static void reload_queue_members(void)
|
|||||||
ast_log(LOG_DEBUG, "Reload Members: Queue: %s Member: %s Penalty: %d\n", pm_queue_name, pm_interface, pm_penalty);
|
ast_log(LOG_DEBUG, "Reload Members: Queue: %s Member: %s Penalty: %d\n", pm_queue_name, pm_interface, pm_penalty);
|
||||||
|
|
||||||
if (add_to_queue(pm_queue_name, pm_interface, pm_penalty) == RES_OUTOFMEMORY) {
|
if (add_to_queue(pm_queue_name, pm_interface, pm_penalty) == RES_OUTOFMEMORY) {
|
||||||
ast_log(LOG_ERROR, "Out of Memory\n");
|
ast_log(LOG_ERROR, "Out of Memory when loading queue member from astdb\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1858,7 +1867,7 @@ static int aqm_exec(struct ast_channel *chan, void *data)
|
|||||||
*interface = '\0';
|
*interface = '\0';
|
||||||
interface = tmpchan;
|
interface = tmpchan;
|
||||||
}
|
}
|
||||||
if (penaltys && strlen(penaltys)) {
|
if (penaltys && !ast_strlen_zero(penaltys)) {
|
||||||
if ((sscanf(penaltys, "%d", &penalty) != 1) || penalty < 0) {
|
if ((sscanf(penaltys, "%d", &penalty) != 1) || penalty < 0) {
|
||||||
ast_log(LOG_WARNING, "Penalty '%s' is invalid, must be an integer >= 0\n", penaltys);
|
ast_log(LOG_WARNING, "Penalty '%s' is invalid, must be an integer >= 0\n", penaltys);
|
||||||
penalty = 0;
|
penalty = 0;
|
||||||
@@ -1883,7 +1892,7 @@ static int aqm_exec(struct ast_channel *chan, void *data)
|
|||||||
res = 0;
|
res = 0;
|
||||||
break;
|
break;
|
||||||
case RES_OUTOFMEMORY:
|
case RES_OUTOFMEMORY:
|
||||||
ast_log(LOG_ERROR, "Out of memory\n");
|
ast_log(LOG_ERROR, "Out of memory adding member %s to queue %s\n", interface, queuename);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1913,7 +1922,7 @@ static int queue_exec(struct ast_channel *chan, void *data)
|
|||||||
struct queue_ent qe;
|
struct queue_ent qe;
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
ast_log(LOG_WARNING, "Queue requires an argument (queuename[|[timeout][|URL]])\n");
|
ast_log(LOG_WARNING, "Queue requires an argument: queuename[|options[|URL][|announceoverride][|timeout]]\n"
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1950,7 +1959,7 @@ static int queue_exec(struct ast_channel *chan, void *data)
|
|||||||
prio = 0;
|
prio = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (option_debug)
|
if (option_debug > 2)
|
||||||
ast_log(LOG_DEBUG, "NO QUEUE_PRIO variable found. Using default.\n");
|
ast_log(LOG_DEBUG, "NO QUEUE_PRIO variable found. Using default.\n");
|
||||||
prio = 0;
|
prio = 0;
|
||||||
}
|
}
|
||||||
@@ -1961,7 +1970,7 @@ static int queue_exec(struct ast_channel *chan, void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if (option_debug) */
|
if (option_debug)
|
||||||
ast_log(LOG_DEBUG, "queue: %s, options: %s, url: %s, announce: %s, expires: %ld, priority: %d\n",
|
ast_log(LOG_DEBUG, "queue: %s, options: %s, url: %s, announce: %s, expires: %ld, priority: %d\n",
|
||||||
queuename, options, url, announceoverride, (long)qe.expire, (int)prio);
|
queuename, options, url, announceoverride, (long)qe.expire, (int)prio);
|
||||||
|
|
||||||
@@ -1988,7 +1997,7 @@ check_turns:
|
|||||||
record_abandoned(&qe);
|
record_abandoned(&qe);
|
||||||
ast_queue_log(queuename, chan->uniqueid, "NONE", "ABANDON", "%d|%d|%ld", qe.pos, qe.opos, (long)time(NULL) - qe.start);
|
ast_queue_log(queuename, chan->uniqueid, "NONE", "ABANDON", "%d|%d|%ld", qe.pos, qe.opos, (long)time(NULL) - qe.start);
|
||||||
if (option_verbose > 2) {
|
if (option_verbose > 2) {
|
||||||
ast_verbose(VERBOSE_PREFIX_3 "User disconnected while waiting their turn\n");
|
ast_verbose(VERBOSE_PREFIX_3 "User disconnected from queue %s while waiting their turn\n", queuename);
|
||||||
res = -1;
|
res = -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2049,7 +2058,7 @@ check_turns:
|
|||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
ast_queue_log(queuename, chan->uniqueid, "NONE", "ABANDON", "%d|%d|%ld", qe.pos, qe.opos, (long)time(NULL) - qe.start);
|
ast_queue_log(queuename, chan->uniqueid, "NONE", "ABANDON", "%d|%d|%ld", qe.pos, qe.opos, (long)time(NULL) - qe.start);
|
||||||
if (option_verbose > 2) {
|
if (option_verbose > 2) {
|
||||||
ast_verbose(VERBOSE_PREFIX_3 "User disconnected when they almost made it\n");
|
ast_verbose(VERBOSE_PREFIX_3 "User disconnected from queue %s when they almost made it\n", queuename);
|
||||||
res = -1;
|
res = -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2073,6 +2082,7 @@ check_turns:
|
|||||||
* of the queue, go and check for our turn again.
|
* of the queue, go and check for our turn again.
|
||||||
*/
|
*/
|
||||||
if (!is_our_turn(&qe)) {
|
if (!is_our_turn(&qe)) {
|
||||||
|
if (option_debug)
|
||||||
ast_log(LOG_DEBUG, "Darn priorities, going back in queue (%s)!\n",
|
ast_log(LOG_DEBUG, "Darn priorities, going back in queue (%s)!\n",
|
||||||
qe.chan->name);
|
qe.chan->name);
|
||||||
goto check_turns;
|
goto check_turns;
|
||||||
@@ -2110,7 +2120,7 @@ static void reload_queues(void)
|
|||||||
|
|
||||||
cfg = ast_load("queues.conf");
|
cfg = ast_load("queues.conf");
|
||||||
if (!cfg) {
|
if (!cfg) {
|
||||||
ast_log(LOG_NOTICE, "No call queueing config file, so no call queues\n");
|
ast_log(LOG_NOTICE, "No call queueing config file (queues.conf), so no call queues\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ast_mutex_lock(&qlock);
|
ast_mutex_lock(&qlock);
|
||||||
@@ -2123,7 +2133,7 @@ static void reload_queues(void)
|
|||||||
/* Chug through config file */
|
/* Chug through config file */
|
||||||
cat = ast_category_browse(cfg, NULL);
|
cat = ast_category_browse(cfg, NULL);
|
||||||
while(cat) {
|
while(cat) {
|
||||||
if (strcasecmp(cat, "general")) {
|
if (strcasecmp(cat, "general")) { /* Define queue */
|
||||||
/* Look for an existing one */
|
/* Look for an existing one */
|
||||||
q = queues;
|
q = queues;
|
||||||
while(q) {
|
while(q) {
|
||||||
@@ -2459,8 +2469,8 @@ static char *complete_queue(char *line, char *word, int pos, int state)
|
|||||||
static int manager_queues_show( struct mansession *s, struct message *m )
|
static int manager_queues_show( struct mansession *s, struct message *m )
|
||||||
{
|
{
|
||||||
char *a[] = { "show", "queues" };
|
char *a[] = { "show", "queues" };
|
||||||
return queues_show( s->fd, 2, a );
|
return queues_show(s->fd, 2, a);
|
||||||
} /* /JDG */
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Dump queue status */
|
/* Dump queue status */
|
||||||
@@ -2474,6 +2484,7 @@ static int manager_queues_status( struct mansession *s, struct message *m )
|
|||||||
struct queue_ent *qe;
|
struct queue_ent *qe;
|
||||||
float sl = 0;
|
float sl = 0;
|
||||||
struct member *mem;
|
struct member *mem;
|
||||||
|
|
||||||
astman_send_ack(s, m, "Queue status will follow");
|
astman_send_ack(s, m, "Queue status will follow");
|
||||||
time(&now);
|
time(&now);
|
||||||
ast_mutex_lock(&qlock);
|
ast_mutex_lock(&qlock);
|
||||||
|
@@ -14,11 +14,6 @@ persistentmembers = yes
|
|||||||
; Queue(queuename|[options]|[optionalurl]|[announceoverride]|[timeout])
|
; Queue(queuename|[options]|[optionalurl]|[announceoverride]|[timeout])
|
||||||
; example: Queue(dave|t|||45)
|
; example: Queue(dave|t|||45)
|
||||||
|
|
||||||
[default]
|
|
||||||
;
|
|
||||||
; Default settings for queues (currently unused)
|
|
||||||
;
|
|
||||||
|
|
||||||
;[markq]
|
;[markq]
|
||||||
;
|
;
|
||||||
; A sample call queue
|
; A sample call queue
|
||||||
@@ -47,6 +42,10 @@ persistentmembers = yes
|
|||||||
;
|
;
|
||||||
;strategy = ringall
|
;strategy = ringall
|
||||||
;
|
;
|
||||||
|
; Second settings for service level (default 0)
|
||||||
|
; Used for service level statistics (calls completed within service level time frame)
|
||||||
|
;servicelevel = 60
|
||||||
|
;
|
||||||
; A context may be specified, in which if the user types a SINGLE
|
; A context may be specified, in which if the user types a SINGLE
|
||||||
; digit extension while they are in the queue, they will be taken out
|
; digit extension while they are in the queue, they will be taken out
|
||||||
; of the queue and sent to that extension in this context.
|
; of the queue and sent to that extension in this context.
|
||||||
|
@@ -96,6 +96,10 @@ ${AGENTNUMBER} Agent number (username) set at login
|
|||||||
${AGENTSTATUS} Status of login ( fail | on | off )
|
${AGENTSTATUS} Status of login ( fail | on | off )
|
||||||
${AGENTEXTEN} Extension for logged in agent
|
${AGENTEXTEN} Extension for logged in agent
|
||||||
|
|
||||||
|
The queue() application uses the following variables:
|
||||||
|
${MONITOR_FILENAME} File for monitoring (recording) calls in queue
|
||||||
|
${QUEUE_PRIO} Queue priority
|
||||||
|
|
||||||
There are two reference modes - reference by value and reference by name.
|
There are two reference modes - reference by value and reference by name.
|
||||||
To refer to a variable with its name (as an argument to a function that
|
To refer to a variable with its name (as an argument to a function that
|
||||||
requires a variable), just write the name. To refer to the variable's value,
|
requires a variable), just write the name. To refer to the variable's value,
|
||||||
|
Reference in New Issue
Block a user