app_privacy.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2005, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. *
  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.
  13. *
  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.
  17. */
  18. /*! \file
  19. *
  20. * \brief Block all calls without Caller*ID, require phone # to be entered
  21. *
  22. * \author Mark Spencer <markster@digium.com>
  23. *
  24. * \ingroup applications
  25. */
  26. /*** MODULEINFO
  27. <support_level>core</support_level>
  28. ***/
  29. #include "asterisk.h"
  30. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  31. #include "asterisk/lock.h"
  32. #include "asterisk/file.h"
  33. #include "asterisk/utils.h"
  34. #include "asterisk/channel.h"
  35. #include "asterisk/pbx.h"
  36. #include "asterisk/module.h"
  37. #include "asterisk/translate.h"
  38. #include "asterisk/callerid.h"
  39. #include "asterisk/app.h"
  40. #include "asterisk/config.h"
  41. /*** DOCUMENTATION
  42. <application name="PrivacyManager" language="en_US">
  43. <synopsis>
  44. Require phone number to be entered, if no CallerID sent
  45. </synopsis>
  46. <syntax>
  47. <parameter name="maxretries">
  48. <para>Total tries caller is allowed to input a callerid. Defaults to <literal>3</literal>.</para>
  49. </parameter>
  50. <parameter name="minlength">
  51. <para>Minimum allowable digits in the input callerid number. Defaults to <literal>10</literal>.</para>
  52. </parameter>
  53. <parameter name="options">
  54. <para>Position reserved for options.</para>
  55. </parameter>
  56. <parameter name="context">
  57. <para>Context to check the given callerid against patterns.</para>
  58. </parameter>
  59. </syntax>
  60. <description>
  61. <para>If no Caller*ID is sent, PrivacyManager answers the channel and asks
  62. the caller to enter their phone number. The caller is given
  63. <replaceable>maxretries</replaceable> attempts to do so. The application does
  64. <emphasis>nothing</emphasis> if Caller*ID was received on the channel.</para>
  65. <para>The application sets the following channel variable upon completion:</para>
  66. <variablelist>
  67. <variable name="PRIVACYMGRSTATUS">
  68. <para>The status of the privacy manager's attempt to collect a phone number from the user.</para>
  69. <value name="SUCCESS"/>
  70. <value name="FAILED"/>
  71. </variable>
  72. </variablelist>
  73. </description>
  74. <see-also>
  75. <ref type="application">Zapateller</ref>
  76. </see-also>
  77. </application>
  78. ***/
  79. static char *app = "PrivacyManager";
  80. static int privacy_exec(struct ast_channel *chan, const char *data)
  81. {
  82. int res=0;
  83. int retries;
  84. int maxretries = 3;
  85. int minlength = 10;
  86. int x = 0;
  87. char phone[30];
  88. char *parse = NULL;
  89. AST_DECLARE_APP_ARGS(args,
  90. AST_APP_ARG(maxretries);
  91. AST_APP_ARG(minlength);
  92. AST_APP_ARG(options);
  93. AST_APP_ARG(checkcontext);
  94. );
  95. if (ast_channel_caller(chan)->id.number.valid
  96. && !ast_strlen_zero(ast_channel_caller(chan)->id.number.str)) {
  97. ast_verb(3, "CallerID number present: Skipping\n");
  98. } else {
  99. /*Answer the channel if it is not already*/
  100. if (ast_channel_state(chan) != AST_STATE_UP) {
  101. if ((res = ast_answer(chan))) {
  102. return -1;
  103. }
  104. }
  105. parse = ast_strdupa(data);
  106. AST_STANDARD_APP_ARGS(args, parse);
  107. if (!ast_strlen_zero(args.maxretries)) {
  108. if (sscanf(args.maxretries, "%30d", &x) == 1 && x > 0) {
  109. maxretries = x;
  110. } else {
  111. ast_log(LOG_WARNING, "Invalid max retries argument: '%s'\n", args.maxretries);
  112. }
  113. }
  114. if (!ast_strlen_zero(args.minlength)) {
  115. if (sscanf(args.minlength, "%30d", &x) == 1 && x > 0) {
  116. minlength = x;
  117. } else {
  118. ast_log(LOG_WARNING, "Invalid min length argument: '%s'\n", args.minlength);
  119. }
  120. }
  121. /* Play unidentified call */
  122. res = ast_safe_sleep(chan, 1000);
  123. if (!res) {
  124. res = ast_streamfile(chan, "privacy-unident", ast_channel_language(chan));
  125. }
  126. if (!res) {
  127. res = ast_waitstream(chan, "");
  128. }
  129. /* Ask for 10 digit number, give 3 attempts */
  130. for (retries = 0; retries < maxretries; retries++) {
  131. if (!res) {
  132. res = ast_streamfile(chan, "privacy-prompt", ast_channel_language(chan));
  133. }
  134. if (!res) {
  135. res = ast_waitstream(chan, "");
  136. }
  137. if (!res) {
  138. res = ast_readstring(chan, phone, sizeof(phone) - 1, /* digit timeout ms */ 3200, /* first digit timeout */ 5000, "#");
  139. }
  140. if (res < 0) {
  141. break;
  142. }
  143. /* Make sure we get at least digits */
  144. if (strlen(phone) >= minlength ) {
  145. /* if we have a checkcontext argument, do pattern matching */
  146. if (!ast_strlen_zero(args.checkcontext)) {
  147. if (!ast_exists_extension(NULL, args.checkcontext, phone, 1, NULL)) {
  148. res = ast_streamfile(chan, "privacy-incorrect", ast_channel_language(chan));
  149. if (!res) {
  150. res = ast_waitstream(chan, "");
  151. }
  152. } else {
  153. break;
  154. }
  155. } else {
  156. break;
  157. }
  158. } else {
  159. res = ast_streamfile(chan, "privacy-incorrect", ast_channel_language(chan));
  160. if (!res) {
  161. res = ast_waitstream(chan, "");
  162. }
  163. }
  164. }
  165. /* Got a number, play sounds and send them on their way */
  166. if ((retries < maxretries) && res >= 0) {
  167. res = ast_streamfile(chan, "privacy-thankyou", ast_channel_language(chan));
  168. if (!res) {
  169. res = ast_waitstream(chan, "");
  170. }
  171. /*
  172. * This is a caller entered number that is going to be used locally.
  173. * Therefore, the given number presentation is allowed and should
  174. * be passed out to other channels. This is the point of the
  175. * privacy application.
  176. */
  177. ast_channel_caller(chan)->id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
  178. ast_channel_caller(chan)->id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
  179. ast_channel_caller(chan)->id.number.plan = 0;/* Unknown */
  180. ast_set_callerid(chan, phone, "Privacy Manager", NULL);
  181. ast_verb(3, "Changed Caller*ID number to '%s'\n", phone);
  182. pbx_builtin_setvar_helper(chan, "PRIVACYMGRSTATUS", "SUCCESS");
  183. } else {
  184. pbx_builtin_setvar_helper(chan, "PRIVACYMGRSTATUS", "FAILED");
  185. }
  186. }
  187. return 0;
  188. }
  189. static int unload_module(void)
  190. {
  191. return ast_unregister_application(app);
  192. }
  193. static int load_module(void)
  194. {
  195. return ast_register_application_xml(app, privacy_exec);
  196. }
  197. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Require phone number to be entered, if no CallerID sent");