Asterisk - The Open Source Telephony Project  18.5.0
func_timeout.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <[email protected]>
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 
19 /*! \file
20  *
21  * \brief Channel timeout related dialplan functions
22  *
23  * \author Mark Spencer <[email protected]>
24  * \ingroup functions
25  */
26 
27 /*** MODULEINFO
28  <support_level>core</support_level>
29  ***/
30 
31 #include "asterisk.h"
32 
33 #include "asterisk/module.h"
34 #include "asterisk/channel.h"
35 #include "asterisk/pbx.h"
36 #include "asterisk/utils.h"
37 #include "asterisk/app.h"
38 
39 /*** DOCUMENTATION
40  <function name="TIMEOUT" language="en_US">
41  <synopsis>
42  Gets or sets timeouts on the channel. Timeout values are in seconds.
43  </synopsis>
44  <syntax>
45  <parameter name="timeouttype" required="true">
46  <para>The timeout that will be manipulated. The possible timeout types
47  are: <literal>absolute</literal>, <literal>digit</literal> or
48  <literal>response</literal></para>
49  </parameter>
50  </syntax>
51  <description>
52  <para>The timeouts that can be manipulated are:</para>
53  <para><literal>absolute</literal>: The absolute maximum amount of time permitted for a call.
54  Setting of 0 disables the timeout.</para>
55  <para><literal>digit</literal>: The maximum amount of time permitted between digits when the
56  user is typing in an extension. When this timeout expires,
57  after the user has started to type in an extension, the
58  extension will be considered complete, and will be
59  interpreted. Note that if an extension typed in is valid,
60  it will not have to timeout to be tested, so typically at
61  the expiry of this timeout, the extension will be considered
62  invalid (and thus control would be passed to the <literal>i</literal>
63  extension, or if it doesn't exist the call would be
64  terminated). The default timeout is 5 seconds.</para>
65  <para><literal>response</literal>: The maximum amount of time permitted after falling through a
66  series of priorities for a channel in which the user may
67  begin typing an extension. If the user does not type an
68  extension in this amount of time, control will pass to the
69  <literal>t</literal> extension if it exists, and if not the call would be
70  terminated. The default timeout is 10 seconds.</para>
71  </description>
72  </function>
73  ***/
74 
75 static int timeout_read(struct ast_channel *chan, const char *cmd, char *data,
76  char *buf, size_t len)
77 {
78  struct timeval myt;
79 
80  if (!chan)
81  return -1;
82 
83  if (!data) {
84  ast_log(LOG_ERROR, "Must specify type of timeout to get.\n");
85  return -1;
86  }
87 
88  switch (*data) {
89  case 'a':
90  case 'A':
92  ast_copy_string(buf, "0", len);
93  } else {
94  myt = ast_tvnow();
95  snprintf(buf, len, "%.3f", ast_tvdiff_ms(*ast_channel_whentohangup(chan), myt) / 1000.0);
96  }
97  break;
98 
99  case 'r':
100  case 'R':
101  if (ast_channel_pbx(chan)) {
102  snprintf(buf, len, "%.3f", ast_channel_pbx(chan)->rtimeoutms / 1000.0);
103  }
104  break;
105 
106  case 'd':
107  case 'D':
108  if (ast_channel_pbx(chan)) {
109  snprintf(buf, len, "%.3f", ast_channel_pbx(chan)->dtimeoutms / 1000.0);
110  }
111  break;
112 
113  default:
114  ast_log(LOG_ERROR, "Unknown timeout type specified.\n");
115  return -1;
116  }
117 
118  return 0;
119 }
120 
121 static int timeout_write(struct ast_channel *chan, const char *cmd, char *data,
122  const char *value)
123 {
124  double x = 0.0;
125  long sec = 0L;
126  char timestr[64];
127  struct ast_tm myt;
128  struct timeval when = {0,};
129  int res;
130 
131  if (!chan)
132  return -1;
133 
134  if (!data) {
135  ast_log(LOG_ERROR, "Must specify type of timeout to set.\n");
136  return -1;
137  }
138 
139  if (!value)
140  return -1;
141 
142  res = sscanf(value, "%30ld%30lf", &sec, &x);
143  if (res == 0 || sec < 0) {
144  when.tv_sec = 0;
145  when.tv_usec = 0;
146  } else if (res == 1) {
147  when.tv_sec = sec;
148  } else if (res == 2) {
149  when.tv_sec = sec;
150  when.tv_usec = x * 1000000;
151  }
152 
153  switch (*data) {
154  case 'a':
155  case 'A':
156  ast_channel_lock(chan);
157  ast_channel_setwhentohangup_tv(chan, when);
158  ast_channel_unlock(chan);
159  if (VERBOSITY_ATLEAST(3)) {
160  if (!ast_tvzero(*ast_channel_whentohangup(chan))) {
161  when = ast_tvadd(when, ast_tvnow());
162  ast_strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S.%3q %Z",
163  ast_localtime(&when, &myt, NULL));
164  ast_verb(3, "Channel will hangup at %s.\n", timestr);
165  } else {
166  ast_verb(3, "Channel hangup cancelled.\n");
167  }
168  }
169  break;
170 
171  case 'r':
172  case 'R':
173  if (ast_channel_pbx(chan)) {
174  ast_channel_pbx(chan)->rtimeoutms = when.tv_sec * 1000 + when.tv_usec / 1000;
175  ast_verb(3, "Response timeout set to %.3f\n", ast_channel_pbx(chan)->rtimeoutms / 1000.0);
176  }
177  break;
178 
179  case 'd':
180  case 'D':
181  if (ast_channel_pbx(chan)) {
182  ast_channel_pbx(chan)->dtimeoutms = when.tv_sec * 1000 + when.tv_usec / 1000;
183  ast_verb(3, "Digit timeout set to %.3f\n", ast_channel_pbx(chan)->dtimeoutms / 1000.0);
184  }
185  break;
186 
187  default:
188  ast_log(LOG_ERROR, "Unknown timeout type specified.\n");
189  break;
190  }
191 
192  return 0;
193 }
194 
196  .name = "TIMEOUT",
197  .read = timeout_read,
198  .read_max = 22,
199  .write = timeout_write,
200 };
201 
202 static int unload_module(void)
203 {
204  return ast_custom_function_unregister(&timeout_function);
205 }
206 
207 static int load_module(void)
208 {
209  return ast_custom_function_register(&timeout_function);
210 }
211 
212 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel timeout dialplan functions");
const char * name
Definition: pbx.h:119
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
Asterisk main include file. File version handling, generic pbx functions.
void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
Set when to hang a channel up.
Definition: channel.c:510
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define VERBOSITY_ATLEAST(level)
Definition: logger.h:461
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
static int timeout_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
Definition: func_timeout.c:121
#define ast_verb(level,...)
Definition: logger.h:463
static struct ast_custom_function timeout_function
Definition: func_timeout.c:195
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Utility functions.
struct timeval * ast_channel_whentohangup(struct ast_channel *chan)
#define ast_log
Definition: astobj2.c:42
General Asterisk PBX channel definitions.
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
Data structure associated with a custom dialplan function.
Definition: pbx.h:118
static int timeout_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_timeout.c:75
Core PBX routines and definitions.
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
static int unload_module(void)
Definition: func_timeout.c:202
#define ast_channel_unlock(chan)
Definition: channel.h:2946
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
static int load_module(void)
Definition: func_timeout.c:207
int dtimeoutms
Definition: pbx.h:212
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508
int rtimeoutms
Definition: pbx.h:213