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 #include "asterisk.h"
00032
00033 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 352029 $")
00034
00035 #include "asterisk/module.h"
00036 #include "asterisk/channel.h"
00037 #include "asterisk/pbx.h"
00038 #include "asterisk/utils.h"
00039 #include "asterisk/app.h"
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 static int timeout_read(struct ast_channel *chan, const char *cmd, char *data,
00078 char *buf, size_t len)
00079 {
00080 struct timeval myt;
00081
00082 if (!chan)
00083 return -1;
00084
00085 if (!data) {
00086 ast_log(LOG_ERROR, "Must specify type of timeout to get.\n");
00087 return -1;
00088 }
00089
00090 switch (*data) {
00091 case 'a':
00092 case 'A':
00093 if (ast_tvzero(chan->whentohangup)) {
00094 ast_copy_string(buf, "0", len);
00095 } else {
00096 myt = ast_tvnow();
00097 snprintf(buf, len, "%.3f", ast_tvdiff_ms(chan->whentohangup, myt) / 1000.0);
00098 }
00099 break;
00100
00101 case 'r':
00102 case 'R':
00103 if (chan->pbx) {
00104 snprintf(buf, len, "%.3f", chan->pbx->rtimeoutms / 1000.0);
00105 }
00106 break;
00107
00108 case 'd':
00109 case 'D':
00110 if (chan->pbx) {
00111 snprintf(buf, len, "%.3f", chan->pbx->dtimeoutms / 1000.0);
00112 }
00113 break;
00114
00115 default:
00116 ast_log(LOG_ERROR, "Unknown timeout type specified.\n");
00117 return -1;
00118 }
00119
00120 return 0;
00121 }
00122
00123 static int timeout_write(struct ast_channel *chan, const char *cmd, char *data,
00124 const char *value)
00125 {
00126 double x = 0.0;
00127 long sec = 0L;
00128 char timestr[64];
00129 struct ast_tm myt;
00130 struct timeval when = {0,};
00131 int res;
00132
00133 if (!chan)
00134 return -1;
00135
00136 if (!data) {
00137 ast_log(LOG_ERROR, "Must specify type of timeout to set.\n");
00138 return -1;
00139 }
00140
00141 if (!value)
00142 return -1;
00143
00144 res = sscanf(value, "%30ld%30lf", &sec, &x);
00145 if (res == 0 || sec < 0) {
00146 when.tv_sec = 0;
00147 when.tv_usec = 0;
00148 } else if (res == 1) {
00149 when.tv_sec = sec;
00150 } else if (res == 2) {
00151 when.tv_sec = sec;
00152 when.tv_usec = x * 1000000;
00153 }
00154
00155 switch (*data) {
00156 case 'a':
00157 case 'A':
00158 ast_channel_setwhentohangup_tv(chan, when);
00159 if (VERBOSITY_ATLEAST(3)) {
00160 if (!ast_tvzero(chan->whentohangup)) {
00161 when = ast_tvadd(when, ast_tvnow());
00162 ast_strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S.%3q %Z",
00163 ast_localtime(&when, &myt, NULL));
00164 ast_verbose("Channel will hangup at %s.\n", timestr);
00165 } else {
00166 ast_verbose("Channel hangup cancelled.\n");
00167 }
00168 }
00169 break;
00170
00171 case 'r':
00172 case 'R':
00173 if (chan->pbx) {
00174 chan->pbx->rtimeoutms = when.tv_sec * 1000 + when.tv_usec / 1000;
00175 ast_verb(3, "Response timeout set to %.3f\n", chan->pbx->rtimeoutms / 1000.0);
00176 }
00177 break;
00178
00179 case 'd':
00180 case 'D':
00181 if (chan->pbx) {
00182 chan->pbx->dtimeoutms = when.tv_sec * 1000 + when.tv_usec / 1000;
00183 ast_verb(3, "Digit timeout set to %.3f\n", chan->pbx->dtimeoutms / 1000.0);
00184 }
00185 break;
00186
00187 default:
00188 ast_log(LOG_ERROR, "Unknown timeout type specified.\n");
00189 break;
00190 }
00191
00192 return 0;
00193 }
00194
00195 static struct ast_custom_function timeout_function = {
00196 .name = "TIMEOUT",
00197 .read = timeout_read,
00198 .read_max = 22,
00199 .write = timeout_write,
00200 };
00201
00202 static int unload_module(void)
00203 {
00204 return ast_custom_function_unregister(&timeout_function);
00205 }
00206
00207 static int load_module(void)
00208 {
00209 return ast_custom_function_register(&timeout_function);
00210 }
00211
00212 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel timeout dialplan functions");