#include "asterisk.h"
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <zaptel/zaptel.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/options.h"
Go to the source code of this file.
Defines | |
#define | PPP_EXEC "/usr/sbin/pppd" |
#define | PPP_MAX_ARGS 32 |
Functions | |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Zap RAS Application") | |
static int | load_module (void) |
static void | run_ras (struct ast_channel *chan, char *args) |
static pid_t | spawn_ras (struct ast_channel *chan, char *args) |
static int | unload_module (void) |
static int | zapras_exec (struct ast_channel *chan, void *data) |
Variables | |
static char * | app = "ZapRAS" |
static char * | descrip |
static char * | synopsis = "Executes Zaptel ISDN RAS application" |
Definition in file app_zapras.c.
#define PPP_EXEC "/usr/sbin/pppd" |
#define PPP_MAX_ARGS 32 |
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"Zap RAS Application" | ||||
) |
static int load_module | ( | void | ) | [static] |
Definition at line 252 of file app_zapras.c.
References ast_register_application(), and zapras_exec().
00253 { 00254 return ast_register_application(app, zapras_exec, synopsis, descrip); 00255 }
static void run_ras | ( | struct ast_channel * | chan, | |
char * | args | |||
) | [static] |
Definition at line 140 of file app_zapras.c.
References ast_channel::_softhangup, ast_log(), ast_verbose(), ast_channel::fds, LOG_DEBUG, LOG_WARNING, option_verbose, spawn_ras(), and VERBOSE_PREFIX_3.
Referenced by zapras_exec().
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 /* Check for hangup */ 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 /* Try again */ 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 /* Throw back into audio mode */ 00186 x = 1; 00187 ioctl(chan->fds[0], ZT_AUDIOMODE, &x); 00188 00189 /* Restore saved values */ 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 }
static pid_t spawn_ras | ( | struct ast_channel * | chan, | |
char * | args | |||
) | [static] |
Definition at line 76 of file app_zapras.c.
References ast_opt_high_priority, ast_set_priority(), ast_channel::fds, PPP_EXEC, PPP_MAX_ARGS, and strsep().
Referenced by run_ras().
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 /* Start by forking */ 00091 pid = fork(); 00092 if (pid) { 00093 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 00094 return pid; 00095 } 00096 00097 /* Restore original signal handlers */ 00098 for (x=0;x<NSIG;x++) 00099 signal(x, SIG_DFL); 00100 00101 pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); 00102 00103 /* Execute RAS on File handles */ 00104 dup2(chan->fds[0], STDIN_FILENO); 00105 00106 /* Drop high priority */ 00107 if (ast_opt_high_priority) 00108 ast_set_priority(0); 00109 00110 /* Close other file descriptors */ 00111 for (x=STDERR_FILENO + 1;x<1024;x++) 00112 close(x); 00113 00114 /* Reset all arguments */ 00115 memset(argv, 0, sizeof(argv)); 00116 00117 /* First argument is executable, followed by standard 00118 arguments for zaptel PPP */ 00119 argv[argc++] = PPP_EXEC; 00120 argv[argc++] = "nodetach"; 00121 00122 /* And all the other arguments */ 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 /* Finally launch PPP */ 00135 execv(PPP_EXEC, argv); 00136 fprintf(stderr, "Failed to exec PPPD!\n"); 00137 exit(1); 00138 }
static int unload_module | ( | void | ) | [static] |
Definition at line 241 of file app_zapras.c.
References ast_module_user_hangup_all, and ast_unregister_application().
00242 { 00243 int res; 00244 00245 res = ast_unregister_application(app); 00246 00247 ast_module_user_hangup_all(); 00248 00249 return res; 00250 }
static int zapras_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 199 of file app_zapras.c.
References ast_channel::_state, ast_answer(), ast_log(), ast_module_user_add, ast_module_user_remove, AST_STATE_UP, ast_strdupa, ast_verbose(), ast_channel::fds, LOG_WARNING, option_verbose, run_ras(), ast_channel::tech, ast_channel_tech::type, VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3.
Referenced by load_module().
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 /* Answer the channel if it's not up */ 00214 if (chan->_state != AST_STATE_UP) 00215 ast_answer(chan); 00216 if (strcasecmp(chan->tech->type, "Zap")) { 00217 /* If it's not a zap channel, we're done. Wait a couple of 00218 seconds and then hangup... */ 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 /* Everything should be okay. Run PPP. */ 00231 if (option_verbose > 2) 00232 ast_verbose(VERBOSE_PREFIX_3 "Starting RAS on %s\n", chan->name); 00233 /* Execute RAS */ 00234 run_ras(chan, args); 00235 } 00236 } 00237 ast_module_user_remove(u); 00238 return res; 00239 }
char* app = "ZapRAS" [static] |
Definition at line 61 of file app_zapras.c.
char* descrip [static] |
Definition at line 65 of file app_zapras.c.
char* synopsis = "Executes Zaptel ISDN RAS application" [static] |
Definition at line 63 of file app_zapras.c.