Thu May 24 14:21:39 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 259 of file app_zapras.c.

References tdesc.

00260 {
00261    return tdesc;
00262 }

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 271 of file app_zapras.c.

References ASTERISK_GPL_KEY.

00272 {
00273    return ASTERISK_GPL_KEY;
00274 }

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 254 of file app_zapras.c.

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

00255 {
00256    return ast_register_application(app, zapras_exec, synopsis, descrip);
00257 }

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

Definition at line 137 of file app_zapras.c.

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

Referenced by zapras_exec().

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

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

Definition at line 81 of file app_zapras.c.

References ast_set_priority(), localuser::chan, ast_channel::fds, option_highpriority, 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    /* Drop high priority */
00100    if (option_highpriority)
00101       ast_set_priority(0);
00102 
00103    /* Close other file descriptors */
00104    for (x=STDERR_FILENO + 1;x<1024;x++) 
00105       close(x);
00106 
00107    /* Restore original signal handlers */
00108    for (x=0;x<NSIG;x++)
00109       signal(x, SIG_DFL);
00110 
00111    /* Reset all arguments */
00112    memset(argv, 0, sizeof(argv));
00113 
00114    /* First argument is executable, followed by standard
00115       arguments for zaptel PPP */
00116    argv[argc++] = PPP_EXEC;
00117    argv[argc++] = "nodetach";
00118 
00119    /* And all the other arguments */
00120    stringp=args;
00121    c = strsep(&stringp, "|");
00122    while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
00123       argv[argc++] = c;
00124       c = strsep(&stringp, "|");
00125    }
00126 
00127    argv[argc++] = "plugin";
00128    argv[argc++] = "zaptel.so";
00129    argv[argc++] = "stdin";
00130 
00131    /* Finally launch PPP */
00132    execv(PPP_EXEC, argv);
00133    fprintf(stderr, "Failed to exec PPPD!\n");
00134    exit(1);
00135 }

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 243 of file app_zapras.c.

References app, ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS.

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

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 264 of file app_zapras.c.

References STANDARD_USECOUNT.

00265 {
00266    int res;
00267    STANDARD_USECOUNT(res);
00268    return res;
00269 }

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

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

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


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 Thu May 24 14:21:40 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.7