Wed Jan 8 2020 09:49:53

Asterisk developer's documentation


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"

Go to the source code of this file.

Macros

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

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
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 struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "DAHDI ISDN Remote Access Server" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
 
static const char app [] = "DAHDIRAS"
 
static struct ast_module_infoast_module_info = &__mod_info
 

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

#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().

Function Documentation

static void __reg_module ( void  )
static

Definition at line 236 of file app_dahdiras.c.

static void __unreg_module ( void  )
static

Definition at line 236 of file app_dahdiras.c.

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, ast_channel::name, run_ras(), ast_channel::tech, and ast_channel_tech::type.

Referenced by load_module().

192 {
193  int res=-1;
194  char *args;
195  struct dahdi_params dahdip;
196 
197  if (!data)
198  data = "";
199 
200  args = ast_strdupa(data);
201 
202  /* Answer the channel if it's not up */
203  if (chan->_state != AST_STATE_UP)
204  ast_answer(chan);
205  if (strcasecmp(chan->tech->type, "DAHDI")) {
206  /* If it's not a DAHDI channel, we're done. Wait a couple of
207  seconds and then hangup... */
208  ast_verb(2, "Channel %s is not a DAHDI channel\n", chan->name);
209  sleep(2);
210  } else {
211  memset(&dahdip, 0, sizeof(dahdip));
212  if (ioctl(chan->fds[0], DAHDI_GET_PARAMS, &dahdip)) {
213  ast_log(LOG_WARNING, "Unable to get DAHDI parameters\n");
214  } else if (dahdip.sigtype != DAHDI_SIG_CLEAR) {
215  ast_verb(2, "Channel %s is not a clear channel\n", chan->name);
216  } else {
217  /* Everything should be okay. Run PPP. */
218  ast_verb(3, "Starting RAS on %s\n", chan->name);
219  /* Execute RAS */
220  run_ras(chan, args);
221  }
222  }
223  return res;
224 }
const char *const type
Definition: channel.h:508
#define LOG_WARNING
Definition: logger.h:144
#define ast_verb(level,...)
Definition: logger.h:243
int fds[AST_MAX_FDS]
Definition: channel.h:829
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
static void run_ras(struct ast_channel *chan, char *args)
Definition: app_dahdiras.c:133
struct ast_channel_tech * tech
Definition: channel.h:743
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().

232 {
234 }
static int dahdiras_exec(struct ast_channel *chan, const char *data)
Definition: app_dahdiras.c:191
static const char app[]
Definition: app_dahdiras.c:77
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
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, ast_channel::name, spawn_ras(), status, WEXITSTATUS, and WIFEXITED.

Referenced by dahdiras_exec().

