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
00033
00034
00035 #include "asterisk.h"
00036
00037 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 239718 $")
00038
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 #include <string.h>
00042 #include <unistd.h>
00043
00044 #include "asterisk/file.h"
00045 #include "asterisk/logger.h"
00046 #include "asterisk/channel.h"
00047 #include "asterisk/pbx.h"
00048 #include "asterisk/dsp.h"
00049 #include "asterisk/module.h"
00050 #include "asterisk/options.h"
00051
00052 static char *app = "WaitForSilence";
00053 static char *synopsis = "Waits for a specified amount of silence";
00054 static char *descrip =
00055 " WaitForSilence(silencerequired[|iterations][|timeout]) \n"
00056 "Wait for Silence: Waits for up to 'silencerequired' \n"
00057 "milliseconds of silence, 'iterations' times or once if omitted.\n"
00058 "An optional timeout specified the number of seconds to return\n"
00059 "after, even if we do not receive the specified amount of silence.\n"
00060 "Use 'timeout' with caution, as it may defeat the purpose of this\n"
00061 "application, which is to wait indefinitely until silence is detected\n"
00062 "on the line. This is particularly useful for reverse-911-type\n"
00063 "call broadcast applications where you need to wait for an answering\n"
00064 "machine to complete its spiel before playing a message.\n"
00065 "The timeout parameter is specified only to avoid an infinite loop in\n"
00066 "cases where silence is never achieved. Typically you will want to\n"
00067 "include two or more calls to WaitForSilence when dealing with an answering\n"
00068 "machine; first waiting for the spiel to finish, then waiting for the beep, etc.\n\n"
00069 "Examples:\n"
00070 " - WaitForSilence(500|2) will wait for 1/2 second of silence, twice\n"
00071 " - WaitForSilence(1000) will wait for 1 second of silence, once\n"
00072 " - WaitForSilence(300|3|10) will wait for 300ms silence, 3 times,\n"
00073 " and returns after 10 sec, even if silence is not detected\n\n"
00074 "Sets the channel variable WAITSTATUS with to one of these values:\n"
00075 "SILENCE - if exited with silence detected\n"
00076 "TIMEOUT - if exited without silence detected after timeout\n";
00077
00078 static int do_waiting(struct ast_channel *chan, int silencereqd, time_t waitstart, int timeout) {
00079 struct ast_frame *f;
00080 int dspsilence = 0;
00081 static int silencethreshold = 128;
00082 int rfmt = 0;
00083 int res = 0;
00084 struct ast_dsp *sildet;
00085 time_t now;
00086
00087 rfmt = chan->readformat;
00088 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
00089 if (res < 0) {
00090 ast_log(LOG_WARNING, "Unable to set channel to linear mode, giving up\n");
00091 return -1;
00092 }
00093
00094 sildet = ast_dsp_new();
00095 if (!sildet) {
00096 ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
00097 return -1;
00098 }
00099 ast_dsp_set_threshold(sildet, silencethreshold);
00100
00101
00102 f = NULL;
00103 for(;;) {
00104
00105 dspsilence = 0;
00106
00107 res = ast_waitfor(chan, silencereqd);
00108
00109
00110 if (res < 0) {
00111 f = NULL;
00112 break;
00113 }
00114
00115
00116 if (res == 0) {
00117 dspsilence = silencereqd;
00118 } else {
00119
00120 f = ast_read(chan);
00121 if (!f)
00122 break;
00123 if (f && f->frametype == AST_FRAME_VOICE) {
00124 ast_dsp_silence(sildet, f, &dspsilence);
00125 }
00126 if (f) {
00127 ast_frfree(f);
00128 }
00129 }
00130
00131 if (option_verbose > 6)
00132 ast_verbose(VERBOSE_PREFIX_3 "Got %dms silence< %dms required\n", dspsilence, silencereqd);
00133
00134 if (dspsilence >= silencereqd) {
00135 if (option_verbose > 2)
00136 ast_verbose(VERBOSE_PREFIX_3 "Exiting with %dms silence >= %dms required\n", dspsilence, silencereqd);
00137
00138 res = 1;
00139 pbx_builtin_setvar_helper(chan, "WAITSTATUS", "SILENCE");
00140 ast_log(LOG_DEBUG, "WAITSTATUS was set to SILENCE\n");
00141 break;
00142 }
00143
00144 if ( timeout && (difftime(time(&now),waitstart) >= timeout) ) {
00145 pbx_builtin_setvar_helper(chan, "WAITSTATUS", "TIMEOUT");
00146 ast_log(LOG_DEBUG, "WAITSTATUS was set to TIMEOUT\n");
00147 res = 0;
00148 break;
00149 }
00150 }
00151
00152
00153 if (rfmt && ast_set_read_format(chan, rfmt)) {
00154 ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name);
00155 }
00156 ast_dsp_free(sildet);
00157 return res;
00158 }
00159
00160 static int waitforsilence_exec(struct ast_channel *chan, void *data)
00161 {
00162 int res = 1;
00163 int silencereqd = 1000;
00164 int timeout = 0;
00165 int iterations = 1, i;
00166 time_t waitstart;
00167 struct ast_silence_generator *silgen = NULL;
00168
00169 res = ast_answer(chan);
00170
00171 if (!data || ( (sscanf(data, "%30d|%30d|%30d", &silencereqd, &iterations, &timeout) != 3) &&
00172 (sscanf(data, "%30d|%30d", &silencereqd, &iterations) != 2) &&
00173 (sscanf(data, "%30d", &silencereqd) != 1) ) ) {
00174 ast_log(LOG_WARNING, "Using default value of 1000ms, 1 iteration, no timeout\n");
00175 }
00176
00177 if (option_verbose > 2)
00178 ast_verbose(VERBOSE_PREFIX_3 "Waiting %d time(s) for %d ms silence with %d timeout\n", iterations, silencereqd, timeout);
00179
00180 if (ast_opt_transmit_silence) {
00181 silgen = ast_channel_start_silence_generator(chan);
00182 }
00183 time(&waitstart);
00184 res = 1;
00185 for (i=0; (i<iterations) && (res == 1); i++) {
00186 res = do_waiting(chan, silencereqd, waitstart, timeout);
00187 }
00188 if (silgen) {
00189 ast_channel_stop_silence_generator(chan, silgen);
00190 }
00191
00192 if (res > 0)
00193 res = 0;
00194 return res;
00195 }
00196
00197
00198 static int unload_module(void)
00199 {
00200 int res;
00201
00202 res = ast_unregister_application(app);
00203
00204 ast_module_user_hangup_all();
00205
00206 return res;
00207 }
00208
00209 static int load_module(void)
00210 {
00211 return ast_register_application(app, waitforsilence_exec, synopsis, descrip);
00212 }
00213
00214 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Wait For Silence");
00215