Sat Aug 6 00:39:19 2011

Asterisk developer's documentation


app_chanisavail.c

Go to the documentation of this file.
00001 /*
00002 * Asterisk -- An open source telephony toolkit.
00003 *
00004 * Copyright (C) 1999 - 2005, Digium, Inc.
00005 *
00006 * Mark Spencer <markster@digium.com>
00007 * James Golovich <james@gnuinter.net>
00008 *
00009 * See http://www.asterisk.org for more information about
00010 * the Asterisk project. Please do not directly contact
00011 * any of the maintainers of this project for assistance;
00012 * the project provides a web site, mailing lists and IRC
00013 * channels for your use.
00014 *
00015 * This program is free software, distributed under the terms of
00016 * the GNU General Public License Version 2. See the LICENSE file
00017 * at the top of the source tree.
00018 */
00019 
00020 /*! \file
00021  * 
00022  * \brief Check if Channel is Available
00023  * 
00024  * \author Mark Spencer <markster@digium.com>
00025  * \author James Golovich <james@gnuinter.net>
00026 
00027  * \ingroup applications
00028  */
00029 
00030 #include "asterisk.h"
00031 
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 229965 $")
00033 
00034 #include <stdlib.h>
00035 #include <stdio.h>
00036 #include <string.h>
00037 #include <unistd.h>
00038 #include <errno.h>
00039 #include <sys/ioctl.h>
00040 
00041 #include "asterisk/lock.h"
00042 #include "asterisk/file.h"
00043 #include "asterisk/logger.h"
00044 #include "asterisk/channel.h"
00045 #include "asterisk/pbx.h"
00046 #include "asterisk/module.h"
00047 #include "asterisk/app.h"
00048 #include "asterisk/devicestate.h"
00049 #include "asterisk/options.h"
00050 
00051 static char *app = "ChanIsAvail";
00052 
00053 static char *synopsis = "Check channel availability";
00054 
00055 static char *descrip = 
00056 "  ChanIsAvail(Technology/resource[&Technology2/resource2...][|options]): \n"
00057 "This application will check to see if any of the specified channels are\n"
00058 "available. Note that the AVAILSTATUS variable is used for both device state\n"
00059 "and cause code. It is therefore possible for it to give a value that may\n"
00060 "indicate a device is available when it is not. It is suggested that the\n"
00061 "AVAILORIGCHAN variable is used instead to see whether a device is available\n"
00062 "or not.\n"
00063 "The following variables will be set by this application:\n"
00064 "  ${AVAILCHAN}     - the name of the available channel, if one exists\n"
00065 "  ${AVAILORIGCHAN} - the canonical channel name that was used to create the channel\n"
00066 "  ${AVAILSTATUS}   - the status code for the available channel\n"
00067 "  Options:\n"
00068 "    s - Consider the channel unavailable if the channel is in use at all\n"
00069 "    j - Support jumping to priority n+101 if no channel is available\n";
00070 
00071 
00072 static int chanavail_exec(struct ast_channel *chan, void *data)
00073 {
00074    int res=-1, inuse=-1, option_state=0, priority_jump=0;
00075    int status;
00076    struct ast_module_user *u;
00077    char *info, tmp[512], trychan[512], *peers, *tech, *number, *rest, *cur;
00078    struct ast_channel *tempchan;
00079    AST_DECLARE_APP_ARGS(args,
00080       AST_APP_ARG(reqchans);
00081       AST_APP_ARG(options);
00082    );
00083 
00084    if (ast_strlen_zero(data)) {
00085       ast_log(LOG_WARNING, "ChanIsAvail requires an argument (Zap/1&Zap/2)\n");
00086       return -1;
00087    }
00088 
00089    u = ast_module_user_add(chan);
00090 
00091    info = ast_strdupa(data); 
00092 
00093    AST_STANDARD_APP_ARGS(args, info);
00094 
00095    if (args.options) {
00096       if (strchr(args.options, 's'))
00097          option_state = 1;
00098       if (strchr(args.options, 'j'))
00099          priority_jump = 1;
00100    }
00101    peers = args.reqchans;
00102    if (peers) {
00103       cur = peers;
00104       do {
00105          /* remember where to start next time */
00106          rest = strchr(cur, '&');
00107          if (rest) {
00108             *rest = 0;
00109             rest++;
00110          }
00111          tech = cur;
00112          number = strchr(tech, '/');
00113          if (!number) {
00114             ast_log(LOG_WARNING, "ChanIsAvail argument takes format ([technology]/[device])\n");
00115             ast_module_user_remove(u);
00116             return -1;
00117          }
00118          *number = '\0';
00119          number++;
00120          
00121          if (option_state) {
00122             /* If the pbx says in use then don't bother trying further.
00123                This is to permit testing if someone's on a call, even if the 
00124                channel can permit more calls (ie callwaiting, sip calls, etc).  */
00125                                
00126             snprintf(trychan, sizeof(trychan), "%s/%s",cur,number);
00127             status = inuse = ast_device_state(trychan);
00128          }
00129          if ((inuse <= 1) && (tempchan = ast_request(tech, chan->nativeformats, number, &status))) {
00130                pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name);
00131                /* Store the originally used channel too */
00132                snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
00133                pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", tmp);
00134                snprintf(tmp, sizeof(tmp), "%d", status);
00135                pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp);
00136                ast_hangup(tempchan);
00137                tempchan = NULL;
00138                res = 1;
00139                break;
00140          } else {
00141             snprintf(tmp, sizeof(tmp), "%d", status);
00142             pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp);
00143          }
00144          cur = rest;
00145       } while (cur);
00146    }
00147    if (res < 1) {
00148       pbx_builtin_setvar_helper(chan, "AVAILCHAN", "");
00149       pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", "");
00150       if (priority_jump || ast_opt_priority_jumping) {
00151          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
00152             ast_module_user_remove(u);
00153             return -1;
00154          }
00155       }
00156    }
00157 
00158    ast_module_user_remove(u);
00159    return 0;
00160 }
00161 
00162 static int unload_module(void)
00163 {
00164    int res = 0;
00165 
00166    res = ast_unregister_application(app);
00167 
00168    ast_module_user_hangup_all();
00169    
00170    return res;
00171 }
00172 
00173 static int load_module(void)
00174 {
00175    return ast_register_application(app, chanavail_exec, synopsis, descrip);
00176 }
00177 
00178 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Check channel availability");

Generated on Sat Aug 6 00:39:19 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7