Thu Jul 9 13:40:44 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 <dahdi/user.h>
#include <fcntl.h>
#include <sys/capability.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, }
static char * app = "DAHDIRAS"
static const 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 71 of file app_dahdiras.c.

Referenced by spawn_ras().

#define PPP_MAX_ARGS   32

Definition at line 70 of file app_dahdiras.c.

Referenced by spawn_ras().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 252 of file app_dahdiras.c.

static void __unreg_module ( void   )  [static]

Definition at line 252 of file app_dahdiras.c.

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

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

00208 {
00209    int res=-1;
00210    char *args;
00211    struct dahdi_params dahdip;
00212 
00213    if (!data) 
00214       data = "";
00215 
00216    args = ast_strdupa(data);
00217    
00218    /* Answer the channel if it's not up */
00219    if (chan->_state != AST_STATE_UP)
00220       ast_answer(chan);
00221    if (strcasecmp(chan->tech->type, "DAHDI")) {
00222       /* If it's not a DAHDI channel, we're done.  Wait a couple of
00223          seconds and then hangup... */
00224       ast_verb(2, "Channel %s is not a DAHDI channel\n", chan->name);
00225       sleep(2);
00226    } else {
00227       memset(&dahdip, 0, sizeof(dahdip));
00228       if (ioctl(chan->fds[0], DAHDI_GET_PARAMS, &dahdip)) {
00229          ast_log(LOG_WARNING, "Unable to get DAHDI parameters\n");
00230       } else if (dahdip.sigtype != DAHDI_SIG_CLEAR) {
00231          ast_verb(2, "Channel %s is not a clear channel\n", chan->name);
00232       } else {
00233          /* Everything should be okay.  Run PPP. */
00234          ast_verb(3, "Starting RAS on %s\n", chan->name);
00235          /* Execute RAS */
00236          run_ras(chan, args);
00237       }
00238    }
00239    return res;
00240 }

static int load_module ( void   )  [static]

Definition at line 247 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 150 of file app_dahdiras.c.

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

Referenced by dahdiras_exec().

00151 {
00152    pid_t pid;
00153    int status;
00154    int res;
00155    int signalled = 0;
00156    struct dahdi_bufferinfo savebi;
00157    int x;
00158    
00159    res = ioctl(chan->fds[0], DAHDI_GET_BUFINFO, &savebi);
00160    if(res) {
00161       ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name);
00162       return;
00163    }
00164 
00165    pid = spawn_ras(chan, args);
00166    if (pid < 0) {
00167       ast_log(LOG_WARNING, "Failed to spawn RAS\n");
00168    } else {
00169       for (;;) {
00170          res = wait4(pid, &status, WNOHANG, NULL);
00171          if (!res) {
00172             /* Check for hangup */
00173             if (ast_check_hangup(chan) && !signalled) {
00174                ast_debug(1, "Channel '%s' hungup.  Signalling RAS at %d to die...\n", chan->name, pid);
00175                kill(pid, SIGTERM);
00176                signalled=1;
00177             }
00178             /* Try again */
00179             sleep(1);
00180             continue;
00181          }
00182          if (res < 0) {
00183             ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno));
00184          }
00185          if (WIFEXITED(status)) {
00186             ast_verb(3, "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status));
00187          } else if (WIFSIGNALED(status)) {
00188             ast_verb(3, "RAS on %s terminated with signal %d\n", 
00189                 chan->name, WTERMSIG(status));
00190          } else {
00191             ast_verb(3, "RAS on %s terminated weirdly.\n", chan->name);
00192          }
00193          /* Throw back into audio mode */
00194          x = 1;
00195          ioctl(chan->fds[0], DAHDI_AUDIOMODE, &x);
00196 
00197          /* Restore saved values */
00198          res = ioctl(chan->fds[0], DAHDI_SET_BUFINFO, &savebi);
00199          if (res < 0) {
00200             ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name);
00201          }
00202          break;
00203       }
00204    }
00205 }

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

Definition at line 73 of file app_dahdiras.c.

References ast_log(), ast_opt_high_priority, ast_set_priority(), chan, ast_channel::fds, LOG_WARNING, PPP_EXEC, PPP_MAX_ARGS, and strsep().

Referenced by run_ras().

00074 {
00075    pid_t pid;
00076    int x;   
00077    char *c;
00078 
00079    char *argv[PPP_MAX_ARGS];
00080    int argc = 0;
00081    char *stringp=NULL;
00082    sigset_t fullset, oldset;
00083 #ifdef HAVE_CAP
00084    cap_t cap;
00085 #endif
00086 
00087    sigfillset(&fullset);
00088    pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
00089 
00090    /* Start by forking */
00091    pid = fork();
00092    if (pid) {
00093       pthread_sigmask(SIG_SETMASK, &oldset, NULL);
00094       return pid;
00095    }
00096 
00097 #ifdef HAVE_CAP
00098    cap = cap_from_text("cap_net_admin-eip");
00099 
00100    if (cap_set_proc(cap)) {
00101       /* Careful with order! Logging cannot happen after we close FDs */
00102       ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
00103    }
00104    cap_free(cap);
00105 #endif
00106 
00107    /* Restore original signal handlers */
00108    for (x=0;x<NSIG;x++)
00109       signal(x, SIG_DFL);
00110 
00111    pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
00112 
00113    /* Execute RAS on File handles */
00114    dup2(chan->fds[0], STDIN_FILENO);
00115 
00116    /* Drop high priority */
00117    if (ast_opt_high_priority)
00118       ast_set_priority(0);
00119 
00120    /* Close other file descriptors */
00121    for (x=STDERR_FILENO + 1;x<1024;x++) 
00122       close(x);
00123 
00124    /* Reset all arguments */
00125    memset(argv, 0, sizeof(argv));
00126 
00127    /* First argument is executable, followed by standard
00128       arguments for dahdi PPP */
00129    argv[argc++] = PPP_EXEC;
00130    argv[argc++] = "nodetach";
00131 
00132    /* And all the other arguments */
00133    stringp=args;
00134    c = strsep(&stringp, ",");
00135    while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
00136       argv[argc++] = c;
00137       c = strsep(&stringp, ",");
00138    }
00139 
00140    argv[argc++] = "plugin";
00141    argv[argc++] = "dahdi.so";
00142    argv[argc++] = "stdin";
00143 
00144    /* Finally launch PPP */
00145    execv(PPP_EXEC, argv);
00146    fprintf(stderr, "Failed to exec PPPD!\n");
00147    exit(1);
00148 }

static int unload_module ( void   )  [static]

Definition at line 242 of file app_dahdiras.c.

References ast_unregister_application().

00243 {
00244    return ast_unregister_application(app);
00245 }


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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } [static]

Definition at line 252 of file app_dahdiras.c.

char* app = "DAHDIRAS" [static]

Definition at line 58 of file app_dahdiras.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 252 of file app_dahdiras.c.

char* descrip [static]

Definition at line 62 of file app_dahdiras.c.

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

Definition at line 60 of file app_dahdiras.c.


Generated on Thu Jul 9 13:40:44 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7