Wed Feb 11 12:00:02 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 <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.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"
#include "asterisk/dahdi_compat.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 = "f450f61f60e761b3aa089ebed76ca8a5" , .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 83 of file app_dahdiras.c.

Referenced by spawn_ras().

#define PPP_MAX_ARGS   32

Definition at line 82 of file app_dahdiras.c.

Referenced by spawn_ras().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 287 of file app_dahdiras.c.

static void __unreg_module ( void   )  [static]

Definition at line 287 of file app_dahdiras.c.

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

Definition at line 212 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.

00213 {
00214    int res=-1;
00215    char *args;
00216    struct ast_module_user *u;
00217    struct dahdi_params ztp;
00218 
00219    if (!data) 
00220       data = "";
00221 
00222    u = ast_module_user_add(chan);
00223 
00224    args = ast_strdupa(data);
00225    
00226    /* Answer the channel if it's not up */
00227    if (chan->_state != AST_STATE_UP)
00228       ast_answer(chan);
00229    if (strcasecmp(chan->tech->type, dahdi_chan_name)) {
00230       if (option_verbose > 1)
00231          ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a %s channel\n", chan->name, dahdi_chan_name);
00232       sleep(2);
00233    } else {
00234       memset(&ztp, 0, sizeof(ztp));
00235       if (ioctl(chan->fds[0], DAHDI_GET_PARAMS, &ztp)) {
00236          ast_log(LOG_WARNING, "Unable to get parameters\n");
00237       } else if (ztp.sigtype != DAHDI_SIG_CLEAR) {
00238          if (option_verbose > 1)
00239             ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a clear channel\n", chan->name);
00240       } else {
00241          /* Everything should be okay.  Run PPP. */
00242          if (option_verbose > 2)
00243             ast_verbose(VERBOSE_PREFIX_3 "Starting RAS on %s\n", chan->name);
00244          /* Execute RAS */
00245          run_ras(chan, args);
00246       }
00247    }
00248    ast_module_user_remove(u);
00249    return res;
00250 }

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

Definition at line 252 of file app_dahdiras.c.

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

Referenced by load_module().

00253 {
00254    ast_log(LOG_WARNING, "Use of the command %s is deprecated, please use %s instead.\n", zap_app, dahdi_app);
00255 
00256    return exec(chan, data);
00257 }

static int load_module ( void   )  [static]

Definition at line 274 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.

00275 {
00276    int res = 0;
00277 
00278    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
00279       res |= ast_register_application(dahdi_app, exec, dahdi_synopsis, dahdi_descrip);
00280    }
00281 
00282    res |= ast_register_application(zap_app, exec_warn, zap_synopsis, zap_descrip);
00283 
00284    return res;
00285 }

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

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

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

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

Definition at line 85 of file app_dahdiras.c.

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

Referenced by run_ras().

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

static int unload_module ( void   )  [static]

Definition at line 259 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.

00260 {
00261    int res = 0;
00262 
00263    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
00264       res |= ast_unregister_application(dahdi_app);
00265    }
00266 
00267    res |= ast_unregister_application(zap_app);
00268    
00269    ast_module_user_hangup_all();
00270 
00271    return res;
00272 }


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

Definition at line 287 of file app_dahdiras.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 287 of file app_dahdiras.c.

char* dahdi_app = "DAHDIRAS" [static]

Definition at line 62 of file app_dahdiras.c.

char* dahdi_descrip [static]

Definition at line 68 of file app_dahdiras.c.

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

Definition at line 65 of file app_dahdiras.c.

char* zap_app = "ZapRAS" [static]

Definition at line 63 of file app_dahdiras.c.

char* zap_descrip [static]

Definition at line 75 of file app_dahdiras.c.

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

Definition at line 66 of file app_dahdiras.c.


Generated on Wed Feb 11 12:00:02 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7