Sat Aug 6 00:39:34 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 <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include "asterisk/dahdi_compat.h"
#include <sys/capability.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/options.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 exec (struct ast_channel *chan, void *data)
static int exec_warn (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 | AST_MODFLAG_BUILDSUM, .description = "DAHDI RAS Application" , .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, }
static const struct ast_module_infoast_module_info = &__mod_info
static char * dahdi_app = "DAHDIRAS"
static char * dahdi_descrip
static char * dahdi_synopsis = "Executes DAHDI ISDN RAS application"
static char * zap_app = "ZapRAS"
static char * zap_descrip
static char * zap_synopsis = "Executes Zaptel 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 88 of file app_dahdiras.c.

Referenced by spawn_ras().

#define PPP_MAX_ARGS   32

Definition at line 87 of file app_dahdiras.c.

Referenced by spawn_ras().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 305 of file app_dahdiras.c.

static void __unreg_module ( void   )  [static]

Definition at line 305 of file app_dahdiras.c.

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

Definition at line 230 of file app_dahdiras.c.

References ast_channel::_state, ast_answer(), ast_log(), ast_module_user_add, ast_module_user_remove, AST_STATE_UP, ast_strdupa, ast_verbose(), dahdi_chan_name, LOG_WARNING, option_verbose, run_ras(), VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3.

00231 {
00232    int res=-1;
00233    char *args;
00234    struct ast_module_user *u;
00235    struct dahdi_params ztp;
00236 
00237    if (!data) 
00238       data = "";
00239 
00240    u = ast_module_user_add(chan);
00241 
00242    args = ast_strdupa(data);
00243    
00244    /* Answer the channel if it's not up */
00245    if (chan->_state != AST_STATE_UP)
00246       ast_answer(chan);
00247    if (strcasecmp(chan->tech->type, dahdi_chan_name)) {
00248       if (option_verbose > 1)
00249          ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a %s channel\n", chan->name, dahdi_chan_name);
00250       sleep(2);
00251    } else {
00252       memset(&ztp, 0, sizeof(ztp));
00253       if (ioctl(chan->fds[0], DAHDI_GET_PARAMS, &ztp)) {
00254          ast_log(LOG_WARNING, "Unable to get parameters\n");
00255       } else if (ztp.sigtype != DAHDI_SIG_CLEAR) {
00256          if (option_verbose > 1)
00257             ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a clear channel\n", chan->name);
00258       } else {
00259          /* Everything should be okay.  Run PPP. */
00260          if (option_verbose > 2)
00261             ast_verbose(VERBOSE_PREFIX_3 "Starting RAS on %s\n", chan->name);
00262          /* Execute RAS */
00263          run_ras(chan, args);
00264       }
00265    }
00266    ast_module_user_remove(u);
00267    return res;
00268 }

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

Definition at line 270 of file app_dahdiras.c.

References ast_log(), dahdi_app, exec(), LOG_WARNING, and zap_app.

Referenced by load_module().

00271 {
00272    ast_log(LOG_WARNING, "Use of the command %s is deprecated, please use %s instead.\n", zap_app, dahdi_app);
00273 
00274    return exec(chan, data);
00275 }

static int load_module ( void   )  [static]

Definition at line 292 of file app_dahdiras.c.

References ast_register_application(), CHAN_DAHDI_PLUS_ZAP_MODE, dahdi_app, dahdi_chan_mode, dahdi_descrip, dahdi_synopsis, exec(), exec_warn(), zap_app, zap_descrip, and zap_synopsis.

00293 {
00294    int res = 0;
00295 
00296    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
00297       res |= ast_register_application(dahdi_app, exec, dahdi_synopsis, dahdi_descrip);
00298    }
00299 
00300    res |= ast_register_application(zap_app, exec_warn, zap_synopsis, zap_descrip);
00301 
00302    return res;
00303 }

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

Definition at line 171 of file app_dahdiras.c.

References ast_channel::_softhangup, ast_log(), ast_verbose(), errno, ast_channel::fds, LOG_DEBUG, LOG_WARNING, ast_channel::name, option_verbose, spawn_ras(), VERBOSE_PREFIX_3, WEXITSTATUS, and WIFEXITED.

Referenced by exec().

00172 {
00173    pid_t pid;
00174    int status;
00175    int res;
00176    int signalled = 0;
00177    struct dahdi_bufferinfo savebi;
00178    int x;
00179    
00180    res = ioctl(chan->fds[0], DAHDI_GET_BUFINFO, &savebi);
00181    if(res) {
00182       ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name);
00183       return;
00184    }
00185 
00186    pid = spawn_ras(chan, args);
00187    if (pid < 0) {
00188       ast_log(LOG_WARNING, "Failed to spawn RAS\n");
00189    } else {
00190       for (;;) {
00191          res = wait4(pid, &status, WNOHANG, NULL);
00192          if (!res) {
00193             /* Check for hangup */
00194             if (chan->_softhangup && !signalled) {
00195                ast_log(LOG_DEBUG, "Channel '%s' hungup.  Signalling RAS at %d to die...\n", chan->name, pid);
00196                kill(pid, SIGTERM);
00197                signalled=1;
00198             }
00199             /* Try again */
00200             sleep(1);
00201             continue;
00202          }
00203          if (res < 0) {
00204             ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno));
00205          }
00206          if (option_verbose > 2) {
00207             if (WIFEXITED(status)) {
00208                ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status));
00209             } else if (WIFSIGNALED(status)) {
00210                ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with signal %d\n", 
00211                    chan->name, WTERMSIG(status));
00212             } else {
00213                ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated weirdly.\n", chan->name);
00214             }
00215          }
00216          /* Throw back into audio mode */
00217          x = 1;
00218          ioctl(chan->fds[0], DAHDI_AUDIOMODE, &x);
00219 
00220          /* Restore saved values */
00221          res = ioctl(chan->fds[0], DAHDI_SET_BUFINFO, &savebi);
00222          if (res < 0) {
00223             ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name);
00224          }
00225          break;
00226       }
00227    }
00228 }

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

Definition at line 90 of file app_dahdiras.c.

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

Referenced by run_ras().

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

static int unload_module ( void   )  [static]

Definition at line 277 of file app_dahdiras.c.

References ast_module_user_hangup_all, ast_unregister_application(), CHAN_DAHDI_PLUS_ZAP_MODE, dahdi_app, dahdi_chan_mode, and zap_app.

00278 {
00279    int res = 0;
00280 
00281    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
00282       res |= ast_unregister_application(dahdi_app);
00283    }
00284 
00285    res |= ast_unregister_application(zap_app);
00286    
00287    ast_module_user_hangup_all();
00288 
00289    return res;
00290 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "DAHDI RAS Application" , .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 305 of file app_dahdiras.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 305 of file app_dahdiras.c.

char* dahdi_app = "DAHDIRAS" [static]

Definition at line 67 of file app_dahdiras.c.

char* dahdi_descrip [static]

Definition at line 73 of file app_dahdiras.c.

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

Definition at line 70 of file app_dahdiras.c.

char* zap_app = "ZapRAS" [static]

Definition at line 68 of file app_dahdiras.c.

char* zap_descrip [static]

Definition at line 80 of file app_dahdiras.c.

char* zap_synopsis = "Executes Zaptel ISDN RAS application" [static]

Definition at line 71 of file app_dahdiras.c.


Generated on Sat Aug 6 00:39:34 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7