add option 'a' to chanisavail.

If you give chanisavail a list of channels, it will only
return the first available channel.
When this option is set, it will return all the available
channels from the given list.

(closes issue #12248)
Reported by: dagmoller
Patches:
      app_chanisavail-snv.patch-v2.txt uploaded by dagmoller (license 436)
	   - major changes by me because russellb pointed out some buffer overflows
	     and codeguideline issues.
		 Converted it all to the ast_str_* api
Tested by: dagmoller, mvanbaak


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@118101 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Michiel van Baak
2008-05-23 17:12:04 +00:00
parent 41ad55749d
commit 8f45823dda
2 changed files with 30 additions and 14 deletions

View File

@@ -75,6 +75,8 @@ Application Changes
* ExternalIVR now takes several options that affect the way it performs, as * ExternalIVR now takes several options that affect the way it performs, as
well as having several new commands. Please see doc/externalivr.txt for the well as having several new commands. Please see doc/externalivr.txt for the
complete documentation. complete documentation.
* ChanIsAvail has a new option, 'a', which will return all available channels instead
of just the first one if you give the function more then one channel to check.
SIP Changes SIP Changes
----------- -----------

View File

@@ -50,6 +50,7 @@ static char *descrip =
"This application will check to see if any of the specified channels are\n" "This application will check to see if any of the specified channels are\n"
"available.\n" "available.\n"
" Options:\n" " Options:\n"
" a - Check for all available channels, not only the first one.\n"
" s - Consider the channel unavailable if the channel is in use at all.\n" " s - Consider the channel unavailable if the channel is in use at all.\n"
" t - Simply checks if specified channels exist in the channel list\n" " t - Simply checks if specified channels exist in the channel list\n"
" (implies option s).\n" " (implies option s).\n"
@@ -61,9 +62,12 @@ static char *descrip =
static int chanavail_exec(struct ast_channel *chan, void *data) static int chanavail_exec(struct ast_channel *chan, void *data)
{ {
int res=-1, inuse=-1, option_state=0, string_compare=0; int inuse=-1, option_state=0, string_compare=0, option_all_avail=0;
int status; int status;
char *info, tmp[512], trychan[512], *peers, *tech, *number, *rest, *cur; char *info, tmp[512], trychan[512], *peers, *tech, *number, *rest, *cur;
struct ast_str *tmp_availchan = ast_str_alloca(2048);
struct ast_str *tmp_availorig = ast_str_alloca(2048);
struct ast_str *tmp_availstat = ast_str_alloca(2048);
struct ast_channel *tempchan; struct ast_channel *tempchan;
AST_DECLARE_APP_ARGS(args, AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(reqchans); AST_APP_ARG(reqchans);
@@ -80,11 +84,16 @@ static int chanavail_exec(struct ast_channel *chan, void *data)
AST_STANDARD_APP_ARGS(args, info); AST_STANDARD_APP_ARGS(args, info);
if (args.options) { if (args.options) {
if (strchr(args.options, 's')) if (strchr(args.options, 'a')) {
option_all_avail = 1;
}
if (strchr(args.options, 's')) {
option_state = 1; option_state = 1;
if (strchr(args.options, 't')) }
if (strchr(args.options, 't')) {
string_compare = 1; string_compare = 1;
} }
}
peers = args.reqchans; peers = args.reqchans;
if (peers) { if (peers) {
cur = peers; cur = peers;
@@ -119,27 +128,32 @@ static int chanavail_exec(struct ast_channel *chan, void *data)
status = inuse = ast_device_state(trychan); status = inuse = ast_device_state(trychan);
} }
if ((inuse <= 1) && (tempchan = ast_request(tech, chan->nativeformats, number, &status))) { if ((inuse <= 1) && (tempchan = ast_request(tech, chan->nativeformats, number, &status))) {
pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name); ast_str_append(&tmp_availchan, 0, "%s%s", tmp_availchan->used ? "&" : "", tempchan->name);
/* Store the originally used channel too */
snprintf(tmp, sizeof(tmp), "%s/%s", tech, number); snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", tmp); ast_str_append(&tmp_availorig, 0, "%s%s", tmp_availorig->used ? "&" : "", tmp);
snprintf(tmp, sizeof(tmp), "%d", status); snprintf(tmp, sizeof(tmp), "%d", status);
pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp); ast_str_append(&tmp_availstat, 0, "%s%s", tmp_availstat->used ? "&" : "", tmp);
ast_hangup(tempchan); ast_hangup(tempchan);
tempchan = NULL; tempchan = NULL;
res = 1;
if (!option_all_avail) {
break; break;
}
} else { } else {
snprintf(tmp, sizeof(tmp), "%d", status); snprintf(tmp, sizeof(tmp), "%d", status);
pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp); ast_str_append(&tmp_availstat, 0, "%s%s", tmp_availstat->used ? "&" : "", tmp);
} }
cur = rest; cur = rest;
} while (cur); } while (cur);
} }
if (res < 1) {
pbx_builtin_setvar_helper(chan, "AVAILCHAN", ""); pbx_builtin_setvar_helper(chan, "AVAILCHAN", tmp_availchan->str);
pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", ""); /* Store the originally used channel too */
} pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", tmp_availorig->str);
pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp_availstat->str);
return 0; return 0;
} }