various coding style cleanup and minor fixes

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@34193 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Kevin P. Fleming 2006-06-14 23:20:08 +00:00
parent 794d0e4d1f
commit 7518a91032

View file

@ -420,20 +420,24 @@ static void set_queue_result(struct ast_channel *chan, enum queue_result res)
static char *int2strat(int strategy) static char *int2strat(int strategy)
{ {
int x; int x;
for (x=0;x<sizeof(strategies) / sizeof(strategies[0]);x++) {
for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
if (strategy == strategies[x].strategy) if (strategy == strategies[x].strategy)
return strategies[x].name; return strategies[x].name;
} }
return "<unknown>"; return "<unknown>";
} }
static int strat2int(const char *strategy) static int strat2int(const char *strategy)
{ {
int x; int x;
for (x=0;x<sizeof(strategies) / sizeof(strategies[0]);x++) {
for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
if (!strcasecmp(strategy, strategies[x].name)) if (!strcasecmp(strategy, strategies[x].name))
return strategies[x].strategy; return strategies[x].strategy;
} }
return -1; return -1;
} }
@ -587,8 +591,6 @@ static struct member *create_queue_member(char *interface, int penalty, int paus
{ {
struct member *cur; struct member *cur;
/* Add a new member */
if ((cur = ast_calloc(1, sizeof(*cur)))) { if ((cur = ast_calloc(1, sizeof(*cur)))) {
cur->penalty = penalty; cur->penalty = penalty;
cur->paused = paused; cur->paused = paused;
@ -615,6 +617,7 @@ static struct ast_call_queue *alloc_queue(const char *queuename)
static void init_queue(struct ast_call_queue *q) static void init_queue(struct ast_call_queue *q)
{ {
int i; int i;
q->dead = 0; q->dead = 0;
q->retry = DEFAULT_RETRY; q->retry = DEFAULT_RETRY;
q->timeout = -1; q->timeout = -1;
@ -642,7 +645,7 @@ static void init_queue(struct ast_call_queue *q)
ast_copy_string(q->sound_lessthan, "queue-less-than", sizeof(q->sound_lessthan)); ast_copy_string(q->sound_lessthan, "queue-less-than", sizeof(q->sound_lessthan));
ast_copy_string(q->sound_reporthold, "queue-reporthold", sizeof(q->sound_reporthold)); ast_copy_string(q->sound_reporthold, "queue-reporthold", sizeof(q->sound_reporthold));
ast_copy_string(q->sound_periodicannounce[0], "queue-periodic-announce", sizeof(q->sound_periodicannounce[0])); ast_copy_string(q->sound_periodicannounce[0], "queue-periodic-announce", sizeof(q->sound_periodicannounce[0]));
for (i=1;i<MAX_PERIODIC_ANNOUNCEMENTS;i++) { for (i = 1; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
q->sound_periodicannounce[i][0]='\0'; q->sound_periodicannounce[i][0]='\0';
} }
} }
@ -749,6 +752,7 @@ static void queue_set_param(struct ast_call_queue *q, const char *param, const c
int i = 0; int i = 0;
char *c, *lastc; char *c, *lastc;
char buff[80]; char buff[80];
if (!strcasecmp(param, "music") || !strcasecmp(param, "musiconhold")) { if (!strcasecmp(param, "music") || !strcasecmp(param, "musiconhold")) {
ast_copy_string(q->moh, val, sizeof(q->moh)); ast_copy_string(q->moh, val, sizeof(q->moh));
} else if (!strcasecmp(param, "announce")) { } else if (!strcasecmp(param, "announce")) {
@ -898,24 +902,20 @@ static void rt_handle_member_record(struct ast_call_queue *q, char *interface, c
struct member *m, *prev_m; struct member *m, *prev_m;
int penalty = 0; int penalty = 0;
if(penalty_str) { if (penalty_str) {
penalty = atoi(penalty_str); penalty = atoi(penalty_str);
if(penalty < 0) if (penalty < 0)
penalty = 0; penalty = 0;
} }
/* Find the member, or the place to put a new one. */ /* Find the member, or the place to put a new one. */
prev_m = NULL; for (m = q->members, prev_m = NULL;
m = q->members; m && strcmp(m->interface, interface);
while (m && strcmp(m->interface, interface)) { prev_m = m, m = m->next);
prev_m = m;
m = m->next;
}
/* Create a new one if not found, else update penalty */ /* Create a new one if not found, else update penalty */
if (!m) { if (!m) {
m = create_queue_member(interface, penalty, 0); if ((m = create_queue_member(interface, penalty, 0))) {
if (m) {
m->dead = 0; m->dead = 0;
add_to_interfaces(interface); add_to_interfaces(interface);
if (prev_m) { if (prev_m) {
@ -970,10 +970,9 @@ static struct ast_call_queue *find_queue_by_name_rt(const char *queuename, struc
/* Find the queue in the in-core list (we will create a new one if not found). */ /* Find the queue in the in-core list (we will create a new one if not found). */
AST_LIST_TRAVERSE(&queues, q, list) { AST_LIST_TRAVERSE(&queues, q, list) {
if (!strcasecmp(q->name, queuename)) { if (!strcasecmp(q->name, queuename))
break; break;
} }
}
/* Static queues override realtime. */ /* Static queues override realtime. */
if (q) { if (q) {
@ -1024,38 +1023,32 @@ static struct ast_call_queue *find_queue_by_name_rt(const char *queuename, struc
} }
init_queue(q); /* Ensure defaults for all parameters not set explicitly. */ init_queue(q); /* Ensure defaults for all parameters not set explicitly. */
v = queue_vars;
memset(tmpbuf, 0, sizeof(tmpbuf)); memset(tmpbuf, 0, sizeof(tmpbuf));
while(v) { for (v = queue_vars; v; v = v->next) {
/* Convert to dashes `-' from underscores `_' as the latter are more SQL friendly. */ /* Convert to dashes `-' from underscores `_' as the latter are more SQL friendly. */
if((tmp = strchr(v->name, '_')) != NULL) { if ((tmp = strchr(v->name, '_'))) {
ast_copy_string(tmpbuf, v->name, sizeof(tmpbuf)); ast_copy_string(tmpbuf, v->name, sizeof(tmpbuf));
tmp_name = tmpbuf; tmp_name = tmpbuf;
tmp = tmp_name; tmp = tmp_name;
while((tmp = strchr(tmp, '_')) != NULL) while ((tmp = strchr(tmp, '_')))
*tmp++ = '-'; *tmp++ = '-';
} else } else
tmp_name = v->name; tmp_name = v->name;
queue_set_param(q, tmp_name, v->value, -1, 0); queue_set_param(q, tmp_name, v->value, -1, 0);
v = v->next;
} }
if (q->strategy == QUEUE_STRATEGY_ROUNDROBIN) if (q->strategy == QUEUE_STRATEGY_ROUNDROBIN)
rr_dep_warning(); rr_dep_warning();
/* Temporarily set non-dynamic members dead so we can detect deleted ones. */ /* Temporarily set non-dynamic members dead so we can detect deleted ones. */
m = q->members; for (m = q->members; m; m = m->next) {
while (m) {
if (!m->dynamic) if (!m->dynamic)
m->dead = 1; m->dead = 1;
m = m->next;
} }
interface = ast_category_browse(member_config, NULL); interface = NULL;
while (interface) { while (ast_category_browse(member_config, interface))
rt_handle_member_record(q, interface, ast_variable_retrieve(member_config, interface, "penalty")); rt_handle_member_record(q, interface, ast_variable_retrieve(member_config, interface, "penalty"));
interface = ast_category_browse(member_config, interface);
}
/* Delete all realtime members that have been deleted in DB. */ /* Delete all realtime members that have been deleted in DB. */
m = q->members; m = q->members;
@ -1083,7 +1076,7 @@ static struct ast_call_queue *find_queue_by_name_rt(const char *queuename, struc
static struct ast_call_queue *load_realtime_queue(char *queuename) static struct ast_call_queue *load_realtime_queue(char *queuename)
{ {
struct ast_variable *queue_vars = NULL; struct ast_variable *queue_vars;
struct ast_config *member_config = NULL; struct ast_config *member_config = NULL;
struct ast_call_queue *q; struct ast_call_queue *q;
@ -1137,8 +1130,7 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *
int inserted = 0; int inserted = 0;
enum queue_member_status stat; enum queue_member_status stat;
q = load_realtime_queue(queuename); if (!(q = load_realtime_queue(queuename)))
if (!q)
return res; return res;
AST_LIST_LOCK(&queues); AST_LIST_LOCK(&queues);
@ -1159,7 +1151,7 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *
inserted = 0; inserted = 0;
prev = NULL; prev = NULL;
cur = q->head; cur = q->head;
while(cur) { while (cur) {
/* We have higher priority than the current user, enter /* We have higher priority than the current user, enter
* before him, after all the other users with priority * before him, after all the other users with priority
* higher or equal to our priority. */ * higher or equal to our priority. */
@ -1179,7 +1171,6 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *
ast_copy_string(qe->context, q->context, sizeof(qe->context)); ast_copy_string(qe->context, q->context, sizeof(qe->context));
q->count++; q->count++;
res = 0; res = 0;
/* XXX missing CalledIDnum ? */
manager_event(EVENT_FLAG_CALL, "Join", manager_event(EVENT_FLAG_CALL, "Join",
"Channel: %s\r\nCallerID: %s\r\nCallerIDName: %s\r\nQueue: %s\r\nPosition: %d\r\nCount: %d\r\nUniqueid: %s\r\n", "Channel: %s\r\nCallerID: %s\r\nCallerIDName: %s\r\nQueue: %s\r\nPosition: %d\r\nCount: %d\r\nUniqueid: %s\r\n",
qe->chan->name, qe->chan->name,
@ -1191,6 +1182,7 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *
} }
ast_mutex_unlock(&q->lock); ast_mutex_unlock(&q->lock);
AST_LIST_UNLOCK(&queues); AST_LIST_UNLOCK(&queues);
return res; return res;
} }
@ -1200,12 +1192,8 @@ static int play_file(struct ast_channel *chan, char *filename)
ast_stopstream(chan); ast_stopstream(chan);
res = ast_streamfile(chan, filename, chan->language); res = ast_streamfile(chan, filename, chan->language);
if (!res) if (!res)
res = ast_waitstream(chan, AST_DIGIT_ANY); res = ast_waitstream(chan, AST_DIGIT_ANY);
else
res = 0;
ast_stopstream(chan); ast_stopstream(chan);
return res; return res;
@ -1239,6 +1227,7 @@ static int valid_exit(struct queue_ent *qe, char digit)
/* Return 1 on a successful goto */ /* Return 1 on a successful goto */
return 1; return 1;
} }
return 0; return 0;
} }
@ -1249,11 +1238,11 @@ static int say_position(struct queue_ent *qe)
/* Check to see if this is ludicrous -- if we just announced position, don't do it again*/ /* Check to see if this is ludicrous -- if we just announced position, don't do it again*/
time(&now); time(&now);
if ( (now - qe->last_pos) < 15 ) if ((now - qe->last_pos) < 15)
return 0; return 0;
/* If either our position has changed, or we are over the freq timer, say position */ /* If either our position has changed, or we are over the freq timer, say position */
if ( (qe->last_pos_said == qe->pos) && ((now - qe->last_pos) < qe->parent->announcefrequency) ) if ((qe->last_pos_said == qe->pos) && ((now - qe->last_pos) < qe->parent->announcefrequency))
return 0; return 0;
ast_moh_stop(qe->chan); ast_moh_stop(qe->chan);
@ -1276,14 +1265,14 @@ static int say_position(struct queue_ent *qe)
goto playout; goto playout;
} }
/* Round hold time to nearest minute */ /* Round hold time to nearest minute */
avgholdmins = abs(( (qe->parent->holdtime + 30) - (now - qe->start) ) / 60); avgholdmins = abs(((qe->parent->holdtime + 30) - (now - qe->start)) / 60);
/* If they have specified a rounding then round the seconds as well */ /* If they have specified a rounding then round the seconds as well */
if(qe->parent->roundingseconds) { if (qe->parent->roundingseconds) {
avgholdsecs = (abs(( (qe->parent->holdtime + 30) - (now - qe->start) )) - 60 * avgholdmins) / qe->parent->roundingseconds; avgholdsecs = (abs(((qe->parent->holdtime + 30) - (now - qe->start))) - 60 * avgholdmins) / qe->parent->roundingseconds;
avgholdsecs*= qe->parent->roundingseconds; avgholdsecs *= qe->parent->roundingseconds;
} else { } else {
avgholdsecs=0; avgholdsecs = 0;
} }
if (option_verbose > 2) if (option_verbose > 2)
@ -1297,17 +1286,17 @@ static int say_position(struct queue_ent *qe)
if (res && valid_exit(qe, res)) if (res && valid_exit(qe, res))
goto playout; goto playout;
if (avgholdmins>0) { if (avgholdmins > 0) {
if (avgholdmins < 2) { if (avgholdmins < 2) {
res = play_file(qe->chan, qe->parent->sound_lessthan); res = play_file(qe->chan, qe->parent->sound_lessthan);
if (res && valid_exit(qe, res)) if (res && valid_exit(qe, res))
goto playout; goto playout;
res = ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, (char *)NULL); res = ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, NULL);
if (res && valid_exit(qe, res)) if (res && valid_exit(qe, res))
goto playout; goto playout;
} else { } else {
res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, (char*) NULL); res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL);
if (res && valid_exit(qe, res)) if (res && valid_exit(qe, res))
goto playout; goto playout;
} }
@ -1317,7 +1306,7 @@ static int say_position(struct queue_ent *qe)
goto playout; goto playout;
} }
if (avgholdsecs>0) { if (avgholdsecs>0) {
res = ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, (char*) NULL); res = ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL);
if (res && valid_exit(qe, res)) if (res && valid_exit(qe, res))
goto playout; goto playout;
@ -1373,14 +1362,12 @@ static void leave_queue(struct queue_ent *qe)
struct queue_ent *cur, *prev = NULL; struct queue_ent *cur, *prev = NULL;
int pos = 0; int pos = 0;
q = qe->parent; if (!(q = qe->parent))
if (!q)
return; return;
ast_mutex_lock(&q->lock); ast_mutex_lock(&q->lock);
prev = NULL; prev = NULL;
cur = q->head; for (cur = q->head; cur; cur = cur->next) {
while(cur) {
if (cur == qe) { if (cur == qe) {
q->count--; q->count--;
@ -1400,9 +1387,9 @@ static void leave_queue(struct queue_ent *qe)
cur->pos = ++pos; cur->pos = ++pos;
prev = cur; prev = cur;
} }
cur = cur->next;
} }
ast_mutex_unlock(&q->lock); ast_mutex_unlock(&q->lock);
if (q->dead && !q->count) { if (q->dead && !q->count) {
/* It's dead and nobody is in it, so kill it */ /* It's dead and nobody is in it, so kill it */
AST_LIST_LOCK(&queues); AST_LIST_LOCK(&queues);
@ -1417,12 +1404,12 @@ static void hangupcalls(struct callattempt *outgoing, struct ast_channel *except
{ {
struct callattempt *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->q_next; outgoing = outgoing->q_next;
free(oo); free(oo);
} }
} }
@ -1435,7 +1422,9 @@ static int update_status(struct ast_call_queue *q, struct member *member, int st
be sure it's still valid */ be sure it's still valid */
ast_mutex_lock(&q->lock); ast_mutex_lock(&q->lock);
for (cur = q->members; cur; cur = cur->next) { for (cur = q->members; cur; cur = cur->next) {
if (member == cur) { if (member != cur)
continue;
cur->status = status; cur->status = status;
if (!q->maskmemberstatus) { if (!q->maskmemberstatus) {
manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus", manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
@ -1450,8 +1439,6 @@ static int update_status(struct ast_call_queue *q, struct member *member, int st
q->name, cur->interface, cur->dynamic ? "dynamic" : "static", q->name, cur->interface, cur->dynamic ? "dynamic" : "static",
cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused); cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
} }
break;
}
} }
ast_mutex_unlock(&q->lock); ast_mutex_unlock(&q->lock);
return 0; return 0;
@ -1486,7 +1473,9 @@ static int compare_weight(struct ast_call_queue *rq, struct member *member)
ast_mutex_lock(&q->lock); ast_mutex_lock(&q->lock);
if (q->count && q->members) { if (q->count && q->members) {
for (mem = q->members; mem; mem = mem->next) { for (mem = q->members; mem; mem = mem->next) {
if (!strcmp(mem->interface, member->interface)) { if (strcmp(mem->interface, member->interface))
continue;
ast_log(LOG_DEBUG, "Found matching member %s in queue '%s'\n", mem->interface, q->name); ast_log(LOG_DEBUG, "Found matching member %s in queue '%s'\n", mem->interface, q->name);
if (q->weight > rq->weight) { if (q->weight > rq->weight) {
ast_log(LOG_DEBUG, "Queue '%s' (weight %d, calls %d) is preferred over '%s' (weight %d, calls %d)\n", q->name, q->weight, q->count, rq->name, rq->weight, rq->count); ast_log(LOG_DEBUG, "Queue '%s' (weight %d, calls %d) is preferred over '%s' (weight %d, calls %d)\n", q->name, q->weight, q->count, rq->name, rq->weight, rq->count);
@ -1495,7 +1484,6 @@ static int compare_weight(struct ast_call_queue *rq, struct member *member)
} }
} }
} }
}
ast_mutex_unlock(&q->lock); ast_mutex_unlock(&q->lock);
if (found) if (found)
break; break;
@ -1564,9 +1552,6 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
/* Request the peer */ /* Request the peer */
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
ast_log(LOG_NOTICE, "Unable to create channel of type '%s' for Queue\n", cur->tech);
#endif
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;
@ -1596,8 +1581,7 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
tmp->chan->adsicpe = qe->chan->adsicpe; tmp->chan->adsicpe = qe->chan->adsicpe;
/* Place the call, but don't wait on the answer */ /* Place the call, but don't wait on the answer */
res = ast_call(tmp->chan, location, 0); if ((res = ast_call(tmp->chan, location, 0))) {
if (res) {
/* Again, keep going even if there's an error */ /* Again, keep going even if there's an error */
if (option_debug) if (option_debug)
ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res); ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
@ -1624,6 +1608,7 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
if (option_verbose > 2) if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", tmp->interface); ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", tmp->interface);
} }
return 1; return 1;
} }
@ -1639,6 +1624,7 @@ static struct callattempt *find_best(struct callattempt *outgoing)
best = cur; best = cur;
} }
} }
return best; return best;
} }
@ -1672,6 +1658,7 @@ static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *bus
if (best->chan) /* break out with result = 1 */ if (best->chan) /* break out with result = 1 */
ret = 1; ret = 1;
} }
return ret; return ret;
} }
@ -1695,6 +1682,7 @@ static int store_next(struct queue_ent *qe, struct callattempt *outgoing)
} }
} }
qe->parent->wrapped = 0; qe->parent->wrapped = 0;
return 0; return 0;
} }
@ -1713,15 +1701,8 @@ static int background_file(struct queue_ent *qe, struct ast_channel *chan, char
/* Stop playback */ /* Stop playback */
ast_stopstream(chan); ast_stopstream(chan);
} else {
res = 0;
} }
/*if (res) {
ast_log(LOG_WARNING, "ast_streamfile failed on %s \n", chan->name);
res = 0;
}*/
return res; return res;
} }
@ -1782,7 +1763,6 @@ static void record_abandoned(struct queue_ent *qe)
/*! \brief RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer. */ /*! \brief RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer. */
static void rna(int rnatime, struct queue_ent *qe, char *membername) static void rna(int rnatime, struct queue_ent *qe, char *membername)
{ {
if (option_verbose > 2) if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", rnatime); ast_verbose( VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", rnatime);
ast_queue_log(qe->parent->name, qe->chan->uniqueid, membername, "RINGNOANSWER", "%d", rnatime); ast_queue_log(qe->parent->name, qe->chan->uniqueid, membername, "RINGNOANSWER", "%d", rnatime);
@ -1818,7 +1798,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
long starttime = 0; long starttime = 0;
long endtime = 0; long endtime = 0;
starttime = (long)time(NULL); starttime = (long) time(NULL);
while(*to && !peer) { while(*to && !peer) {
int numlines, retry, pos = 1; int numlines, retry, pos = 1;
@ -1863,9 +1843,10 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
} else if (o->chan && (o->chan == winner)) { } else if (o->chan && (o->chan == winner)) {
ast_copy_string(on, o->member->interface, sizeof(on)); ast_copy_string(on, o->member->interface, sizeof(on));
if (!ast_strlen_zero(o->chan->call_forward)) { if (!ast_strlen_zero(o->chan->call_forward)) {
char tmpchan[256]=""; char tmpchan[256];
char *stuff; char *stuff;
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';
@ -1979,9 +1960,8 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
} }
ast_frfree(f); ast_frfree(f);
} else { } else {
endtime = (long)time(NULL); endtime = (long) time(NULL) - starttime;
endtime -= starttime; rna(endtime * 1000, qe, on);
rna(endtime*1000, qe, on);
do_hang(o); do_hang(o);
if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) { if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
if (qe->parent->timeoutrestart) if (qe->parent->timeoutrestart)
@ -1993,15 +1973,9 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
} }
if (winner == in) { if (winner == in) {
f = ast_read(in); f = ast_read(in);
#if 0
if (f && (f->frametype != AST_FRAME_VOICE))
printf("Frame type: %d, %d\n", f->frametype, f->subclass);
else if (!f || (f->frametype != AST_FRAME_VOICE))
printf("Hangup received on %s\n", in->name);
#endif
if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) { if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
/* Got hung up */ /* Got hung up */
*to=-1; *to = -1;
if (f) if (f)
ast_frfree(f); ast_frfree(f);
return NULL; return NULL;
@ -2009,15 +1983,15 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass == '*')) { if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass == '*')) {
if (option_verbose > 3) if (option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass); ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
*to=0; *to = 0;
ast_frfree(f); ast_frfree(f);
return NULL; return NULL;
} }
if ((f->frametype == AST_FRAME_DTMF) && (f->subclass != '*') && valid_exit(qe, f->subclass)) { if ((f->frametype == AST_FRAME_DTMF) && (f->subclass != '*') && valid_exit(qe, f->subclass)) {
if (option_verbose > 3) if (option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_3 "User pressed digit: %c\n", f->subclass); ast_verbose(VERBOSE_PREFIX_3 "User pressed digit: %c\n", f->subclass);
*to=0; *to = 0;
*digit=f->subclass; *digit = f->subclass;
ast_frfree(f); ast_frfree(f);
return NULL; return NULL;
} }
@ -2028,7 +2002,6 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
} }
return peer; return peer;
} }
static int is_our_turn(struct queue_ent *qe) static int is_our_turn(struct queue_ent *qe)
@ -2054,29 +2027,27 @@ static int is_our_turn(struct queue_ent *qe)
} }
} else { } else {
/* This needs a lock. How many members are available to be served? */ /* This needs a lock. How many members are available to be served? */
ast_mutex_lock(&qe->parent->lock); ast_mutex_lock(&qe->parent->lock);
ch = qe->parent->head; ch = qe->parent->head;
cur = qe->parent->members;
if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
if (option_debug)
ast_log(LOG_DEBUG, "Even though there are %d available members, the strategy is ringall so only the head call is allowed in\n", avl);
avl = 1;
} else {
cur = qe->parent->members;
while (cur) { while (cur) {
if (cur->status == 1) if (cur->status == 1)
avl++; avl++;
cur = cur->next; cur = cur->next;
} }
}
if (option_debug) if (option_debug)
ast_log(LOG_DEBUG, "There are %d available members.\n", avl); ast_log(LOG_DEBUG, "There are %d available members.\n", avl);
if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
if (option_debug)
ast_log(LOG_DEBUG, "Even though there are %d available members, the strategy is ringall so only the head call is allowed in!\n", avl);
avl = 1;
}
while ((idx < avl) && (ch) && (ch != qe)) { while ((idx < avl) && (ch) && (ch != qe)) {
idx++; idx++;
ch = ch->next; ch = ch->next;
@ -2149,6 +2120,7 @@ static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *r
if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000)))
break; break;
} }
return res; return res;
} }
@ -2231,7 +2203,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, const char *agi) static int try_calling(struct queue_ent *qe, const char *options, char *announceoverride, const char *url, int *go_on, const char *agi)
{ {
struct member *cur; struct member *cur;
struct callattempt *outgoing=NULL; /* the queue we are building */ struct callattempt *outgoing = NULL; /* the list of calls we are building */
int to; int to;
char oldexten[AST_MAX_EXTENSION]=""; char oldexten[AST_MAX_EXTENSION]="";
char oldcontext[AST_MAX_CONTEXT]=""; char oldcontext[AST_MAX_CONTEXT]="";
@ -2261,7 +2233,6 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
struct ast_app *mixmonapp = NULL; struct ast_app *mixmonapp = NULL;
char *p; char *p;
memset(&bridge_config, 0, sizeof(bridge_config)); memset(&bridge_config, 0, sizeof(bridge_config));
time(&now); time(&now);
@ -2308,8 +2279,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;
for (;cur; cur = cur->next) { for (; cur; cur = cur->next) {
struct callattempt *tmp = ast_calloc(1, sizeof(*tmp)); struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
if (!tmp) { if (!tmp) {
ast_mutex_unlock(&qe->parent->lock); ast_mutex_unlock(&qe->parent->lock);
if (use_weight) if (use_weight)
@ -2317,13 +2289,6 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
goto out; goto out;
} }
tmp->stillgoing = -1; tmp->stillgoing = -1;
if (option_debug) {
if (url)
ast_log(LOG_DEBUG, "Queue with URL=%s_\n", url);
else
ast_log(LOG_DEBUG, "Simple queue (no URL)\n");
}
tmp->member = cur; /* Never directly dereference! Could change on reload */ tmp->member = cur; /* Never directly dereference! Could change on reload */
tmp->oldstatus = cur->status; tmp->oldstatus = cur->status;
tmp->lastcall = cur->lastcall; tmp->lastcall = cur->lastcall;
@ -2383,6 +2348,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
outgoing = NULL; outgoing = NULL;
if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) { if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) {
int res2; int res2;
res2 = ast_autoservice_start(qe->chan); res2 = ast_autoservice_start(qe->chan);
if (!res2) { if (!res2) {
if (qe->parent->memberdelay) { if (qe->parent->memberdelay) {
@ -2514,14 +2480,13 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
} }
if (!monitor_options) if (!monitor_options)
monitor_options = ast_strdupa(""); monitor_options = "";
if (strchr(monitor_options, '|')) { if (strchr(monitor_options, '|')) {
ast_log(LOG_WARNING, "MONITOR_OPTIONS cannot contain a '|'! Not recording.\n"); ast_log(LOG_WARNING, "MONITOR_OPTIONS cannot contain a '|'! Not recording.\n");
mixmonapp = NULL; mixmonapp = NULL;
} }
if (mixmonapp) { if (mixmonapp) {
if (!ast_strlen_zero(monitor_exec) && !ast_strlen_zero(monitor_options)) if (!ast_strlen_zero(monitor_exec) && !ast_strlen_zero(monitor_options))
snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s|%s", tmpid2, monitor_options, monitor_exec); snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s|%s", tmpid2, monitor_options, monitor_exec);
@ -2567,7 +2532,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
"Holdtime: %ld\r\n" "Holdtime: %ld\r\n"
"BridgedChannel: %s\r\n", "BridgedChannel: %s\r\n",
queuename, qe->chan->uniqueid, peer->name, member->interface, queuename, qe->chan->uniqueid, peer->name, member->interface,
(long)time(NULL) - qe->start,peer->uniqueid); (long) time(NULL) - qe->start,peer->uniqueid);
ast_copy_string(oldcontext, qe->chan->context, sizeof(oldcontext)); ast_copy_string(oldcontext, qe->chan->context, sizeof(oldcontext));
ast_copy_string(oldexten, qe->chan->exten, sizeof(oldexten)); ast_copy_string(oldexten, qe->chan->exten, sizeof(oldexten));
time(&callstart); time(&callstart);
@ -2576,10 +2541,11 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) { if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) {
ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "TRANSFER", "%s|%s|%ld|%ld", ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "TRANSFER", "%s|%s|%ld|%ld",
qe->chan->exten, qe->chan->context, (long)(callstart - qe->start), (long)(time(NULL) - callstart)); qe->chan->exten, qe->chan->context, (long) (callstart - qe->start),
(long) (time(NULL) - callstart));
} else if (qe->chan->_softhangup) { } else if (qe->chan->_softhangup) {
ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "COMPLETECALLER", "%ld|%ld", ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "COMPLETECALLER", "%ld|%ld",
(long)(callstart - qe->start), (long)(time(NULL) - callstart)); (long) (callstart - qe->start), (long) (time(NULL) - callstart));
if (qe->parent->eventwhencalled) if (qe->parent->eventwhencalled)
manager_event(EVENT_FLAG_AGENT, "AgentComplete", manager_event(EVENT_FLAG_AGENT, "AgentComplete",
"Queue: %s\r\n" "Queue: %s\r\n"
@ -2590,9 +2556,10 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
"TalkTime: %ld\r\n" "TalkTime: %ld\r\n"
"Reason: caller\r\n", "Reason: caller\r\n",
queuename, qe->chan->uniqueid, peer->name, member->interface, queuename, qe->chan->uniqueid, peer->name, member->interface,
(long)(callstart - qe->start), (long)(time(NULL) - callstart)); (long) (callstart - qe->start), (long) (time(NULL) - callstart));
} else { } else {
ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "COMPLETEAGENT", "%ld|%ld", (long)(callstart - qe->start), (long)(time(NULL) - callstart)); ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "COMPLETEAGENT", "%ld|%ld",
(long) (callstart - qe->start), (long) (time(NULL) - callstart));
if (qe->parent->eventwhencalled) if (qe->parent->eventwhencalled)
manager_event(EVENT_FLAG_AGENT, "AgentComplete", manager_event(EVENT_FLAG_AGENT, "AgentComplete",
"Queue: %s\r\n" "Queue: %s\r\n"
@ -2602,7 +2569,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
"TalkTime: %ld\r\n" "TalkTime: %ld\r\n"
"Reason: agent\r\n", "Reason: agent\r\n",
queuename, qe->chan->uniqueid, peer->name, (long)(callstart - qe->start), queuename, qe->chan->uniqueid, peer->name, (long)(callstart - qe->start),
(long)(time(NULL) - callstart)); (long) (time(NULL) - callstart));
} }
if (bridge != AST_PBX_NO_HANGUP_PEER) if (bridge != AST_PBX_NO_HANGUP_PEER)
@ -2612,6 +2579,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
} }
out: out:
hangupcalls(outgoing, NULL); hangupcalls(outgoing, NULL);
return res; return res;
} }
@ -2627,10 +2595,13 @@ static struct member * interface_exists(struct ast_call_queue *q, char *interfac
{ {
struct member *mem; struct member *mem;
if (q) if (!q)
for (mem = q->members; mem; mem = mem->next) return NULL;
for (mem = q->members; mem; mem = mem->next) {
if (!strcasecmp(interface, mem->interface)) if (!strcasecmp(interface, mem->interface))
return mem; return mem;
}
return NULL; return NULL;
} }
@ -2684,7 +2655,11 @@ static int remove_from_queue(char *queuename, char *interface)
AST_LIST_LOCK(&queues); AST_LIST_LOCK(&queues);
AST_LIST_TRAVERSE(&queues, q, list) { AST_LIST_TRAVERSE(&queues, q, list) {
ast_mutex_lock(&q->lock); ast_mutex_lock(&q->lock);
if (!strcmp(q->name, queuename)) { if (strcmp(q->name, queuename)) {
ast_mutex_unlock(&q->lock);
continue;
}
if ((last_member = interface_exists(q, interface))) { if ((last_member = interface_exists(q, interface))) {
if ((look = q->members) == last_member) { if ((look = q->members) == last_member) {
q->members = last_member->next; q->members = last_member->next;
@ -2714,12 +2689,12 @@ static int remove_from_queue(char *queuename, char *interface)
ast_mutex_unlock(&q->lock); ast_mutex_unlock(&q->lock);
break; break;
} }
ast_mutex_unlock(&q->lock);
} if (res == RES_OKAY)
if (res == RES_OKAY) {
remove_from_interfaces(interface); remove_from_interfaces(interface);
}
AST_LIST_UNLOCK(&queues); AST_LIST_UNLOCK(&queues);
return res; return res;
} }
@ -2732,19 +2707,15 @@ static int add_to_queue(char *queuename, char *interface, int penalty, int pause
/* \note Ensure the appropriate realtime queue is loaded. Note that this /* \note Ensure the appropriate realtime queue is loaded. Note that this
* short-circuits if the queue is already in memory. */ * short-circuits if the queue is already in memory. */
q = load_realtime_queue(queuename); if (!(q = load_realtime_queue(queuename)))
return res;
AST_LIST_LOCK(&queues); AST_LIST_LOCK(&queues);
if (q) {
ast_mutex_lock(&q->lock); ast_mutex_lock(&q->lock);
if (interface_exists(q, interface) == NULL) { if (interface_exists(q, interface) == NULL) {
add_to_interfaces(interface); add_to_interfaces(interface);
if ((new_member = create_queue_member(interface, penalty, paused))) {
new_member = create_queue_member(interface, penalty, paused);
if (new_member != NULL) {
new_member->dynamic = 1; new_member->dynamic = 1;
new_member->next = q->members; new_member->next = q->members;
q->members = new_member; q->members = new_member;
@ -2758,7 +2729,8 @@ static int add_to_queue(char *queuename, char *interface, int penalty, int pause
"Status: %d\r\n" "Status: %d\r\n"
"Paused: %d\r\n", "Paused: %d\r\n",
q->name, new_member->interface, new_member->dynamic ? "dynamic" : "static", q->name, new_member->interface, new_member->dynamic ? "dynamic" : "static",
new_member->penalty, new_member->calls, (int)new_member->lastcall, new_member->status, new_member->paused); new_member->penalty, new_member->calls, (int) new_member->lastcall,
new_member->status, new_member->paused);
if (dump) if (dump)
dump_queue_members(q); dump_queue_members(q);
@ -2771,8 +2743,8 @@ static int add_to_queue(char *queuename, char *interface, int penalty, int pause
res = RES_EXISTS; res = RES_EXISTS;
} }
ast_mutex_unlock(&q->lock); ast_mutex_unlock(&q->lock);
}
AST_LIST_UNLOCK(&queues); AST_LIST_UNLOCK(&queues);
return res; return res;
} }
@ -2813,10 +2785,7 @@ static int set_member_paused(char *queuename, char *interface, int paused)
} }
AST_LIST_UNLOCK(&queues); AST_LIST_UNLOCK(&queues);
if (found) return found ? RESULT_SUCCESS : RESULT_FAILURE;
return RESULT_SUCCESS;
else
return RESULT_FAILURE;
} }
/* Reload dynamic queue members persisted into the astdb */ /* Reload dynamic queue members persisted into the astdb */
@ -2956,6 +2925,7 @@ static int pqm_exec(struct ast_channel *chan, void *data)
LOCAL_USER_REMOVE(lu); LOCAL_USER_REMOVE(lu);
pbx_builtin_setvar_helper(chan, "PQMSTATUS", "PAUSED"); pbx_builtin_setvar_helper(chan, "PQMSTATUS", "PAUSED");
return 0; return 0;
} }
@ -3008,6 +2978,7 @@ static int upqm_exec(struct ast_channel *chan, void *data)
LOCAL_USER_REMOVE(lu); LOCAL_USER_REMOVE(lu);
pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "UNPAUSED"); pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "UNPAUSED");
return 0; return 0;
} }
@ -3071,6 +3042,7 @@ static int rqm_exec(struct ast_channel *chan, void *data)
} }
LOCAL_USER_REMOVE(lu); LOCAL_USER_REMOVE(lu);
return res; return res;
} }
@ -3143,6 +3115,7 @@ static int aqm_exec(struct ast_channel *chan, void *data)
} }
LOCAL_USER_REMOVE(lu); LOCAL_USER_REMOVE(lu);
return res; return res;
} }
@ -3156,10 +3129,8 @@ static int queue_exec(struct ast_channel *chan, void *data)
int prio; int prio;
int max_penalty; int max_penalty;
enum queue_result reason = QUEUE_UNKNOWN; enum queue_result reason = QUEUE_UNKNOWN;
/* whether to exit Queue application after the timeout hits */ /* whether to exit Queue application after the timeout hits */
int go_on = 0; int go_on = 0;
char *parse; char *parse;
AST_DECLARE_APP_ARGS(args, AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(queuename); AST_APP_ARG(queuename);
@ -3169,7 +3140,6 @@ static int queue_exec(struct ast_channel *chan, void *data)
AST_APP_ARG(queuetimeoutstr); AST_APP_ARG(queuetimeoutstr);
AST_APP_ARG(agi); AST_APP_ARG(agi);
); );
/* Our queue entry */ /* Our queue entry */
struct queue_ent qe; struct queue_ent qe;
@ -3257,7 +3227,8 @@ check_turns:
if (res < 0) { if (res < 0) {
/* Record this abandoned call */ /* Record this abandoned call */
record_abandoned(&qe); record_abandoned(&qe);
ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ABANDON", "%d|%d|%ld", qe.pos, qe.opos, (long)time(NULL) - qe.start); ast_queue_log(args.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 from queue %s while waiting their turn\n", args.queuename); ast_verbose(VERBOSE_PREFIX_3 "User disconnected from queue %s while waiting their turn\n", args.queuename);
} }
@ -3273,6 +3244,7 @@ check_turns:
} }
if (!res) { if (!res) {
int makeannouncement = 0; int makeannouncement = 0;
for (;;) { for (;;) {
/* This is the wait loop for the head caller*/ /* This is the wait loop for the head caller*/
/* To exit, they may get their call answered; */ /* To exit, they may get their call answered; */
@ -3314,10 +3286,13 @@ check_turns:
if (res < 0) { if (res < 0) {
if (!qe.handled) { if (!qe.handled) {
record_abandoned(&qe); record_abandoned(&qe);
ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ABANDON", "%d|%d|%ld", qe.pos, qe.opos, (long)time(NULL) - qe.start); ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ABANDON",
"%d|%d|%ld", qe.pos, qe.opos,
(long) time(NULL) - qe.start);
} }
} else if (valid_exit(&qe, res)) { } else if (valid_exit(&qe, res)) {
ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%s|%d", qe.digits, qe.pos); ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHKEY",
"%s|%d", qe.digits, qe.pos);
} }
break; break;
} }
@ -3405,6 +3380,7 @@ check_turns:
res = 0; res = 0;
} }
LOCAL_USER_REMOVE(lu); LOCAL_USER_REMOVE(lu);
return res; return res;
} }
@ -3425,15 +3401,12 @@ static int queue_function_qac(struct ast_channel *chan, char *cmd, char *data, c
LOCAL_USER_ADD(lu); LOCAL_USER_ADD(lu);
AST_LIST_LOCK(&queues); AST_LIST_LOCK(&queues);
/* Find the right queue */
AST_LIST_TRAVERSE(&queues, q, list) { AST_LIST_TRAVERSE(&queues, q, list) {
if (!strcasecmp(q->name, data)) { if (!strcasecmp(q->name, data)) {
ast_mutex_lock(&q->lock); ast_mutex_lock(&q->lock);
break; break;
} }
} }
AST_LIST_UNLOCK(&queues); AST_LIST_UNLOCK(&queues);
if (q) { if (q) {
@ -3449,6 +3422,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(lu); LOCAL_USER_REMOVE(lu);
return 0; return 0;
} }
@ -3468,15 +3442,12 @@ static int queue_function_queuewaitingcount(struct ast_channel *chan, char *cmd,
LOCAL_USER_ADD(lu); LOCAL_USER_ADD(lu);
AST_LIST_LOCK(&queues); AST_LIST_LOCK(&queues);
/* Find the right queue */
AST_LIST_TRAVERSE(&queues, q, list) { AST_LIST_TRAVERSE(&queues, q, list) {
if (!strcasecmp(q->name, data)) { if (!strcasecmp(q->name, data)) {
ast_mutex_lock(&q->lock); ast_mutex_lock(&q->lock);
break; break;
} }
} }
AST_LIST_UNLOCK(&queues); AST_LIST_UNLOCK(&queues);
if (q) { if (q) {
@ -3507,19 +3478,17 @@ static int queue_function_queuememberlist(struct ast_channel *chan, char *cmd, c
LOCAL_USER_ADD(u); LOCAL_USER_ADD(u);
AST_LIST_LOCK(&queues); AST_LIST_LOCK(&queues);
/* Find the right queue */
AST_LIST_TRAVERSE(&queues, q, list) { AST_LIST_TRAVERSE(&queues, q, list) {
if (!strcasecmp(q->name, data)) { if (!strcasecmp(q->name, data)) {
ast_mutex_lock(&q->lock); ast_mutex_lock(&q->lock);
break; break;
} }
} }
AST_LIST_UNLOCK(&queues); AST_LIST_UNLOCK(&queues);
if (q) { if (q) {
int buflen = 0, count = 0; int buflen = 0, count = 0;
for (m = q->members; m; m = m->next) { for (m = q->members; m; m = m->next) {
/* strcat() is always faster than printf() */ /* strcat() is always faster than printf() */
if (count++) { if (count++) {
@ -3541,6 +3510,7 @@ static int queue_function_queuememberlist(struct ast_channel *chan, char *cmd, c
/* We should already be terminated, but let's make sure. */ /* We should already be terminated, but let's make sure. */
buf[len - 1] = '\0'; buf[len - 1] = '\0';
LOCAL_USER_REMOVE(u); LOCAL_USER_REMOVE(u);
return 0; return 0;
} }
@ -3593,8 +3563,7 @@ static void reload_queues(void)
char interface[80]; char interface[80];
int penalty; int penalty;
cfg = ast_config_load("queues.conf"); if (!(cfg = ast_config_load("queues.conf"))) {
if (!cfg) {
ast_log(LOG_NOTICE, "No call queueing config file (queues.conf), so no call queues\n"); ast_log(LOG_NOTICE, "No call queueing config file (queues.conf), so no call queues\n");
return; return;
} }
@ -3602,9 +3571,9 @@ static void reload_queues(void)
AST_LIST_LOCK(&queues); AST_LIST_LOCK(&queues);
use_weight=0; use_weight=0;
/* Mark all queues as dead for the moment */ /* Mark all queues as dead for the moment */
AST_LIST_TRAVERSE(&queues, q, list) { AST_LIST_TRAVERSE(&queues, q, list)
q->dead = 1; q->dead = 1;
}
/* Chug through config file */ /* Chug through config file */
cat = NULL; cat = NULL;
while ((cat = ast_category_browse(cfg, cat)) ) { while ((cat = ast_category_browse(cfg, cat)) ) {
@ -3791,11 +3760,12 @@ static int __queues_show(struct mansession *s, int manager, int fd, int argc, ch
else else
ast_build_string(&max, &max_left, "unlimited"); ast_build_string(&max, &max_left, "unlimited");
sl = 0; sl = 0;
if(q->callscompleted > 0) if (q->callscompleted > 0)
sl = 100*((float)q->callscompletedinsl/(float)q->callscompleted); sl = 100 * ((float) q->callscompletedinsl / (float) q->callscompleted);
if (s) if (s)
astman_append(s, "%-12.12s has %d calls (max %s) in '%s' strategy (%ds holdtime), W:%d, C:%d, A:%d, SL:%2.1f%% within %ds%s", astman_append(s, "%-12.12s has %d calls (max %s) in '%s' strategy (%ds holdtime), W:%d, C:%d, A:%d, SL:%2.1f%% within %ds%s",
q->name, q->count, max_buf, int2strat(q->strategy), q->holdtime, q->weight, q->callscompleted, q->callsabandoned,sl,q->servicelevel, term); q->name, q->count, max_buf, int2strat(q->strategy), q->holdtime, q->weight,
q->callscompleted, q->callsabandoned,sl,q->servicelevel, term);
else else
ast_cli(fd, "%-12.12s has %d calls (max %s) in '%s' strategy (%ds holdtime), W:%d, C:%d, A:%d, SL:%2.1f%% within %ds%s", ast_cli(fd, "%-12.12s has %d calls (max %s) in '%s' strategy (%ds holdtime), W:%d, C:%d, A:%d, SL:%2.1f%% within %ds%s",
q->name, q->count, max_buf, int2strat(q->strategy), q->holdtime, q->weight, q->callscompleted, q->callsabandoned,sl,q->servicelevel, term); q->name, q->count, max_buf, int2strat(q->strategy), q->holdtime, q->weight, q->callscompleted, q->callsabandoned,sl,q->servicelevel, term);
@ -3817,7 +3787,7 @@ static int __queues_show(struct mansession *s, int manager, int fd, int argc, ch
ast_build_string(&max, &max_left, " (%s)", devstate2str(mem->status)); ast_build_string(&max, &max_left, " (%s)", devstate2str(mem->status));
if (mem->calls) { if (mem->calls) {
ast_build_string(&max, &max_left, " has taken %d calls (last was %ld secs ago)", ast_build_string(&max, &max_left, " has taken %d calls (last was %ld secs ago)",
mem->calls, (long)(time(NULL) - mem->lastcall)); mem->calls, (long) (time(NULL) - mem->lastcall));
} else } else
ast_build_string(&max, &max_left, " has taken no calls yet"); ast_build_string(&max, &max_left, " has taken no calls yet");
if (s) if (s)
@ -3837,11 +3807,13 @@ static int __queues_show(struct mansession *s, int manager, int fd, int argc, ch
ast_cli(fd, " Callers: %s", term); ast_cli(fd, " Callers: %s", term);
for (qe = q->head; qe; qe = qe->next) { for (qe = q->head; qe; qe = qe->next) {
if (s) if (s)
astman_append(s, " %d. %s (wait: %ld:%2.2ld, prio: %d)%s", pos++, qe->chan->name, astman_append(s, " %d. %s (wait: %ld:%2.2ld, prio: %d)%s",
(long)(now - qe->start) / 60, (long)(now - qe->start) % 60, qe->prio, term); pos++, qe->chan->name, (long) (now - qe->start) / 60,
(long) (now - qe->start) % 60, qe->prio, term);
else else
ast_cli(fd, " %d. %s (wait: %ld:%2.2ld, prio: %d)%s", pos++, qe->chan->name, ast_cli(fd, " %d. %s (wait: %ld:%2.2ld, prio: %d)%s", pos++,
(long)(now - qe->start) / 60, (long)(now - qe->start) % 60, qe->prio, term); qe->chan->name, (long) (now - qe->start) / 60,
(long) (now - qe->start) % 60, qe->prio, term);
} }
} else if (s) } else if (s)
astman_append(s, " No Callers%s", term); astman_append(s, " No Callers%s", term);
@ -3894,6 +3866,7 @@ static char *complete_queue(const char *line, const char *word, int pos, int sta
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" };
__queues_show(s, 1, -1, 2, a, 0); __queues_show(s, 1, -1, 2, a, 0);
astman_append(s, "\r\n\r\n"); /* Properly terminate Manager output */ astman_append(s, "\r\n\r\n"); /* Properly terminate Manager output */
@ -3917,16 +3890,16 @@ static int manager_queues_status( struct mansession *s, struct message *m )
astman_send_ack(s, m, "Queue status will follow"); astman_send_ack(s, m, "Queue status will follow");
time(&now); time(&now);
AST_LIST_LOCK(&queues); AST_LIST_LOCK(&queues);
if (!ast_strlen_zero(id)) { if (!ast_strlen_zero(id))
snprintf(idText,256,"ActionID: %s\r\n",id); snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
}
AST_LIST_TRAVERSE(&queues, q, list) { AST_LIST_TRAVERSE(&queues, q, list) {
ast_mutex_lock(&q->lock); ast_mutex_lock(&q->lock);
/* List queue properties */ /* List queue properties */
if (ast_strlen_zero(queuefilter) || !strcmp(q->name, queuefilter)) { if (ast_strlen_zero(queuefilter) || !strcmp(q->name, queuefilter)) {
if(q->callscompleted > 0) if (q->callscompleted > 0)
sl = 100*((float)q->callscompletedinsl/(float)q->callscompleted); sl = 100 * ((float) q->callscompletedinsl / (float) q->callscompleted);
astman_append(s, "Event: QueueParams\r\n" astman_append(s, "Event: QueueParams\r\n"
"Queue: %s\r\n" "Queue: %s\r\n"
"Max: %d\r\n" "Max: %d\r\n"
@ -3974,7 +3947,7 @@ static int manager_queues_status( struct mansession *s, struct message *m )
q->name, pos++, qe->chan->name, q->name, pos++, qe->chan->name,
S_OR(qe->chan->cid.cid_num, "unknown"), S_OR(qe->chan->cid.cid_num, "unknown"),
S_OR(qe->chan->cid.cid_name, "unknown"), S_OR(qe->chan->cid.cid_name, "unknown"),
(long)(now - qe->start), idText); (long) (now - qe->start), idText);
} }
} }
ast_mutex_unlock(&q->lock); ast_mutex_unlock(&q->lock);
@ -4035,6 +4008,7 @@ static int manager_add_queue_member(struct mansession *s, struct message *m)
astman_send_error(s, m, "Out of memory"); astman_send_error(s, m, "Out of memory");
break; break;
} }
return 0; return 0;
} }
@ -4064,6 +4038,7 @@ static int manager_remove_queue_member(struct mansession *s, struct message *m)
astman_send_error(s, m, "Out of memory"); astman_send_error(s, m, "Out of memory");
break; break;
} }
return 0; return 0;
} }
@ -4223,6 +4198,7 @@ static char *complete_remove_queue_member(const char *line, const char *word, in
ast_mutex_unlock(&q->lock); ast_mutex_unlock(&q->lock);
} }
} }
return NULL; return NULL;
} }
@ -4260,7 +4236,6 @@ static int unload_module(void *mod)
{ {
int res; int res;
clear_and_free_interfaces();
res = ast_cli_unregister(&cli_show_queue); res = ast_cli_unregister(&cli_show_queue);
res |= ast_cli_unregister(&cli_show_queues); res |= ast_cli_unregister(&cli_show_queues);
res |= ast_cli_unregister(&cli_add_queue_member); res |= ast_cli_unregister(&cli_add_queue_member);
@ -4280,6 +4255,8 @@ static int unload_module(void *mod)
res |= ast_custom_function_unregister(&queuewaitingcount_function); res |= ast_custom_function_unregister(&queuewaitingcount_function);
res |= ast_unregister_application(app); res |= ast_unregister_application(app);
clear_and_free_interfaces();
STANDARD_HANGUP_LOCALUSERS; STANDARD_HANGUP_LOCALUSERS;
return res; return res;