Mon Mar 19 11:30:31 2012

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.

Defines

#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 = "88eaa8f5c1bd988bedd71113385e0886" , .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 <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

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, LOG_WARNING, and run_ras().

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

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

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


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 = "88eaa8f5c1bd988bedd71113385e0886" , .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.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 236 of file app_dahdiras.c.


Generated on Mon Mar 19 11:30:31 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7