app_waitforring.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2005, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief Wait for Ring Application
  21. *
  22. * \ingroup applications
  23. */
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <unistd.h>
  28. #include <sys/types.h>
  29. #include "asterisk.h"
  30. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  31. #include "asterisk/file.h"
  32. #include "asterisk/logger.h"
  33. #include "asterisk/channel.h"
  34. #include "asterisk/pbx.h"
  35. #include "asterisk/module.h"
  36. #include "asterisk/options.h"
  37. #include "asterisk/lock.h"
  38. static char *synopsis = "Wait for Ring Application";
  39. static char *tdesc = "Waits until first ring after time";
  40. static char *desc = " WaitForRing(timeout)\n"
  41. "Returns 0 after waiting at least timeout seconds. and\n"
  42. "only after the next ring has completed. Returns 0 on\n"
  43. "success or -1 on hangup\n";
  44. static char *app = "WaitForRing";
  45. STANDARD_LOCAL_USER;
  46. LOCAL_USER_DECL;
  47. static int waitforring_exec(struct ast_channel *chan, void *data)
  48. {
  49. struct localuser *u;
  50. struct ast_frame *f;
  51. int res = 0;
  52. int ms;
  53. if (!data || (sscanf(data, "%d", &ms) != 1)) {
  54. ast_log(LOG_WARNING, "WaitForRing requires an argument (minimum seconds)\n");
  55. return 0;
  56. }
  57. LOCAL_USER_ADD(u);
  58. ms *= 1000;
  59. while(ms > 0) {
  60. ms = ast_waitfor(chan, ms);
  61. if (ms < 0) {
  62. res = ms;
  63. break;
  64. }
  65. if (ms > 0) {
  66. f = ast_read(chan);
  67. if (!f) {
  68. res = -1;
  69. break;
  70. }
  71. if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
  72. if (option_verbose > 2)
  73. ast_verbose(VERBOSE_PREFIX_3 "Got a ring but still waiting for timeout\n");
  74. }
  75. ast_frfree(f);
  76. }
  77. }
  78. /* Now we're really ready for the ring */
  79. if (!res) {
  80. ms = 99999999;
  81. while(ms > 0) {
  82. ms = ast_waitfor(chan, ms);
  83. if (ms < 0) {
  84. res = ms;
  85. break;
  86. }
  87. if (ms > 0) {
  88. f = ast_read(chan);
  89. if (!f) {
  90. res = -1;
  91. break;
  92. }
  93. if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
  94. if (option_verbose > 2)
  95. ast_verbose(VERBOSE_PREFIX_3 "Got a ring after the timeout\n");
  96. ast_frfree(f);
  97. break;
  98. }
  99. ast_frfree(f);
  100. }
  101. }
  102. }
  103. LOCAL_USER_REMOVE(u);
  104. return res;
  105. }
  106. int unload_module(void)
  107. {
  108. int res;
  109. res = ast_unregister_application(app);
  110. STANDARD_HANGUP_LOCALUSERS;
  111. return res;
  112. }
  113. int load_module(void)
  114. {
  115. return ast_register_application(app, waitforring_exec, synopsis, desc);
  116. }
  117. char *description(void)
  118. {
  119. return tdesc;
  120. }
  121. int usecount(void)
  122. {
  123. int res;
  124. STANDARD_USECOUNT(res);
  125. return res;
  126. }
  127. char *key()
  128. {
  129. return ASTERISK_GPL_KEY;
  130. }