diff options
author | Mark Spencer <markster@digium.com> | 2003-08-02 21:10:06 +0000 |
---|---|---|
committer | Mark Spencer <markster@digium.com> | 2003-08-02 21:10:06 +0000 |
commit | 1fb2eaabf39561a716a7201bbfbb734a381809ea (patch) | |
tree | c9af9a797a291625ccdeb296c413dbf36c469f55 /apps/app_queue.c | |
parent | 7ab4290896f657ef3363fe050e67b870be06815c (diff) |
Implement remaining queue strategies, ADSI fixes, and queue config updates
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@1252 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps/app_queue.c')
-rwxr-xr-x | apps/app_queue.c | 70 |
1 files changed, 57 insertions, 13 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c index 6fec751a2..cddf31165 100755 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -111,7 +111,6 @@ struct localuser { char numsubst[256]; char tech[40]; int stillgoing; - int penalty; int metric; int allowredirect_in; int allowredirect_out; @@ -119,6 +118,7 @@ struct localuser { int musiconhold; int dataquality; int allowdisconnect; + struct member *member; struct localuser *next; }; @@ -139,7 +139,8 @@ struct member { char tech[80]; /* Technology */ char loc[256]; /* Location */ int penalty; /* Are we a last resort? */ - struct timeval lastcall; /* When last successful call was hungup */ + int calls; + time_t lastcall; /* When last successful call was hungup */ struct member *next; /* Next member */ }; @@ -429,7 +430,7 @@ static int valid_exit(struct queue_ent *qe, char digit) #define MAX 256 -static struct ast_channel *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect, char *digit) +static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect, char *digit) { char *queue = qe->parent->name; struct localuser *o; @@ -439,7 +440,7 @@ static struct ast_channel *wait_for_answer(struct queue_ent *qe, struct localuse int numbusies = 0; int orig = *to; struct ast_frame *f; - struct ast_channel *peer = NULL; + struct localuser *peer = NULL; struct ast_channel *watchers[MAX]; int pos; struct ast_channel *winner; @@ -476,7 +477,7 @@ static struct ast_channel *wait_for_answer(struct queue_ent *qe, struct localuse if (!peer) { if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name); - peer = o->chan; + peer = o; *allowredir_in = o->allowredirect_in; *allowredir_out = o->allowredirect_out; *allowdisconnect = o->allowdisconnect; @@ -491,7 +492,7 @@ static struct ast_channel *wait_for_answer(struct queue_ent *qe, struct localuse if (!peer) { if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name); - peer = o->chan; + peer = o; *allowredir_in = o->allowredirect_in; *allowredir_out = o->allowredirect_out; *allowdisconnect = o->allowdisconnect; @@ -604,7 +605,26 @@ static int wait_our_turn(struct queue_ent *qe) return res; } -static int calc_metric(struct ast_call_queue *q, int pos, struct queue_ent *qe, struct localuser *tmp) +static int update_queue(struct ast_call_queue *q, struct localuser *user) +{ + struct member *cur; + /* Since a reload could have taken place, we have to traverse the list to + be sure it's still valid */ + ast_pthread_mutex_lock(&q->lock); + cur = q->members; + while(cur) { + if (user->member == cur) { + time(&cur->lastcall); + cur->calls++; + break; + } + cur = cur->next; + } + ast_pthread_mutex_unlock(&q->lock); + return 0; +} + +static int calc_metric(struct ast_call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct localuser *tmp) { switch (q->strategy) { case QUEUE_STRATEGY_RINGALL: @@ -626,11 +646,22 @@ static int calc_metric(struct ast_call_queue *q, int pos, struct queue_ent *qe, q->wrapped = 1; tmp->metric = pos; } - tmp->metric += tmp->penalty * 1000000; + tmp->metric += mem->penalty * 1000000; break; case QUEUE_STRATEGY_RANDOM: tmp->metric = rand() % 1000; - tmp->metric += tmp->penalty * 1000000; + tmp->metric += mem->penalty * 1000000; + break; + case QUEUE_STRATEGY_FEWESTCALLS: + tmp->metric = mem->calls; + tmp->metric += mem->penalty * 1000000; + break; + case QUEUE_STRATEGY_LEASTRECENT: + if (!mem->lastcall) + tmp->metric = 0; + else + tmp->metric = 1000000 - (time(NULL) - mem->lastcall); + tmp->metric += mem->penalty * 1000000; break; default: ast_log(LOG_WARNING, "Can't calculate metric for unknown strategy %d\n", q->strategy); @@ -650,6 +681,7 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri char restofit[AST_MAX_EXTENSION]; char *newnum; struct ast_channel *peer; + struct localuser *lpeer; int res = 0, bridge = 0; int zapx = 2; int x=0; @@ -690,9 +722,9 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri } else ast_log(LOG_DEBUG, "Simple queue (no URL)\n"); + tmp->member = cur; /* Never directly dereference! Could change on reload */ strncpy(tmp->tech, cur->tech, sizeof(tmp->tech)-1); strncpy(tmp->numsubst, cur->loc, sizeof(tmp->numsubst)-1); - tmp->penalty = cur->penalty; /* If we're dialing by extension, look at the extension to know what to dial */ if ((newnum = strstr(tmp->numsubst, "BYEXTENSION"))) { strncpy(restofit, newnum + strlen("BYEXTENSION"), sizeof(restofit)-1); @@ -705,7 +737,7 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri if (!qe->parent->strategy) ring_entry(qe, tmp); else - calc_metric(qe->parent, x++, qe, tmp); + calc_metric(qe->parent, cur, x++, qe, tmp); /* Put them in the list of outgoing thingies... We're ready now. XXX If we're forcibly removed, these outgoing calls won't get hung up XXX */ @@ -724,7 +756,11 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri if (qe->parent->strategy) ring_one(qe, outgoing); ast_pthread_mutex_unlock(&qe->parent->lock); - peer = wait_for_answer(qe, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect, &digit); + lpeer = wait_for_answer(qe, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect, &digit); + if (lpeer) + peer = lpeer->chan; + else + peer = NULL; if (!peer) { if (to) { /* Musta gotten hung up */ @@ -750,6 +786,8 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri if (tmp->dataquality) zapx = 0; ast_channel_setoption(peer,AST_OPTION_TONE_VERIFY,&zapx,sizeof(char),0); } + /* Update parameters for the queue */ + update_queue(qe->parent, lpeer); hanguptree(outgoing, peer); /* Stop music on hold */ ast_moh_stop(qe->chan); @@ -1270,6 +1308,7 @@ static int queues_show(int fd, int argc, char **argv) int pos; time_t now; char max[80]; + char calls[80]; time(&now); if (argc != 2) @@ -1293,7 +1332,12 @@ static int queues_show(int fd, int argc, char **argv) snprintf(max, sizeof(max), " with penalty %d", mem->penalty); else strcpy(max, ""); - ast_cli(fd, " %s/%s%s\n", mem->tech, mem->loc, max); + if (mem->calls) { + snprintf(calls, sizeof(calls), " has taken %d calls (last was %ld secs ago)", + mem->calls, time(NULL) - mem->lastcall); + } else + strcpy(calls, " has taken no calls yet"); + ast_cli(fd, " %s/%s%s%s\n", mem->tech, mem->loc, max, calls); } } else ast_cli(fd, " No Members\n"); |