app_waitforring.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. * \author Mark Spencer <markster@digium.com>
  23. *
  24. * \ingroup applications
  25. */
  26. #include "asterisk.h"
  27. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  28. #include "asterisk/file.h"
  29. #include "asterisk/channel.h"
  30. #include "asterisk/pbx.h"
  31. #include "asterisk/module.h"
  32. #include "asterisk/lock.h"
  33. static char *synopsis = "Wait for Ring Application";
  34. static char *desc = " WaitForRing(timeout):\n"
  35. "Returns 0 after waiting at least timeout seconds. and\n"
  36. "only after the next ring has completed. Returns 0 on\n"
  37. "success or -1 on hangup\n";
  38. static char *app = "WaitForRing";
  39. static int waitforring_exec(struct ast_channel *chan, void *data)
  40. {
  41. struct ast_frame *f;
  42. struct ast_silence_generator *silgen = NULL;
  43. int res = 0;
  44. double s;
  45. int ms;
  46. if (!data || (sscanf(data, "%30lg", &s) != 1)) {
  47. ast_log(LOG_WARNING, "WaitForRing requires an argument (minimum seconds)\n");
  48. return 0;
  49. }
  50. if (ast_opt_transmit_silence) {
  51. silgen = ast_channel_start_silence_generator(chan);
  52. }
  53. ms = s * 1000.0;
  54. while (ms > 0) {
  55. ms = ast_waitfor(chan, ms);
  56. if (ms < 0) {
  57. res = ms;
  58. break;
  59. }
  60. if (ms > 0) {
  61. f = ast_read(chan);
  62. if (!f) {
  63. res = -1;
  64. break;
  65. }
  66. if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
  67. ast_verb(3, "Got a ring but still waiting for timeout\n");
  68. }
  69. ast_frfree(f);
  70. }
  71. }
  72. /* Now we're really ready for the ring */
  73. if (!res) {
  74. ms = 99999999;
  75. while(ms > 0) {
  76. ms = ast_waitfor(chan, ms);
  77. if (ms < 0) {
  78. res = ms;
  79. break;
  80. }
  81. if (ms > 0) {
  82. f = ast_read(chan);
  83. if (!f) {
  84. res = -1;
  85. break;
  86. }
  87. if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
  88. ast_verb(3, "Got a ring after the timeout\n");
  89. ast_frfree(f);
  90. break;
  91. }
  92. ast_frfree(f);
  93. }
  94. }
  95. }
  96. if (silgen) {
  97. ast_channel_stop_silence_generator(chan, silgen);
  98. }
  99. return res;
  100. }
  101. static int unload_module(void)
  102. {
  103. return ast_unregister_application(app);
  104. }
  105. static int load_module(void)
  106. {
  107. return ast_register_application(app, waitforring_exec, synopsis, desc);
  108. }
  109. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Waits until first ring after time");