From df31b25e4934a7363399e4418b4bfff75ce51f61 Mon Sep 17 00:00:00 2001 From: markster Date: Sat, 2 Aug 2003 21:10:06 +0000 Subject: Implement remaining queue strategies, ADSI fixes, and queue config updates git-svn-id: http://svn.digium.com/svn/asterisk/trunk@1252 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_queue.c | 70 +++++++++++++++++++++++++++++++++++++++++---------- apps/app_voicemail2.c | 31 ++++++++++++++++++++++- 2 files changed, 87 insertions(+), 14 deletions(-) (limited to 'apps') 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"); diff --git a/apps/app_voicemail2.c b/apps/app_voicemail2.c index 3d1010ae4..54c9e2de1 100755 --- a/apps/app_voicemail2.c +++ b/apps/app_voicemail2.c @@ -1303,7 +1303,7 @@ static int adsi_load_vmail(struct ast_channel *chan, int *useadsi) bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); - bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "4", 1); + bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); bytes += adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); @@ -1446,6 +1446,7 @@ static void adsi_password(struct ast_channel *chan) bytes += adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); bytes += adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); bytes += adsi_set_keys(buf + bytes, keys); + bytes += adsi_voice_mode(buf + bytes, 0); adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); } @@ -1473,6 +1474,8 @@ static void adsi_folders(struct ast_channel *chan, int start, char *label) bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); bytes += adsi_set_keys(buf + bytes, keys); + bytes += adsi_voice_mode(buf + bytes, 0); + adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); } @@ -1559,6 +1562,8 @@ static void adsi_message(struct ast_channel *chan, char *folder, int msg, int la bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); bytes += adsi_set_keys(buf + bytes, keys); + bytes += adsi_voice_mode(buf + bytes, 0); + adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); } @@ -1602,6 +1607,8 @@ static void adsi_delete(struct ast_channel *chan, int msg, int last, int deleted /* Except "Exit" */ keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); bytes += adsi_set_keys(buf + bytes, keys); + bytes += adsi_voice_mode(buf + bytes, 0); + adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); } @@ -1645,6 +1652,8 @@ static void adsi_status(struct ast_channel *chan, int new, int old, int lastmsg) keys[0] = 1; bytes += adsi_set_keys(buf + bytes, keys); + bytes += adsi_voice_mode(buf + bytes, 0); + adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); } @@ -1683,6 +1692,8 @@ static void adsi_status2(struct ast_channel *chan, char *folder, int messages) bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); bytes += adsi_set_keys(buf + bytes, keys); + bytes += adsi_voice_mode(buf + bytes, 0); + adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); } @@ -1694,6 +1705,8 @@ static void adsi_clear(struct ast_channel *chan) if (!adsi_available(chan)) return; bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); + bytes += adsi_voice_mode(buf + bytes, 0); + adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); } @@ -1708,6 +1721,8 @@ static void adsi_goodbye(struct ast_channel *chan) bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); + bytes += adsi_voice_mode(buf + bytes, 0); + adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); } @@ -2399,6 +2414,18 @@ static int vm_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct char newpassword[80] = ""; char newpassword2[80] = ""; char prefile[256]=""; + char buf[256]; + int bytes=0; + + if (adsi_available(chan)) + { + bytes += adsi_logo(buf + bytes); + bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); + bytes += adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); + bytes += adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); + bytes += adsi_voice_mode(buf + bytes, 0); + adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); + } while((cmd >= 0) && (cmd != 't')) { if (cmd) retries = 0; @@ -2723,6 +2750,8 @@ static int vm_execmain(struct ast_channel *chan, void *data) break; case '0': cmd = vm_options(chan, vmu, &vms, vmfmts); + if (useadsi) + adsi_status(chan, vms.newmessages, vms.oldmessages, vms.lastmsg); break; default: /* Nothing */ cmd = vm_instructions(chan, &vms); -- cgit v1.2.3