2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
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.
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.
21 * \brief Block all calls without Caller*ID, require phone # to be entered
23 * \author Mark Spencer <markster@digium.com>
25 * \ingroup applications
30 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
36 #include "asterisk/lock.h"
37 #include "asterisk/file.h"
38 #include "asterisk/utils.h"
39 #include "asterisk/logger.h"
40 #include "asterisk/options.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/pbx.h"
43 #include "asterisk/module.h"
44 #include "asterisk/translate.h"
45 #include "asterisk/image.h"
46 #include "asterisk/callerid.h"
47 #include "asterisk/app.h"
48 #include "asterisk/config.h"
50 #define PRIV_CONFIG "privacy.conf"
52 static char *app
= "PrivacyManager";
54 static char *synopsis
= "Require phone number to be entered, if no CallerID sent";
56 static char *descrip
=
57 " PrivacyManager([maxretries[|minlength[|options]]]): If no Caller*ID \n"
58 "is sent, PrivacyManager answers the channel and asks the caller to\n"
59 "enter their phone number. The caller is given 3 attempts to do so.\n"
60 "The application does nothing if Caller*ID was received on the channel.\n"
61 " Configuration file privacy.conf contains two variables:\n"
62 " maxretries default 3 -maximum number of attempts the caller is allowed \n"
63 " to input a callerid.\n"
64 " minlength default 10 -minimum allowable digits in the input callerid number.\n"
65 "If you don't want to use the config file and have an i/o operation with\n"
66 "every call, you can also specify maxretries and minlength as application\n"
67 "parameters. Doing so supercedes any values set in privacy.conf.\n"
68 "The option string may contain the following character: \n"
69 " 'j' -- jump to n+101 priority after <maxretries> failed attempts to collect\n"
70 " the minlength number of digits.\n"
71 "The application sets the following channel variable upon completion: \n"
72 "PRIVACYMGRSTATUS The status of the privacy manager's attempt to collect \n"
73 " a phone number from the user. A text string that is either:\n"
74 " SUCCESS | FAILED \n"
78 static int privacy_exec (struct ast_channel
*chan
, void *data
)
87 struct ast_module_user
*u
;
88 struct ast_config
*cfg
= NULL
;
90 int priority_jump
= 0;
91 AST_DECLARE_APP_ARGS(args
,
92 AST_APP_ARG(maxretries
);
93 AST_APP_ARG(minlength
);
97 u
= ast_module_user_add(chan
);
99 if (!ast_strlen_zero(chan
->cid
.cid_num
)) {
100 if (option_verbose
> 2)
101 ast_verbose (VERBOSE_PREFIX_3
"CallerID Present: Skipping\n");
103 /*Answer the channel if it is not already*/
104 if (chan
->_state
!= AST_STATE_UP
) {
105 res
= ast_answer(chan
);
107 ast_module_user_remove(u
);
112 if (!ast_strlen_zero(data
)) {
113 parse
= ast_strdupa(data
);
115 AST_STANDARD_APP_ARGS(args
, parse
);
117 if (args
.maxretries
) {
118 if (sscanf(args
.maxretries
, "%d", &x
) == 1)
121 ast_log(LOG_WARNING
, "Invalid max retries argument\n");
123 if (args
.minlength
) {
124 if (sscanf(args
.minlength
, "%d", &x
) == 1)
127 ast_log(LOG_WARNING
, "Invalid min length argument\n");
130 if (strchr(args
.options
, 'j'))
137 /*Read in the config file*/
138 cfg
= ast_config_load(PRIV_CONFIG
);
140 if (cfg
&& (s
= ast_variable_retrieve(cfg
, "general", "maxretries"))) {
141 if (sscanf(s
, "%d", &x
) == 1)
144 ast_log(LOG_WARNING
, "Invalid max retries argument\n");
147 if (cfg
&& (s
= ast_variable_retrieve(cfg
, "general", "minlength"))) {
148 if (sscanf(s
, "%d", &x
) == 1)
151 ast_log(LOG_WARNING
, "Invalid min length argument\n");
155 /*Play unidentified call*/
156 res
= ast_safe_sleep(chan
, 1000);
158 res
= ast_streamfile(chan
, "privacy-unident", chan
->language
);
160 res
= ast_waitstream(chan
, "");
162 /*Ask for 10 digit number, give 3 attempts*/
163 for (retries
= 0; retries
< maxretries
; retries
++) {
165 res
= ast_streamfile(chan
, "privacy-prompt", chan
->language
);
167 res
= ast_waitstream(chan
, "");
170 res
= ast_readstring(chan
, phone
, sizeof(phone
) - 1, /* digit timeout ms */ 3200, /* first digit timeout */ 5000, "#");
175 /*Make sure we get at least digits*/
176 if (strlen(phone
) >= minlength
)
179 res
= ast_streamfile(chan
, "privacy-incorrect", chan
->language
);
181 res
= ast_waitstream(chan
, "");
185 /*Got a number, play sounds and send them on their way*/
186 if ((retries
< maxretries
) && res
>= 0 ) {
187 res
= ast_streamfile(chan
, "privacy-thankyou", chan
->language
);
189 res
= ast_waitstream(chan
, "");
191 ast_set_callerid (chan
, phone
, "Privacy Manager", NULL
);
193 /* Clear the unavailable presence bit so if it came in on PRI
194 * the caller id will now be passed out to other channels
196 chan
->cid
.cid_pres
&= (AST_PRES_UNAVAILABLE
^ 0xFF);
198 if (option_verbose
> 2) {
199 ast_verbose (VERBOSE_PREFIX_3
"Changed Caller*ID to %s, callerpres to %d\n",phone
,chan
->cid
.cid_pres
);
201 pbx_builtin_setvar_helper(chan
, "PRIVACYMGRSTATUS", "SUCCESS");
203 if (priority_jump
|| ast_opt_priority_jumping
)
204 ast_goto_if_exists(chan
, chan
->context
, chan
->exten
, chan
->priority
+ 101);
205 pbx_builtin_setvar_helper(chan
, "PRIVACYMGRSTATUS", "FAILED");
208 ast_config_destroy(cfg
);
211 ast_module_user_remove(u
);
216 static int unload_module(void)
220 res
= ast_unregister_application (app
);
222 ast_module_user_hangup_all();
227 static int load_module(void)
229 return ast_register_application (app
, privacy_exec
, synopsis
, descrip
);
232 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "Require phone number to be entered, if no CallerID sent");