Sat Mar 24 23:26:50 2007

Asterisk developer's documentation


app_zapras.c File Reference

Execute an ISDN RAS. More...

#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 <zaptel.h>
#include "asterisk.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 dependency graph for app_zapras.c:

Go to the source code of this file.

Defines

#define PPP_EXEC   "/usr/sbin/pppd"
#define PPP_MAX_ARGS   32

Functions

char * description (void)
 Provides a description of the module.
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
static void run_ras (struct ast_channel *chan, char *args)
static pid_t spawn_ras (struct ast_channel *chan, char *args)
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.
static int zapras_exec (struct ast_channel *chan, void *data)

Variables

static char * app = "ZapRAS"
static char * descrip
 LOCAL_USER_DECL
 STANDARD_LOCAL_USER
static char * synopsis = "Executes Zaptel ISDN RAS application"
static char * tdesc = "Zap RAS Application"


Detailed Description

Execute an ISDN RAS.

Definition in file app_zapras.c.


Define Documentation

#define PPP_EXEC   "/usr/sbin/pppd"
 

Definition at line 79 of file app_zapras.c.

Referenced by spawn_ras().

#define PPP_MAX_ARGS   32
 

Definition at line 78 of file app_zapras.c.

Referenced by spawn_ras().


Function Documentation

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 261 of file app_zapras.c.

References tdesc.

00262 {
00263    return tdesc;
00264 }

char* key void   ) 
 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 273 of file app_zapras.c.

References ASTERISK_GPL_KEY.

00274 {
00275    return ASTERISK_GPL_KEY;
00276 }

int load_module void   ) 
 

Initialize the module.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.

Definition at line 256 of file app_zapras.c.

References app, ast_register_application(), descrip, synopsis, and zapras_exec().

00257 {
00258    return ast_register_application(app, zapras_exec, synopsis, descrip);
00259 }

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

Definition at line 139 of file app_zapras.c.

References ast_channel::_softhangup, ast_log(), ast_channel::fds, LOG_DEBUG, LOG_WARNING, ast_channel::name, and spawn_ras().

Referenced by zapras_exec().

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

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

Definition at line 81 of file app_zapras.c.

References localuser::chan, ast_channel::fds, PPP_EXEC, PPP_MAX_ARGS, and strsep().

Referenced by run_ras().

00082 {
00083    pid_t pid;
00084    int x;   
00085    char *c;
00086 
00087    char *argv[PPP_MAX_ARGS];
00088    int argc = 0;
00089    char *stringp=NULL;
00090 
00091    /* Start by forking */
00092    pid = fork();
00093    if (pid)
00094       return pid;
00095 
00096    /* Execute RAS on File handles */
00097    dup2(chan->fds[0], STDIN_FILENO);
00098 
00099    /* Close other file descriptors */
00100    for (x=STDERR_FILENO + 1;x<1024;x++) 
00101       close(x);
00102 
00103    /* Restore original signal handlers */
00104    for (x=0;x<NSIG;x++)
00105       signal(x, SIG_DFL);
00106 
00107    /* Reset all arguments */
00108    memset(argv, 0, sizeof(argv));
00109 
00110    /* First argument is executable, followed by standard
00111       arguments for zaptel PPP */
00112    argv[argc++] = PPP_EXEC;
00113    argv[argc++] = "nodetach";
00114 
00115    /* And all the other arguments */
00116    stringp=args;
00117    c = strsep(&stringp, "|");
00118    while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
00119       argv[argc++] = c;
00120       c = strsep(&stringp, "|");
00121    }
00122 
00123    argv[argc++] = "plugin";
00124    argv[argc++] = "zaptel.so";
00125    argv[argc++] = "stdin";
00126 
00127 #if 0
00128    for (x=0;x<argc;x++) {
00129       fprintf(stderr, "Arg %d: %s\n", x, argv[x]);
00130    }
00131 #endif
00132 
00133    /* Finally launch PPP */
00134    execv(PPP_EXEC, argv);
00135    fprintf(stderr, "Failed to exec PPPD!\n");
00136    exit(1);
00137 }

int unload_module void   ) 
 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
Zero on success, or non-zero on error.

Definition at line 245 of file app_zapras.c.

References app, ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS.

00246 {
00247    int res;
00248 
00249    res = ast_unregister_application(app);
00250    
00251    STANDARD_HANGUP_LOCALUSERS;
00252 
00253    return res;
00254 }

int usecount void   ) 
 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 266 of file app_zapras.c.

References STANDARD_USECOUNT.

00267 {
00268    int res;
00269    STANDARD_USECOUNT(res);
00270    return res;
00271 }

static int zapras_exec struct ast_channel chan,
void *  data
[static]
 

Definition at line 198 of file app_zapras.c.

References ast_channel::_state, ast_answer(), ast_log(), AST_STATE_UP, ast_strdupa, ast_verbose(), localuser::chan, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_ERROR, LOG_WARNING, option_verbose, run_ras(), VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3.

Referenced by load_module().

00199 {
00200    int res=-1;
00201    char *args;
00202    struct localuser *u;
00203    ZT_PARAMS ztp;
00204 
00205    if (!data) 
00206       data = "";
00207 
00208    LOCAL_USER_ADD(u);
00209 
00210    args = ast_strdupa(data);
00211    if (!args) {
00212       ast_log(LOG_ERROR, "Out of memory\n");
00213       LOCAL_USER_REMOVE(u);
00214       return -1;
00215    }
00216    
00217    /* Answer the channel if it's not up */
00218    if (chan->_state != AST_STATE_UP)
00219       ast_answer(chan);
00220    if (strcasecmp(chan->type, "Zap")) {
00221       /* If it's not a zap channel, we're done.  Wait a couple of
00222          seconds and then hangup... */
00223       if (option_verbose > 1)
00224          ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a Zap channel\n", chan->name);
00225       sleep(2);
00226    } else {
00227       memset(&ztp, 0, sizeof(ztp));
00228       if (ioctl(chan->fds[0], ZT_GET_PARAMS, &ztp)) {
00229          ast_log(LOG_WARNING, "Unable to get zaptel parameters\n");
00230       } else if (ztp.sigtype != ZT_SIG_CLEAR) {
00231          if (option_verbose > 1)
00232             ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a clear channel\n", chan->name);
00233       } else {
00234          /* Everything should be okay.  Run PPP. */
00235          if (option_verbose > 2)
00236             ast_verbose(VERBOSE_PREFIX_3 "Starting RAS on %s\n", chan->name);
00237          /* Execute RAS */
00238          run_ras(chan, args);
00239       }
00240    }
00241    LOCAL_USER_REMOVE(u);
00242    return res;
00243 }


Variable Documentation

char* app = "ZapRAS" [static]
 

Definition at line 63 of file app_zapras.c.

char* descrip [static]
 

Definition at line 67 of file app_zapras.c.

LOCAL_USER_DECL
 

Definition at line 76 of file app_zapras.c.

STANDARD_LOCAL_USER
 

Definition at line 74 of file app_zapras.c.

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

Definition at line 65 of file app_zapras.c.

char* tdesc = "Zap RAS Application" [static]
 

Definition at line 61 of file app_zapras.c.


Generated on Sat Mar 24 23:26:51 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6