app_waitforring.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "asterisk.h"
00033
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 375993 $")
00035
00036 #include "asterisk/file.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/pbx.h"
00039 #include "asterisk/module.h"
00040 #include "asterisk/lock.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 static char *app = "WaitForRing";
00059
00060 static int waitforring_exec(struct ast_channel *chan, const char *data)
00061 {
00062 struct ast_frame *f;
00063 struct ast_silence_generator *silgen = NULL;
00064 int res = 0;
00065 double s;
00066 int timeout_ms;
00067 int ms;
00068 struct timeval start = ast_tvnow();
00069
00070 if (!data || (sscanf(data, "%30lg", &s) != 1)) {
00071 ast_log(LOG_WARNING, "WaitForRing requires an argument (minimum seconds)\n");
00072 return 0;
00073 }
00074
00075 if (s < 0.0) {
00076 ast_log(LOG_WARNING, "Invalid timeout provided for WaitForRing (%lg)\n", s);
00077 return 0;
00078 }
00079
00080 if (ast_opt_transmit_silence) {
00081 silgen = ast_channel_start_silence_generator(chan);
00082 }
00083
00084 timeout_ms = s * 1000.0;
00085 while ((ms = ast_remaining_ms(start, timeout_ms))) {
00086 ms = ast_waitfor(chan, ms);
00087 if (ms < 0) {
00088 res = -1;
00089 break;
00090 }
00091 if (ms > 0) {
00092 f = ast_read(chan);
00093 if (!f) {
00094 res = -1;
00095 break;
00096 }
00097 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_RING)) {
00098 ast_verb(3, "Got a ring but still waiting for timeout\n");
00099 }
00100 ast_frfree(f);
00101 }
00102 }
00103
00104 if (!res) {
00105 for (;;) {
00106 int wait_res = ast_waitfor(chan, -1);
00107 if (wait_res < 0) {
00108 res = -1;
00109 break;
00110 } else {
00111 f = ast_read(chan);
00112 if (!f) {
00113 res = -1;
00114 break;
00115 }
00116 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_RING)) {
00117 ast_verb(3, "Got a ring after the timeout\n");
00118 ast_frfree(f);
00119 break;
00120 }
00121 ast_frfree(f);
00122 }
00123 }
00124 }
00125
00126 if (silgen) {
00127 ast_channel_stop_silence_generator(chan, silgen);
00128 }
00129
00130 return res;
00131 }
00132
00133 static int unload_module(void)
00134 {
00135 return ast_unregister_application(app);
00136 }
00137
00138 static int load_module(void)
00139 {
00140 return ast_register_application_xml(app, waitforring_exec);
00141 }
00142
00143 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Waits until first ring after time");