Wed Jan 8 2020 09:49:47

Asterisk developer's documentation


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 <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 
19 /*! \file
20  *
21  * \brief Channel timeout related dialplan functions
22  *
23  * \author Mark Spencer <markster@digium.com>
24  * \ingroup functions
25  */
26 
27 /*** MODULEINFO
28  <support_level>core</support_level>
29  ***/
30 
31 #include "asterisk.h"
32 
33 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 352029 $")
34 
35 #include "asterisk/module.h"
36 #include "asterisk/channel.h"
37 #include "asterisk/pbx.h"
38 #include "asterisk/utils.h"
39 #include "asterisk/app.h"
40 
41 /*** DOCUMENTATION
42  <function name="TIMEOUT" language="en_US">
43  <synopsis>
44  Gets or sets timeouts on the channel. Timeout values are in seconds.
45  </synopsis>
46  <syntax>
47  <parameter name="timeouttype" required="true">
48  <para>The timeout that will be manipulated. The possible timeout types
49  are: <literal>absolute</literal>, <literal>digit</literal> or
50  <literal>response</literal></para>
51  </parameter>
52  </syntax>
53  <description>
54  <para>The timeouts that can be manipulated are:</para>
55  <para><literal>absolute</literal>: The absolute maximum amount of time permitted for a call.
56  Setting of 0 disables the timeout.</para>
57  <para><literal>digit</literal>: The maximum amount of time permitted between digits when the
58  user is typing in an extension. When this timeout expires,
59  after the user has started to type in an extension, the
60  extension will be considered complete, and will be
61  interpreted. Note that if an extension typed in is valid,
62  it will not have to timeout to be tested, so typically at
63  the expiry of this timeout, the extension will be considered
64  invalid (and thus control would be passed to the <literal>i</literal>
65  extension, or if it doesn't exist the call would be
66  terminated). The default timeout is 5 seconds.</para>
67  <para><literal>response</literal>: The maximum amount of time permitted after falling through a
68  series of priorities for a channel in which the user may
69  begin typing an extension. If the user does not type an
70  extension in this amount of time, control will pass to the
71  <literal>t</literal> extension if it exists, and if not the call would be
72  terminated. The default timeout is 10 seconds.</para>
73  </description>
74  </function>
75  ***/
76 
77 static int timeout_read(struct ast_channel *chan, const char *cmd, char *data,
78  char *buf, size_t len)
79 {
80  struct timeval myt;
81 
82  if (!chan)
83  return -1;
84 
85  if (!data) {
86  ast_log(LOG_ERROR, "Must specify type of timeout to get.\n");
87  return -1;
88  }
89 
90  switch (*data) {
91  case 'a':
92  case 'A':
93  if (ast_tvzero(chan->whentohangup)) {
94  ast_copy_string(buf, "0", len);
95  } else {
96  myt = ast_tvnow();
97  snprintf(buf, len, "%.3f", ast_tvdiff_ms(chan->whentohangup, myt) / 1000.0);
98  }
99  break;
100 
101  case 'r':
102  case 'R':
103  if (chan->pbx) {
104  snprintf(buf, len, "%.3f", chan->pbx->rtimeoutms / 1000.0);
105  }
106  break;
107 
108  case 'd':
109  case 'D':
110  if (chan->pbx) {
111  snprintf(buf, len, "%.3f", chan->pbx->dtimeoutms / 1000.0);
112  }
113  break;
114 
115  default:
116  ast_log(LOG_ERROR, "Unknown timeout type specified.\n");
117  return -1;
118  }
119 
120  return 0;
121 }
122 
123 static int timeout_write(struct ast_channel *chan, const char *cmd, char *data,
124  const char *value)
125 {
126  double x = 0.0;
127  long sec = 0L;
128  char timestr[64];
129  struct ast_tm myt;
130  struct timeval when = {0,};
131  int res;
132 
133  if (!chan)
134  return -1;
135 
136  if (!data) {
137  ast_log(LOG_ERROR, "Must specify type of timeout to set.\n");
138  return -1;
139  }
140 
141  if (!value)
142  return -1;
143 
144  res = sscanf(value, "%30ld%30lf", &sec, &x);
145  if (res == 0 || sec < 0) {
146  when.tv_sec = 0;
147  when.tv_usec = 0;
148  } else if (res == 1) {
149  when.tv_sec = sec;
150  } else if (res == 2) {
151  when.tv_sec = sec;
152  when.tv_usec = x * 1000000;
153  }
154 
155  switch (*data) {
156  case 'a':
157  case 'A':
158  ast_channel_setwhentohangup_tv(chan, when);
159  if (VERBOSITY_ATLEAST(3)) {
160  if (!ast_tvzero(chan->whentohangup)) {
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_verbose("Channel will hangup at %s.\n", timestr);
165  } else {
166  ast_verbose("Channel hangup cancelled.\n");
167  }
168  }
169  break;
170 
171  case 'r':
172  case 'R':
173  if (chan->pbx) {
174  chan->pbx->rtimeoutms = when.tv_sec * 1000 + when.tv_usec / 1000;
175  ast_verb(3, "Response timeout set to %.3f\n", chan->pbx->rtimeoutms / 1000.0);
176  }
177  break;
178 
179  case 'd':
180  case 'D':
181  if (chan->pbx) {
182  chan->pbx->dtimeoutms = when.tv_sec * 1000 + when.tv_usec / 1000;
183  ast_verb(3, "Digit timeout set to %.3f\n", chan->pbx->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");
Main Channel structure associated with a channel.
Definition: channel.h:742
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:396
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:871
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
#define VERBOSITY_ATLEAST(level)
Definition: logger.h:241
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:1570
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
int value
Definition: syslog.c:39
static int timeout_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
Definition: func_timeout.c:123
#define ast_verb(level,...)
Definition: logger.h:243
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.
Definition: pbx.c:3814
Utility functions.
General Asterisk PBX channel definitions.
Data structure associated with a custom dialplan function.
Definition: pbx.h:95
static int timeout_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_timeout.c:77
Core PBX routines and definitions.
#define LOG_ERROR
Definition: logger.h:155
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: utils.c:1587
static int unload_module(void)
Definition: func_timeout.c:202
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
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:2351
static int load_module(void)
Definition: func_timeout.c:207
int dtimeoutms
Definition: pbx.h:180
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
const char * name
Definition: pbx.h:96
struct timeval whentohangup
Definition: channel.h:789
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
struct ast_pbx * pbx
Definition: channel.h:761
int rtimeoutms
Definition: pbx.h:181