Sun Mar 16 07:00:01 CET 2003
[asterisk/asterisk.git] / apps / app_chanisavail.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Check if Channel is Available
5  * 
6  * Copyright (C) 2003, Digium
7  *
8  * Mark Spencer <markster@digium.com>
9  * James Golovich <james@gnuinter.net>
10  *
11  * This program is free software, distributed under the terms of
12  * the GNU General Public License
13  *
14  */
15
16 #include <asterisk/lock.h>
17 #include <asterisk/file.h>
18 #include <asterisk/logger.h>
19 #include <asterisk/channel.h>
20 #include <asterisk/pbx.h>
21 #include <asterisk/module.h>
22 #include <asterisk/app.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <sys/ioctl.h>
29
30 #include <pthread.h>
31
32 static char *tdesc = "Check if channel is available";
33
34 static char *app = "ChanIsAvail";
35
36 static char *synopsis = "Check if channel is available";
37
38 static char *descrip = 
39 "  ChanIsAvail(Technology/resource[&Technology2/resource2...]): \n"
40 "Checks is any of the requested channels are available.  If none\n"
41 "of the requested channels are available the new priority will\n"
42 "be n+101 (unless such a priority does not exist, in which case\n"
43 "ChanIsAvail will return -1.  If any of the requested channels\n"
44 "are available, the next priority will be n+1 and ChanIsAvail\n"
45 "will return 0.\n";
46
47 STANDARD_LOCAL_USER;
48
49 LOCAL_USER_DECL;
50
51 static int chanavail_exec(struct ast_channel *chan, void *data)
52 {
53         int res=-1;
54         struct localuser *u;
55         char info[256], *peers, *tech, *number, *rest, *cur;
56         struct ast_channel *tempchan;
57
58         if (!data) {
59                 ast_log(LOG_WARNING, "ChanIsAvail requires an argument (Zap/1&Zap/2)\n");
60                 return -1;
61         }
62         LOCAL_USER_ADD(u);
63
64         strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION-1);
65         peers = info;
66         if (peers) {
67                 cur = peers;
68                 do {
69                         /* remember where to start next time */
70                         rest = strchr(cur, '&');
71                         if (rest) {
72                                 *rest = 0;
73                                 rest++;
74                         }
75                         tech = cur;
76                         number = strchr(tech, '/');
77                         if (!number) {
78                                 ast_log(LOG_WARNING, "ChanIsAvail argument takes format (Zap/[device])\n");
79                                 continue;
80                         }
81                         *number = '\0';
82                         number++;
83                         if ((tempchan = ast_request(tech, chan->nativeformats, number))) {
84                                         ast_hangup(tempchan);
85                                         tempchan = NULL;
86                                         res = 1;
87                                         break;
88                         }
89                         cur = rest;
90                 } while (cur);
91         }
92
93         if (res < 1) {
94                 if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
95                         chan->priority+=100;
96                 else
97                         return -1;
98         }
99
100         LOCAL_USER_REMOVE(u);
101         return 0;
102 }
103
104 int unload_module(void)
105 {
106         STANDARD_HANGUP_LOCALUSERS;
107         return ast_unregister_application(app);
108 }
109
110 int load_module(void)
111 {
112         return ast_register_application(app, chanavail_exec, synopsis, descrip);
113 }
114
115 char *description(void)
116 {
117         return tdesc;
118 }
119
120 int usecount(void)
121 {
122         int res;
123         STANDARD_USECOUNT(res);
124         return res;
125 }
126
127 char *key()
128 {
129         return ASTERISK_GPL_KEY;
130 }