2972ee73aa7a8daf4ba8a3b4dd0193a34df6574c
[asterisk/asterisk.git] / apps / app_privacy.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Block all calls without Caller*ID, require phone # to be entered
5  * 
6  * Copyright (C) 1999-2004, Digium, Inc.
7  *
8  * Mark Spencer <markster@digium.com>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #include <asterisk/lock.h>
15 #include <asterisk/file.h>
16 #include <asterisk/logger.h>
17 #include <asterisk/options.h>
18 #include <asterisk/channel.h>
19 #include <asterisk/pbx.h>
20 #include <asterisk/module.h>
21 #include <asterisk/translate.h>
22 #include <asterisk/image.h>
23 #include <asterisk/callerid.h>
24 #include <asterisk/app.h>
25 #include <asterisk/config.h>
26 #include <string.h>
27 #include <stdlib.h>
28
29 #define PRIV_CONFIG "privacy.conf"
30
31 static char *tdesc = "Require phone number to be entered, if no CallerID sent";
32
33 static char *app = "PrivacyManager";
34
35 static char *synopsis = "Require phone number to be entered, if no CallerID sent";
36
37 static char *descrip =
38   "  PrivacyManager: If no Caller*ID is sent, PrivacyManager answers the\n"
39   "channel and asks the caller to enter their 10 digit phone number.\n"
40   "The caller is given 3 attempts.  If after 3 attempts, they do not enter\n"
41   "their 10 digit phone number, and if there exists a priority n + 101,\n"
42   "where 'n' is the priority of the current instance, then  the\n"
43   "channel  will  be  setup  to continue at that priority level.\n"
44   "Otherwise, it returns 0.  Does nothing if Caller*ID was received on the\n"
45   "channel.\n";
46
47 STANDARD_LOCAL_USER;
48
49 LOCAL_USER_DECL;
50
51 static int
52 privacy_exec (struct ast_channel *chan, void *data)
53 {
54         int res=0;
55         int retries;
56         int maxretries = 3;
57         int x;
58         char *s;
59         char phone[10];
60         char new_cid[144];
61         struct localuser *u;
62         struct ast_config *cfg;
63
64         LOCAL_USER_ADD (u);
65         if (chan->cid.cid_num)
66         {
67                 if (option_verbose > 2)
68                         ast_verbose (VERBOSE_PREFIX_3 "CallerID Present: Skipping\n");
69         }
70         else
71         {
72                 /*Answer the channel if it is not already*/
73                 if (chan->_state != AST_STATE_UP) {
74                         res = ast_answer(chan);
75                         if (res) {
76                                 LOCAL_USER_REMOVE(u);
77                                 return -1;
78                         }
79                 }
80                 /*Read in the config file*/
81                 cfg = ast_load(PRIV_CONFIG);
82                 
83                 
84                 /*Play unidentified call*/
85                 res = ast_safe_sleep(chan, 1000);
86                 if (!res)
87                         res = ast_streamfile(chan, "privacy-unident", chan->language);
88                 if (!res)
89                         res = ast_waitstream(chan, "");
90
91         if (cfg && (s = ast_variable_retrieve(cfg, "general", "maxretries"))) {
92                 if (sscanf(s, "%d", &x) == 1) {
93                         maxretries = x;
94                 } else {
95                         ast_log(LOG_WARNING, "Invalid max retries argument\n");
96                 }
97         }
98                         
99                 /*Ask for 10 digit number, give 3 attempts*/
100                 for (retries = 0; retries < maxretries; retries++) {
101                         if (!res)
102                                 res = ast_app_getdata(chan, "privacy-prompt", phone, sizeof(phone), 0);
103                         if (res < 0)
104                                 break;
105
106                         /*Make sure we get 10 digits*/
107                         if (strlen(phone) == 10) 
108                                 break;
109                         else {
110                                 res = ast_streamfile(chan, "privacy-incorrect", chan->language);
111                                 if (!res)
112                                         res = ast_waitstream(chan, "");
113                         }
114                 }
115                 
116                 /*Got a number, play sounds and send them on their way*/
117                 if ((retries < maxretries) && !res) {
118                         res = ast_streamfile(chan, "privacy-thankyou", chan->language);
119                         if (!res)
120                                 res = ast_waitstream(chan, "");
121                         ast_set_callerid (chan, phone, "Privacy Manager", NULL);
122                         if (option_verbose > 2)
123                                 ast_verbose (VERBOSE_PREFIX_3 "Changed Caller*ID to %s\n",new_cid);
124                 } else {
125                         /*Send the call to n+101 priority, where n is the current priority*/
126                         if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->cid.cid_num))
127                                 chan->priority+=100;
128                 }
129                 if (cfg) 
130                         ast_destroy(cfg);
131         }
132
133   LOCAL_USER_REMOVE (u);
134   return 0;
135 }
136
137 int
138 unload_module (void)
139 {
140   STANDARD_HANGUP_LOCALUSERS;
141   return ast_unregister_application (app);
142 }
143
144 int
145 load_module (void)
146 {
147   return ast_register_application (app, privacy_exec, synopsis,
148                                    descrip);
149 }
150
151 char *
152 description (void)
153 {
154   return tdesc;
155 }
156
157 int
158 usecount (void)
159 {
160   int res;
161   STANDARD_USECOUNT (res);
162   return res;
163 }
164
165 char *
166 key ()
167 {
168   return ASTERISK_GPL_KEY;
169 }