134 {
135  pid_t pid;
136  int status;
137  int res;
138  int signalled = 0;
139  struct dahdi_bufferinfo savebi;
140  int x;
141 
142  res = ioctl(chan->fds[0], DAHDI_GET_BUFINFO, &savebi);
143  if(res) {
144  ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name);
145  return;
146  }
147 
148  pid = spawn_ras(chan, args);
149  if (pid < 0) {
150  ast_log(LOG_WARNING, "Failed to spawn RAS\n");
151  } else {
152  for (;;) {
153  res = wait4(pid, &status, WNOHANG, NULL);
154  if (!res) {
155  /* Check for hangup */
156  if (ast_check_hangup(chan) && !signalled) {
157  ast_debug(1, "Channel '%s' hungup. Signalling RAS at %d to die...\n", chan->name, pid);
158  kill(pid, SIGTERM);
159  signalled=1;
160  }
161  /* Try again */
162  sleep(1);
163  continue;
164  }
165  if (res < 0) {
166  ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno));
167  }
168  if (WIFEXITED(status)) {
169  ast_verb(3, "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status));
170  } else if (WIFSIGNALED(status)) {
171  ast_verb(3, "RAS on %s terminated with signal %d\n",
172  chan->name, WTERMSIG(status));
173  } else {
174  ast_verb(3, "RAS on %s terminated weirdly.\n", chan->name);
175  }
176  /* Throw back into audio mode */
177  x = 1;
178  ioctl(chan->fds[0], DAHDI_AUDIOMODE, &x);
179 
180  /* Restore saved values */
181  res = ioctl(chan->fds[0], DAHDI_SET_BUFINFO, &savebi);
182  if (res < 0) {
183  ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name);
184  }
185  break;
186  }
187  }
189 }
#define LOG_WARNING
Definition: logger.h:144
void ast_safe_fork_cleanup(void)
Common routine to cleanup after fork&#39;ed process is complete (if reaping was stopped) ...
Definition: app.c:2306
static pid_t spawn_ras(struct ast_channel *chan, char *args)
Definition: app_dahdiras.c:82
#define WIFEXITED(status)
Definition: private.h:105
#define ast_verb(level,...)
Definition: logger.h:243
#define WEXITSTATUS(status)
Definition: private.h:108
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
int fds[AST_MAX_FDS]
Definition: channel.h:829
static struct @350 args
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
jack_status_t status
Definition: app_jack.c:143
static pid_t spawn_ras ( struct ast_channel chan,
char *  args 
)
static

Definition at line 82 of file app_dahdiras.c.

References args, ast_close_fds_above_n(), ast_opt_high_priority, ast_safe_fork(), ast_set_priority(), ast_channel::fds, PPP_EXEC, PPP_MAX_ARGS, and strsep().

Referenced by run_ras().

83 {
84  pid_t pid;
85  char *c;
86 
87  char *argv[PPP_MAX_ARGS];
88  int argc = 0;
89  char *stringp=NULL;
90 
91  /* Start by forking */
92  pid = ast_safe_fork(1);
93  if (pid) {
94  return pid;
95  }
96 
97  /* Execute RAS on File handles */
98  dup2(chan->fds[0], STDIN_FILENO);
99 
100  /* Drop high priority */
102  ast_set_priority(0);
103 
104  /* Close other file descriptors */
105  ast_close_fds_above_n(STDERR_FILENO);
106 
107  /* Reset all arguments */
108  memset(argv, 0, sizeof(argv));
109 
110  /* First argument is executable, followed by standard
111  arguments for DAHDI PPP */
112  argv[argc++] = PPP_EXEC;
113  argv[argc++] = "nodetach";
114 
115  /* And all the other arguments */
116  stringp=args;
117  c = strsep(&stringp, ",");
118  while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
119  argv[argc++] = c;
120  c = strsep(&stringp, ",");
121  }
122 
123  argv[argc++] = "plugin";
124  argv[argc++] = "dahdi.so";
125  argv[argc++] = "stdin";
126 
127  /* Finally launch PPP */
128  execv(PPP_EXEC, argv);
129  fprintf(stderr, "Failed to exec PPPD!\n");
130  exit(1);
131 }
char * strsep(char **str, const char *delims)
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: app.c:2242
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:1650
int fds[AST_MAX_FDS]
Definition: channel.h:829
static struct @350 args
void ast_close_fds_above_n(int n)
Common routine for child processes, to close all fds prior to exec(2)
Definition: app.c:2237
#define PPP_MAX_ARGS
Definition: app_dahdiras.c:79
#define PPP_EXEC
Definition: app_dahdiras.c:80
#define ast_opt_high_priority
Definition: options.h:108
static int unload_module ( void  )
static

Definition at line 226 of file app_dahdiras.c.

References ast_unregister_application().

227 {
229 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
static const char app[]
Definition: app_dahdiras.c:77

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "DAHDI ISDN Remote Access Server" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static

Definition at line 236 of file app_dahdiras.c.

const char app[] = "DAHDIRAS"
static

Definition at line 77 of file app_dahdiras.c.

Definition at line 236 of file app_dahdiras.c.