diff options
author | martinp <martinp@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-11-07 16:55:13 +0000 |
---|---|---|
committer | martinp <martinp@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-11-07 16:55:13 +0000 |
commit | 578e6fddfeec4b995b24137b1fae772619a42f8c (patch) | |
tree | c5eb22e45f80f663d0915cabf39aacbc1a3e3910 /channels | |
parent | 9a9d5665e5d29b906a708b4b3af498bf13104c5c (diff) |
Add round robin to chan_zap with use of Zap/r<number>/<exten> (ascending) or Zap/R<number>/<exten> (descending).
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@1707 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rwxr-xr-x | channels/chan_zap.c | 101 |
1 files changed, 81 insertions, 20 deletions
diff --git a/channels/chan_zap.c b/channels/chan_zap.c index 6ba1ced5e..4df3352a8 100755 --- a/channels/chan_zap.c +++ b/channels/chan_zap.c @@ -468,6 +468,8 @@ static struct zt_pvt { #endif } *iflist = NULL, *ifend = NULL; +struct zt_pvt *round_robin[32]; + #ifdef ZAPATA_PRI static inline int pri_grab(struct zt_pvt *pvt, struct zt_pri *pri) { @@ -4974,15 +4976,48 @@ static struct zt_pvt *mkintf(int channel, int signalling, int radio) memset(tmp, 0, sizeof(struct zt_pvt)); for (x=0;x<3;x++) tmp->subs[x].zfd = -1; - if (!ifend) { + tmp->channel = channel; + /* nothing on the iflist */ + if (!iflist) { iflist = tmp; tmp->prev = NULL; tmp->next = NULL; + ifend = tmp; } else { - ifend->next = tmp; - tmp->prev = ifend; + /* at least one member on the iflist */ + struct zt_pvt *working = iflist; + + /* check if we maybe have to put it on the begining */ + if (working->channel > tmp->channel) { + tmp->next = iflist; + tmp->prev = NULL; + iflist = tmp; + } else { + /* go through all the members and put the member in the right place */ + while (working) { + /* in the middle */ + if (working->next) { + if (working->channel < tmp->channel && working->next->channel > tmp->channel) { + tmp->next = working->next; + tmp->prev = working; + working->next->prev = tmp; + working->next = tmp; + break; + } + } else { + /* the last */ + if (working->channel < tmp->channel) { + working->next = tmp; + tmp->next = NULL; + tmp->prev = working; + ifend = tmp; + break; + } + } + working = working->next; + } + } } - ifend = tmp; } if (tmp) { @@ -5386,6 +5421,7 @@ static struct ast_channel *zt_request(char *type, int format, void *data) char opt=0; int res=0, y=0; int backwards = 0; + struct zt_pvt *exit; /* We do signed linear */ oldformat = format; @@ -5400,7 +5436,7 @@ static struct ast_channel *zt_request(char *type, int format, void *data) ast_log(LOG_WARNING, "Channel requested with no data\n"); return NULL; } - if (toupper(dest[0]) == 'G') { + if (toupper(dest[0]) == 'G' || toupper(dest[0])=='R') { /* Retrieve the group number */ char *stringp=NULL; stringp=dest + 1; @@ -5410,8 +5446,24 @@ static struct ast_channel *zt_request(char *type, int format, void *data) return NULL; } groupmatch = 1 << x; - if (dest[0] == 'G') - backwards = 1; + if (toupper(dest[0]) == 'G') { + if (dest[0] == 'G') { + backwards = 1; + p = ifend; + } else + p = iflist; + } else { + if (dest[0] == 'R') { + backwards = 1; + p = round_robin[x]?round_robin[x]->prev:ifend; + if (!p) + p = ifend; + } else { + p = round_robin[x]?round_robin[x]->next:iflist; + if (!p) + p = iflist; + } + } } else { char *stringp=NULL; stringp=dest; @@ -5424,24 +5476,25 @@ static struct ast_channel *zt_request(char *type, int format, void *data) return NULL; } channelmatch = x; + p = iflist; } /* Search for an unowned channel */ if (ast_mutex_lock(&iflock)) { ast_log(LOG_ERROR, "Unable to lock interface list???\n"); return NULL; } - if (backwards) - p = ifend; - else - p = iflist; + exit = p; while(p && !tmp) { - if (available(p, channelmatch, groupmatch)) { + round_robin[x] = p; +#if 0 + ast_verbose("name = %s, %d\n",p->owner->name,p->channel); +#endif + if (p && available(p, channelmatch, groupmatch)) { if (option_debug) ast_log(LOG_DEBUG, "Using channel %d\n", p->channel); - if (p->inalarm) { - p = p->next; - continue; - } + if (p->inalarm) + goto next; + callwait = (p->owner != NULL); if (p->channel == CHAN_PSEUDO) { p = chandup(p); @@ -5480,10 +5533,19 @@ static struct ast_channel *zt_request(char *type, int format, void *data) tmp->cdrflags |= AST_CDR_CALLWAIT; break; } - if (backwards) +next: + if (backwards) { p = p->prev; - else + if (!p) + p = ifend; + } else { p = p->next; + if (!p) + p = iflist; + } + /* stop when you roll to the one that we started from */ + if (p == exit) + break; } ast_mutex_unlock(&iflock); restart_monitor(); @@ -6662,8 +6724,6 @@ static int zap_show_channel(int fd, int argc, char **argv) return RESULT_FAILURE; } - - static char show_channels_usage[] = "Usage: zap show channels\n" " Shows a list of available channels\n"; @@ -7082,6 +7142,7 @@ int load_module() ast_cli_register(&cli_show_channel); ast_cli_register(&cli_destroy_channel); ast_register_application(app_callingpres, change_callingpres, synopsis_callingpres, descrip_callingpres); + memset(round_robin, 0, sizeof(round_robin)); /* And start the monitor for the first time */ restart_monitor(); return 0; |