Execute an ISDN RAS. More...
#include "asterisk.h"
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <signal.h>
#include <fcntl.h>
#include <dahdi/user.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/app.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 ISDN Remote Access Server") | |
static int | dahdiras_exec (struct ast_channel *chan, const char *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 const char | app [] = "DAHDIRAS" |
Execute an ISDN RAS.
Definition in file app_dahdiras.c.
#define PPP_EXEC "/usr/sbin/pppd" |
Definition at line 80 of file app_dahdiras.c.
Referenced by spawn_ras().
#define PPP_MAX_ARGS 32 |
Definition at line 79 of file app_dahdiras.c.
Referenced by spawn_ras().
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"DAHDI ISDN Remote Access Server" | ||||
) |
static int dahdiras_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 191 of file app_dahdiras.c.
References ast_channel::_state, args, ast_answer(), ast_log(), AST_STATE_UP, ast_strdupa, ast_verb, ast_channel::fds, LOG_WARNING, run_ras(), ast_channel::tech, and ast_channel_tech::type.
Referenced by load_module().
00192 { 00193 int res=-1; 00194 char *args; 00195 struct dahdi_params dahdip; 00196 00197 if (!data) 00198 data = ""; 00199 00200 args = ast_strdupa(data); 00201 00202 /* Answer the channel if it's not up */ 00203 if (chan->_state != AST_STATE_UP) 00204 ast_answer(chan); 00205 if (strcasecmp(chan->tech->type, "DAHDI")) { 00206 /* If it's not a DAHDI channel, we're done. Wait a couple of 00207 seconds and then hangup... */ 00208 ast_verb(2, "Channel %s is not a DAHDI channel\n", chan->name); 00209 sleep(2); 00210 } else { 00211 memset(&dahdip, 0, sizeof(dahdip)); 00212 if (ioctl(chan->fds[0], DAHDI_GET_PARAMS, &dahdip)) { 00213 ast_log(LOG_WARNING, "Unable to get DAHDI parameters\n"); 00214 } else if (dahdip.sigtype != DAHDI_SIG_CLEAR) { 00215 ast_verb(2, "Channel %s is not a clear channel\n", chan->name); 00216 } else { 00217 /* Everything should be okay. Run PPP. */ 00218 ast_verb(3, "Starting RAS on %s\n", chan->name); 00219 /* Execute RAS */ 00220 run_ras(chan, args); 00221 } 00222 } 00223 return res; 00224 }
static int load_module | ( | void | ) | [static] |
Definition at line 231 of file app_dahdiras.c.
References AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application_xml, and dahdiras_exec().
00232 { 00233 return ((ast_register_application_xml(app, dahdiras_exec)) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS); 00234 }
static void run_ras | ( | struct ast_channel * | chan, | |
char * | args | |||
) | [static] |
Definition at line 133 of file app_dahdiras.c.
References ast_check_hangup(), ast_debug, ast_log(), ast_safe_fork_cleanup(), ast_verb, errno, ast_channel::fds, LOG_WARNING, spawn_ras(), status, WEXITSTATUS, and WIFEXITED.
Referenced by dahdiras_exec().
00134 { 00135 pid_t pid; 00136 int status; 00137 int res; 00138 int signalled = 0; 00139 struct dahdi_bufferinfo savebi; 00140 int x; 00141 00142 res = ioctl(chan->fds[0], DAHDI_GET_BUFINFO, &savebi); 00143 if(res) { 00144 ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name); 00145 return; 00146 } 00147 00148 pid = spawn_ras(chan, args); 00149 if (pid < 0) { 00150 ast_log(LOG_WARNING, "Failed to spawn RAS\n"); 00151 } else { 00152 for (;;) { 00153 res = wait4(pid, &status, WNOHANG, NULL); 00154 if (!res) { 00155 /* Check for hangup */ 00156 if (ast_check_hangup(chan) && !signalled) { 00157 ast_debug(1, "Channel '%s' hungup. Signalling RAS at %d to die...\n", chan->name, pid); 00158 kill(pid, SIGTERM); 00159 signalled=1; 00160 } 00161 /* Try again */ 00162 sleep(1); 00163 continue; 00164 } 00165 if (res < 0) { 00166 ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno)); 00167 } 00168 if (WIFEXITED(status)) { 00169 ast_verb(3, "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status)); 00170 } else if (WIFSIGNALED(status)) { 00171 ast_verb(3, "RAS on %s terminated with signal %d\n", 00172 chan->name, WTERMSIG(status)); 00173 } else { 00174 ast_verb(3, "RAS on %s terminated weirdly.\n", chan->name); 00175 } 00176 /* Throw back into audio mode */ 00177 x = 1; 00178 ioctl(chan->fds[0], DAHDI_AUDIOMODE, &x); 00179 00180 /* Restore saved values */ 00181 res = ioctl(chan->fds[0], DAHDI_SET_BUFINFO, &savebi); 00182 if (res < 0) { 00183 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name); 00184 } 00185 break; 00186 } 00187 } 00188 ast_safe_fork_cleanup(); 00189 }
static pid_t spawn_ras | ( | struct ast_channel * | chan, | |
char * | args | |||
) | [static] |
Definition at line 82 of file app_dahdiras.c.
References ast_close_fds_above_n(), ast_opt_high_priority, ast_safe_fork(), ast_set_priority(), ast_channel::fds, PPP_EXEC, and PPP_MAX_ARGS.
Referenced by run_ras().
00083 { 00084 pid_t pid; 00085 char *c; 00086 00087 char *argv[PPP_MAX_ARGS]; 00088 int argc = 0; 00089 char *stringp=NULL; 00090 00091 /* Start by forking */ 00092 pid = ast_safe_fork(1); 00093 if (pid) { 00094 return pid; 00095 } 00096 00097 /* Execute RAS on File handles */ 00098 dup2(chan->fds[0], STDIN_FILENO); 00099 00100 /* Drop high priority */ 00101 if (ast_opt_high_priority) 00102 ast_set_priority(0); 00103 00104 /* Close other file descriptors */ 00105 ast_close_fds_above_n(STDERR_FILENO); 00106 00107 /* Reset all arguments */ 00108 memset(argv, 0, sizeof(argv)); 00109 00110 /* First argument is executable, followed by standard 00111 arguments for DAHDI PPP */ 00112 argv[argc++] = PPP_EXEC; 00113 argv[argc++] = "nodetach"; 00114 00115 /* And all the other arguments */ 00116 stringp=args; 00117 c = strsep(&stringp, ","); 00118 while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) { 00119 argv[argc++] = c; 00120 c = strsep(&stringp, ","); 00121 } 00122 00123 argv[argc++] = "plugin"; 00124 argv[argc++] = "dahdi.so"; 00125 argv[argc++] = "stdin"; 00126 00127 /* Finally launch PPP */ 00128 execv(PPP_EXEC, argv); 00129 fprintf(stderr, "Failed to exec PPPD!\n"); 00130 exit(1); 00131 }
static int unload_module | ( | void | ) | [static] |
Definition at line 226 of file app_dahdiras.c.
References ast_unregister_application().
00227 { 00228 return ast_unregister_application(app); 00229 }
const char app[] = "DAHDIRAS" [static] |
Definition at line 77 of file app_dahdiras.c.