00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "asterisk.h"
00033
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 48375 $")
00035
00036 #include <sys/ioctl.h>
00037 #include <sys/wait.h>
00038 #ifdef __linux__
00039 #include <sys/signal.h>
00040 #else
00041 #include <signal.h>
00042 #endif
00043
00044 #include <stdlib.h>
00045 #include <unistd.h>
00046 #include <string.h>
00047 #include <stdlib.h>
00048 #include <errno.h>
00049 #include <stdio.h>
00050 #include <fcntl.h>
00051 #include <zaptel/zaptel.h>
00052
00053 #include "asterisk/lock.h"
00054 #include "asterisk/file.h"
00055 #include "asterisk/logger.h"
00056 #include "asterisk/channel.h"
00057 #include "asterisk/pbx.h"
00058 #include "asterisk/module.h"
00059 #include "asterisk/options.h"
00060
00061 static char *app = "ZapRAS";
00062
00063 static char *synopsis = "Executes Zaptel ISDN RAS application";
00064
00065 static char *descrip =
00066 " ZapRAS(args): Executes a RAS server using pppd on the given channel.\n"
00067 "The channel must be a clear channel (i.e. PRI source) and a Zaptel\n"
00068 "channel to be able to use this function (No modem emulation is included).\n"
00069 "Your pppd must be patched to be zaptel aware. Arguments should be\n"
00070 "separated by | characters.\n";
00071
00072
00073 #define PPP_MAX_ARGS 32
00074 #define PPP_EXEC "/usr/sbin/pppd"
00075
00076 static pid_t spawn_ras(struct ast_channel *chan, char *args)
00077 {
00078 pid_t pid;
00079 int x;
00080 char *c;
00081
00082 char *argv[PPP_MAX_ARGS];
00083 int argc = 0;
00084 char *stringp=NULL;
00085 sigset_t fullset, oldset;
00086
00087 sigfillset(&fullset);
00088 pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
00089
00090
00091 pid = fork();
00092 if (pid) {
00093 pthread_sigmask(SIG_SETMASK, &oldset, NULL);
00094 return pid;
00095 }
00096
00097
00098 for (x=0;x<NSIG;x++)
00099 signal(x, SIG_DFL);
00100
00101 pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
00102
00103
00104 dup2(chan->fds[0], STDIN_FILENO);
00105
00106
00107 if (ast_opt_high_priority)
00108 ast_set_priority(0);
00109
00110
00111 for (x=STDERR_FILENO + 1;x<1024;x++)
00112 close(x);
00113
00114
00115 memset(argv, 0, sizeof(argv));
00116
00117
00118
00119 argv[argc++] = PPP_EXEC;
00120 argv[argc++] = "nodetach";
00121
00122
00123 stringp=args;
00124 c = strsep(&stringp, "|");
00125 while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
00126 argv[argc++] = c;
00127 c = strsep(&stringp, "|");
00128 }
00129
00130 argv[argc++] = "plugin";
00131 argv[argc++] = "zaptel.so";
00132 argv[argc++] = "stdin";
00133
00134
00135 execv(PPP_EXEC, argv);
00136 fprintf(stderr, "Failed to exec PPPD!\n");
00137 exit(1);
00138 }
00139
00140 static void run_ras(struct ast_channel *chan, char *args)
00141 {
00142 pid_t pid;
00143 int status;
00144 int res;
00145 int signalled = 0;
00146 struct zt_bufferinfo savebi;
00147 int x;
00148
00149 res = ioctl(chan->fds[0], ZT_GET_BUFINFO, &savebi);
00150 if(res) {
00151 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name);
00152 return;
00153 }
00154
00155 pid = spawn_ras(chan, args);
00156 if (pid < 0) {
00157 ast_log(LOG_WARNING, "Failed to spawn RAS\n");
00158 } else {
00159 for (;;) {
00160 res = wait4(pid, &status, WNOHANG, NULL);
00161 if (!res) {
00162
00163 if (chan->_softhangup && !signalled) {
00164 ast_log(LOG_DEBUG, "Channel '%s' hungup. Signalling RAS at %d to die...\n", chan->name, pid);
00165 kill(pid, SIGTERM);
00166 signalled=1;
00167 }
00168
00169 sleep(1);
00170 continue;
00171 }
00172 if (res < 0) {
00173 ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno));
00174 }
00175 if (option_verbose > 2) {
00176 if (WIFEXITED(status)) {
00177 ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status));
00178 } else if (WIFSIGNALED(status)) {
00179 ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with signal %d\n",
00180 chan->name, WTERMSIG(status));
00181 } else {
00182 ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated weirdly.\n", chan->name);
00183 }
00184 }
00185
00186 x = 0;
00187 ioctl(chan->fds[0], ZT_AUDIOMODE, &x);
00188
00189
00190 res = ioctl(chan->fds[0], ZT_SET_BUFINFO, &savebi);
00191 if (res < 0) {
00192 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name);
00193 }
00194 break;
00195 }
00196 }
00197 }
00198
00199 static int zapras_exec(struct ast_channel *chan, void *data)
00200 {
00201 int res=-1;
00202 char *args;
00203 struct ast_module_user *u;
00204 ZT_PARAMS ztp;
00205
00206 if (!data)
00207 data = "";
00208
00209 u = ast_module_user_add(chan);
00210
00211 args = ast_strdupa(data);
00212
00213
00214 if (chan->_state != AST_STATE_UP)
00215 ast_answer(chan);
00216 if (strcasecmp(chan->tech->type, "Zap")) {
00217
00218
00219 if (option_verbose > 1)
00220 ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a Zap channel\n", chan->name);
00221 sleep(2);
00222 } else {
00223 memset(&ztp, 0, sizeof(ztp));
00224 if (ioctl(chan->fds[0], ZT_GET_PARAMS, &ztp)) {
00225 ast_log(LOG_WARNING, "Unable to get zaptel parameters\n");
00226 } else if (ztp.sigtype != ZT_SIG_CLEAR) {
00227 if (option_verbose > 1)
00228 ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a clear channel\n", chan->name);
00229 } else {
00230
00231 if (option_verbose > 2)
00232 ast_verbose(VERBOSE_PREFIX_3 "Starting RAS on %s\n", chan->name);
00233
00234 run_ras(chan, args);
00235 }
00236 }
00237 ast_module_user_remove(u);
00238 return res;
00239 }
00240
00241 static int unload_module(void)
00242 {
00243 int res;
00244
00245 res = ast_unregister_application(app);
00246
00247 ast_module_user_hangup_all();
00248
00249 return res;
00250 }
00251
00252 static int load_module(void)
00253 {
00254 return ast_register_application(app, zapras_exec, synopsis, descrip);
00255 }
00256
00257 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Zap RAS Application");
00258