don't use localuser structure for outbound calls (issue #6216)

various code cleanup and reorganization (issue #6216)


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@10046 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.4
Kevin P. Fleming 20 years ago
parent c6ddfef02d
commit 2f46cb9198

@ -261,7 +261,8 @@ const struct {
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. */
struct localuser { struct callattempt {
struct callattempt *q_next;
struct ast_channel *chan; struct ast_channel *chan;
char interface[256]; char interface[256];
int stillgoing; int stillgoing;
@ -269,11 +270,11 @@ struct localuser {
int oldstatus; int oldstatus;
time_t lastcall; time_t lastcall;
struct member *member; struct member *member;
struct localuser *next;
}; };
LOCAL_USER_DECL; STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
struct queue_ent { struct queue_ent {
struct ast_call_queue *parent; /*!< What queue is our parent */ struct ast_call_queue *parent; /*!< What queue is our parent */
@ -1262,16 +1263,16 @@ ast_log(LOG_NOTICE, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name
} }
/* Hang up a list of outgoing calls */ /* Hang up a list of outgoing calls */
static void hangupcalls(struct localuser *outgoing, struct ast_channel *exception) static void hangupcalls(struct callattempt *outgoing, struct ast_channel *exception)
{ {
struct localuser *oo; struct callattempt *oo;
while(outgoing) { while(outgoing) {
/* Hangup any existing lines we have open */ /* Hangup any existing lines we have open */
if (outgoing->chan && (outgoing->chan != exception)) if (outgoing->chan && (outgoing->chan != exception))
ast_hangup(outgoing->chan); ast_hangup(outgoing->chan);
oo = outgoing; oo = outgoing;
outgoing=outgoing->next; outgoing=outgoing->q_next;
free(oo); free(oo);
} }
} }
@ -1283,8 +1284,7 @@ static int update_status(struct ast_call_queue *q, struct member *member, int st
/* Since a reload could have taken place, we have to traverse the list to /* Since a reload could have taken place, we have to traverse the list to
be sure it's still valid */ be sure it's still valid */
ast_mutex_lock(&q->lock); ast_mutex_lock(&q->lock);
cur = q->members; for (cur = q->members; cur; cur = cur->next) {
while(cur) {
if (member == cur) { if (member == cur) {
cur->status = status; cur->status = status;
if (!q->maskmemberstatus) { if (!q->maskmemberstatus) {
@ -1302,7 +1302,6 @@ static int update_status(struct ast_call_queue *q, struct member *member, int st
} }
break; break;
} }
cur = cur->next;
} }
ast_mutex_unlock(&q->lock); ast_mutex_unlock(&q->lock);
return 0; return 0;
@ -1354,13 +1353,22 @@ static int compare_weight(struct ast_call_queue *rq, struct member *member)
return found; return found;
} }
static int ring_entry(struct queue_ent *qe, struct localuser *tmp, int *busies) /*! \brief common hangup actions */
static void do_hang(struct callattempt *o)
{
o->stillgoing = 0;
ast_hangup(o->chan);
o->chan = NULL;
}
static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies)
{ {
int res; int res;
int status; int status;
char tech[256]; char tech[256];
char *location; char *location;
/* on entry here, we know that tmp->chan == NULL */
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) 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);
@ -1442,9 +1450,7 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp, int *busies)
ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res); ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
else if (option_verbose > 2) else if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", tmp->interface); ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", tmp->interface);
ast_hangup(tmp->chan); do_hang(tmp);
tmp->chan = NULL;
tmp->stillgoing = 0;
(*busies)++; (*busies)++;
return 0; return 0;
} else { } else {
@ -1468,69 +1474,58 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp, int *busies)
return 1; return 1;
} }
static int ring_one(struct queue_ent *qe, struct localuser *outgoing, int *busies) /*! \brief find the entry with the best metric, or NULL */
static struct callattempt *find_best(struct callattempt *outgoing)
{ {
struct localuser *cur; struct callattempt *best = NULL, *cur;
struct localuser *best;
int bestmetric=0;
do { for (cur = outgoing; cur; cur = cur->q_next) {
best = NULL; if (cur->stillgoing && /* Not already done */
cur = outgoing; !cur->chan && /* Isn't already going */
while(cur) { (!best || cur->metric < best->metric)) { /* We haven't found one yet, or it's better */
if (cur->stillgoing && /* Not already done */ best = cur;
!cur->chan && /* Isn't already going */
(!best || (cur->metric < bestmetric))) { /* We haven't found one yet, or it's better */
bestmetric = cur->metric;
best = cur;
}
cur = cur->next;
} }
if (best) { }
if (!qe->parent->strategy) { return best;
/* Ring everyone who shares this best metric (for ringall) */ }
cur = outgoing;
while(cur) { static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)
if (cur->stillgoing && !cur->chan && (cur->metric <= bestmetric)) { {
if (option_debug) int ret = 0;
ast_log(LOG_DEBUG, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric);
ring_entry(qe, cur, busies); while (ret == 0) {
} struct callattempt *best = find_best(outgoing);
cur = cur->next; if (!best) {
if (option_debug)
ast_log(LOG_DEBUG, "Nobody left to try ringing in queue\n");
break;
}
if (!qe->parent->strategy) {
struct callattempt *cur;
/* Ring everyone who shares this best metric (for ringall) */
for (cur = outgoing; cur; cur = cur->q_next) {
if (cur->stillgoing && !cur->chan && cur->metric <= best->metric) {
if (option_debug)
ast_log(LOG_DEBUG, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric);
ring_entry(qe, cur, busies);
} }
} else {
/* 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, busies);
} }
} else {
/* 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, busies);
} }
} while (best && !best->chan); if (best->chan) /* break out with result = 1 */
if (!best) { ret = 1;
if (option_debug)
ast_log(LOG_DEBUG, "Nobody left to try ringing in queue\n");
return 0;
} }
return 1; return ret;
} }
static int store_next(struct queue_ent *qe, struct localuser *outgoing) static int store_next(struct queue_ent *qe, struct callattempt *outgoing)
{ {
struct localuser *cur; struct callattempt *best = find_best(outgoing);
struct localuser *best;
int bestmetric=0;
best = NULL;
cur = outgoing;
while(cur) {
if (cur->stillgoing && /* Not already done */
!cur->chan && /* Isn't already going */
(!best || (cur->metric < bestmetric))) { /* We haven't found one yet, or it's better */
bestmetric = cur->metric;
best = cur;
}
cur = cur->next;
}
if (best) { if (best) {
/* Ring just the best channel */ /* Ring just the best channel */
if (option_debug) if (option_debug)
@ -1625,33 +1620,10 @@ static void record_abandoned(struct queue_ent *qe)
#define AST_MAX_WATCHERS 256 #define AST_MAX_WATCHERS 256
#define BUILD_WATCHERS do { \ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect)
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, char *digit, int prebusies, int caller_disconnect)
{ {
char *queue = qe->parent->name; char *queue = qe->parent->name;
char on[256] = ""; struct callattempt *o;
struct localuser *o;
int found;
int numlines;
int status; int status;
int sentringing = 0; int sentringing = 0;
int numbusies = prebusies; int numbusies = prebusies;
@ -1659,21 +1631,35 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
int stillgoing = 0; int stillgoing = 0;
int orig = *to; int orig = *to;
struct ast_frame *f; struct ast_frame *f;
struct localuser *peer = NULL; struct callattempt *peer = NULL;
struct ast_channel *watchers[AST_MAX_WATCHERS];
int pos;
struct ast_channel *winner; struct ast_channel *winner;
struct ast_channel *in = qe->chan; struct ast_channel *in = qe->chan;
char on[256] = "";
while(*to && !peer) { while(*to && !peer) {
BUILD_WATCHERS; int numlines, retry, pos = 1;
if ((found < 0) && stillgoing && !qe->parent->strategy) { struct ast_channel *watchers[AST_MAX_WATCHERS];
watchers[0] = in;
for (retry = 0; retry < 2; retry++) {
numlines = 0;
for (o = outgoing; o; o = o->q_next) { /* Keep track of important channels */
if (o->stillgoing) { /* Keep track of important channels */
stillgoing = 1;
if (o->chan)
watchers[pos++] = o->chan;
}
numlines++;
}
if (pos > 1 /* found */ || !stillgoing /* nobody listening */ ||
qe->parent->strategy /* ring would not be delivered */)
break;
/* On "ringall" strategy we only move to the next penalty level /* On "ringall" strategy we only move to the next penalty level
when *all* ringing phones are done in the current penalty level */ when *all* ringing phones are done in the current penalty level */
ring_one(qe, outgoing, &numbusies); ring_one(qe, outgoing, &numbusies);
BUILD_WATCHERS; /* and retry... */
} }
if (found < 0) { if (pos == 1 /* not found */) {
if (numlines == (numbusies + numnochan)) { if (numlines == (numbusies + numnochan)) {
ast_log(LOG_DEBUG, "Everyone is busy at this time\n"); ast_log(LOG_DEBUG, "Everyone is busy at this time\n");
} else { } else {
@ -1683,8 +1669,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
return NULL; return NULL;
} }
winner = ast_waitfor_n(watchers, pos, to); winner = ast_waitfor_n(watchers, pos, to);
o = outgoing; for (o = outgoing; o; o = o->q_next) {
while(o) {
if (o->stillgoing && (o->chan) && (o->chan->_state == AST_STATE_UP)) { if (o->stillgoing && (o->chan) && (o->chan->_state == AST_STATE_UP)) {
if (!peer) { if (!peer) {
if (option_verbose > 2) if (option_verbose > 2)
@ -1699,8 +1684,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
char *tech; char *tech;
ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan)); ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan));
if ((stuff = strchr(tmpchan, '/'))) { if ((stuff = strchr(tmpchan, '/'))) {
*stuff = '\0'; *stuff++ = '\0';
stuff++;
tech = tmpchan; tech = tmpchan;
} else { } else {
snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, o->chan->context); snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, o->chan->context);
@ -1752,9 +1736,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
o->chan->cid.cid_rdnis = strdup(in->exten); o->chan->cid.cid_rdnis = strdup(in->exten);
if (ast_call(o->chan, tmpchan, 0)) { if (ast_call(o->chan, tmpchan, 0)) {
ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan); ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
o->stillgoing = 0; do_hang(o);
ast_hangup(o->chan);
o->chan = NULL;
numnochan++; numnochan++;
} }
} }
@ -1777,11 +1759,9 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
case AST_CONTROL_BUSY: case AST_CONTROL_BUSY:
if (option_verbose > 2) if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name); ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name);
o->stillgoing = 0;
if (in->cdr) if (in->cdr)
ast_cdr_busy(in->cdr); ast_cdr_busy(in->cdr);
ast_hangup(o->chan); do_hang(o);
o->chan = NULL;
if (qe->parent->strategy) { if (qe->parent->strategy) {
if (qe->parent->timeoutrestart) if (qe->parent->timeoutrestart)
*to = orig; *to = orig;
@ -1792,11 +1772,9 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
case AST_CONTROL_CONGESTION: case AST_CONTROL_CONGESTION:
if (option_verbose > 2) if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "%s is circuit-busy\n", o->chan->name); ast_verbose( VERBOSE_PREFIX_3 "%s is circuit-busy\n", o->chan->name);
o->stillgoing = 0;
if (in->cdr) if (in->cdr)
ast_cdr_busy(in->cdr); ast_cdr_busy(in->cdr);
ast_hangup(o->chan); do_hang(o);
o->chan = NULL;
if (qe->parent->strategy) { if (qe->parent->strategy) {
if (qe->parent->timeoutrestart) if (qe->parent->timeoutrestart)
*to = orig; *to = orig;
@ -1823,9 +1801,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
} }
ast_frfree(f); ast_frfree(f);
} else { } else {
o->stillgoing = 0; do_hang(o);
ast_hangup(o->chan);
o->chan = NULL;
if (qe->parent->strategy) { if (qe->parent->strategy) {
if (qe->parent->timeoutrestart) if (qe->parent->timeoutrestart)
*to = orig; *to = orig;
@ -1833,7 +1809,6 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
} }
} }
} }
o = o->next;
} }
if (winner == in) { if (winner == in) {
f = ast_read(in); f = ast_read(in);
@ -1883,7 +1858,6 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
} }
return peer; return peer;
} }
static int is_our_turn(struct queue_ent *qe) static int is_our_turn(struct queue_ent *qe)
@ -1979,7 +1953,7 @@ static int update_queue(struct ast_call_queue *q, struct member *member)
return 0; return 0;
} }
static int calc_metric(struct ast_call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct localuser *tmp) static int calc_metric(struct ast_call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
{ {
if (mem->penalty > qe->max_penalty) if (mem->penalty > qe->max_penalty)
return -1; return -1;
@ -2037,7 +2011,7 @@ static int calc_metric(struct ast_call_queue *q, struct member *mem, int pos, st
static int try_calling(struct queue_ent *qe, const char *options, char *announceoverride, const char *url, int *go_on) static int try_calling(struct queue_ent *qe, const char *options, char *announceoverride, const char *url, int *go_on)
{ {
struct member *cur; struct member *cur;
struct localuser *outgoing=NULL, *tmp = NULL; struct callattempt *outgoing=NULL; /* the queue we are building */
int to; int to;
char restofit[AST_MAX_EXTENSION]; char restofit[AST_MAX_EXTENSION];
char oldexten[AST_MAX_EXTENSION]=""; char oldexten[AST_MAX_EXTENSION]="";
@ -2046,7 +2020,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
char *newnum; char *newnum;
struct ast_channel *peer; struct ast_channel *peer;
struct ast_channel *which; struct ast_channel *which;
struct localuser *lpeer; struct callattempt *lpeer;
struct member *member; struct member *member;
int res = 0, bridge = 0; int res = 0, bridge = 0;
int numbusies = 0; int numbusies = 0;
@ -2104,8 +2078,9 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
if (!ast_strlen_zero(announceoverride)) if (!ast_strlen_zero(announceoverride))
announce = announceoverride; announce = announceoverride;
while(cur) { for (;cur; cur = cur->next) {
if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
if (!tmp) {
ast_mutex_unlock(&qe->parent->lock); ast_mutex_unlock(&qe->parent->lock);
if (use_weight) if (use_weight)
AST_LIST_UNLOCK(&queues); AST_LIST_UNLOCK(&queues);
@ -2137,7 +2112,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
/* Put them in the list of outgoing thingies... We're ready now. /* Put them in the list of outgoing thingies... We're ready now.
XXX If we're forcibly removed, these outgoing calls won't get XXX If we're forcibly removed, these outgoing calls won't get
hung up XXX */ hung up XXX */
tmp->next = outgoing; tmp->q_next = outgoing;
outgoing = tmp; outgoing = tmp;
/* If this line is up, don't try anybody else */ /* If this line is up, don't try anybody else */
if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP)) if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
@ -2145,13 +2120,8 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
} else { } else {
free(tmp); free(tmp);
} }
cur = cur->next;
} }
if (qe->parent->timeout) to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
to = qe->parent->timeout * 1000;
else
to = -1;
ring_one(qe, outgoing, &numbusies); ring_one(qe, outgoing, &numbusies);
ast_mutex_unlock(&qe->parent->lock); ast_mutex_unlock(&qe->parent->lock);
if (use_weight) if (use_weight)
@ -2162,10 +2132,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
store_next(qe, outgoing); store_next(qe, outgoing);
} }
ast_mutex_unlock(&qe->parent->lock); ast_mutex_unlock(&qe->parent->lock);
if (lpeer) peer = lpeer ? lpeer->chan : NULL;
peer = lpeer->chan;
else
peer = NULL;
if (!peer) { if (!peer) {
if (to) { if (to) {
/* Must gotten hung up */ /* Must gotten hung up */
@ -2175,9 +2142,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
} }
if (option_debug) if (option_debug)
ast_log(LOG_DEBUG, "%s: Nobody answered.\n", qe->chan->name); ast_log(LOG_DEBUG, "%s: Nobody answered.\n", qe->chan->name);
goto out; } else { /* peer is valid */
}
if (peer) {
/* Ah ha! Someone answered within the desired timeframe. Of course after this /* Ah ha! Someone answered within the desired timeframe. Of course after this
we will always return with -1 so that it is hung up properly after the we will always return with -1 so that it is hung up properly after the
conversation. */ conversation. */
@ -2337,7 +2302,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
res = 1; /* JDG: bridge successfully, leave app_queue */ res = 1; /* JDG: bridge successfully, leave app_queue */
else else
res = bridge; /* bridge error, stay in the queue */ res = bridge; /* bridge error, stay in the queue */
} }
out: out:
hangupcalls(outgoing, NULL); hangupcalls(outgoing, NULL);
return res; return res;
@ -2630,7 +2595,7 @@ static void reload_queue_members(void)
static int pqm_exec(struct ast_channel *chan, void *data) static int pqm_exec(struct ast_channel *chan, void *data)
{ {
struct localuser *u; struct localuser *lu;
char *parse; char *parse;
int priority_jump = 0; int priority_jump = 0;
AST_DECLARE_APP_ARGS(args, AST_DECLARE_APP_ARGS(args,
@ -2649,7 +2614,7 @@ static int pqm_exec(struct ast_channel *chan, void *data)
AST_STANDARD_APP_ARGS(args, parse); AST_STANDARD_APP_ARGS(args, parse);
LOCAL_USER_ADD(u); LOCAL_USER_ADD(lu);
if (args.options) { if (args.options) {
if (strchr(args.options, 'j')) if (strchr(args.options, 'j'))
@ -2658,7 +2623,7 @@ static int pqm_exec(struct ast_channel *chan, void *data)
if (ast_strlen_zero(args.interface)) { if (ast_strlen_zero(args.interface)) {
ast_log(LOG_WARNING, "Missing interface argument to PauseQueueMember ([queuename]|interface[|options])\n"); ast_log(LOG_WARNING, "Missing interface argument to PauseQueueMember ([queuename]|interface[|options])\n");
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(lu);
return -1; return -1;
} }
@ -2667,23 +2632,23 @@ static int pqm_exec(struct ast_channel *chan, void *data)
if (priority_jump || ast_opt_priority_jumping) { if (priority_jump || ast_opt_priority_jumping) {
if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) { if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
pbx_builtin_setvar_helper(chan, "PQMSTATUS", "NOTFOUND"); pbx_builtin_setvar_helper(chan, "PQMSTATUS", "NOTFOUND");
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(lu);
return 0; return 0;
} }
} }
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(lu);
pbx_builtin_setvar_helper(chan, "PQMSTATUS", "NOTFOUND"); pbx_builtin_setvar_helper(chan, "PQMSTATUS", "NOTFOUND");
return -1; return -1;
} }
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(lu);
pbx_builtin_setvar_helper(chan, "PQMSTATUS", "PAUSED"); pbx_builtin_setvar_helper(chan, "PQMSTATUS", "PAUSED");
return 0; return 0;
} }
static int upqm_exec(struct ast_channel *chan, void *data) static int upqm_exec(struct ast_channel *chan, void *data)
{ {
struct localuser *u; struct localuser *lu;
char *parse; char *parse;
int priority_jump = 0; int priority_jump = 0;
AST_DECLARE_APP_ARGS(args, AST_DECLARE_APP_ARGS(args,
@ -2702,7 +2667,7 @@ static int upqm_exec(struct ast_channel *chan, void *data)
AST_STANDARD_APP_ARGS(args, parse); AST_STANDARD_APP_ARGS(args, parse);
LOCAL_USER_ADD(u); LOCAL_USER_ADD(lu);
if (args.options) { if (args.options) {
if (strchr(args.options, 'j')) if (strchr(args.options, 'j'))
@ -2711,7 +2676,7 @@ static int upqm_exec(struct ast_channel *chan, void *data)
if (ast_strlen_zero(args.interface)) { if (ast_strlen_zero(args.interface)) {
ast_log(LOG_WARNING, "Missing interface argument to PauseQueueMember ([queuename]|interface[|options])\n"); ast_log(LOG_WARNING, "Missing interface argument to PauseQueueMember ([queuename]|interface[|options])\n");
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(lu);
return -1; return -1;
} }
@ -2720,16 +2685,16 @@ static int upqm_exec(struct ast_channel *chan, void *data)
if (priority_jump || ast_opt_priority_jumping) { if (priority_jump || ast_opt_priority_jumping) {
if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) { if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "NOTFOUND"); pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "NOTFOUND");
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(lu);
return 0; return 0;
} }
} }
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(lu);
pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "NOTFOUND"); pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "NOTFOUND");
return -1; return -1;
} }
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(lu);
pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "UNPAUSED"); pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "UNPAUSED");
return 0; return 0;
} }
@ -2737,7 +2702,7 @@ static int upqm_exec(struct ast_channel *chan, void *data)
static int rqm_exec(struct ast_channel *chan, void *data) static int rqm_exec(struct ast_channel *chan, void *data)
{ {
int res=-1; int res=-1;
struct localuser *u; struct localuser *lu;
char *parse, *temppos = NULL; char *parse, *temppos = NULL;
int priority_jump = 0; int priority_jump = 0;
AST_DECLARE_APP_ARGS(args, AST_DECLARE_APP_ARGS(args,
@ -2757,7 +2722,7 @@ static int rqm_exec(struct ast_channel *chan, void *data)
AST_STANDARD_APP_ARGS(args, parse); AST_STANDARD_APP_ARGS(args, parse);
LOCAL_USER_ADD(u); LOCAL_USER_ADD(lu);
if (ast_strlen_zero(args.interface)) { if (ast_strlen_zero(args.interface)) {
args.interface = ast_strdupa(chan->name); args.interface = ast_strdupa(chan->name);
@ -2794,14 +2759,14 @@ static int rqm_exec(struct ast_channel *chan, void *data)
break; break;
} }
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(lu);
return res; return res;
} }
static int aqm_exec(struct ast_channel *chan, void *data) static int aqm_exec(struct ast_channel *chan, void *data)
{ {
int res=-1; int res=-1;
struct localuser *u; struct localuser *lu;
char *parse, *temppos = NULL; char *parse, *temppos = NULL;
int priority_jump = 0; int priority_jump = 0;
AST_DECLARE_APP_ARGS(args, AST_DECLARE_APP_ARGS(args,
@ -2822,7 +2787,7 @@ static int aqm_exec(struct ast_channel *chan, void *data)
AST_STANDARD_APP_ARGS(args, parse); AST_STANDARD_APP_ARGS(args, parse);
LOCAL_USER_ADD(u); LOCAL_USER_ADD(lu);
if (ast_strlen_zero(args.interface)) { if (ast_strlen_zero(args.interface)) {
args.interface = ast_strdupa(chan->name); args.interface = ast_strdupa(chan->name);
@ -2867,7 +2832,7 @@ static int aqm_exec(struct ast_channel *chan, void *data)
break; break;
} }
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(lu);
return res; return res;
} }
@ -2875,7 +2840,7 @@ static int queue_exec(struct ast_channel *chan, void *data)
{ {
int res=-1; int res=-1;
int ringing=0; int ringing=0;
struct localuser *u; struct localuser *lu;
const char *user_priority; const char *user_priority;
const char *max_penalty_str; const char *max_penalty_str;
int prio; int prio;
@ -2909,7 +2874,7 @@ static int queue_exec(struct ast_channel *chan, void *data)
} }
AST_STANDARD_APP_ARGS(args, parse); AST_STANDARD_APP_ARGS(args, parse);
LOCAL_USER_ADD(u); LOCAL_USER_ADD(lu);
/* Setup our queue entry */ /* Setup our queue entry */
memset(&qe, 0, sizeof(qe)); memset(&qe, 0, sizeof(qe));
@ -3137,7 +3102,7 @@ check_turns:
set_queue_result(chan, reason); set_queue_result(chan, reason);
res = 0; res = 0;
} }
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(lu);
return res; return res;
} }
@ -3145,7 +3110,7 @@ static int queue_function_qac(struct ast_channel *chan, char *cmd, char *data, c
{ {
int count = 0; int count = 0;
struct ast_call_queue *q; struct ast_call_queue *q;
struct localuser *u; struct localuser *lu;
struct member *m; struct member *m;
buf[0] = '\0'; buf[0] = '\0';
@ -3155,7 +3120,7 @@ static int queue_function_qac(struct ast_channel *chan, char *cmd, char *data, c
return -1; return -1;
} }
LOCAL_USER_ADD(u); LOCAL_USER_ADD(lu);
AST_LIST_LOCK(&queues); AST_LIST_LOCK(&queues);
@ -3180,7 +3145,7 @@ static int queue_function_qac(struct ast_channel *chan, char *cmd, char *data, c
} }
snprintf(buf, len, "%d", count); snprintf(buf, len, "%d", count);
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(lu);
return 0; return 0;
} }
@ -3290,8 +3255,8 @@ static void reload_queues(void)
q->dead = 1; q->dead = 1;
} }
/* Chug through config file */ /* Chug through config file */
cat = ast_category_browse(cfg, NULL); cat = NULL;
while(cat) { while ((cat = ast_category_browse(cfg, cat)) ) {
if (!strcasecmp(cat, "general")) { if (!strcasecmp(cat, "general")) {
/* Initialize global settings */ /* Initialize global settings */
queue_persistent_members = 0; queue_persistent_members = 0;
@ -3324,8 +3289,7 @@ static void reload_queues(void)
while(prev->next) while(prev->next)
prev = prev->next; prev = prev->next;
} }
var = ast_variable_browse(cfg, cat); for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
while(var) {
if (!strcasecmp(var->name, "member")) { if (!strcasecmp(var->name, "member")) {
/* Add a new member */ /* Add a new member */
ast_copy_string(interface, var->value, sizeof(interface)); ast_copy_string(interface, var->value, sizeof(interface));
@ -3349,7 +3313,6 @@ static void reload_queues(void)
} else { } else {
queue_set_param(q, var->name, var->value, var->lineno, 1); queue_set_param(q, var->name, var->value, var->lineno, 1);
} }
var = var->next;
} }
if (new) { if (new) {
AST_LIST_INSERT_HEAD(&queues, q, list); AST_LIST_INSERT_HEAD(&queues, q, list);
@ -3357,7 +3320,6 @@ static void reload_queues(void)
ast_mutex_unlock(&q->lock); ast_mutex_unlock(&q->lock);
} }
} }
cat = ast_category_browse(cfg, cat);
} }
ast_config_destroy(cfg); ast_config_destroy(cfg);
AST_LIST_TRAVERSE_SAFE_BEGIN(&queues, q, list) { AST_LIST_TRAVERSE_SAFE_BEGIN(&queues, q, list) {
@ -3488,11 +3450,9 @@ static char *complete_queue(const char *line, const char *word, int pos, int sta
AST_LIST_LOCK(&queues); AST_LIST_LOCK(&queues);
AST_LIST_TRAVERSE(&queues, q, list) { AST_LIST_TRAVERSE(&queues, q, list) {
if (!strncasecmp(word, q->name, wordlen)) { if (!strncasecmp(word, q->name, wordlen) && (++which > state)) {
if (++which > state) { ret = strdup(q->name);
ret = strdup(q->name); break;
break;
}
} }
} }
AST_LIST_UNLOCK(&queues); AST_LIST_UNLOCK(&queues);
@ -3624,9 +3584,8 @@ static int manager_add_queue_member(struct mansession *s, struct message *m)
if (ast_strlen_zero(penalty_s)) if (ast_strlen_zero(penalty_s))
penalty = 0; penalty = 0;
else if (sscanf(penalty_s, "%d", &penalty) != 1) { else if (sscanf(penalty_s, "%d", &penalty) != 1)
penalty = 0; penalty = 0;
}
if (ast_strlen_zero(paused_s)) if (ast_strlen_zero(paused_s))
paused = 0; paused = 0;
@ -3698,11 +3657,7 @@ static int manager_pause_queue_member(struct mansession *s, struct message *m)
if (set_member_paused(queuename, interface, paused)) if (set_member_paused(queuename, interface, paused))
astman_send_error(s, m, "Interface not found"); astman_send_error(s, m, "Interface not found");
else else
if (paused) astman_send_ack(s, m, paused ? "Interface paused successfully" : "Interface unpaused successfully");
astman_send_ack(s, m, "Interface paused successfully");
else
astman_send_ack(s, m, "Interface unpaused successfully");
return 0; return 0;
} }
@ -3757,24 +3712,14 @@ static char *complete_add_queue_member(const char *line, const char *word, int p
{ {
/* 0 - add; 1 - queue; 2 - member; 3 - <member>; 4 - to; 5 - <queue>; 6 - penalty; 7 - <penalty> */ /* 0 - add; 1 - queue; 2 - member; 3 - <member>; 4 - to; 5 - <queue>; 6 - penalty; 7 - <penalty> */
switch (pos) { switch (pos) {
case 3: case 3: /* Don't attempt to complete name of member (infinite possibilities) */
/* Don't attempt to complete name of member (infinite possibilities) */
return NULL; return NULL;
case 4: case 4: /* only one possible match, "to" */
if (state == 0) { return state == 0 ? strdup("to") : NULL;
return strdup("to"); case 5: /* <queue> */
} else {
return NULL;
}
case 5:
/* No need to duplicate code */
return complete_queue(line, word, pos, state); return complete_queue(line, word, pos, state);
case 6: case 6: /* only one possible match, "penalty" */
if (state == 0) { return state == 0 ? strdup("penalty") : NULL;
return strdup("penalty");
} else {
return NULL;
}
case 7: case 7:
if (state < 100) { /* 0-99 */ if (state < 100) { /* 0-99 */
char *num; char *num;
@ -3827,23 +3772,16 @@ static char *complete_remove_queue_member(const char *line, const char *word, in
struct ast_call_queue *q; struct ast_call_queue *q;
struct member *m; struct member *m;
/* 0 - add; 1 - queue; 2 - member; 3 - <member>; 4 - to; 5 - <queue> */ /* 0 - add; 1 - queue; 2 - member; 3 - <member>; 4 - from; 5 - <queue> */
if ((pos > 5) || (pos < 3)) { if (pos > 5 || pos < 3)
return NULL; return NULL;
} if (pos == 4) /* only one possible match, 'from' */
if (pos == 4) { return state == 0 ? strdup("from") : NULL;
if (state == 0) {
return strdup("from"); if (pos == 5) /* No need to duplicate code */
} else { return complete_queue(line, word, pos, state);
return NULL;
} /* here is the case for 3, <member> */
}
if (pos == 5) {
/* No need to duplicate code */
return complete_queue(line, word, pos, state);
}
if (!AST_LIST_EMPTY(&queues)) { if (!AST_LIST_EMPTY(&queues)) {
AST_LIST_TRAVERSE(&queues, q, list) { AST_LIST_TRAVERSE(&queues, q, list) {
ast_mutex_lock(&q->lock); ast_mutex_lock(&q->lock);

Loading…
Cancel
Save