aboutsummaryrefslogtreecommitdiffstats
path: root/apps/app_queue.c
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2003-07-27 01:55:22 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2003-07-27 01:55:22 +0000
commit1c6679d139e95613dac651bdb8700017e7a425d6 (patch)
treee577688b82bd4c52112266423a5de02b0d337fc1 /apps/app_queue.c
parent70e86c19a5f1b1ac89db9a04daaf27997fbec648 (diff)
Start on queueing strategies
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@1226 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_queue.c')
-rwxr-xr-xapps/app_queue.c153
1 files changed, 84 insertions, 69 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 5d8ca0c1c..fd5fb885e 100755
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -37,6 +37,12 @@
#include <pthread.h>
+#define QUEUE_STRATEGY_RINGALL 0
+#define QUEUE_STRATEGY_ROUNDROBIN 1
+#define QUEUE_STRATEGY_LEASTRECENT 2
+#define QUEUE_STRATEGY_FEWESTCALLS 3
+#define QUEUE_STRATEGY_RANDOM 4
+
#define DEFAULT_RETRY 5
#define DEFAULT_TIMEOUT 15
#define RECHECK 1 /* Recheck every second to see we we're at the top yet */
@@ -91,7 +97,10 @@ static char *app_rqm_descrip =
struct localuser {
struct ast_channel *chan;
+ char numsubst[256];
+ char tech[40];
int stillgoing;
+ int metric;
int allowredirect_in;
int allowredirect_out;
int ringbackonly;
@@ -117,6 +126,7 @@ struct queue_ent {
struct member {
char tech[80]; /* Technology */
char loc[256]; /* Location */
+ struct timeval lastcall; /* When last successful call was hungup */
struct member *next; /* Next member */
};
@@ -126,6 +136,7 @@ struct ast_call_queue {
char moh[80]; /* Name of musiconhold to be used */
char announce[80]; /* Announcement to play */
char context[80]; /* Announcement to play */
+ int strategy; /* Queueing strategy */
int announcetimeout; /* How often to announce their position */
int count; /* How many entries are in the queue */
int maxlen; /* Max number of entries in queue */
@@ -274,7 +285,7 @@ static void hanguptree(struct localuser *outgoing, struct ast_channel *exception
struct localuser *oo;
while(outgoing) {
/* Hangup any existing lines we have open */
- if (outgoing->chan != exception)
+ if (outgoing->chan && (outgoing->chan != exception))
ast_hangup(outgoing->chan);
oo = outgoing;
outgoing=outgoing->next;
@@ -306,7 +317,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
watchers[0] = in;
while(o) {
/* Keep track of important channels */
- if (o->stillgoing) {
+ if (o->stillgoing && o->chan) {
watchers[pos++] = o->chan;
found = 1;
}
@@ -439,6 +450,65 @@ static int wait_our_turn(struct queue_ent *qe)
return res;
}
+static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
+{
+ int res;
+ /* Request the peer */
+ tmp->chan = ast_request(tmp->tech, qe->chan->nativeformats, tmp->numsubst);
+ 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'\n", cur->tech);
+#endif
+ if (qe->chan->cdr)
+ ast_cdr_busy(qe->chan->cdr);
+ tmp->stillgoing = 0;
+ return 0;
+ }
+ tmp->chan->appl = "AppQueue";
+ tmp->chan->data = "(Outgoing Line)";
+ tmp->chan->whentohangup = 0;
+ if (tmp->chan->callerid)
+ free(tmp->chan->callerid);
+ if (tmp->chan->ani)
+ free(tmp->chan->ani);
+ if (qe->chan->callerid)
+ tmp->chan->callerid = strdup(qe->chan->callerid);
+ else
+ tmp->chan->callerid = NULL;
+ if (qe->chan->ani)
+ tmp->chan->ani = strdup(qe->chan->ani);
+ else
+ tmp->chan->ani = NULL;
+ /* Presense of ADSI CPE on outgoing channel follows ours */
+ tmp->chan->adsicpe = qe->chan->adsicpe;
+ /* Place the call, but don't wait on the answer */
+ res = ast_call(tmp->chan, tmp->numsubst, 0);
+ if (res) {
+ /* Again, keep going even if there's an error */
+ if (option_debug)
+ ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
+ else if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", tmp->numsubst);
+ ast_hangup(tmp->chan);
+ tmp->chan = NULL;
+ tmp->stillgoing = 0;
+ return 0;
+ } else
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", tmp->numsubst);
+ return 0;
+}
+
+static int calc_metric(struct ast_call_queue *q, struct queue_ent *qe, struct localuser *tmp)
+{
+ switch (q->strategy) {
+ case QUEUE_STRATEGY_RINGALL:
+ ast_log(LOG_WARNING, "Can't calculate metric for ringall strategy\n");
+ break;
+ }
+ return 0;
+}
+
static int try_calling(struct queue_ent *qe, char *options, char *announceoverride, char *url)
{
struct member *cur;
@@ -447,7 +517,6 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
int allowredir_in=0;
int allowredir_out=0;
int allowdisconnect=0;
- char numsubst[AST_MAX_EXTENSION];
char restofit[AST_MAX_EXTENSION];
char *newnum;
struct ast_channel *peer;
@@ -469,6 +538,7 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
goto out;
}
memset(tmp, 0, sizeof(struct localuser));
+ tmp->stillgoing = -1;
if (options) {
if (strchr(options, 't'))
tmp->allowredirect_in = 1;
@@ -488,83 +558,28 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
} else
ast_log(LOG_DEBUG, "Simple queue (no URL)\n");
- strncpy(numsubst, cur->loc, sizeof(numsubst)-1);
+ strncpy(tmp->tech, cur->tech, sizeof(tmp->tech)-1);
+ strncpy(tmp->numsubst, cur->loc, sizeof(tmp->numsubst)-1);
/* If we're dialing by extension, look at the extension to know what to dial */
- if ((newnum = strstr(numsubst, "BYEXTENSION"))) {
+ if ((newnum = strstr(tmp->numsubst, "BYEXTENSION"))) {
strncpy(restofit, newnum + strlen("BYEXTENSION"), sizeof(restofit)-1);
- snprintf(newnum, sizeof(numsubst) - (newnum - numsubst), "%s%s", qe->chan->exten,restofit);
+ snprintf(newnum, sizeof(tmp->numsubst) - (newnum - tmp->numsubst), "%s%s", qe->chan->exten,restofit);
if (option_debug)
- ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
- }
- /* Request the peer */
- tmp->chan = ast_request(cur->tech, qe->chan->nativeformats, numsubst);
- 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'\n", cur->tech);
-#endif
- if (qe->chan->cdr)
- ast_cdr_busy(qe->chan->cdr);
- free(tmp);
- cur = cur->next;
- continue;
- }
-#if 0
- /* Don't honor call forwarding on a queue! */
- if (strlen(tmp->chan->call_forward)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Forwarding call to '%s@%s'\n", tmp->chan->call_forward, tmp->chan->context);
- /* Setup parameters */
- strncpy(chan->exten, tmp->chan->call_forward, sizeof(chan->exten));
- strncpy(chan->context, tmp->chan->context, sizeof(chan->context));
- chan->priority = 0;
- to = 0;
- ast_hangup(tmp->chan);
- free(tmp);
- cur = rest;
- break;
+ ast_log(LOG_DEBUG, "Dialing by extension %s\n", tmp->numsubst);
}
-#endif
- tmp->chan->appl = "AppQueue";
- tmp->chan->data = "(Outgoing Line)";
- tmp->chan->whentohangup = 0;
- if (tmp->chan->callerid)
- free(tmp->chan->callerid);
- if (tmp->chan->ani)
- free(tmp->chan->ani);
- if (qe->chan->callerid)
- tmp->chan->callerid = strdup(qe->chan->callerid);
- else
- tmp->chan->callerid = NULL;
- if (qe->chan->ani)
- tmp->chan->ani = strdup(qe->chan->ani);
+ /* Special case: If we ring everyone, go ahead and ring them, otherwise
+ just calculate their metric for the appropriate strategy */
+ if (!qe->parent->strategy)
+ ring_entry(qe, tmp);
else
- tmp->chan->ani = NULL;
- /* Presense of ADSI CPE on outgoing channel follows ours */
- tmp->chan->adsicpe = qe->chan->adsicpe;
- /* Place the call, but don't wait on the answer */
- res = ast_call(tmp->chan, numsubst, 0);
- if (res) {
- /* Again, keep going even if there's an error */
- if (option_debug)
- ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
- else if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
- ast_hangup(tmp->chan);
- free(tmp);
- cur = cur->next;
- continue;
- } else
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
+ calc_metric(qe->parent, 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 */
- tmp->stillgoing = -1;
tmp->next = outgoing;
outgoing = tmp;
/* If this line is up, don't try anybody else */
- if (outgoing->chan->_state == AST_STATE_UP)
+ if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
break;
cur = cur->next;