Fri Jun 19 12:09:56 2009

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, void *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_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, }
static char * app = "DAHDIRAS"
static struct ast_module_infoast_module_info = &__mod_info
static char * descrip
static char * synopsis = "Executes DAHDI ISDN RAS application"


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 68 of file app_dahdiras.c.

Referenced by spawn_ras().

#define PPP_MAX_ARGS   32

Definition at line 67 of file app_dahdiras.c.

Referenced by spawn_ras().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 224 of file app_dahdiras.c.

static void __unreg_module ( void   )  [static]

Definition at line 224 of file app_dahdiras.c.

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

Definition at line 179 of file app_dahdiras.c.

References ast_channel::_state, ast_answer(), ast_log(), AST_STATE_UP, ast_strdupa, ast_verb, chan, LOG_WARNING, and run_ras().

Referenced by load_module().

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

static int load_module ( void   )  [static]

Definition at line 219 of file app_dahdiras.c.

References AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application, and dahdiras_exec().

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

Definition at line 121 of file app_dahdiras.c.

References ast_check_hangup(), ast_debug, ast_log(), ast_safe_fork_cleanup(), ast_verb, chan, errno, ast_channel::fds, LOG_WARNING, ast_channel::name, spawn_ras(), status, WEXITSTATUS, and WIFEXITED.

Referenced by dahdiras_exec().

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

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

Definition at line 70 of file app_dahdiras.c.

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

Referenced by run_ras().

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

static int unload_module ( void   )  [static]

Definition at line 214 of file app_dahdiras.c.

References ast_unregister_application().

00215 {
00216    return ast_unregister_application(app);
00217 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static]

Definition at line 224 of file app_dahdiras.c.

char* app = "DAHDIRAS" [static]

Definition at line 55 of file app_dahdiras.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 224 of file app_dahdiras.c.

char* descrip [static]

Definition at line 59 of file app_dahdiras.c.

char* synopsis = "Executes DAHDI ISDN RAS application" [static]

Definition at line 57 of file app_dahdiras.c.


Generated on Fri Jun 19 12:09:56 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7