Thu Apr 28 2011 16:56:50

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 <fcntl.h>
#include <dahdi/user.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/app.h"
Include dependency graph for app_dahdiras.c:

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
__MODULE_INFO_SECTION 
__mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "DAHDI ISDN Remote Access Server" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, }
static char * app = "DAHDIRAS"
static struct ast_module_infoast_module_info = &__mod_info

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 79 of file app_dahdiras.c.

Referenced by spawn_ras().

#define PPP_MAX_ARGS   32

Definition at line 78 of file app_dahdiras.c.

Referenced by spawn_ras().


Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 235 of file app_dahdiras.c.

static void __unreg_module ( void  ) [static]

Definition at line 235 of file app_dahdiras.c.

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

Definition at line 190 of file app_dahdiras.c.

References ast_channel::_state, ast_answer(), ast_log(), AST_STATE_UP, ast_strdupa, ast_verb, ast_channel::fds, LOG_WARNING, ast_channel::name, run_ras(), ast_channel::tech, and ast_channel_tech::type.

Referenced by load_module().

{
   int res=-1;
   char *args;
   struct dahdi_params dahdip;

   if (!data) 
      data = "";

   args = ast_strdupa(data);
   
   /* Answer the channel if it's not up */
   if (chan->_state != AST_STATE_UP)
      ast_answer(chan);
   if (strcasecmp(chan->tech->type, "DAHDI")) {
      /* If it's not a DAHDI channel, we're done.  Wait a couple of
         seconds and then hangup... */
      ast_verb(2, "Channel %s is not a DAHDI channel\n", chan->name);
      sleep(2);
   } else {
      memset(&dahdip, 0, sizeof(dahdip));
      if (ioctl(chan->fds[0], DAHDI_GET_PARAMS, &dahdip)) {
         ast_log(LOG_WARNING, "Unable to get DAHDI parameters\n");
      } else if (dahdip.sigtype != DAHDI_SIG_CLEAR) {
         ast_verb(2, "Channel %s is not a clear channel\n", chan->name);
      } else {
         /* Everything should be okay.  Run PPP. */
         ast_verb(3, "Starting RAS on %s\n", chan->name);
         /* Execute RAS */
         run_ras(chan, args);
      }
   }
   return res;
}
static void run_ras ( struct ast_channel chan,
char *  args 
) [static]

Definition at line 132 of file app_dahdiras.c.

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

Referenced by dahdiras_exec().

{
   pid_t pid;
   int status;
   int res;
   int signalled = 0;
   struct dahdi_bufferinfo savebi;
   int x;
   
   res = ioctl(chan->fds[0], DAHDI_GET_BUFINFO, &savebi);
   if(res) {
      ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name);
      return;
   }

   pid = spawn_ras(chan, args);
   if (pid < 0) {
      ast_log(LOG_WARNING, "Failed to spawn RAS\n");
   } else {
      for (;;) {
         res = wait4(pid, &status, WNOHANG, NULL);
         if (!res) {
            /* Check for hangup */
            if (ast_check_hangup(chan) && !signalled) {
               ast_debug(1, "Channel '%s' hungup.  Signalling RAS at %d to die...\n", chan->name, pid);
               kill(pid, SIGTERM);
               signalled=1;
            }
            /* Try again */
            sleep(1);
            continue;
         }
         if (res < 0) {
            ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno));
         }
         if (WIFEXITED(status)) {
            ast_verb(3, "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status));
         } else if (WIFSIGNALED(status)) {
            ast_verb(3, "RAS on %s terminated with signal %d\n", 
                chan->name, WTERMSIG(status));
         } else {
            ast_verb(3, "RAS on %s terminated weirdly.\n", chan->name);
         }
         /* Throw back into audio mode */
         x = 1;
         ioctl(chan->fds[0], DAHDI_AUDIOMODE, &x);

         /* Restore saved values */
         res = ioctl(chan->fds[0], DAHDI_SET_BUFINFO, &savebi);
         if (res < 0) {
            ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name);
         }
         break;
      }
   }
   ast_safe_fork_cleanup();
}
static pid_t spawn_ras ( struct ast_channel chan,
char *  args 
) [static]

Definition at line 81 of file app_dahdiras.c.

References ast_close_fds_above_n(), ast_opt_high_priority, ast_safe_fork(), ast_set_priority(), ast_channel::fds, PPP_EXEC, PPP_MAX_ARGS, and strsep().

Referenced by run_ras().

{
   pid_t pid;
   char *c;

   char *argv[PPP_MAX_ARGS];
   int argc = 0;
   char *stringp=NULL;

   /* Start by forking */
   pid = ast_safe_fork(1);
   if (pid) {
      return pid;
   }

   /* Execute RAS on File handles */
   dup2(chan->fds[0], STDIN_FILENO);

   /* Drop high priority */
   if (ast_opt_high_priority)
      ast_set_priority(0);

   /* Close other file descriptors */
   ast_close_fds_above_n(STDERR_FILENO);

   /* Reset all arguments */
   memset(argv, 0, sizeof(argv));

   /* First argument is executable, followed by standard
      arguments for DAHDI PPP */
   argv[argc++] = PPP_EXEC;
   argv[argc++] = "nodetach";

   /* And all the other arguments */
   stringp=args;
   c = strsep(&stringp, ",");
   while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
      argv[argc++] = c;
      c = strsep(&stringp, ",");
   }

   argv[argc++] = "plugin";
   argv[argc++] = "dahdi.so";
   argv[argc++] = "stdin";

   /* Finally launch PPP */
   execv(PPP_EXEC, argv);
   fprintf(stderr, "Failed to exec PPPD!\n");
   exit(1);
}
static int unload_module ( void  ) [static]

Definition at line 225 of file app_dahdiras.c.

References ast_unregister_application().


Variable Documentation

struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "DAHDI ISDN Remote Access Server" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static]

Definition at line 235 of file app_dahdiras.c.

char* app = "DAHDIRAS" [static]

Definition at line 76 of file app_dahdiras.c.

Definition at line 235 of file app_dahdiras.c.