add option 'a' to chanisavail.
authorMichiel van Baak <michiel@vanbaak.info>
Fri, 23 May 2008 17:12:04 +0000 (17:12 +0000)
committerMichiel van Baak <michiel@vanbaak.info>
Fri, 23 May 2008 17:12:04 +0000 (17:12 +0000)
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

CHANGES
apps/app_chanisavail.c

diff --git a/CHANGES b/CHANGES
index 9d3c8cd..b917295 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -75,6 +75,8 @@ Application Changes
  * 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
    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
 -----------
index d0b29bd..4504d49 100644 (file)
@@ -50,6 +50,7 @@ static char *descrip =
 "This application will check to see if any of the specified channels are\n"
 "available.\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"
 "    t - Simply checks if specified channels exist in the channel list\n"
 "        (implies option s).\n"
@@ -61,9 +62,12 @@ static char *descrip =
 
 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;
        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;
        AST_DECLARE_APP_ARGS(args,
                AST_APP_ARG(reqchans);
@@ -80,10 +84,15 @@ static int chanavail_exec(struct ast_channel *chan, void *data)
        AST_STANDARD_APP_ARGS(args, info);
 
        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;
-               if (strchr(args.options, 't'))
+               }
+               if (strchr(args.options, 't')) {
                        string_compare = 1;
+               }
        }
        peers = args.reqchans;
        if (peers) {
@@ -119,27 +128,32 @@ static int chanavail_exec(struct ast_channel *chan, void *data)
                                status = inuse = ast_device_state(trychan);
                        }
                        if ((inuse <= 1) && (tempchan = ast_request(tech, chan->nativeformats, number, &status))) {
-                                       pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name);
-                                       /* Store the originally used channel too */
+                                       ast_str_append(&tmp_availchan, 0, "%s%s", tmp_availchan->used ? "&" : "", tempchan->name);
+                                       
                                        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);
-                                       pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp);
+                                       ast_str_append(&tmp_availstat, 0, "%s%s", tmp_availstat->used ? "&" : "", tmp);
+
                                        ast_hangup(tempchan);
                                        tempchan = NULL;
-                                       res = 1;
-                                       break;
+
+                                       if (!option_all_avail) {
+                                               break;
+                                       }
                        } else {
                                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;
                } while (cur);
        }
-       if (res < 1) {
-               pbx_builtin_setvar_helper(chan, "AVAILCHAN", "");
-               pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", "");
-       }
+
+       pbx_builtin_setvar_helper(chan, "AVAILCHAN", tmp_availchan->str);
+       /* 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;
 }