Sat Aug 6 00:39:20 2011

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  * \author Mark Spencer <markster@digium.com>
00024  * 
00025  * \ingroup applications
00026  */
00027 
00028 #include "asterisk.h"
00029 
00030 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 211528 $")
00031 
00032 #include <stdlib.h>
00033 #include <stdio.h>
00034 #include <string.h>
00035 
00036 #include "asterisk/lock.h"
00037 #include "asterisk/file.h"
00038 #include "asterisk/utils.h"
00039 #include "asterisk/logger.h"
00040 #include "asterisk/options.h"
00041 #include "asterisk/channel.h"
00042 #include "asterisk/pbx.h"
00043 #include "asterisk/module.h"
00044 #include "asterisk/translate.h"
00045 #include "asterisk/image.h"
00046 #include "asterisk/callerid.h"
00047 #include "asterisk/app.h"
00048 #include "asterisk/config.h"
00049 
00050 #define PRIV_CONFIG "privacy.conf"
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 
00078 static int privacy_exec (struct ast_channel *chan, void *data)
00079 {
00080    int res=0;
00081    int retries;
00082    int maxretries = 3;
00083    int minlength = 10;
00084    int x = 0;
00085    const char *s;
00086    char phone[30];
00087    struct ast_module_user *u;
00088    struct ast_config *cfg = NULL;
00089    char *parse = NULL;
00090    int priority_jump = 0;
00091    AST_DECLARE_APP_ARGS(args,
00092       AST_APP_ARG(maxretries);
00093       AST_APP_ARG(minlength);
00094       AST_APP_ARG(options);
00095    );
00096 
00097    u = ast_module_user_add(chan);
00098 
00099    if (!ast_strlen_zero(chan->cid.cid_num)) {
00100       if (option_verbose > 2)
00101          ast_verbose (VERBOSE_PREFIX_3 "CallerID Present: Skipping\n");
00102    } else {
00103       /*Answer the channel if it is not already*/
00104       if (chan->_state != AST_STATE_UP) {
00105          res = ast_answer(chan);
00106          if (res) {
00107             ast_module_user_remove(u);
00108             return -1;
00109          }
00110       }
00111 
00112       if (!ast_strlen_zero(data)) {
00113          parse = ast_strdupa(data);
00114          
00115          AST_STANDARD_APP_ARGS(args, parse);
00116 
00117          if (args.maxretries) {
00118             if (sscanf(args.maxretries, "%30d", &x) == 1)
00119                maxretries = x;
00120             else
00121                ast_log(LOG_WARNING, "Invalid max retries argument\n");
00122          }
00123          if (args.minlength) {
00124             if (sscanf(args.minlength, "%30d", &x) == 1)
00125                minlength = x;
00126             else
00127                ast_log(LOG_WARNING, "Invalid min length argument\n");
00128          }
00129          if (args.options)
00130             if (strchr(args.options, 'j'))
00131                priority_jump = 1;
00132 
00133       }     
00134 
00135       if (!x)
00136       {
00137          /*Read in the config file*/
00138          cfg = ast_config_load(PRIV_CONFIG);
00139       
00140          if (cfg && (s = ast_variable_retrieve(cfg, "general", "maxretries"))) {
00141             if (sscanf(s, "%30d", &x) == 1) 
00142                maxretries = x;
00143             else
00144                ast_log(LOG_WARNING, "Invalid max retries argument\n");
00145             }
00146 
00147          if (cfg && (s = ast_variable_retrieve(cfg, "general", "minlength"))) {
00148             if (sscanf(s, "%30d", &x) == 1) 
00149                minlength = x;
00150             else
00151                ast_log(LOG_WARNING, "Invalid min length argument\n");
00152          }
00153       }  
00154       
00155       /*Play unidentified call*/
00156       res = ast_safe_sleep(chan, 1000);
00157       if (!res)
00158          res = ast_streamfile(chan, "privacy-unident", chan->language);
00159       if (!res)
00160          res = ast_waitstream(chan, "");
00161 
00162       /*Ask for 10 digit number, give 3 attempts*/
00163       for (retries = 0; retries < maxretries; retries++) {
00164          if (!res)
00165             res = ast_streamfile(chan, "privacy-prompt", chan->language);
00166          if (!res)
00167             res = ast_waitstream(chan, "");
00168 
00169          if (!res ) 
00170             res = ast_readstring(chan, phone, sizeof(phone) - 1, /* digit timeout ms */ 3200, /* first digit timeout */ 5000, "#");
00171 
00172          if (res < 0)
00173             break;
00174 
00175          /*Make sure we get at least digits*/
00176          if (strlen(phone) >= minlength ) 
00177             break;
00178          else {
00179             res = ast_streamfile(chan, "privacy-incorrect", chan->language);
00180             if (!res)
00181                res = ast_waitstream(chan, "");
00182          }
00183       }
00184       
00185       /*Got a number, play sounds and send them on their way*/
00186       if ((retries < maxretries) && res >= 0 ) {
00187          res = ast_streamfile(chan, "privacy-thankyou", chan->language);
00188          if (!res)
00189             res = ast_waitstream(chan, "");
00190 
00191          ast_set_callerid (chan, phone, "Privacy Manager", NULL); 
00192 
00193          /* Clear the unavailable presence bit so if it came in on PRI
00194           * the caller id will now be passed out to other channels
00195           */
00196          chan->cid.cid_pres &= (AST_PRES_UNAVAILABLE ^ 0xFF);
00197 
00198          if (option_verbose > 2) {
00199             ast_verbose (VERBOSE_PREFIX_3 "Changed Caller*ID to %s, callerpres to %d\n",phone,chan->cid.cid_pres);
00200          }
00201          pbx_builtin_setvar_helper(chan, "PRIVACYMGRSTATUS", "SUCCESS");
00202       } else {
00203          if (priority_jump || ast_opt_priority_jumping)  
00204             ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
00205          pbx_builtin_setvar_helper(chan, "PRIVACYMGRSTATUS", "FAILED");
00206       }
00207       if (cfg) 
00208          ast_config_destroy(cfg);
00209    }
00210 
00211    ast_module_user_remove(u);
00212 
00213    return 0;
00214 }
00215 
00216 static int unload_module(void)
00217 {
00218    int res;
00219 
00220    res = ast_unregister_application (app);
00221 
00222    ast_module_user_hangup_all();
00223 
00224    return res;
00225 }
00226 
00227 static int load_module(void)
00228 {
00229    return ast_register_application (app, privacy_exec, synopsis, descrip);
00230 }
00231 
00232 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Require phone number to be entered, if no CallerID sent");

Generated on Sat Aug 6 00:39:20 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7