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"
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, const char *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_LOAD_ORDER , .description = "DAHDI ISDN Remote Access Server" , .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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } |
| static const char | app [] = "DAHDIRAS" |
| static struct ast_module_info * | ast_module_info = &__mod_info |
Execute an ISDN RAS.
Definition in file app_dahdiras.c.
| #define PPP_EXEC "/usr/sbin/pppd" |
Definition at line 80 of file app_dahdiras.c.
Referenced by spawn_ras().
| #define PPP_MAX_ARGS 32 |
Definition at line 79 of file app_dahdiras.c.
Referenced by spawn_ras().
| static void __reg_module | ( | void | ) | [static] |
Definition at line 236 of file app_dahdiras.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 236 of file app_dahdiras.c.
| static int dahdiras_exec | ( | struct ast_channel * | chan, |
| const char * | data | ||
| ) | [static] |
Definition at line 191 of file app_dahdiras.c.
References args, ast_answer(), ast_channel_fd(), ast_channel_name(), ast_channel_tech(), ast_log(), AST_STATE_UP, ast_verb, LOG_WARNING, run_ras(), and 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 (ast_channel_state(chan) != AST_STATE_UP)
ast_answer(chan);
if (strcasecmp(ast_channel_tech(chan)->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", ast_channel_name(chan));
sleep(2);
} else {
memset(&dahdip, 0, sizeof(dahdip));
if (ioctl(ast_channel_fd(chan, 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", ast_channel_name(chan));
} else {
/* Everything should be okay. Run PPP. */
ast_verb(3, "Starting RAS on %s\n", ast_channel_name(chan));
/* Execute RAS */
run_ras(chan, args);
}
}
return res;
}
| static int load_module | ( | void | ) | [static] |
Definition at line 231 of file app_dahdiras.c.
References AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application_xml, and dahdiras_exec().
{
return ((ast_register_application_xml(app, dahdiras_exec)) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS);
}
| static void run_ras | ( | struct ast_channel * | chan, |
| char * | args | ||
| ) | [static] |
Definition at line 133 of file app_dahdiras.c.
References ast_channel_fd(), ast_channel_name(), ast_check_hangup(), ast_debug, ast_log(), ast_safe_fork_cleanup(), ast_verb, errno, LOG_WARNING, spawn_ras(), and status.
Referenced by dahdiras_exec().
{
pid_t pid;
int status;
int res;
int signalled = 0;
struct dahdi_bufferinfo savebi;
int x;
res = ioctl(ast_channel_fd(chan, 0), DAHDI_GET_BUFINFO, &savebi);
if(res) {
ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", ast_channel_name(chan));
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", ast_channel_name(chan), 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", ast_channel_name(chan), WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
ast_verb(3, "RAS on %s terminated with signal %d\n",
ast_channel_name(chan), WTERMSIG(status));
} else {
ast_verb(3, "RAS on %s terminated weirdly.\n", ast_channel_name(chan));
}
/* Throw back into audio mode */
x = 1;
ioctl(ast_channel_fd(chan, 0), DAHDI_AUDIOMODE, &x);
/* Restore saved values */
res = ioctl(ast_channel_fd(chan, 0), DAHDI_SET_BUFINFO, &savebi);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", ast_channel_name(chan));
}
break;
}
}
ast_safe_fork_cleanup();
}
| static pid_t spawn_ras | ( | struct ast_channel * | chan, |
| char * | args | ||
| ) | [static] |
Definition at line 82 of file app_dahdiras.c.
References args, ast_channel_fd(), ast_close_fds_above_n(), ast_opt_high_priority, ast_safe_fork(), ast_set_priority(), PPP_EXEC, and PPP_MAX_ARGS.
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(ast_channel_fd(chan, 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 226 of file app_dahdiras.c.
References ast_unregister_application().
{
return ast_unregister_application(app);
}
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "DAHDI ISDN Remote Access Server" , .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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static] |
Definition at line 236 of file app_dahdiras.c.
const char app[] = "DAHDIRAS" [static] |
Definition at line 77 of file app_dahdiras.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 236 of file app_dahdiras.c.