2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief Execute an ISDN RAS
23 * \author Mark Spencer <markster@digium.com>
25 * \ingroup applications
29 <depend>zaptel</depend>
34 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
36 #include <sys/ioctl.h>
39 #include <sys/signal.h>
42 #endif /* __linux__ */
46 #include "asterisk/zapata.h"
48 #include "asterisk/lock.h"
49 #include "asterisk/file.h"
50 #include "asterisk/channel.h"
51 #include "asterisk/pbx.h"
52 #include "asterisk/module.h"
53 #include "asterisk/app.h"
55 static char *app
= "ZapRAS";
57 static char *synopsis
= "Executes Zaptel ISDN RAS application";
59 static char *descrip
=
60 " ZapRAS(args): Executes a RAS server using pppd on the given channel.\n"
61 "The channel must be a clear channel (i.e. PRI source) and a Zaptel\n"
62 "channel to be able to use this function (No modem emulation is included).\n"
63 "Your pppd must be patched to be zaptel aware. Arguments should be\n"
64 "separated by , characters.\n";
67 #define PPP_MAX_ARGS 32
68 #define PPP_EXEC "/usr/sbin/pppd"
70 static pid_t
spawn_ras(struct ast_channel
*chan
, char *args
)
75 char *argv
[PPP_MAX_ARGS
];
79 /* Start by forking */
80 pid
= ast_safe_fork(1);
85 /* Execute RAS on File handles */
86 dup2(chan
->fds
[0], STDIN_FILENO
);
88 /* Drop high priority */
89 if (ast_opt_high_priority
)
92 /* Close other file descriptors */
93 ast_close_fds_above_n(STDERR_FILENO
);
95 /* Reset all arguments */
96 memset(argv
, 0, sizeof(argv
));
98 /* First argument is executable, followed by standard
99 arguments for zaptel PPP */
100 argv
[argc
++] = PPP_EXEC
;
101 argv
[argc
++] = "nodetach";
103 /* And all the other arguments */
105 c
= strsep(&stringp
, ",");
106 while(c
&& strlen(c
) && (argc
< (PPP_MAX_ARGS
- 4))) {
108 c
= strsep(&stringp
, ",");
111 argv
[argc
++] = "plugin";
112 argv
[argc
++] = "zaptel.so";
113 argv
[argc
++] = "stdin";
115 /* Finally launch PPP */
116 execv(PPP_EXEC
, argv
);
117 fprintf(stderr
, "Failed to exec PPPD!\n");
121 static void run_ras(struct ast_channel
*chan
, char *args
)
127 struct zt_bufferinfo savebi
;
130 res
= ioctl(chan
->fds
[0], ZT_GET_BUFINFO
, &savebi
);
132 ast_log(LOG_WARNING
, "Unable to check buffer policy on channel %s\n", chan
->name
);
136 pid
= spawn_ras(chan
, args
);
138 ast_log(LOG_WARNING
, "Failed to spawn RAS\n");
141 res
= wait4(pid
, &status
, WNOHANG
, NULL
);
143 /* Check for hangup */
144 if (ast_check_hangup(chan
) && !signalled
) {
145 ast_debug(1, "Channel '%s' hungup. Signalling RAS at %d to die...\n", chan
->name
, pid
);
154 ast_log(LOG_WARNING
, "wait4 returned %d: %s\n", res
, strerror(errno
));
156 if (WIFEXITED(status
)) {
157 ast_verb(3, "RAS on %s terminated with status %d\n", chan
->name
, WEXITSTATUS(status
));
158 } else if (WIFSIGNALED(status
)) {
159 ast_verb(3, "RAS on %s terminated with signal %d\n",
160 chan
->name
, WTERMSIG(status
));
162 ast_verb(3, "RAS on %s terminated weirdly.\n", chan
->name
);
164 /* Throw back into audio mode */
166 ioctl(chan
->fds
[0], ZT_AUDIOMODE
, &x
);
168 /* Restore saved values */
169 res
= ioctl(chan
->fds
[0], ZT_SET_BUFINFO
, &savebi
);
171 ast_log(LOG_WARNING
, "Unable to set buffer policy on channel %s\n", chan
->name
);
176 ast_safe_fork_cleanup();
179 static int zapras_exec(struct ast_channel
*chan
, void *data
)
188 args
= ast_strdupa(data
);
190 /* Answer the channel if it's not up */
191 if (chan
->_state
!= AST_STATE_UP
)
193 if (strcasecmp(chan
->tech
->type
, "Zap")) {
194 /* If it's not a zap channel, we're done. Wait a couple of
195 seconds and then hangup... */
196 ast_verb(2, "Channel %s is not a Zap channel\n", chan
->name
);
199 memset(&ztp
, 0, sizeof(ztp
));
200 if (ioctl(chan
->fds
[0], ZT_GET_PARAMS
, &ztp
)) {
201 ast_log(LOG_WARNING
, "Unable to get zaptel parameters\n");
202 } else if (ztp
.sigtype
!= ZT_SIG_CLEAR
) {
203 ast_verb(2, "Channel %s is not a clear channel\n", chan
->name
);
205 /* Everything should be okay. Run PPP. */
206 ast_verb(3, "Starting RAS on %s\n", chan
->name
);
214 static int unload_module(void)
216 return ast_unregister_application(app
);
219 static int load_module(void)
221 return ((ast_register_application(app
, zapras_exec
, synopsis
, descrip
)) ? AST_MODULE_LOAD_FAILURE
: AST_MODULE_LOAD_SUCCESS
);
224 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "Zaptel ISDN Remote Access Server");