| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Asterisk -- An open source telephony toolkit. | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  |  * Copyright (C) 1999 - 2006, Digium, Inc. | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Mark Spencer <markster@digium.com> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * See http://www.asterisk.org for more information about
 | 
					
						
							|  |  |  |  * the Asterisk project. Please do not directly contact | 
					
						
							|  |  |  |  * any of the maintainers of this project for assistance; | 
					
						
							|  |  |  |  * the project provides a web site, mailing lists and IRC | 
					
						
							|  |  |  |  * channels for your use. | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This program is free software, distributed under the terms of | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * the GNU General Public License Version 2. See the LICENSE file | 
					
						
							|  |  |  |  * at the top of the source tree. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | /*! \file
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  |  * \brief Channel timeout related dialplan functions | 
					
						
							| 
									
										
										
										
											2005-12-30 21:18:06 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * \author Mark Spencer <markster@digium.com>  | 
					
						
							| 
									
										
										
										
											2007-01-24 09:05:29 +00:00
										 |  |  |  * \ingroup functions | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-07 18:54:56 +00:00
										 |  |  | #include "asterisk.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-11 03:14:05 +00:00
										 |  |  | #include "asterisk/module.h"
 | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | #include "asterisk/channel.h"
 | 
					
						
							|  |  |  | #include "asterisk/pbx.h"
 | 
					
						
							|  |  |  | #include "asterisk/utils.h"
 | 
					
						
							|  |  |  | #include "asterisk/app.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-06 00:13:33 +00:00
										 |  |  | static int timeout_read(struct ast_channel *chan, const char *cmd, char *data, | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 			char *buf, size_t len) | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-05-01 23:06:23 +00:00
										 |  |  | 	struct timeval myt; | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-19 02:51:21 +00:00
										 |  |  | 	if (!chan) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 	if (!data) { | 
					
						
							| 
									
										
										
										
											2006-09-28 18:09:01 +00:00
										 |  |  | 		ast_log(LOG_ERROR, "Must specify type of timeout to get.\n"); | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	switch (*data) { | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 	case 'a': | 
					
						
							|  |  |  | 	case 'A': | 
					
						
							| 
									
										
										
										
											2008-05-01 23:06:23 +00:00
										 |  |  | 		if (ast_tvzero(chan->whentohangup)) { | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 			ast_copy_string(buf, "0", len); | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2008-05-01 23:06:23 +00:00
										 |  |  | 			myt = ast_tvnow(); | 
					
						
							|  |  |  | 			snprintf(buf, len, "%.3f", ast_tvdiff_ms(myt, chan->whentohangup) / 1000.0); | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case 'r': | 
					
						
							|  |  |  | 	case 'R': | 
					
						
							|  |  |  | 		if (chan->pbx) { | 
					
						
							| 
									
										
										
										
											2008-05-01 23:06:23 +00:00
										 |  |  | 			snprintf(buf, len, "%.3f", chan->pbx->rtimeoutms / 1000.0); | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case 'd': | 
					
						
							|  |  |  | 	case 'D': | 
					
						
							|  |  |  | 		if (chan->pbx) { | 
					
						
							| 
									
										
										
										
											2008-05-01 23:06:23 +00:00
										 |  |  | 			snprintf(buf, len, "%.3f", chan->pbx->dtimeoutms / 1000.0); | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2006-09-28 18:09:01 +00:00
										 |  |  | 		ast_log(LOG_ERROR, "Unknown timeout type specified.\n"); | 
					
						
							| 
									
										
										
										
											2008-10-06 21:32:42 +00:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-06 00:13:33 +00:00
										 |  |  | static int timeout_write(struct ast_channel *chan, const char *cmd, char *data, | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 			 const char *value) | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-22 16:17:17 +00:00
										 |  |  | 	double x = 0.0; | 
					
						
							|  |  |  | 	long sec = 0L; | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 	char timestr[64]; | 
					
						
							| 
									
										
										
										
											2007-07-18 19:47:20 +00:00
										 |  |  | 	struct ast_tm myt; | 
					
						
							| 
									
										
										
										
											2008-12-22 16:17:17 +00:00
										 |  |  | 	struct timeval when = {0,}; | 
					
						
							|  |  |  | 	int res; | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-19 02:51:21 +00:00
										 |  |  | 	if (!chan) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 	if (!data) { | 
					
						
							| 
									
										
										
										
											2006-09-28 18:09:01 +00:00
										 |  |  | 		ast_log(LOG_ERROR, "Must specify type of timeout to set.\n"); | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 	if (!value) | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 16:17:17 +00:00
										 |  |  | 	res = sscanf(value, "%ld%lf", &sec, &x); | 
					
						
							|  |  |  | 	if (res == 0 || sec < 0) { | 
					
						
							| 
									
										
										
										
											2008-08-07 01:07:40 +00:00
										 |  |  | 		when.tv_sec = 0; | 
					
						
							| 
									
										
										
										
											2008-12-22 16:17:17 +00:00
										 |  |  | 		when.tv_usec = 0; | 
					
						
							|  |  |  | 	} else if (res == 1) { | 
					
						
							|  |  |  | 		when.tv_sec = sec; | 
					
						
							|  |  |  | 	} else if (res == 2) { | 
					
						
							| 
									
										
										
										
											2008-08-07 01:07:40 +00:00
										 |  |  | 		when.tv_sec = sec; | 
					
						
							|  |  |  | 		when.tv_usec = x * 1000000; | 
					
						
							| 
									
										
										
										
											2008-05-15 10:56:29 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 	switch (*data) { | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 	case 'a': | 
					
						
							|  |  |  | 	case 'A': | 
					
						
							| 
									
										
										
										
											2008-08-07 01:07:40 +00:00
										 |  |  | 		ast_channel_setwhentohangup_tv(chan, when); | 
					
						
							| 
									
										
										
										
											2007-12-14 19:19:07 +00:00
										 |  |  | 		if (VERBOSITY_ATLEAST(3)) { | 
					
						
							| 
									
										
										
										
											2008-05-01 23:06:23 +00:00
										 |  |  | 			if (!ast_tvzero(chan->whentohangup)) { | 
					
						
							| 
									
										
										
										
											2008-08-07 01:07:40 +00:00
										 |  |  | 				when = ast_tvadd(when, ast_tvnow()); | 
					
						
							| 
									
										
										
										
											2007-07-18 19:47:20 +00:00
										 |  |  | 				ast_strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S.%3q %Z", | 
					
						
							| 
									
										
										
										
											2008-08-07 01:07:40 +00:00
										 |  |  | 					ast_localtime(&when, &myt, NULL)); | 
					
						
							| 
									
										
										
										
											2007-12-14 15:59:09 +00:00
										 |  |  | 				ast_verbose("Channel will hangup at %s.\n", timestr); | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2007-12-14 15:59:09 +00:00
										 |  |  | 				ast_verbose("Channel hangup cancelled.\n"); | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2007-12-14 15:59:09 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case 'r': | 
					
						
							|  |  |  | 	case 'R': | 
					
						
							|  |  |  | 		if (chan->pbx) { | 
					
						
							| 
									
										
										
										
											2008-08-07 01:07:40 +00:00
										 |  |  | 			chan->pbx->rtimeoutms = when.tv_sec * 1000 + when.tv_usec / 1000.0; | 
					
						
							| 
									
										
										
										
											2008-05-01 23:06:23 +00:00
										 |  |  | 			ast_verb(3, "Response timeout set to %.3f\n", chan->pbx->rtimeoutms / 1000.0); | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case 'd': | 
					
						
							|  |  |  | 	case 'D': | 
					
						
							|  |  |  | 		if (chan->pbx) { | 
					
						
							| 
									
										
										
										
											2008-08-07 01:07:40 +00:00
										 |  |  | 			chan->pbx->dtimeoutms = when.tv_sec * 1000 + when.tv_usec / 1000.0; | 
					
						
							| 
									
										
										
										
											2008-05-01 23:06:23 +00:00
										 |  |  | 			ast_verb(3, "Digit timeout set to %.3f\n", chan->pbx->dtimeoutms / 1000.0); | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2006-09-28 18:09:01 +00:00
										 |  |  | 		ast_log(LOG_ERROR, "Unknown timeout type specified.\n"); | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-11 03:14:05 +00:00
										 |  |  | static struct ast_custom_function timeout_function = { | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 	.name = "TIMEOUT", | 
					
						
							| 
									
										
										
										
											2006-10-09 18:23:21 +00:00
										 |  |  | 	.synopsis = "Gets or sets timeouts on the channel. Timeout values are in seconds.", | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | 	.syntax = "TIMEOUT(timeouttype)", | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 	.desc = | 
					
						
							|  |  |  | 		"Gets or sets various channel timeouts. The timeouts that can be\n" | 
					
						
							|  |  |  | 		"manipulated are:\n" "\n" | 
					
						
							|  |  |  | 		"absolute: The absolute maximum amount of time permitted for a call.  A\n" | 
					
						
							| 
									
										
										
										
											2007-07-31 01:10:47 +00:00
										 |  |  | 		"          setting of 0 disables the timeout.\n" "\n" | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 		"digit:    The maximum amount of time permitted between digits when the\n" | 
					
						
							|  |  |  | 		"          user is typing in an extension.  When this timeout expires,\n" | 
					
						
							|  |  |  | 		"          after the user has started to type in an extension, the\n" | 
					
						
							|  |  |  | 		"          extension will be considered complete, and will be\n" | 
					
						
							|  |  |  | 		"          interpreted.  Note that if an extension typed in is valid,\n" | 
					
						
							|  |  |  | 		"          it will not have to timeout to be tested, so typically at\n" | 
					
						
							|  |  |  | 		"          the expiry of this timeout, the extension will be considered\n" | 
					
						
							|  |  |  | 		"          invalid (and thus control would be passed to the 'i'\n" | 
					
						
							|  |  |  | 		"          extension, or if it doesn't exist the call would be\n" | 
					
						
							|  |  |  | 		"          terminated).  The default timeout is 5 seconds.\n" "\n" | 
					
						
							|  |  |  | 		"response: The maximum amount of time permitted after falling through a\n" | 
					
						
							| 
									
										
										
										
											2007-07-31 01:10:47 +00:00
										 |  |  | 		"          series of priorities for a channel in which the user may\n" | 
					
						
							|  |  |  | 		"          begin typing an extension.  If the user does not type an\n" | 
					
						
							|  |  |  | 		"          extension in this amount of time, control will pass to the\n" | 
					
						
							|  |  |  | 		"          't' extension if it exists, and if not the call would be\n" | 
					
						
							|  |  |  | 		"          terminated.  The default timeout is 10 seconds.\n", | 
					
						
							| 
									
										
										
										
											2006-02-11 03:14:05 +00:00
										 |  |  | 	.read = timeout_read, | 
					
						
							|  |  |  | 	.write = timeout_write, | 
					
						
							| 
									
										
										
										
											2005-05-15 17:45:30 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | static int unload_module(void) | 
					
						
							| 
									
										
										
										
											2006-02-11 03:14:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 	return ast_custom_function_unregister(&timeout_function); | 
					
						
							| 
									
										
										
										
											2006-02-11 03:14:05 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | static int load_module(void) | 
					
						
							| 
									
										
										
										
											2006-02-11 03:14:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-02-12 04:28:58 +00:00
										 |  |  | 	return ast_custom_function_register(&timeout_function); | 
					
						
							| 
									
										
										
										
											2006-02-11 03:14:05 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel timeout dialplan functions"); |