#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 "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"
#include "asterisk/dahdi_compat.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,"DAHDI RAS Application") | |
static int | exec (struct ast_channel *chan, void *data) |
static int | exec_warn (struct ast_channel *chan, void *data) |
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) |
Variables | |
static char * | dahdi_app = "DAHDIRAS" |
static char * | dahdi_descrip |
static char * | dahdi_synopsis = "Executes DAHDI ISDN RAS application" |
static char * | zap_app = "ZapRAS" |
static char * | zap_descrip |
static char * | zap_synopsis = "Executes Zaptel ISDN RAS application" |
Definition in file app_dahdiras.c.
#define PPP_EXEC "/usr/sbin/pppd" |
#define PPP_MAX_ARGS 32 |
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"DAHDI RAS Application" | ||||
) |
static int exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 212 of file app_dahdiras.c.
References ast_channel::_state, ast_answer(), ast_log(), ast_module_user_add, ast_module_user_remove, AST_STATE_UP, ast_strdupa, ast_verbose(), dahdi_chan_name, LOG_WARNING, option_verbose, run_ras(), VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3.
00213 { 00214 int res=-1; 00215 char *args; 00216 struct ast_module_user *u; 00217 struct dahdi_params ztp; 00218 00219 if (!data) 00220 data = ""; 00221 00222 u = ast_module_user_add(chan); 00223 00224 args = ast_strdupa(data); 00225 00226 /* Answer the channel if it's not up */ 00227 if (chan->_state != AST_STATE_UP) 00228 ast_answer(chan); 00229 if (strcasecmp(chan->tech->type, dahdi_chan_name)) { 00230 if (option_verbose > 1) 00231 ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a %s channel\n", chan->name, dahdi_chan_name); 00232 sleep(2); 00233 } else { 00234 memset(&ztp, 0, sizeof(ztp)); 00235 if (ioctl(chan->fds[0], DAHDI_GET_PARAMS, &ztp)) { 00236 ast_log(LOG_WARNING, "Unable to get parameters\n"); 00237 } else if (ztp.sigtype != DAHDI_SIG_CLEAR) { 00238 if (option_verbose > 1) 00239 ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a clear channel\n", chan->name); 00240 } else { 00241 /* Everything should be okay. Run PPP. */ 00242 if (option_verbose > 2) 00243 ast_verbose(VERBOSE_PREFIX_3 "Starting RAS on %s\n", chan->name); 00244 /* Execute RAS */ 00245 run_ras(chan, args); 00246 } 00247 } 00248 ast_module_user_remove(u); 00249 return res; 00250 }
static int exec_warn | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 252 of file app_dahdiras.c.
References ast_log(), dahdi_app, exec(), LOG_WARNING, and zap_app.
Referenced by load_module().
00253 { 00254 ast_log(LOG_WARNING, "Use of the command %s is deprecated, please use %s instead.\n", zap_app, dahdi_app); 00255 00256 return exec(chan, data); 00257 }
static int load_module | ( | void | ) | [static] |
Definition at line 274 of file app_dahdiras.c.
References ast_register_application(), CHAN_DAHDI_PLUS_ZAP_MODE, dahdi_app, dahdi_chan_mode, dahdi_descrip, dahdi_synopsis, exec(), exec_warn(), zap_app, zap_descrip, and zap_synopsis.
00275 { 00276 int res = 0; 00277 00278 if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { 00279 res |= ast_register_application(dahdi_app, exec, dahdi_synopsis, dahdi_descrip); 00280 } 00281 00282 res |= ast_register_application(zap_app, exec_warn, zap_synopsis, zap_descrip); 00283 00284 return res; 00285 }
static void run_ras | ( | struct ast_channel * | chan, | |
char * | args | |||
) | [static] |
Definition at line 153 of file app_dahdiras.c.
References ast_channel::_softhangup, ast_log(), ast_verbose(), errno, ast_channel::fds, LOG_DEBUG, LOG_WARNING, option_verbose, spawn_ras(), VERBOSE_PREFIX_3, WEXITSTATUS, and WIFEXITED.
Referenced by exec().
00154 { 00155 pid_t pid; 00156 int status; 00157 int res; 00158 int signalled = 0; 00159 struct dahdi_bufferinfo savebi; 00160 int x; 00161 00162 res = ioctl(chan->fds[0], DAHDI_GET_BUFINFO, &savebi); 00163 if(res) { 00164 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name); 00165 return; 00166 } 00167 00168 pid = spawn_ras(chan, args); 00169 if (pid < 0) { 00170 ast_log(LOG_WARNING, "Failed to spawn RAS\n"); 00171 } else { 00172 for (;;) { 00173 res = wait4(pid, &status, WNOHANG, NULL); 00174 if (!res) { 00175 /* Check for hangup */ 00176 if (chan->_softhangup && !signalled) { 00177 ast_log(LOG_DEBUG, "Channel '%s' hungup. Signalling RAS at %d to die...\n", chan->name, pid); 00178 kill(pid, SIGTERM); 00179 signalled=1; 00180 } 00181 /* Try again */ 00182 sleep(1); 00183 continue; 00184 } 00185 if (res < 0) { 00186 ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno)); 00187 } 00188 if (option_verbose > 2) { 00189 if (WIFEXITED(status)) { 00190 ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status)); 00191 } else if (WIFSIGNALED(status)) { 00192 ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with signal %d\n", 00193 chan->name, WTERMSIG(status)); 00194 } else { 00195 ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated weirdly.\n", chan->name); 00196 } 00197 } 00198 /* Throw back into audio mode */ 00199 x = 1; 00200 ioctl(chan->fds[0], DAHDI_AUDIOMODE, &x); 00201 00202 /* Restore saved values */ 00203 res = ioctl(chan->fds[0], DAHDI_SET_BUFINFO, &savebi); 00204 if (res < 0) { 00205 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name); 00206 } 00207 break; 00208 } 00209 } 00210 }
static pid_t spawn_ras | ( | struct ast_channel * | chan, | |
char * | args | |||
) | [static] |
Definition at line 85 of file app_dahdiras.c.
References ast_opt_high_priority, ast_set_priority(), ast_module_user::chan, ast_channel::fds, PPP_EXEC, PPP_MAX_ARGS, and strsep().
Referenced by run_ras().
00086 { 00087 pid_t pid; 00088 int x; 00089 char *c; 00090 00091 char *argv[PPP_MAX_ARGS]; 00092 int argc = 0; 00093 char *stringp=NULL; 00094 sigset_t fullset, oldset; 00095 00096 sigfillset(&fullset); 00097 pthread_sigmask(SIG_BLOCK, &fullset, &oldset); 00098 00099 /* Start by forking */ 00100 pid = fork(); 00101 if (pid) { 00102 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 00103 return pid; 00104 } 00105 00106 /* Restore original signal handlers */ 00107 for (x=0;x<NSIG;x++) 00108 signal(x, SIG_DFL); 00109 00110 pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); 00111 00112 /* Execute RAS on File handles */ 00113 dup2(chan->fds[0], STDIN_FILENO); 00114 00115 /* Drop high priority */ 00116 if (ast_opt_high_priority) 00117 ast_set_priority(0); 00118 00119 /* Close other file descriptors */ 00120 for (x=STDERR_FILENO + 1;x<1024;x++) 00121 close(x); 00122 00123 /* Reset all arguments */ 00124 memset(argv, 0, sizeof(argv)); 00125 00126 /* First argument is executable, followed by standard 00127 arguments for DAHDI PPP */ 00128 argv[argc++] = PPP_EXEC; 00129 argv[argc++] = "nodetach"; 00130 00131 /* And all the other arguments */ 00132 stringp=args; 00133 c = strsep(&stringp, "|"); 00134 while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) { 00135 argv[argc++] = c; 00136 c = strsep(&stringp, "|"); 00137 } 00138 00139 argv[argc++] = "plugin"; 00140 #ifdef HAVE_ZAPTEL 00141 argv[argc++] = "zaptel.so"; 00142 #else 00143 argv[argc++] = "dahdi.so"; 00144 #endif 00145 argv[argc++] = "stdin"; 00146 00147 /* Finally launch PPP */ 00148 execv(PPP_EXEC, argv); 00149 fprintf(stderr, "Failed to exec PPPD!\n"); 00150 exit(1); 00151 }
static int unload_module | ( | void | ) | [static] |
Definition at line 259 of file app_dahdiras.c.
References ast_module_user_hangup_all, ast_unregister_application(), CHAN_DAHDI_PLUS_ZAP_MODE, dahdi_app, dahdi_chan_mode, and zap_app.
00260 { 00261 int res = 0; 00262 00263 if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { 00264 res |= ast_unregister_application(dahdi_app); 00265 } 00266 00267 res |= ast_unregister_application(zap_app); 00268 00269 ast_module_user_hangup_all(); 00270 00271 return res; 00272 }
char* dahdi_app = "DAHDIRAS" [static] |
Definition at line 62 of file app_dahdiras.c.
char* dahdi_descrip [static] |
Definition at line 68 of file app_dahdiras.c.
char* dahdi_synopsis = "Executes DAHDI ISDN RAS application" [static] |
Definition at line 65 of file app_dahdiras.c.
char* zap_app = "ZapRAS" [static] |
Definition at line 63 of file app_dahdiras.c.
char* zap_descrip [static] |
Definition at line 75 of file app_dahdiras.c.
char* zap_synopsis = "Executes Zaptel ISDN RAS application" [static] |
Definition at line 66 of file app_dahdiras.c.