Wed Apr 6 11:29:49 2011

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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 79 of file app_dahdiras.c.

Referenced by spawn_ras().

#define PPP_MAX_ARGS   32

Definition at line 78 of file app_dahdiras.c.

Referenced by spawn_ras().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 235 of file app_dahdiras.c.

static void __unreg_module ( void   )  [static]

Definition at line 235 of file app_dahdiras.c.

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

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

00191 {
00192    int res=-1;
00193    char *args;
00194    struct dahdi_params dahdip;
00195 
00196    if (!data) 
00197       data = "";
00198 
00199    args = ast_strdupa(data);
00200    
00201    /* Answer the channel if it's not up */
00202    if (chan->_state != AST_STATE_UP)
00203       ast_answer(chan);
00204    if (strcasecmp(chan->tech->type, "DAHDI")) {
00205       /* If it's not a DAHDI channel, we're done.  Wait a couple of
00206          seconds and then hangup... */
00207       ast_verb(2, "Channel %s is not a DAHDI channel\n", chan->name);
00208       sleep(2);
00209    } else {
00210       memset(&dahdip, 0, sizeof(dahdip));
00211       if (ioctl(chan->fds[0], DAHDI_GET_PARAMS, &dahdip)) {
00212          ast_log(LOG_WARNING, "Unable to get DAHDI parameters\n");
00213       } else if (dahdip.sigtype != DAHDI_SIG_CLEAR) {
00214          ast_verb(2, "Channel %s is not a clear channel\n", chan->name);
00215       } else {
00216          /* Everything should be okay.  Run PPP. */
00217          ast_verb(3, "Starting RAS on %s\n", chan->name);
00218          /* Execute RAS */
00219          run_ras(chan, args);
00220       }
00221    }
00222    return res;
00223 }

static int load_module ( void   )  [static]

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

00133 {
00134    pid_t pid;
00135    int status;
00136    int res;
00137    int signalled = 0;
00138    struct dahdi_bufferinfo savebi;
00139    int x;
00140    
00141    res = ioctl(chan->fds[0], DAHDI_GET_BUFINFO, &savebi);
00142    if(res) {
00143       ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name);
00144       return;
00145    }
00146 
00147    pid = spawn_ras(chan, args);
00148    if (pid < 0) {
00149       ast_log(LOG_WARNING, "Failed to spawn RAS\n");
00150    } else {
00151       for (;;) {
00152          res = wait4(pid, &status, WNOHANG, NULL);
00153          if (!res) {
00154             /* Check for hangup */
00155             if (ast_check_hangup(chan) && !signalled) {
00156                ast_debug(1, "Channel '%s' hungup.  Signalling RAS at %d to die...\n", chan->name, pid);
00157                kill(pid, SIGTERM);
00158                signalled=1;
00159             }
00160             /* Try again */
00161             sleep(1);
00162             continue;
00163          }
00164          if (res < 0) {
00165             ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno));
00166          }
00167          if (WIFEXITED(status)) {
00168             ast_verb(3, "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status));
00169          } else if (WIFSIGNALED(status)) {
00170             ast_verb(3, "RAS on %s terminated with signal %d\n", 
00171                 chan->name, WTERMSIG(status));
00172          } else {
00173             ast_verb(3, "RAS on %s terminated weirdly.\n", chan->name);
00174          }
00175          /* Throw back into audio mode */
00176          x = 1;
00177          ioctl(chan->fds[0], DAHDI_AUDIOMODE, &x);
00178 
00179          /* Restore saved values */
00180          res = ioctl(chan->fds[0], DAHDI_SET_BUFINFO, &savebi);
00181          if (res < 0) {
00182             ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name);
00183          }
00184          break;
00185       }
00186    }
00187    ast_safe_fork_cleanup();
00188 }

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

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

00082 {
00083    pid_t pid;
00084    char *c;
00085 
00086    char *argv[PPP_MAX_ARGS];
00087    int argc = 0;
00088    char *stringp=NULL;
00089 
00090    /* Start by forking */
00091    pid = ast_safe_fork(1);
00092    if (pid) {
00093       return pid;
00094    }
00095 
00096    /* Execute RAS on File handles */
00097    dup2(chan->fds[0], STDIN_FILENO);
00098 
00099    /* Drop high priority */
00100    if (ast_opt_high_priority)
00101       ast_set_priority(0);
00102 
00103    /* Close other file descriptors */
00104    ast_close_fds_above_n(STDERR_FILENO);
00105 
00106    /* Reset all arguments */
00107    memset(argv, 0, sizeof(argv));
00108 
00109    /* First argument is executable, followed by standard
00110       arguments for DAHDI PPP */
00111    argv[argc++] = PPP_EXEC;
00112    argv[argc++] = "nodetach";
00113 
00114    /* And all the other arguments */
00115    stringp=args;
00116    c = strsep(&stringp, ",");
00117    while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
00118       argv[argc++] = c;
00119       c = strsep(&stringp, ",");
00120    }
00121 
00122    argv[argc++] = "plugin";
00123    argv[argc++] = "dahdi.so";
00124    argv[argc++] = "stdin";
00125 
00126    /* Finally launch PPP */
00127    execv(PPP_EXEC, argv);
00128    fprintf(stderr, "Failed to exec PPPD!\n");
00129    exit(1);
00130 }

static int unload_module ( void   )  [static]

Definition at line 225 of file app_dahdiras.c.

References ast_unregister_application().

00226 {
00227    return ast_unregister_application(app);
00228 }


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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 235 of file app_dahdiras.c.

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

Definition at line 76 of file app_dahdiras.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 235 of file app_dahdiras.c.


Generated on Wed Apr 6 11:29:49 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7