Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
app_dahdiras.c File Reference

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"
Include dependency graph for app_dahdiras.c:

Go to the source code of this file.

Macros

#define PPP_EXEC   "/usr/sbin/pppd"
 
#define PPP_MAX_ARGS   32
 

Functions

 AST_MODULE_INFO_STANDARD_DEPRECATED (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"
 

Detailed Description

Execute an ISDN RAS.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file app_dahdiras.c.

Macro Definition Documentation

◆ PPP_EXEC

#define PPP_EXEC   "/usr/sbin/pppd"

Definition at line 73 of file app_dahdiras.c.

Referenced by spawn_ras().

◆ PPP_MAX_ARGS

#define PPP_MAX_ARGS   32

Definition at line 72 of file app_dahdiras.c.

Referenced by spawn_ras().

Function Documentation

◆ AST_MODULE_INFO_STANDARD_DEPRECATED()

AST_MODULE_INFO_STANDARD_DEPRECATED ( ASTERISK_GPL_KEY  ,
"DAHDI ISDN Remote Access Server"   
)

Referenced by load_module().

◆ dahdiras_exec()

static int dahdiras_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 186 of file app_dahdiras.c.

References args, ast_answer(), ast_channel_fd(), ast_channel_name(), ast_channel_tech(), ast_log, AST_STATE_UP, ast_strdupa, ast_verb, LOG_WARNING, run_ras(), and type.

Referenced by load_module().

187 {
188  int res=-1;
189  char *args;
190  struct dahdi_params dahdip;
191 
192  if (!data)
193  data = "";
194 
195  args = ast_strdupa(data);
196 
197  /* Answer the channel if it's not up */
198  if (ast_channel_state(chan) != AST_STATE_UP)
199  ast_answer(chan);
200  if (strcasecmp(ast_channel_tech(chan)->type, "DAHDI")) {
201  /* If it's not a DAHDI channel, we're done. Wait a couple of
202  seconds and then hangup... */
203  ast_verb(2, "Channel %s is not a DAHDI channel\n", ast_channel_name(chan));
204  sleep(2);
205  } else {
206  memset(&dahdip, 0, sizeof(dahdip));
207  if (ioctl(ast_channel_fd(chan, 0), DAHDI_GET_PARAMS, &dahdip)) {
208  ast_log(LOG_WARNING, "Unable to get DAHDI parameters\n");
209  } else if (dahdip.sigtype != DAHDI_SIG_CLEAR) {
210  ast_verb(2, "Channel %s is not a clear channel\n", ast_channel_name(chan));
211  } else {
212  /* Everything should be okay. Run PPP. */
213  ast_verb(3, "Starting RAS on %s\n", ast_channel_name(chan));
214  /* Execute RAS */
215  run_ras(chan, args);
216  }
217  }
218  return res;
219 }
static const char type[]
Definition: chan_ooh323.c:109
#define LOG_WARNING
Definition: logger.h:274
ast_channel_state
ast_channel states
Definition: channelstate.h:35
const char * args
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_channel_fd(const struct ast_channel *chan, int which)
const char * ast_channel_name(const struct ast_channel *chan)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
static void run_ras(struct ast_channel *chan, char *args)
Definition: app_dahdiras.c:128
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)

◆ load_module()

static int load_module ( void  )
static

Definition at line 226 of file app_dahdiras.c.

