#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"
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. | |
void | run_ras (struct ast_channel *chan, char *args) |
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. | |
int | zapras_exec (struct ast_channel *chan, void *data) |
Variables | |
char * | app = "ZapRAS" |
char * | descrip |
LOCAL_USER_DECL | |
STANDARD_LOCAL_USER | |
char * | synopsis = "Executes Zaptel ISDN RAS application" |
char * | tdesc = "Zap RAS Application" |
Definition in file app_zapras.c.
|
Definition at line 79 of file app_zapras.c. Referenced by spawn_ras(). |
|
Definition at line 78 of file app_zapras.c. Referenced by spawn_ras(). |
|
Provides a description of the module.
Definition at line 261 of file app_zapras.c. 00262 {
00263 return tdesc;
00264 }
|
|
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; }
Definition at line 273 of file app_zapras.c. 00274 {
00275 return ASTERISK_GPL_KEY;
00276 }
|
|
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.
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 }
|
|
Definition at line 139 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(). 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 }
|
|
Definition at line 81 of file app_zapras.c. References 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 }
|
|
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).
Definition at line 245 of file app_zapras.c. References app, and ast_unregister_application(). 00246 { 00247 int res; 00248 00249 res = ast_unregister_application(app); 00250 00251 STANDARD_HANGUP_LOCALUSERS; 00252 00253 return res; 00254 }
|
|
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.
Definition at line 266 of file app_zapras.c. References STANDARD_USECOUNT. 00267 { 00268 int res; 00269 STANDARD_USECOUNT(res); 00270 return res; 00271 }
|
|
Definition at line 198 of file app_zapras.c. References ast_channel::_state, ast_answer(), ast_log(), ast_strdupa, ast_verbose(), ast_channel::fds, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_ERROR, LOG_WARNING, ast_channel::name, option_verbose, run_ras(), ast_channel::type, 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 }
|
|
Definition at line 63 of file app_zapras.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 67 of file app_zapras.c. Referenced by load_module(). |
|
Definition at line 76 of file app_zapras.c. |
|
Definition at line 74 of file app_zapras.c. |
|
Definition at line 65 of file app_zapras.c. Referenced by load_module(). |
|
Definition at line 61 of file app_zapras.c. |