Fri Sep 29 11:12:23 2006

Asterisk developer's documentation


app_privacy.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Block all calls without Caller*ID, require phone # to be entered
00022  * 
00023  * \ingroup applications
00024  */
00025 
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <string.h>
00029 
00030 #include "asterisk.h"
00031 
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 24097 $")
00033 
00034 #include "asterisk/lock.h"
00035 #include "asterisk/file.h"
00036 #include "asterisk/utils.h"
00037 #include "asterisk/logger.h"
00038 #include "asterisk/options.h"
00039 #include "asterisk/channel.h"
00040 #include "asterisk/pbx.h"
00041 #include "asterisk/module.h"
00042 #include "asterisk/translate.h"
00043 #include "asterisk/image.h"
00044 #include "asterisk/callerid.h"
00045 #include "asterisk/app.h"
00046 #include "asterisk/config.h"
00047 
00048 #define PRIV_CONFIG "privacy.conf"
00049 
00050 static char *tdesc = "Require phone number to be entered, if no CallerID sent";
00051 
00052 static char *app = "PrivacyManager";
00053 
00054 static char *synopsis = "Require phone number to be entered, if no CallerID sent";
00055 
00056 static char *descrip =
00057   "  PrivacyManager([maxretries[|minlength[|options]]]): If no Caller*ID \n"
00058   "is sent, PrivacyManager answers the channel and asks the caller to\n"
00059   "enter their phone number. The caller is given 3 attempts to do so.\n"
00060   "The application does nothing if Caller*ID was received on the channel.\n"
00061   "  Configuration file privacy.conf contains two variables:\n"
00062   "   maxretries  default 3  -maximum number of attempts the caller is allowed \n"
00063   "               to input a callerid.\n"
00064   "   minlength   default 10 -minimum allowable digits in the input callerid number.\n"
00065   "If you don't want to use the config file and have an i/o operation with\n"
00066   "every call, you can also specify maxretries and minlength as application\n"
00067   "parameters. Doing so supercedes any values set in privacy.conf.\n"
00068   "The option string may contain the following character: \n"
00069   "  'j' -- jump to n+101 priority after <maxretries> failed attempts to collect\n"
00070   "         the minlength number of digits.\n"
00071   "The application sets the following channel variable upon completion: \n"
00072   "PRIVACYMGRSTATUS  The status of the privacy manager's attempt to collect \n"
00073   "                  a phone number from the user. A text string that is either:\n" 
00074   "          SUCCESS | FAILED \n"
00075 ;
00076 
00077 STANDARD_LOCAL_USER;
00078 
00079 LOCAL_USER_DECL;
00080 
00081 
00082 
00083 static int privacy_exec (struct ast_channel *chan, void *data)
00084 {
00085    int res=0;
00086    int retries;
00087    int maxretries = 3;
00088    int minlength = 10;
00089    int x = 0;
00090    char *s;
00091    char phone[30];
00092    struct localuser *u;
00093    struct ast_config *cfg = NULL;
00094    char *parse = NULL;
00095    int priority_jump = 0;
00096    AST_DECLARE_APP_ARGS(args,
00097       AST_APP_ARG(maxretries);
00098       AST_APP_ARG(minlength);
00099       AST_APP_ARG(options);
00100    );
00101 
00102    LOCAL_USER_ADD (u);
00103    if (!ast_strlen_zero(chan->cid.cid_num)) {
00104       if (option_verbose > 2)
00105          ast_verbose (VERBOSE_PREFIX_3 "CallerID Present: Skipping\n");
00106    } else {
00107       /*Answer the channel if it is not already*/
00108       if (chan->_state != AST_STATE_UP) {
00109          res = ast_answer(chan);
00110          if (res) {
00111             LOCAL_USER_REMOVE(u);
00112             return -1;
00113          }
00114       }
00115 
00116       if (!ast_strlen_zero((char *)data))
00117       {
00118          parse = ast_strdupa(data);
00119          if (!parse) {
00120             ast_log(LOG_ERROR, "Out of memory!\n");
00121             LOCAL_USER_REMOVE(u);
00122             return -1;
00123          }
00124          
00125          AST_STANDARD_APP_ARGS(args, parse);
00126 
00127          if (args.maxretries) {
00128             if (sscanf(args.maxretries, "%d", &x) == 1)
00129                maxretries = x;
00130             else
00131                ast_log(LOG_WARNING, "Invalid max retries argument\n");
00132          }
00133          if (args.minlength) {
00134             if (sscanf(args.minlength, "%d", &x) == 1)
00135                minlength = x;
00136             else
00137                ast_log(LOG_WARNING, "Invalid min length argument\n");
00138          }
00139          if (args.options)
00140             if (strchr(args.options, 'j'))
00141                priority_jump = 1;
00142 
00143       }     
00144 
00145       if (!x)
00146       {
00147          /*Read in the config file*/
00148          cfg = ast_config_load(PRIV_CONFIG);
00149       
00150          if (cfg && (s = ast_variable_retrieve(cfg, "general", "maxretries"))) {
00151             if (sscanf(s, "%d", &x) == 1) 
00152                maxretries = x;
00153             else
00154                ast_log(LOG_WARNING, "Invalid max retries argument\n");
00155             }
00156 
00157          if (cfg && (s = ast_variable_retrieve(cfg, "general", "minlength"))) {
00158             if (sscanf(s, "%d", &x) == 1) 
00159                minlength = x;
00160             else
00161                ast_log(LOG_WARNING, "Invalid min length argument\n");
00162          }
00163       }  
00164       
00165       /*Play unidentified call*/
00166       res = ast_safe_sleep(chan, 1000);
00167       if (!res)
00168          res = ast_streamfile(chan, "privacy-unident", chan->language);
00169       if (!res)
00170          res = ast_waitstream(chan, "");
00171 
00172       /*Ask for 10 digit number, give 3 attempts*/
00173       for (retries = 0; retries < maxretries; retries++) {
00174          if (!res)
00175             res = ast_streamfile(chan, "privacy-prompt", chan->language);
00176          if (!res)
00177             res = ast_waitstream(chan, "");
00178 
00179          if (!res ) 
00180             res = ast_readstring(chan, phone, sizeof(phone) - 1, /* digit timeout ms */ 3200, /* first digit timeout */ 5000, "#");
00181 
00182          if (res < 0)
00183             break;
00184 
00185          /*Make sure we get at least digits*/
00186          if (strlen(phone) >= minlength ) 
00187             break;
00188          else {
00189             res = ast_streamfile(chan, "privacy-incorrect", chan->language);
00190             if (!res)
00191                res = ast_waitstream(chan, "");
00192          }
00193       }
00194       
00195       /*Got a number, play sounds and send them on their way*/
00196       if ((retries < maxretries) && res >= 0 ) {
00197          res = ast_streamfile(chan, "privacy-thankyou", chan->language);
00198          if (!res)
00199             res = ast_waitstream(chan, "");
00200 
00201          ast_set_callerid (chan, phone, "Privacy Manager", NULL); 
00202 
00203          /* Clear the unavailable presence bit so if it came in on PRI
00204           * the caller id will now be passed out to other channels
00205           */
00206          chan->cid.cid_pres &= (AST_PRES_UNAVAILABLE ^ 0xFF);
00207 
00208          if (option_verbose > 2) {
00209             ast_verbose (VERBOSE_PREFIX_3 "Changed Caller*ID to %s, callerpres to %d\n",phone,chan->cid.cid_pres);
00210          }
00211          pbx_builtin_setvar_helper(chan, "PRIVACYMGRSTATUS", "SUCCESS");
00212       } else {
00213          if (priority_jump || option_priority_jumping)   
00214             ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
00215          pbx_builtin_setvar_helper(chan, "PRIVACYMGRSTATUS", "FAILED");
00216       }
00217       if (cfg) 
00218          ast_config_destroy(cfg);
00219    }
00220 
00221   LOCAL_USER_REMOVE (u);
00222   return 0;
00223 }
00224 
00225 int
00226 unload_module (void)
00227 {
00228    int res;
00229 
00230    res = ast_unregister_application (app);
00231 
00232    STANDARD_HANGUP_LOCALUSERS;
00233 
00234    return res;
00235 }
00236 
00237 int
00238 load_module (void)
00239 {
00240   return ast_register_application (app, privacy_exec, synopsis,
00241                descrip);
00242 }
00243 
00244 char *
00245 description (void)
00246 {
00247   return tdesc;
00248 }
00249 
00250 int
00251 usecount (void)
00252 {
00253   int res;
00254   STANDARD_USECOUNT (res);
00255   return res;
00256 }
00257 
00258 char *
00259 key ()
00260 {
00261   return ASTERISK_GPL_KEY;
00262 }

Generated on Fri Sep 29 11:12:23 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7