References app, AST_MODULE_INFO_STANDARD_DEPRECATED(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_application_xml, ASTERISK_GPL_KEY, and dahdiras_exec().

227 {
229 }
static int dahdiras_exec(struct ast_channel *chan, const char *data)
Definition: app_dahdiras.c:186
static const char app[]
Definition: app_dahdiras.c:70
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

◆ run_ras()

static void run_ras ( struct ast_channel chan,
char *  args 
)
static

Definition at line 128 of file app_dahdiras.c.

References ast_channel_fd(), ast_channel_name(), ast_check_hangup(), ast_debug, ast_log, ast_safe_fork_cleanup(), ast_verb, errno, LOG_WARNING, spawn_ras(), status, WEXITSTATUS, and WIFEXITED.

Referenced by dahdiras_exec().

129 {
130  pid_t pid;
131  int status;
132  int res;
133  int signalled = 0;
134  struct dahdi_bufferinfo savebi;
135  int x;
136 
137  res = ioctl(ast_channel_fd(chan, 0), DAHDI_GET_BUFINFO, &savebi);
138  if(res) {
139  ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", ast_channel_name(chan));
140  return;
141  }
142 
143  pid = spawn_ras(chan, args);
144  if (pid < 0) {
145  ast_log(LOG_WARNING, "Failed to spawn RAS\n");
146  } else {
147  for (;;) {
148  res = waitpid(pid, &status, WNOHANG);
149  if (!res) {
150  /* Check for hangup */
151  if (ast_check_hangup(chan) && !signalled) {
152  ast_debug(1, "Channel '%s' hungup. Signalling RAS at %d to die...\n", ast_channel_name(chan), pid);
153  kill(pid, SIGTERM);
154  signalled=1;
155  }
156  /* Try again */
157  sleep(1);
158  continue;
159  }
160  if (res < 0) {
161  ast_log(LOG_WARNING, "waitpid returned %d: %s\n", res, strerror(errno));
162  }
163  if (WIFEXITED(status)) {
164  ast_verb(3, "RAS on %s terminated with status %d\n", ast_channel_name(chan), WEXITSTATUS(status));
165  } else if (WIFSIGNALED(status)) {
166  ast_verb(3, "RAS on %s terminated with signal %d\n",
167  ast_channel_name(chan), WTERMSIG(status));
168  } else {
169  ast_verb(3, "RAS on %s terminated weirdly.\n", ast_channel_name(chan));
170  }
171  /* Throw back into audio mode */
172  x = 1;
173  ioctl(ast_channel_fd(chan, 0), DAHDI_AUDIOMODE, &x);
174 
175  /* Restore saved values */
176  res = ioctl(ast_channel_fd(chan, 0), DAHDI_SET_BUFINFO, &savebi);
177  if (res < 0) {
178  ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", ast_channel_name(chan));
179  }
180  break;
181  }
182  }
184 }
#define LOG_WARNING
Definition: logger.h:274
static pid_t spawn_ras(struct ast_channel *chan, char *args)
Definition: app_dahdiras.c:75
const char * args
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
void ast_safe_fork_cleanup(void)
Common routine to cleanup after fork&#39;ed process is complete (if reaping was stopped) ...
Definition: main/app.c:3108
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
int errno
int ast_channel_fd(const struct ast_channel *chan, int which)
const char * ast_channel_name(const struct ast_channel *chan)
#define WEXITSTATUS(status)
#define WIFEXITED(status)
jack_status_t status
Definition: app_jack.c:146

◆ spawn_ras()

static pid_t spawn_ras ( struct ast_channel chan,
char *  args 
)
static

Definition at line 75 of file app_dahdiras.c.

References args, ast_channel_fd(), ast_close_fds_above_n(), ast_opt_high_priority, ast_safe_fork(), ast_set_priority(), c, NULL, PPP_EXEC, PPP_MAX_ARGS, and strsep().

Referenced by run_ras().

76 {
77  pid_t pid;
78  char *c;
79 
80  char *argv[PPP_MAX_ARGS];
81  int argc = 0;
82  char *stringp=NULL;
83 
84  /* Start by forking */
85  pid = ast_safe_fork(1);
86  if (pid) {
87  return pid;
88  }
89 
90  /* Execute RAS on File handles */
91  dup2(ast_channel_fd(chan, 0), STDIN_FILENO);
92 
93  /* Drop high priority */
96 
97  /* Close other file descriptors */
98  ast_close_fds_above_n(STDERR_FILENO);
99 
100  /* Reset all arguments */
101  memset(argv, 0, sizeof(argv));
102 
103  /* First argument is executable, followed by standard
104  arguments for DAHDI PPP */
105  argv[argc++] = PPP_EXEC;
106  argv[argc++] = "nodetach";
107 
108  /* And all the other arguments */
109  stringp=args;
110  c = strsep(&stringp, ",");
111  while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
112  argv[argc++] = c;
113  c = strsep(&stringp, ",");
114  }
115 
116  if (geteuid() == 0) {
117  argv[argc++] = "plugin";
118  argv[argc++] = "dahdi.so";
119  }
120  argv[argc++] = "stdin";
121 
122  /* Finally launch PPP */
123  execv(PPP_EXEC, argv);
124  fprintf(stderr, "Failed to exec PPPD!\n");
125  exit(1);
126 }
void ast_close_fds_above_n(int n)
Common routine for child processes, to close all fds prior to exec(2)
Definition: main/app.c:3042
static struct test_val c
const char * args
#define NULL
Definition: resample.c:96
int ast_set_priority(int)
We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy ac...
Definition: asterisk.c:1799
int ast_safe_fork(int stop_reaper)
Common routine to safely fork without a chance of a signal handler firing badly in the child...
Definition: main/app.c:3047
#define PPP_MAX_ARGS
Definition: app_dahdiras.c:72
int ast_channel_fd(const struct ast_channel *chan, int which)
char * strsep(char **str, const char *delims)
#define PPP_EXEC
Definition: app_dahdiras.c:73
#define ast_opt_high_priority
Definition: options.h:110

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 221 of file app_dahdiras.c.

References app, and ast_unregister_application().

222 {
224 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
static const char app[]
Definition: app_dahdiras.c:70

Variable Documentation

◆ app

const char app[] = "DAHDIRAS"
static

Definition at line 70 of file app_dahdiras.c.

Referenced by load_module(), and unload_module().