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.

Defines

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

Functions

 AST_MODULE_INFO_STANDARD_EXTENDED (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 <markster@digium.com>

Definition in file app_dahdiras.c.


Define 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

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

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 (ast_channel_state(chan) != AST_STATE_UP)
00204       ast_answer(chan);
00205    if (strcasecmp(ast_channel_tech(chan)->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", ast_channel_name(chan));
00209       sleep(2);
00210    } else {
00211       memset(&dahdip, 0, sizeof(dahdip));
00212       if (ioctl(ast_channel_fd(chan, 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", ast_channel_name(chan));
00216       } else {
00217          /* Everything should be okay.  Run PPP. */
00218          ast_verb(3, "Starting RAS on %s\n", ast_channel_name(chan));
00219          /* Execute RAS */
00220          run_ras(chan, args);
00221       }
00222    }
00223    return res;
00224 }

static int load_module ( void   )  [static]

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

Definition at line 133 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().

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(ast_channel_fd(chan, 0), DAHDI_GET_BUFINFO, &savebi);
00143    if(res) {
00144       ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", ast_channel_name(chan));
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 = waitpid(pid, &status, WNOHANG);
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", ast_channel_name(chan), 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, "waitpid returned %d: %s\n", res, strerror(errno));
00167          }
00168          if (WIFEXITED(status)) {
00169             ast_verb(3, "RAS on %s terminated with status %d\n", ast_channel_name(chan), WEXITSTATUS(status));
00170          } else if (WIFSIGNALED(status)) {
00171             ast_verb(3, "RAS on %s terminated with signal %d\n", 
00172                 ast_channel_name(chan), WTERMSIG(status));
00173          } else {
00174             ast_verb(3, "RAS on %s terminated weirdly.\n", ast_channel_name(chan));
00175          }
00176          /* Throw back into audio mode */
00177          x = 1;
00178          ioctl(ast_channel_fd(chan, 0), DAHDI_AUDIOMODE, &x);
00179 
00180          /* Restore saved values */
00181          res = ioctl(ast_channel_fd(chan, 0), DAHDI_SET_BUFINFO, &savebi);
00182          if (res < 0) {
00183             ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", ast_channel_name(chan));
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_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().

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(ast_channel_fd(chan, 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 }


Variable Documentation

const char app[] = "DAHDIRAS" [static]

Definition at line 77 of file app_dahdiras.c.


Generated on Thu Apr 16 06:28:23 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6