app_zapras.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * Asterisk -- A telephony toolkit for Linux.
  3. *
  4. * Execute an ISDN RAS
  5. *
  6. * Copyright (C) 1999, Mark Spencer
  7. *
  8. * Mark Spencer <markster@linux-support.net>
  9. *
  10. * This program is free software, distributed under the terms of
  11. * the GNU General Public License
  12. */
  13. #include <asterisk/lock.h>
  14. #include <asterisk/file.h>
  15. #include <asterisk/logger.h>
  16. #include <asterisk/channel.h>
  17. #include <asterisk/pbx.h>
  18. #include <asterisk/module.h>
  19. #include <asterisk/options.h>
  20. #include <sys/ioctl.h>
  21. #include <sys/wait.h>
  22. #ifdef __linux__
  23. #include <sys/signal.h>
  24. #else
  25. #include <signal.h>
  26. #endif /* __linux__ */
  27. #include <stdlib.h>
  28. #include <unistd.h>
  29. #include <string.h>
  30. #include <stdlib.h>
  31. #include <errno.h>
  32. #include <stdio.h>
  33. #include <fcntl.h>
  34. /* Need some zaptel help here */
  35. #ifdef __linux__
  36. #include <linux/zaptel.h>
  37. #else
  38. #include <zaptel.h>
  39. #endif /* __linux__ */
  40. static char *tdesc = "Zap RAS Application";
  41. static char *app = "ZapRAS";
  42. static char *synopsis = "Executes Zaptel ISDN RAS application";
  43. static char *descrip =
  44. " ZapRAS(args): Executes a RAS server using pppd on the given channel.\n"
  45. "The channel must be a clear channel (i.e. PRI source) and a Zaptel\n"
  46. "channel to be able to use this function (No modem emulation is included).\n"
  47. "Your pppd must be patched to be zaptel aware. Arguments should be\n"
  48. "separated by | characters. Always returns -1.\n";
  49. STANDARD_LOCAL_USER;
  50. LOCAL_USER_DECL;
  51. #define PPP_MAX_ARGS 32
  52. #define PPP_EXEC "/usr/sbin/pppd"
  53. static pid_t spawn_ras(struct ast_channel *chan, char *args)
  54. {
  55. pid_t pid;
  56. int x;
  57. char *c;
  58. char *argv[PPP_MAX_ARGS];
  59. int argc = 0;
  60. char *stringp=NULL;
  61. /* Start by forking */
  62. pid = fork();
  63. if (pid)
  64. return pid;
  65. /* Execute RAS on File handles */
  66. dup2(chan->fds[0], STDIN_FILENO);
  67. /* Close other file descriptors */
  68. for (x=STDERR_FILENO + 1;x<1024;x++)
  69. close(x);
  70. /* Restore original signal handlers */
  71. for (x=0;x<NSIG;x++)
  72. signal(x, SIG_DFL);
  73. /* Reset all arguments */
  74. memset(argv, 0, sizeof(argv));
  75. /* First argument is executable, followed by standard
  76. arguments for zaptel PPP */
  77. argv[argc++] = PPP_EXEC;
  78. argv[argc++] = "nodetach";
  79. /* And all the other arguments */
  80. stringp=args;
  81. c = strsep(&stringp, "|");
  82. while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
  83. argv[argc++] = c;
  84. c = strsep(&stringp, "|");
  85. }
  86. argv[argc++] = "plugin";
  87. argv[argc++] = "zaptel.so";
  88. argv[argc++] = "stdin";
  89. #if 0
  90. for (x=0;x<argc;x++) {
  91. fprintf(stderr, "Arg %d: %s\n", x, argv[x]);
  92. }
  93. #endif
  94. /* Finally launch PPP */
  95. execv(PPP_EXEC, argv);
  96. fprintf(stderr, "Failed to exec PPPD!\n");
  97. exit(1);
  98. }
  99. static void run_ras(struct ast_channel *chan, char *args)
  100. {
  101. pid_t pid;
  102. int status;
  103. int res;
  104. int signalled = 0;
  105. struct zt_bufferinfo savebi;
  106. int x;
  107. res = ioctl(chan->fds[0], ZT_GET_BUFINFO, &savebi);
  108. if(res) {
  109. ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name);
  110. return;
  111. }
  112. pid = spawn_ras(chan, args);
  113. if (pid < 0) {
  114. ast_log(LOG_WARNING, "Failed to spawn RAS\n");
  115. } else {
  116. for (;;) {
  117. res = wait4(pid, &status, WNOHANG, NULL);
  118. if (!res) {
  119. /* Check for hangup */
  120. if (chan->_softhangup && !signalled) {
  121. ast_log(LOG_DEBUG, "Channel '%s' hungup. Signalling RAS at %d to die...\n", chan->name, pid);
  122. kill(pid, SIGTERM);
  123. signalled=1;
  124. }
  125. /* Try again */
  126. sleep(1);
  127. continue;
  128. }
  129. if (res < 0) {
  130. ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno));
  131. }
  132. if (option_verbose > 2) {
  133. if (WIFEXITED(status)) {
  134. ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status));
  135. } else if (WIFSIGNALED(status)) {
  136. ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with signal %d\n",
  137. chan->name, WTERMSIG(status));
  138. } else {
  139. ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated weirdly.\n", chan->name);
  140. }
  141. }
  142. /* Throw back into audio mode */
  143. x = 1;
  144. ioctl(chan->fds[0], ZT_AUDIOMODE, &x);
  145. /* Restore saved values */
  146. res = ioctl(chan->fds[0], ZT_SET_BUFINFO, &savebi);
  147. if (res < 0) {
  148. ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name);
  149. }
  150. break;
  151. }
  152. }
  153. }
  154. static int zapras_exec(struct ast_channel *chan, void *data)
  155. {
  156. int res=-1;
  157. char args[256];
  158. struct localuser *u;
  159. ZT_PARAMS ztp;
  160. if (!data)
  161. data = "";
  162. LOCAL_USER_ADD(u);
  163. strncpy(args, data, sizeof(args) - 1);
  164. /* Answer the channel if it's not up */
  165. if (chan->_state != AST_STATE_UP)
  166. ast_answer(chan);
  167. if (strcasecmp(chan->type, "Zap")) {
  168. /* If it's not a zap channel, we're done. Wait a couple of
  169. seconds and then hangup... */
  170. if (option_verbose > 1)
  171. ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a Zap channel\n", chan->name);
  172. sleep(2);
  173. } else {
  174. memset(&ztp, 0, sizeof(ztp));
  175. if (ioctl(chan->fds[0], ZT_GET_PARAMS, &ztp)) {
  176. ast_log(LOG_WARNING, "Unable to get zaptel parameters\n");
  177. } else if (ztp.sigtype != ZT_SIG_CLEAR) {
  178. if (option_verbose > 1)
  179. ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a clear channel\n", chan->name);
  180. } else {
  181. /* Everything should be okay. Run PPP. */
  182. if (option_verbose > 2)
  183. ast_verbose(VERBOSE_PREFIX_3 "Starting RAS on %s\n", chan->name);
  184. /* Execute RAS */
  185. run_ras(chan, args);
  186. }
  187. }
  188. LOCAL_USER_REMOVE(u);
  189. return res;
  190. }
  191. int unload_module(void)
  192. {
  193. STANDARD_HANGUP_LOCALUSERS;
  194. return ast_unregister_application(app);
  195. }
  196. int load_module(void)
  197. {
  198. return ast_register_application(app, zapras_exec, synopsis, descrip);
  199. }
  200. char *description(void)
  201. {
  202. return tdesc;
  203. }
  204. int usecount(void)
  205. {
  206. int res;
  207. STANDARD_USECOUNT(res);
  208. return res;
  209. }
  210. char *key()
  211. {
  212. return ASTERISK_GPL_KEY;
  213. }