| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Asterisk -- An open source telephony toolkit. | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Copyright (C) 1999 - 2005, Digium, Inc. | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  |  * Made only slightly more sane by Mark Spencer <markster@digium.com> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * 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. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +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 DISA -- Direct Inward System Access Application | 
					
						
							| 
									
										
										
										
											2005-11-06 15:09:47 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * \author Jim Dixon <jim@lambdatel.com> | 
					
						
							| 
									
										
										
										
											2008-02-09 11:27:10 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-11-06 15:09:47 +00:00
										 |  |  |  * \ingroup applications | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-02-09 11:27:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-14 20:13:06 +00:00
										 |  |  | /*** MODULEINFO
 | 
					
						
							|  |  |  | 	<support_level>core</support_level> | 
					
						
							|  |  |  |  ***/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-07 18:54:56 +00:00
										 |  |  | #include "asterisk.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-06 22:39:32 +00:00
										 |  |  | #include <math.h>
 | 
					
						
							|  |  |  | #include <sys/time.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-21 06:02:45 +00:00
										 |  |  | #include "asterisk/lock.h"
 | 
					
						
							|  |  |  | #include "asterisk/file.h"
 | 
					
						
							|  |  |  | #include "asterisk/channel.h"
 | 
					
						
							|  |  |  | #include "asterisk/app.h"
 | 
					
						
							|  |  |  | #include "asterisk/indications.h"
 | 
					
						
							|  |  |  | #include "asterisk/pbx.h"
 | 
					
						
							|  |  |  | #include "asterisk/module.h"
 | 
					
						
							|  |  |  | #include "asterisk/translate.h"
 | 
					
						
							|  |  |  | #include "asterisk/ulaw.h"
 | 
					
						
							|  |  |  | #include "asterisk/callerid.h"
 | 
					
						
							| 
									
										
										
										
											2006-02-01 23:05:28 +00:00
										 |  |  | #include "asterisk/stringfields.h"
 | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-01 21:10:07 +00:00
										 |  |  | /*** DOCUMENTATION
 | 
					
						
							|  |  |  | 	<application name="DISA" language="en_US"> | 
					
						
							|  |  |  | 		<synopsis> | 
					
						
							|  |  |  | 			Direct Inward System Access. | 
					
						
							|  |  |  | 		</synopsis> | 
					
						
							|  |  |  | 		<syntax> | 
					
						
							|  |  |  | 			<parameter name="passcode|filename" required="true"> | 
					
						
							|  |  |  | 				<para>If you need to present a DISA dialtone without entering a password, | 
					
						
							|  |  |  | 				simply set <replaceable>passcode</replaceable> to <literal>no-password</literal></para> | 
					
						
							|  |  |  | 				<para>You may specified a <replaceable>filename</replaceable> instead of a | 
					
						
							|  |  |  | 				<replaceable>passcode</replaceable>, this filename must contain individual passcodes</para> | 
					
						
							|  |  |  | 			</parameter> | 
					
						
							|  |  |  | 			<parameter name="context"> | 
					
						
							|  |  |  | 				<para>Specifies the dialplan context in which the user-entered extension | 
					
						
							|  |  |  | 				will be matched. If no context is specified, the DISA application defaults | 
					
						
							|  |  |  | 				to the <literal>disa</literal> context. Presumably a normal system will have a special | 
					
						
							|  |  |  | 				context set up for DISA use with some or a lot of restrictions.</para> | 
					
						
							|  |  |  | 			</parameter> | 
					
						
							|  |  |  | 			<parameter name="cid"> | 
					
						
							|  |  |  | 				<para>Specifies a new (different) callerid to be used for this call.</para> | 
					
						
							|  |  |  | 			</parameter> | 
					
						
							|  |  |  | 			<parameter name="mailbox" argsep="@"> | 
					
						
							|  |  |  | 				<para>Will cause a stutter-dialtone (indication <emphasis>dialrecall</emphasis>) | 
					
						
							|  |  |  | 				to be used, if the specified mailbox contains any new messages.</para> | 
					
						
							|  |  |  | 				<argument name="mailbox" required="true" /> | 
					
						
							|  |  |  | 				<argument name="context" required="false" /> | 
					
						
							|  |  |  | 			</parameter> | 
					
						
							|  |  |  | 			<parameter name="options"> | 
					
						
							|  |  |  | 				<optionlist> | 
					
						
							|  |  |  | 					<option name="n"> | 
					
						
							|  |  |  | 						<para>The DISA application will not answer initially.</para> | 
					
						
							|  |  |  | 					</option> | 
					
						
							|  |  |  | 					<option name="p"> | 
					
						
							|  |  |  | 						<para>The extension entered will be considered complete when a <literal>#</literal> | 
					
						
							|  |  |  | 						is entered.</para> | 
					
						
							|  |  |  | 					</option> | 
					
						
							|  |  |  | 				</optionlist> | 
					
						
							|  |  |  | 			</parameter> | 
					
						
							|  |  |  | 		</syntax> | 
					
						
							|  |  |  | 		<description> | 
					
						
							|  |  |  | 			<para>The DISA, Direct Inward System Access, application allows someone from | 
					
						
							|  |  |  | 			outside the telephone switch (PBX) to obtain an <emphasis>internal</emphasis> system | 
					
						
							|  |  |  | 			dialtone and to place calls from it as if they were placing a call from | 
					
						
							|  |  |  | 			within the switch. | 
					
						
							|  |  |  | 			DISA plays a dialtone. The user enters their numeric passcode, followed by | 
					
						
							|  |  |  | 			the pound sign <literal>#</literal>. If the passcode is correct, the user is then given | 
					
						
							|  |  |  | 			system dialtone within <replaceable>context</replaceable> on which a call may be placed. | 
					
						
							|  |  |  | 			If the user enters an invalid extension and extension <literal>i</literal> exists in the specified | 
					
						
							|  |  |  | 			<replaceable>context</replaceable>, it will be used. | 
					
						
							|  |  |  | 			</para> | 
					
						
							|  |  |  | 			<para>Be aware that using this may compromise the security of your PBX.</para> | 
					
						
							|  |  |  | 			<para>The arguments to this application (in <filename>extensions.conf</filename>) allow either | 
					
						
							|  |  |  | 			specification of a single global <replaceable>passcode</replaceable> (that everyone uses), or | 
					
						
							|  |  |  | 			individual passcodes contained in a file (<replaceable>filename</replaceable>).</para> | 
					
						
							|  |  |  | 			<para>The file that contains the passcodes (if used) allows a complete | 
					
						
							|  |  |  | 			specification of all of the same arguments available on the command | 
					
						
							|  |  |  | 			line, with the sole exception of the options. The file may contain blank | 
					
						
							|  |  |  | 			lines, or comments starting with <literal>#</literal> or <literal>;</literal>.</para> | 
					
						
							|  |  |  | 		</description> | 
					
						
							| 
									
										
										
										
											2008-11-05 13:07:29 +00:00
										 |  |  | 		<see-also> | 
					
						
							|  |  |  | 			<ref type="application">Authenticate</ref> | 
					
						
							|  |  |  | 			<ref type="application">VMAuthenticate</ref> | 
					
						
							|  |  |  | 		</see-also> | 
					
						
							| 
									
										
										
										
											2008-11-01 21:10:07 +00:00
										 |  |  | 	</application> | 
					
						
							|  |  |  |  ***/ | 
					
						
							| 
									
										
										
										
											2009-06-07 14:55:51 +00:00
										 |  |  | static const char app[] = "DISA"; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-11 22:21:28 +00:00
										 |  |  | enum { | 
					
						
							|  |  |  | 	NOANSWER_FLAG = (1 << 0), | 
					
						
							|  |  |  | 	POUND_TO_END_FLAG = (1 << 1), | 
					
						
							| 
									
										
										
										
											2009-06-07 14:55:51 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-06-11 22:21:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | AST_APP_OPTIONS(app_opts, { | 
					
						
							|  |  |  | 	AST_APP_OPTION('n', NOANSWER_FLAG), | 
					
						
							|  |  |  | 	AST_APP_OPTION('p', POUND_TO_END_FLAG), | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-31 23:28:42 +00:00
										 |  |  | static void play_dialtone(struct ast_channel *chan, char *mailbox) | 
					
						
							| 
									
										
										
										
											2004-08-28 19:41:18 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-17 20:41:24 +00:00
										 |  |  | 	struct ast_tone_zone_sound *ts = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ast_app_has_voicemail(mailbox, NULL)) { | 
					
						
							| 
									
										
										
										
											2004-10-31 23:28:42 +00:00
										 |  |  | 		ts = ast_get_indication_tone(chan->zone, "dialrecall"); | 
					
						
							| 
									
										
										
										
											2009-02-17 20:41:24 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2004-10-31 23:28:42 +00:00
										 |  |  | 		ts = ast_get_indication_tone(chan->zone, "dial"); | 
					
						
							| 
									
										
										
										
											2009-02-17 20:41:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ts) { | 
					
						
							| 
									
										
										
										
											2004-08-28 19:41:18 +00:00
										 |  |  | 		ast_playtones_start(chan, 0, ts->data, 0); | 
					
						
							| 
									
										
										
										
											2009-02-17 20:41:24 +00:00
										 |  |  | 		ts = ast_tone_zone_sound_unref(ts); | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2004-08-28 19:41:18 +00:00
										 |  |  | 		ast_tonepair_start(chan, 350, 440, 0, 0); | 
					
						
							| 
									
										
										
										
											2009-02-17 20:41:24 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-08-28 19:41:18 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 21:13:09 +00:00
										 |  |  | static int disa_exec(struct ast_channel *chan, const char *data) | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-09-19 15:05:35 +00:00
										 |  |  | 	int i = 0, j, k = 0, did_ignore = 0, special_noanswer = 0; | 
					
						
							| 
									
										
										
										
											2008-05-01 23:06:23 +00:00
										 |  |  | 	int firstdigittimeout = (chan->pbx ? chan->pbx->rtimeoutms : 20000); | 
					
						
							|  |  |  | 	int digittimeout = (chan->pbx ? chan->pbx->dtimeoutms : 10000); | 
					
						
							| 
									
										
										
										
											2007-06-11 22:21:28 +00:00
										 |  |  | 	struct ast_flags flags; | 
					
						
							| 
									
										
										
										
											2007-09-19 15:05:35 +00:00
										 |  |  | 	char *tmp, exten[AST_MAX_EXTENSION] = "", acctcode[20]=""; | 
					
						
							| 
									
										
										
										
											2005-11-11 00:53:19 +00:00
										 |  |  | 	char pwline[256]; | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	char ourcidname[256],ourcidnum[256]; | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 	struct ast_frame *f; | 
					
						
							| 
									
										
										
										
											2005-07-15 23:00:47 +00:00
										 |  |  | 	struct timeval lastdigittime; | 
					
						
							| 
									
										
										
										
											2002-05-13 22:29:39 +00:00
										 |  |  | 	int res; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 	FILE *fp; | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	AST_DECLARE_APP_ARGS(args, | 
					
						
							|  |  |  | 		AST_APP_ARG(passcode); | 
					
						
							|  |  |  | 		AST_APP_ARG(context); | 
					
						
							|  |  |  | 		AST_APP_ARG(cid); | 
					
						
							|  |  |  | 		AST_APP_ARG(mailbox); | 
					
						
							| 
									
										
										
										
											2007-06-11 22:21:28 +00:00
										 |  |  | 		AST_APP_ARG(options); | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-26 19:48:14 +00:00
										 |  |  | 	if (ast_strlen_zero(data)) { | 
					
						
							| 
									
										
										
										
											2006-07-15 21:56:58 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "DISA requires an argument (passcode/passcode file)\n"); | 
					
						
							| 
									
										
										
										
											2005-10-19 18:19:02 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-02-09 11:27:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-14 19:39:12 +00:00
										 |  |  | 	ast_debug(1, "Digittimeout: %d\n", digittimeout); | 
					
						
							|  |  |  | 	ast_debug(1, "Responsetimeout: %d\n", firstdigittimeout); | 
					
						
							| 
									
										
										
										
											2005-10-19 18:19:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-10 13:22:15 +00:00
										 |  |  | 	tmp = ast_strdupa(data); | 
					
						
							| 
									
										
										
										
											2005-10-19 18:19:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	AST_STANDARD_APP_ARGS(args, tmp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-09 11:27:10 +00:00
										 |  |  | 	if (ast_strlen_zero(args.context)) | 
					
						
							|  |  |  | 		args.context = "disa"; | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	if (ast_strlen_zero(args.mailbox)) | 
					
						
							| 
									
										
										
										
											2005-11-15 19:40:08 +00:00
										 |  |  | 		args.mailbox = ""; | 
					
						
							| 
									
										
										
										
											2007-06-11 22:21:28 +00:00
										 |  |  | 	if (!ast_strlen_zero(args.options)) | 
					
						
							|  |  |  | 		ast_app_parse_options(app_opts, &flags, NULL, args.options); | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-14 19:39:12 +00:00
										 |  |  | 	ast_debug(1, "Mailbox: %s\n",args.mailbox); | 
					
						
							| 
									
										
										
										
											2006-01-16 18:52:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-19 15:05:35 +00:00
										 |  |  | 	if (!ast_test_flag(&flags, NOANSWER_FLAG)) { | 
					
						
							| 
									
										
										
										
											2006-01-16 18:52:13 +00:00
										 |  |  | 		if (chan->_state != AST_STATE_UP) { | 
					
						
							|  |  |  | 			/* answer */ | 
					
						
							|  |  |  | 			ast_answer(chan); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-09-24 19:41:02 +00:00
										 |  |  | 	} else special_noanswer = 1; | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-14 19:39:12 +00:00
										 |  |  | 	ast_debug(1, "Context: %s\n",args.context); | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	if (!strcasecmp(args.passcode, "no-password")) { | 
					
						
							| 
									
										
										
										
											2005-03-26 07:08:47 +00:00
										 |  |  | 		k |= 1; /* We have the password */ | 
					
						
							| 
									
										
										
										
											2007-06-14 19:39:12 +00:00
										 |  |  | 		ast_debug(1, "DISA no-password login success\n"); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-09-19 15:05:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-15 23:00:47 +00:00
										 |  |  | 	lastdigittime = ast_tvnow(); | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	play_dialtone(chan, args.mailbox); | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-19 15:08:43 +00:00
										 |  |  | 	ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-19 18:19:02 +00:00
										 |  |  | 	for (;;) { | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		  /* if outa time, give em reorder */ | 
					
						
							| 
									
										
										
										
											2007-09-19 15:05:35 +00:00
										 |  |  | 		if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) > ((k&2) ? digittimeout : firstdigittimeout)) { | 
					
						
							| 
									
										
										
										
											2007-06-14 19:39:12 +00:00
										 |  |  | 			ast_debug(1,"DISA %s entry timeout on chan %s\n", | 
					
						
							| 
									
										
										
										
											2008-02-09 11:27:10 +00:00
										 |  |  | 				((k&1) ? "extension" : "password"),chan->name); | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-02-09 11:27:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-13 22:29:39 +00:00
										 |  |  | 		if ((res = ast_waitfor(chan, -1) < 0)) { | 
					
						
							| 
									
										
										
										
											2007-06-14 19:39:12 +00:00
										 |  |  | 			ast_debug(1, "Waitfor returned %d\n", res); | 
					
						
							| 
									
										
										
										
											2002-05-13 22:29:39 +00:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-09-19 15:05:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-19 15:08:43 +00:00
										 |  |  | 		if (!(f = ast_read(chan))) { | 
					
						
							|  |  |  | 			ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2007-09-19 15:08:43 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-09-19 15:05:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 14:05:12 +00:00
										 |  |  | 		if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP)) { | 
					
						
							| 
									
										
										
										
											2008-05-22 16:29:54 +00:00
										 |  |  | 			if (f->data.uint32) | 
					
						
							|  |  |  | 				chan->hangupcause = f->data.uint32; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 			ast_frfree(f); | 
					
						
							| 
									
										
										
										
											2007-09-19 15:08:43 +00:00
										 |  |  | 			ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2002-05-13 22:29:39 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-19 15:05:35 +00:00
										 |  |  | 		/* If the frame coming in is not DTMF, just drop it and continue */ | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 		if (f->frametype != AST_FRAME_DTMF) { | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 			ast_frfree(f); | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2002-05-13 22:29:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 14:05:12 +00:00
										 |  |  | 		j = f->subclass.integer;  /* save digit */ | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		ast_frfree(f); | 
					
						
							| 
									
										
										
										
											2007-09-19 15:05:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (!i) { | 
					
						
							| 
									
										
										
										
											2008-02-09 11:27:10 +00:00
										 |  |  | 			k |= 2; /* We have the first digit */ | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 			ast_playtones_stop(chan); | 
					
						
							| 
									
										
										
										
											2005-03-26 07:08:47 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-09-19 15:05:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-15 23:00:47 +00:00
										 |  |  | 		lastdigittime = ast_tvnow(); | 
					
						
							| 
									
										
										
										
											2007-09-19 15:05:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* got a DTMF tone */ | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 		if (i < AST_MAX_EXTENSION) { /* if still valid number of digits */ | 
					
						
							|  |  |  | 			if (!(k&1)) { /* if in password state */ | 
					
						
							|  |  |  | 				if (j == '#') { /* end of password */ | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 					  /* see if this is an integer */ | 
					
						
							| 
									
										
										
										
											2009-08-10 19:20:57 +00:00
										 |  |  | 					if (sscanf(args.passcode,"%30d",&j) < 1) { /* nope, it must be a filename */ | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 						fp = fopen(args.passcode,"r"); | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 						if (!fp) { | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 							ast_log(LOG_WARNING,"DISA password file %s not found on chan %s\n",args.passcode,chan->name); | 
					
						
							| 
									
										
										
										
											2007-09-19 15:08:43 +00:00
										 |  |  | 							ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 							return -1; | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2005-11-11 00:53:19 +00:00
										 |  |  | 						pwline[0] = 0; | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 						while(fgets(pwline,sizeof(pwline) - 1,fp)) { | 
					
						
							|  |  |  | 							if (!pwline[0]) | 
					
						
							|  |  |  | 								continue; | 
					
						
							| 
									
										
										
										
											2008-02-09 11:27:10 +00:00
										 |  |  | 							if (pwline[strlen(pwline) - 1] == '\n') | 
					
						
							| 
									
										
										
										
											2005-11-11 00:53:19 +00:00
										 |  |  | 								pwline[strlen(pwline) - 1] = 0; | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 							if (!pwline[0]) | 
					
						
							|  |  |  | 								continue; | 
					
						
							|  |  |  | 							 /* skip comments */ | 
					
						
							|  |  |  | 							if (pwline[0] == '#') | 
					
						
							|  |  |  | 								continue; | 
					
						
							|  |  |  | 							if (pwline[0] == ';') | 
					
						
							|  |  |  | 								continue; | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							AST_STANDARD_APP_ARGS(args, pwline); | 
					
						
							| 
									
										
										
										
											2008-02-09 11:27:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-14 19:39:12 +00:00
										 |  |  | 							ast_debug(1, "Mailbox: %s\n",args.mailbox); | 
					
						
							| 
									
										
										
										
											2005-07-07 22:42:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 							/* password must be in valid format (numeric) */ | 
					
						
							| 
									
										
										
										
											2009-08-10 19:20:57 +00:00
										 |  |  | 							if (sscanf(args.passcode,"%30d", &j) < 1) | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 								continue; | 
					
						
							|  |  |  | 							 /* if we got it */ | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 							if (!strcmp(exten,args.passcode)) { | 
					
						
							|  |  |  | 								if (ast_strlen_zero(args.context)) | 
					
						
							| 
									
										
										
										
											2005-11-15 19:40:08 +00:00
										 |  |  | 									args.context = "disa"; | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 								if (ast_strlen_zero(args.mailbox)) | 
					
						
							| 
									
										
										
										
											2005-11-15 19:40:08 +00:00
										 |  |  | 									args.mailbox = ""; | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 								break; | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 						fclose(fp); | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					/* compare the two */ | 
					
						
							|  |  |  | 					if (strcmp(exten,args.passcode)) { | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 						ast_log(LOG_WARNING,"DISA on chan %s got bad password %s\n",chan->name,exten); | 
					
						
							|  |  |  | 						goto reorder; | 
					
						
							| 
									
										
										
										
											2001-12-07 22:57:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					 /* password good, set to dial state */ | 
					
						
							| 
									
										
										
										
											2007-06-14 19:39:12 +00:00
										 |  |  | 					ast_debug(1,"DISA on chan %s password is good\n",chan->name); | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 					play_dialtone(chan, args.mailbox); | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-26 07:08:47 +00:00
										 |  |  | 					k|=1; /* In number mode */ | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 					i = 0;  /* re-set buffer pointer */ | 
					
						
							| 
									
										
										
										
											2001-12-07 22:57:34 +00:00
										 |  |  | 					exten[sizeof(acctcode)] = 0; | 
					
						
							| 
									
										
										
										
											2005-10-27 02:48:56 +00:00
										 |  |  | 					ast_copy_string(acctcode, exten, sizeof(acctcode)); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 					exten[0] = 0; | 
					
						
							| 
									
										
										
										
											2007-06-14 19:39:12 +00:00
										 |  |  | 					ast_debug(1,"Successful DISA log-in on chan %s\n", chan->name); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 					continue; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2007-09-20 17:10:14 +00:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2008-12-09 16:47:39 +00:00
										 |  |  | 				if (j == '#') { /* end of extension .. maybe */ | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 					if (i == 0 | 
					
						
							|  |  |  | 						&& (ast_matchmore_extension(chan, args.context, "#", 1, | 
					
						
							|  |  |  | 							S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)) | 
					
						
							|  |  |  | 							|| ast_exists_extension(chan, args.context, "#", 1, | 
					
						
							|  |  |  | 								S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) ) { | 
					
						
							| 
									
										
										
										
											2008-12-09 16:47:39 +00:00
										 |  |  | 						/* Let the # be the part of, or the entire extension */ | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2007-09-20 17:10:14 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2004-09-15 22:06:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 			exten[i++] = j;  /* save digit */ | 
					
						
							|  |  |  | 			exten[i] = 0; | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 			if (!(k&1)) | 
					
						
							|  |  |  | 				continue; /* if getting password, continue doing it */ | 
					
						
							|  |  |  | 			/* if this exists */ | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-11 22:21:28 +00:00
										 |  |  | 			/* user wants end of number, remove # */ | 
					
						
							|  |  |  | 			if (ast_test_flag(&flags, POUND_TO_END_FLAG) && j == '#') { | 
					
						
							|  |  |  | 				exten[--i] = 0; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 			if (ast_ignore_pattern(args.context, exten)) { | 
					
						
							| 
									
										
										
										
											2004-10-31 23:28:42 +00:00
										 |  |  | 				play_dialtone(chan, ""); | 
					
						
							| 
									
										
										
										
											2004-09-15 22:06:30 +00:00
										 |  |  | 				did_ignore = 1; | 
					
						
							|  |  |  | 			} else | 
					
						
							|  |  |  | 				if (did_ignore) { | 
					
						
							|  |  |  | 					ast_playtones_stop(chan); | 
					
						
							|  |  |  | 					did_ignore = 0; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 			/* if can do some more, do it */ | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 			if (!ast_matchmore_extension(chan, args.context, exten, 1, | 
					
						
							|  |  |  | 				S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-19 15:08:43 +00:00
										 |  |  | 	ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 	if (k == 3) { | 
					
						
							|  |  |  | 		int recheck = 0; | 
					
						
							| 
									
										
										
										
											2008-08-10 14:45:25 +00:00
										 |  |  | 		struct ast_flags cdr_flags = { AST_CDR_FLAG_POSTED }; | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 		if (!ast_exists_extension(chan, args.context, exten, 1, | 
					
						
							|  |  |  | 			S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { | 
					
						
							| 
									
										
										
										
											2005-10-23 01:39:40 +00:00
										 |  |  | 			pbx_builtin_setvar_helper(chan, "INVALID_EXTEN", exten); | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 			exten[0] = 'i'; | 
					
						
							|  |  |  | 			exten[1] = '\0'; | 
					
						
							|  |  |  | 			recheck = 1; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 		if (!recheck | 
					
						
							|  |  |  | 			|| ast_exists_extension(chan, args.context, exten, 1, | 
					
						
							|  |  |  | 				S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 			ast_playtones_stop(chan); | 
					
						
							|  |  |  | 			/* We're authenticated and have a target extension */ | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 			if (!ast_strlen_zero(args.cid)) { | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 				ast_callerid_split(args.cid, ourcidname, sizeof(ourcidname), ourcidnum, sizeof(ourcidnum)); | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 				ast_set_callerid(chan, ourcidnum, ourcidname, ourcidnum); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!ast_strlen_zero(acctcode)) | 
					
						
							| 
									
										
										
										
											2006-02-01 23:05:28 +00:00
										 |  |  | 				ast_string_field_set(chan, accountcode, acctcode); | 
					
						
							| 
									
										
										
										
											2005-09-07 19:13:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-10 14:45:25 +00:00
										 |  |  | 			if (special_noanswer) cdr_flags.flags = 0; | 
					
						
							|  |  |  | 			ast_cdr_reset(chan->cdr, &cdr_flags); | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 			ast_explicit_goto(chan, args.context, exten, 1); | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 			return 0; | 
					
						
							| 
									
										
										
										
											2005-07-19 23:45:21 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 	/* Received invalid, but no "i" extension exists in the given context */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | reorder: | 
					
						
							| 
									
										
										
										
											2007-09-19 15:05:35 +00:00
										 |  |  | 	/* Play congestion for a bit */ | 
					
						
							|  |  |  | 	ast_indicate(chan, AST_CONTROL_CONGESTION); | 
					
						
							|  |  |  | 	ast_safe_sleep(chan, 10*1000); | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ast_playtones_stop(chan); | 
					
						
							| 
									
										
										
										
											2007-09-19 15:05:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  | 	return -1; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | static int unload_module(void) | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-07-16 13:35:20 +00:00
										 |  |  | 	return ast_unregister_application(app); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | static int load_module(void) | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-11-01 21:10:07 +00:00
										 |  |  | 	return ast_register_application_xml(app, disa_exec) ? | 
					
						
							| 
									
										
										
										
											2008-06-03 19:48:37 +00:00
										 |  |  | 		AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "DISA (Direct Inward System Access) Application"); |