app_privacy.c 6.3 KB

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