diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-07-27 01:55:22 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-07-27 01:55:22 +0000 |
commit | 1c6679d139e95613dac651bdb8700017e7a425d6 (patch) | |
tree | e577688b82bd4c52112266423a5de02b0d337fc1 /apps | |
parent | 70e86c19a5f1b1ac89db9a04daaf27997fbec648 (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')
-rwxr-xr-x | apps/app_queue.c | 153 |
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; |