home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / voice.zip / V_MBX4.CMD < prev    next >
OS/2 REXX Batch file  |  1996-09-09  |  31KB  |  874 lines

  1. /* V_MBX4.CMD - Voice/Fax Answer Script for FaxWorks/PMfax (REXX) */
  2. /* 
  3.                   Keller Group Inc.  September 9, 1996
  4.    You may freely use or modify this script for use with licensed
  5.         products which are developed by Keller Group Inc.
  6.       For new scripts or to share your scripts with others,
  7.                  see http://www.kellergroup.com
  8. */
  9. /*******************************************************************
  10. V_MBX4.CMD - 4-line Version of V_MBX.CMD voice/fax mailbox system
  11.  
  12. For use with any of the following Keller software configurations:
  13.   Stand-alone (multiline)
  14.   LAN Shared Mode (multiline)
  15.   LAN Private Mode (with fax server as router & retrieval from server log)
  16.  
  17. Notes:
  18.  
  19. This is a slightly-modified version of the basic V_MBX.CMD script.
  20. It shows how the script can be modified for use with a 4-line system
  21. in which one line is primarily for fax, one line is primarily
  22. answered for voice calls, a two lines are roll-over or auxiliary
  23. voice/fax lines.  Note the use of the LID variable in the script as
  24. discussed in the section called "TO USE WITH MULTILINE VERSIONS".
  25.  
  26. As written, line 1 (FAX) goes immediately to fax receiving, line 3
  27. (MAIN VOICE) plays the standard OGM outgoing message, and lines 2 and
  28. 4 (EXTRA VOICE/FAX) will play the special OGM2 message if the OGM2
  29. script variable is set, otherwise the standard OGM outgoing message
  30. will be used.  Lines 2, 3 and 4 can be used for all of the features
  31. of the V_MBX script as noted immediately below.
  32.  
  33. Features:
  34.  
  35.   Callers can:
  36.      send a fax,
  37.      leave a voice message,
  38.      listen to an announcement, or
  39.      enter the special password to enter remote retrieval mode
  40.  
  41.   In the password-protected remote retrieval mode, you can do:
  42.      greeting modification - remotely update your greeting message
  43.      voice retrieval - get voice messages by phone
  44.      fax retrieval - get fax messages, or send them to a fax number
  45.      log retrieval - get a fax of your log (or the last part of it)
  46.      "fax on demand" from log - retrieve items from log using index
  47.  
  48.   You can also set configuration values to provide:
  49.      forwarding by fax - forward all received faxes to a fax number
  50.      forwarding by voice - forward all received voice messages to phone #
  51.      forwarding by email - forward received fax and/or voice via email
  52.        and also...
  53.      paging by beeper - notify you by pager when voice or fax is received
  54.      paging by voice - notify you by calling and playing a voice message
  55.      paging by fax - notify you by sending a fax to a designated fax # 
  56.  
  57. See also:
  58.     V_MBXLAN.CMD - Advanced voice/fax mailbox system (LAN multiuser)
  59.  
  60. DESCRIPTION:
  61. -----------
  62. This script plays your outgoing message (OGM).  The caller can press
  63. the # or * key to skip the OGM and immediately record their message,
  64. otherwise the script will provide a beep and record the caller's
  65. message if no special action is taken.
  66.  
  67. If the call is from a fax device and your fax hardware detects the
  68. caller's fax (CNG) tones, the script automatically receives the fax.
  69.  
  70. If the caller enters '2' during playing of the OGM, the script plays
  71. the "announcement" and then returns to the OGM again so that the
  72. caller can leave a message on the same call.
  73.  
  74. If the caller enters '9' during or immediately after the playing of
  75. the OGM and then enters the user-configurable access code followed by
  76. the # key, the script enters its "remote retrieval" mode so the
  77. caller can hear received voice messages, have received faxes sent to
  78. them via fax, and other features.  When in this mode, the keys on the
  79. telephone do the following:
  80.  
  81.    1 - HELP       - Play help message which describes these commands
  82.    3 - GREETING   - Enter new outgoing message (change greeting)
  83.  
  84.    4 - PREV MSG   - Play previous voice message
  85.    5 - REPLAY MSG - Play current voice message (again)
  86.    6 - NEXT MSG   - Play next voice message
  87.  
  88.    7 - GET FAXES  - Retrieve new fax messages by fax
  89.    8 - GET LOG    - Retrieve fax log by fax
  90.    9 - FOD LOG    - Retrieve voice/fax msgs from log ("fax-on-demand")
  91.  
  92. Other features are controlled by setting "script variables" as
  93. described below.  These values can cause the script to do automatic
  94. forwarding by fax, voice or email and automatic paging via beeper,
  95. voice or fax.
  96.  
  97. USAGE INSTRUCTIONS:
  98. ------------------
  99. You must be using the program with supported voice/fax hardware to
  100. use this script.  Consult the README.DOC file for tested voice/fax
  101. hardware and recommended configuration settings for your hardware.
  102. Before using this script, first test your system with our built-in
  103. voice answering machine feature by enabling "Voice" and setting the
  104. "Answer script" to * (an asterisk character) on the Voice page of the
  105. Settings notebook.  If you are using supported voice/fax hardware
  106. with the proper configuration settings, you can then use
  107. "Fax/Receive/All calls" mode to answer calls, play the outgoing
  108. message (OGM), and record a voice message (or receive a fax).
  109.  
  110. Then, to change to this advanced script, specify the full pathname of
  111. this file in the "Answer script" field on the Voice page of the
  112. settings notebook.
  113.  
  114. NOTE: The script expects to find the LIB_FOD.CMD file and its Wave
  115. audio files in the fax program (EXE) directory.  The script also uses
  116. Wave files from the c:\mmos2\sounds directory for special effects.
  117.  
  118. SCRIPT VARIABLES:
  119. ----------------
  120. The following script variable is used by this script.  Script
  121. variables are set on the Voice page of the Settings Notebook.
  122.  
  123. General:
  124.  
  125.     OGM - Pathname of the "outgoing message" file which is played
  126.     to the caller.  By default, the program sets OGM to be the
  127.     file OGM.WAV in the program directory.
  128.     Example: OGM = C:\FAX\OGM.WAV
  129.  
  130.     OGM2 - (optional) Pathname of the "outgoing message" file which
  131.     is played to the caller on the "secondary voice" lines.  By
  132.     default, the program sets OGM2 to be the same as OGM.
  133.     Example: OGM2 = C:\FAX\OGM2.WAV
  134.  
  135.     CODE - Access code for retrieving messages or changing
  136.     settings.  By default, the program sets CODE to be 42.  You
  137.     can change this to be any number of up to 5 digits in length.
  138.     Example: CODE = 42
  139.  
  140.     CALLER - (optional, default "Person") - Name of the person
  141.     who will be using the access code to retrieve messages/faxes
  142.     by phone.  This is used for addressing faxes when the
  143.     caller uses the access code for remote retrieval.
  144.     Example: CALLER = Jim Smith
  145.  
  146.     LOGMAXLINE - (optional, default 56) - Maximum number of log
  147.     entries, from the end of the log, to be sent to the caller
  148.     when they retrieve the log by fax.  If set to 0, then
  149.     the entire log is sent.
  150.     Example: LOGMAXLINE = 120
  151.  
  152.     EMAILCMD - (optional) - The command line to be executed to send a
  153.     fax, voice or text file via email.  We append the file pathname
  154.     to the end of this command line and execute it to tell your email
  155.     software to send the file.  If the EMAILPARAM script variable is
  156.     set, then it is appended to the command line following the file
  157.     pathname (which can be used to add additional parameters).
  158.     Email support requires the use of an email package which provides
  159.     a command line interface and is configured to automatically
  160.     send the email which is submitted to it.
  161.     Example: To demo by inserting into our log rather than emailing:
  162.            EMAILCMD = c:\fax\fxrcv -rcvd
  163.     Example for Post Road Mailer version 2.0 using its PRMFAX.EXE:
  164.            EMAILCMD = c:\postroad\prmfax
  165.            EMAILPARAM = "yourid@ibm.net" "Forwarded fax/voice"
  166.  
  167. Forwarding:
  168.  
  169.     FWDFAX - (optional) - A fax number.  If specified, received
  170.     faxes are automatically forwarded to the specified fax
  171.     number.  All faxes are also kept in the fax log.
  172.     Example: FWDFAX = 1 612 555-5555
  173.  
  174.     FWDVOICE - (optional) - A voice number.  If specified,
  175.     received voice messages are automatically forwarded to the
  176.     specified number.  Add comma characters to the end of the
  177.     number if additional pauses are desired before the message is
  178.     played.  This can be used to pass a voice message along to a
  179.     second answering machine or a cellular phone, but delivery is
  180.     not guaranteed since dialing delays, busy signals and other
  181.     events may interfere.
  182.     Example: FWDVOICE = 555-5555
  183.  
  184.     FWDEMAIL - (optional) - Set to FAX, VOICE or ALL.  If
  185.     specified (and if the EMAILCMD script variable is also
  186.     specified), received faxes, voice messages or both will be
  187.     forwarded by emailing the file using the EMAILCMD command
  188.     line.
  189.     Example: FWDEMAIL = ALL
  190.  
  191. Paging:
  192.  
  193.     PAGEBEEPFAX - (optional) - If paging is desired upon receipt of each
  194.     fax, this script variable is defined and is set to the dial string
  195.     which to be called for paging.  (See Paging below.)
  196.  
  197.     PAGEBEEPVOICE - (optional) - If paging is desired upon receipt of
  198.     each voice message, this script variable is defined and is set to
  199.     the dial string which to be called for paging.  (See Paging below.)
  200.  
  201.     PAGEVOICE - (optional) - A voice number.  If specified,
  202.     the system calls this number and plays the RCVD_FAX.WAV or
  203.     RCVD_MSG.WAV voice prompt file.  Add comma characters to the
  204.     end of the number if additional pauses are desired before the
  205.     message is played.
  206.     Example: PAGEVOICE = 555-5555
  207.  
  208.     PAGEFAX - (optional) - A fax number.  If specified, the
  209.     system sends a fax to this number to say that a fax or voice
  210.     message was received.  
  211.     Example: PAGEFAX = 1 612 555-5555
  212.  
  213. PAGING:
  214. ------
  215. You can have the script call your pager if you wish to be notified
  216. when a call or fax is received.  To enable paging, define and set the
  217. PAGEBEEPFAX or PAGEBEEPVOICE script variables on the Voice page of
  218. the Settings notebook.
  219.  
  220. The value of the script variable is the dial string for calling and
  221. using your paging system.  The value should include:
  222.  
  223.     1) the telephone number of your paging system,
  224.  
  225.     2) several commas (each comma delays for 2 seconds - enter
  226.     the number of commas required for the proper delay for your
  227.     paging system),
  228.  
  229.     3) your Pager ID followed by another comma (if your paging
  230.     system uses IDs to identify a specific pager - paging systems
  231.     which use a unique telephone number for each pager will not
  232.     require this step),
  233.  
  234.     4) the page message (your telephone number or some number
  235.     to show you that you have received a fax or voice message).
  236.  
  237. For example, for a paging system which does not use Pager IDs, the
  238. value might be of the form "PAGEBEEPVOICE=555-5555,,,,555-1234".  For
  239. a paging system which uses Pager IDs where your Pager ID is 123456,
  240. the value might be "PAGEBEEPVOICE=1-800-555-5555,,,,123456,555-1234".
  241.  
  242. VOICE PROMPT FILES:
  243. ------------------
  244. The script expects to find the following Wave audio files in the fax
  245. program (EXE) directory.  The script also uses Wave files from the
  246. c:\mmos2\sounds directory for special effects.
  247.  
  248. To record or modify your own voice prompt files, use your OS/2
  249. Multimedia microphone and record voice prompts using the "Fax/New
  250. message" command then save them to a .WAV file with the "Fax/Save
  251. file/Wave" command.  You can also use the OS/2 Digital Audio program
  252. to record, save, edit and modify the Wave files (be sure to use
  253. "Type" of Mono, 8-bit, 11.025 kHz).
  254.  
  255.     OGM.WAV - The main "outgoing message" as recorded with the
  256.     Utilities/Outgoing message command.
  257.  
  258.     ENTR_COD.WAV - Short: "Enter code."
  259.     Long: "Please enter your access code and the # key."
  260.  
  261.     ENTR_CMD.WAV - Short: "Enter command."
  262.     Long: "To play current message press 5, to play next message
  263.     press 6, to play previous message press 4...."
  264.  
  265.     ENTR_MSG.WAV - Short: "Enter message, then press # key."
  266.     Long: "Please leave your message at the beep.  Press # key to end."
  267.  
  268.     ANNOUNC.WAV - Short: "No announcement."
  269.     Long: "Our annoucement for this week is...."
  270.  
  271.     HELP.WAV - "Press 3 to change outgoing message, 4 for previous..."
  272.  
  273.     NO_MSGS.WAV - Short: "No more messages."
  274.  
  275.     RCVD_FAX.WAV - Short: "A fax has been received."
  276.  
  277.     RCVD_MSG.WAV - Short: "A voice message has been received."
  278.  
  279. And used by any fax retrieval actions (LIB_FOD.CMD procedure):
  280.  
  281.     ENTR_DOC.WAV - Short: "Enter document number and # key, or
  282.     press the # key if done."
  283.     Long: "Please enter the document number followed by the # key,
  284.     or press the # key if done.  To receive an index of available
  285.     documents, enter document 1000."
  286.  
  287.     HOW_FAX.WAV - Short: "Enter 1 if calling from fax machine, 2
  288.     if not."
  289.     Long: "If you are calling from your fax machine and are ready
  290.     to receive the fax press 1, to send the fax to a different
  291.     number press 2." 
  292.  
  293.     ENTR_FAX.WAV - Short: "Enter fax number and # key."
  294.     Long: "Please enter your fax number followed by the # key,
  295.     including 1 and area code if this is not a local call." 
  296.  
  297.     NO_FILE.WAV - Short: "File not found."
  298.     Long: "That document was not found, please try again."
  299.  
  300.     WAIT.WAV - Short: "Please wait."
  301.     Long: "Please wait while we process your request."
  302.  
  303.     THANKYOU.WAV - Short: "Thank you."
  304.  
  305. TO MODIFY THE SCRIPT:
  306. --------------------
  307. The script is REXX and uses calls from the Keller REXX API which are
  308. automatically loaded into the OS/2 REXX environment by the retail
  309. versions of Keller's fax products (version 3.0 and later).  See the
  310. Reference Manual for documentation of the FxRx and FxLn calls.  You
  311. may modify the script as desired, and then use it as the "Answer
  312. script" with Keller fax software products.
  313.  
  314. Note - For voice message retrieval, this script uses the RCVD/N_RCVD
  315. mode of FxRxFind, which means that it will report only those voice
  316. messages which have been received but not already played at the
  317. computer and not previously retrieved via phone.  If desired, you can
  318. change this to use READ/N_READ mode which will report all voice
  319. messages which have not been previously retrieved via phone (even
  320. those that have been played at the computer).  You can also retrieve
  321. any desired voice message, whether or not it has been played or
  322. retrieved, using the "fax log" and "fax-on-demand" features in this
  323. script which allow you to play any voice message by its index number.
  324.  
  325. Note - For fax message retrieval, this script uses the RCVD/N_RCVD
  326. mode of FxRxFind, which means that it will report only those faxes
  327. which have been received but not already viewed at the computer and
  328. not previously retrieved via phone.  If desired, you can change this
  329. to use READ/N_READ mode which will report all faxes which have not
  330. been previously retrieved via phone (even those that have been viewed
  331. at the computer).  You can also retrieve any desired fax, whether or
  332. not it has been viewed or retrieved, using the "fax log" and
  333. "fax-on-demand" features in this script which allow you to retrieve
  334. any fax by its index number.  In version 3 of the fax program,
  335. viewing a received fax changes its status from Rcvd to Read, but
  336. printing of faxes does NOT change the status, so you can auto-print
  337. all received faxes at the computer and still retrieve them as "Rcvd"
  338. faxes by phone. 
  339.  
  340. TO USE WITH MULTILINE VERSIONS:
  341. ------------------------------
  342. This script can be used with multiline versions of Keller fax
  343. software.  All lines are handled identically, so calls can be
  344. received on any of your "receive" lines.  If you prefer to have
  345. different lines be handled differently you can modify the script to
  346. test the LID variable.  For example, to have line 1 immediately jump
  347. to the "please enter your message" prompt, you could add a line like
  348. the following after the "call FxLnInit" line in the script: "if LID =
  349. 1 then signal voice" where "voice" is a label in the script.
  350.  
  351. *******************************************************************/
  352.  
  353.   call FxLnInit
  354.  
  355.   VOXDIR = FxRxPath( 'EXE' )    /* get voice prompts from exe dir */
  356.   LIBDIR = FxRxPath( 'EXE' )    /* get REXX subroutines from exe dir */
  357.   FODPROCEDURE = LIBDIR||'lib_fod.cmd'  /* use this external procedure */
  358.  
  359.  
  360.   /* default values for script variables */
  361.   if CALLER = 'CALLER' then CALLER = 'Person'
  362.   if LOGMAXLINE = 'LOGMAXLINE' then LOGMAXLINE = 56
  363.   if EMAILCMD = 'EMAILCMD' then EMAILCMD = ''
  364.   if EMAILPARAM = 'EMAILPARAM' then EMAILPARAM = ''
  365.   if OGM2 = 'OGM2' then OGM2 = OGM    /** secondary greeting **/
  366.  
  367.   if FWDFAX = 'FWDFAX' then FWDFAX = ''
  368.   if FWDVOICE = 'FWDVOICE' then FWDVOICE = ''
  369.   if FWDEMAIL = 'FWDEMAIL' then FWDEMAIL = ''
  370.  
  371.   if PAGEBEEPFAX = 'PAGEBEEPFAX' then PAGEBEEPFAX = ''
  372.   if PAGEBEEPVOICE = 'PAGEBEEPVOICE' then PAGEBEEPVOICE = ''
  373.   if PAGEVOICE = 'PAGEVOICE' then PAGEVOICE = ''
  374.   if PAGEFAX = 'PAGEFAX' then PAGEFAX = ''
  375.  
  376. hello:
  377.   if LID = 1 then signal fax    /** line 1 is for fax, so go there **/
  378.  
  379.   call FxLnMsg 'OGM'                /* show in status window */
  380.     if result = 'NOTOK' then signal byebye
  381.  
  382.   /** Line 3 is our main voice line, and lines 2 and 4 are rollover. **/
  383.   /** If it is defined, use OGM2 for the secondary/rollover lines. **/
  384.   if LID <> 3
  385.   then call FxLnPlay OGM2
  386.   else call FxLnPlay OGM            /* play greeting prompt */
  387.     if result = 'NOTOK' then signal byebye
  388.     if result = 'FAX' then signal fax
  389.     if result = 'DATA' then signal data
  390.  
  391.   call FxLnDtmf 1, 3, 'digits'            /* get key, if any... */
  392.     if result = 'NOTOK' then signal byebye
  393.     if result = 'FAX' then signal fax
  394.     if result = 'DATA' then signal data
  395.     if result <> 'DTMF' then signal voice
  396.  
  397.   if digits = 2 then signal announce        /* use key value... */
  398.   if digits = 9 then signal accesscode
  399.  
  400.  
  401. voice:                    /* take voice message, hangup */
  402.   call FxLnMsg "Record Msg"
  403.   call FxLnTone 1850
  404.     if result = 'NOTOK' then signal byebye
  405.   call FxLnDtmf        /* flush buffer */
  406.   call FxLnRecord
  407.     if result = 'NOTOK' then signal byebye
  408.     if result = 'FAX' then signal fax
  409.     if result = 'DATA' then signal data
  410.   /* caller can hang up or press a key to end recording */
  411.   call FxLnTone 1850, 1850, 1850
  412.   call Forwarding 'voice'
  413.   call Paging 'voice'
  414.   signal out
  415.  
  416.  
  417. fax:                    /* receive fax and hangup */
  418.   call FxLnReceive
  419.   if result = 'OK' then do
  420.     call Forwarding 'fax'
  421.     call Paging 'fax'
  422.   end
  423.   signal out
  424.  
  425.  
  426. data:                    /* report data call, hangup */
  427.   call FxLnMsg 'Data call, oh well...'
  428.   LREC.!Status = '*Data!'   /* log status of call */
  429.   signal out
  430.  
  431.  
  432. announce:                /* play annoucement, restart */
  433.   call FxLnMsg "Announcement"
  434.   call FxLnPlay VOXDIR||'ANNOUNC.WAV'
  435.     if result = 'NOTOK' then signal byebye
  436.   signal hello
  437.  
  438.  
  439. accesscode:
  440.   call FxLnMsg 'Code ???'        /* get & check access code */
  441.   call FxLnPlay VOXDIR||'ENTR_COD.WAV'
  442.     if result = 'NOTOK' then signal byebye
  443.   digits = GetNumber( 6, 10 )
  444.   if digits <> CODE then signal evil
  445.  
  446.   call FxLnMsg 'Code Mode'
  447.   call FxLnVout 'Valid code entered'
  448.   call FxRxBeep 354, 393, 295, 354, 0, 393
  449.  
  450.   call FxRxFind 'MSG', 'N_RCVD'        /* get # of new voice msgs */
  451.   if result = 'NOTOK' then do
  452.     call FxLnPlay 'c:\mmos2\sounds\BOING.wav'
  453.     signal byebye
  454.   end
  455.   n = result
  456.  
  457.   /* if no messages... stay in command mode for other (fax) commands */
  458.   if n = 0 then do
  459.         call FxLnPlay VOXDIR||'NO_MSGS.WAV'
  460.         if result = 'NOTOK' then signal byebye
  461.   end
  462.  
  463.   i = n                /* Play 1 beep for each voice message */
  464.   call FxLnMsg 'Code Mode' n 'messages'
  465.   call FxLnVout 'Beep' n 'times'
  466.   do while i > 0
  467.     call FxLnTone 2100
  468.     i = i - 1
  469.   end
  470.  
  471.   call FxLnVout 'Enter message loop'
  472.   i = 0
  473.   j = 0
  474.   do forever
  475.     call FxLnMsg 'Waiting for next command'
  476.     call FxLnPlay VOXDIR||'ENTR_CMD.WAV'
  477.     call FxLnDtmf 1, 30, 'digits'
  478.     if result <> 'DTMF' then do
  479.       signal goodbye
  480.     end
  481.     else do
  482.       call FxLnMsg 'Code Mode command' digits
  483.       call FxLnVout 'Command' digits 'entered'
  484.  
  485.  
  486.       if digits = '1' then do            /* 1 = Play help msg */
  487.         call FxLnVout 'Help message'
  488.         call FxLnPlay VOXDIR||'HELP.WAV'
  489.       if result = 'NOTOK' then signal byebye
  490.         iterate
  491.       end
  492.  
  493.  
  494.       if digits = '3' then do            /* 3 = Enter outgoing msg */
  495.         call FxLnVout 'Enter outgoing message'
  496.         call FxLnPlay VOXDIR||'ENTR_MSG.WAV'
  497.       if result = 'NOTOK' then signal byebye
  498.         call FxLnTone 1850
  499.       if result = 'NOTOK' then signal byebye
  500.         call FxLnDtmf        /* flush buffer */
  501.         call FxLnRecord OGM
  502.       if result = 'NOTOK' then signal byebye
  503.         call FxLnTone 1850, 1850, 1850
  504.         call FxLnDtmf        /* flush buffer */
  505.         call FxLnPlay OGM
  506.       if result = 'NOTOK' then signal byebye
  507.         iterate
  508.       end
  509.  
  510.  
  511.       if digits = '4' then do            /* 4 = Previous msg */
  512.         call FxLnVout 'Play previous message' i
  513.         if i <= 1
  514.     then call FxLnPlay VOXDIR||'NO_MSGS.WAV'
  515.     else do
  516.       i = i - 1
  517.           call FxLnMsg 'Code Mode command' digits 'Msg' list.i
  518.         call FxLnPlay list.i
  519.       end
  520.         iterate
  521.       end
  522.  
  523.  
  524.       if digits = '5' then do            /* 5 = Replay msg */
  525.         call FxLnVout 'Replay message' i
  526.         if i <= 0
  527.     then digits = '6'    /* replay = next if just starting */
  528.     else do
  529.           call FxLnMsg 'Code Mode command' digits 'Msg' list.i
  530.       call FxLnPlay list.i
  531.           iterate
  532.     end
  533.       end
  534.  
  535.  
  536.       if digits = '6' then do            /* 6 = Next message */
  537.         call FxLnVout 'Play next message' i j
  538.         if i = n 
  539.     then call FxLnPlay VOXDIR||'NO_MSGS.WAV'
  540.     else do
  541.         i = i + 1
  542.         if i > j then do
  543.         call FxRxFind 'MSG', 'RCVD', 'LREC'
  544.         call FxLnVout 'Found' LREC.!ID
  545.         list.i = LREC.!ID
  546.         j = i
  547.       end
  548.           call FxLnMsg 'Code Mode command' digits 'Msg' list.i
  549.         call FxLnPlay list.i
  550.         end
  551.         iterate
  552.       end
  553.  
  554.  
  555.       if digits = '7' then do            /* 7 = send rcvd faxes */
  556.         call FxLnVout 'Send rcvd faxes'
  557.         call FxLnMsg 'Code Mode command' digits
  558.         call FxRxFind 'FAX', 'N_RCVD'        /* get # of new faxes */
  559.         if result = 'NOTOK' then do
  560.           call FxLnPlay 'c:\mmos2\sounds\BOING.wav'
  561.           signal byebye
  562.         end
  563.         nfax = result
  564.         if nfax = 0 then do
  565.           call FxLnPlay VOXDIR||'NO_MSGS.WAV'
  566.           if result = 'NOTOK' then signal byebye
  567.         end
  568.         else do
  569.           ifax = nfax        /* Get faxes into list and beep per fax */
  570.           faxlist = ''
  571.           flist = ''
  572.           call FxLnMsg 'Code Mode' nfax 'faxes'
  573.           call FxLnVout 'FaxBeep' nfax 'times'
  574.           do while ifax > 0
  575.             call FxLnTone 2100
  576.             ifax = ifax - 1
  577.             call FxRxFind 'FAX', 'RCVD', 'LREC'
  578.             call FxLnVout 'Found' LREC.!ID
  579.             faxlist = AddToCsvList( LREC.!ID, faxlist )
  580.             flist = flist LREC.!ID
  581.           end
  582.           /* call our FOD procedure to do the faxing */
  583.           FODPARAMS = "FxRxPath( 'LOG' ), VOXDIR, , CALLER, faxlist," ,
  584.             "'As you requested, your received faxes are attached:' flist," ,
  585.             "'Remote fax retrieval...'"
  586.           interpret 'call' "'"||FODPROCEDURE||"'" FODPARAMS
  587.           if result = 'BYEBYE' then signal BYEBYE
  588.           if result = 'OUT' then signal OUT
  589.         end
  590.         iterate
  591.       end
  592.  
  593.  
  594.       if digits = '8' then do            /* 8 = send log */
  595.         call FxLnVout 'Send log'
  596.         call FxLnMsg 'Code Mode command' digits
  597.         call FxLnPlay VOXDIR||'WAIT.WAV'
  598.       if result = 'NOTOK' then signal byebye
  599.         call SendLog
  600.           if result = 'BYEBYE' then signal BYEBYE
  601.           if result = 'OUT' then signal OUT
  602.         iterate
  603.       end
  604.  
  605.  
  606.       if digits = '9' then do            /* 9 = FOD from log */
  607.         call FxLnVout 'FOD from log'
  608.         call FxLnMsg 'Code Mode command' digits
  609.         FODPARAMS = "FxRxPath( 'LOG' ), VOXDIR, , CALLER, , ," ,
  610.                "'FOD Retrieval...'"
  611.         interpret 'call' "'"||FODPROCEDURE||"'" FODPARAMS
  612.           if result = 'BYEBYE' then signal BYEBYE
  613.           if result = 'OUT' then signal OUT
  614.         iterate
  615.       end
  616.  
  617.  
  618.       if digits = '*' | digits = '#' then do
  619.         signal goodbye
  620.       end
  621.  
  622.  
  623.       /* otherwise, if none were matched... */
  624.       call FxLnVout 'Unknown command' i
  625.       call FxLnPlay 'c:\mmos2\sounds\EEERRUPP.wav'
  626.       iterate
  627.  
  628.     end
  629.   end
  630.  
  631.  
  632. goodbye:
  633.   call FxLnVout 'Exit Code Mode'
  634.   call FxLnPlay 'c:\mmos2\sounds\DRUMROLL.wav'
  635.   signal byebye
  636.  
  637.  
  638. evil:
  639.   call FxLnVout 'Bad code entered:' digits 'vs' CODE
  640.   call FxLnPlay 'c:\mmos2\sounds\BOO.wav'
  641.   call FxRxBeep 1318, 1396, 1318, 1090, 1318, 1396, 1318, 1090
  642.   signal byebye
  643.  
  644.  
  645. byebye:                    /* called for error cases */
  646.   LREC.!Status = ''            /* don't log anything */
  647.   signal out
  648.  
  649.  
  650. out:                    /* clean up and quit */
  651.   call FxLnTerm
  652.   exit
  653.  
  654.  
  655. /************************ Procedures ************************/
  656.  
  657.  
  658. GetNumber: procedure
  659.   /* Gets DTMF input until # or * key or "digits" are entered. */
  660.   /* TimeOut is seconds to wait for each digit (default 15).       */
  661.   parse arg digits, TimeOut
  662.   number = ''
  663.   if TimeOut = '' then TimeOut = 15  /* default to 15 seconds */
  664.   do digits
  665.     call FxLnDtmf 1, TimeOut, 'newkey'
  666.       if result <> 'DTMF' | newkey = '#' | newkey = '*' then leave
  667.     number = number||newkey
  668.   end
  669.   return number
  670.  
  671.  
  672. TmpFile: procedure
  673.   /* Generate a unique base file name using seconds since midnight */
  674.   return 'TMP'||time( S )
  675.  
  676.  
  677. AddToCsvList: procedure
  678.   /* returns a comma-separated value list with item added */
  679.   parse arg item, list
  680.   if list = ''
  681.     then list = item
  682.     else list = list||','||item
  683.   return list
  684.  
  685.  
  686. SendLog:    /* sends the log file by fax */
  687.   tmp1 = VOXDIR||TmpFile()||'.TXT'
  688.   tmp2 = VOXDIR||TmpFile()||'.FAX'
  689.   log = FxRxPath( 'LOG' )||'fax.log'
  690.  
  691.   call LineOut tmp1, 'Fax Log   ' Date('W') ' '||Date('N') ' ' Time('C')
  692.   call LineOut tmp1, ''
  693.   call LineOut tmp1, ,
  694.        'Type ID      Date    Time  Pg Status Elpsd  Name/RemoteID/CallerID'
  695.   call LineOut tmp1, ''
  696.  
  697.   if LOGMAXLINE <= 0 then do /* send the entire fax log */
  698.     do while Lines( log ) > 0
  699.       record = LineIn( log )        /* read a record from log */
  700.       if FxRxParseLog( record, 'lrec' ) = OK then do
  701.         call LogRpt tmp1
  702.       end
  703.     end
  704.   end
  705.   else do /* send the last x lines from the log */
  706.     head = 1
  707.     tail = 1
  708.     do while Lines( log ) > 0    /* collect last x lines */
  709.       buf.head = LineIn( log )
  710.       head = head + 1
  711.       if head > LOGMAXLINE then head = 1
  712.       if head = tail then tail = tail + 1
  713.       if tail > LOGMAXLINE then tail = 1
  714.     end
  715.     if tail <> head & FxRxParseLog( buf.head, 'lrec' ) = OK then do
  716.       call LogRpt tmp1
  717.     end
  718.     do while tail <> head
  719.       if FxRxParseLog( buf.tail, 'lrec' ) = OK then do
  720.         call LogRpt tmp1
  721.       end
  722.       tail = tail + 1
  723.       if tail > LOGMAXLINE then tail = 1
  724.     end
  725.   end
  726.   rc = LineOut( log )            /* close the files */
  727.   rc = LineOut( tmp1 )
  728.   call FxRxTextToFax tmp1, tmp2        /* convert text to fax */
  729.   /* call our FOD procedure to do the faxing */
  730.   FODPARAMS = "FxRxPath( 'LOG' ), VOXDIR, , CALLER, tmp2," ,
  731.           "'As you requested, the log is attached.', 'Log retrieval...'"
  732.   interpret 'call' "'"||FODPROCEDURE||"'" FODPARAMS
  733.   fodresult = result
  734.   call FxLnVout 'Deleting:' tmp1
  735.   'DEL "'||tmp1||'"'
  736.   call FxLnVout 'Deleting:' tmp2
  737.   'DEL "'||tmp2||'"'
  738.   return fodresult
  739.  
  740.  
  741. LogRpt:
  742.   /* Using global lrec., write a report line to a file */
  743.   parse arg Rfile
  744.  
  745.   if BitTest( lrec.!Flags, 256 ) then mtype = 'MSG'
  746.   else if BitTest( lrec.!Flags, 512 ) then mtype = 'Txt'
  747.   else if BitTest( lrec.!Flags, 1024 ) then mtype = 'Dat'
  748.   else mtype = 'Fax'
  749.  
  750.   if lrec.!Company = ''
  751.   then namestr = lrec.!Name
  752.   else namestr = lrec.!Name||', '||lrec.!Company
  753.  
  754.   if lrec.!Pages = 0
  755.   then pagestr = ''    /* don't show 0 pages */
  756.   else pagestr = lrec.!Pages
  757.       
  758.   call LineOut Rfile, mtype left( lrec.!ID, 6 ) ,
  759.          left( lrec.!Date, 9 ) left( lrec.!Time, 5 ) ,
  760.          right( pagestr, 2 ) left( lrec.!Status, 6 ) ,
  761.          right( lrec.!Elapsed, 5) ' '||strip( left( namestr, 46 ) )
  762.   return
  763.  
  764.  
  765. BitTest: procedure
  766.   /* Given a number and a bit number, return 1 if bit is set */
  767.   parse arg value, bit
  768.   return (value % bit) // 2
  769.  
  770.  
  771. Forwarding:
  772.   parse arg mode /* 'voice' or 'fax' */
  773.  
  774.   if mode = 'voice' then do
  775.  
  776.     /* voice forwarding */
  777.     if FWDVOICE <> '' then do
  778.       call DeliverVoice LREC.!ID FWDVOICE
  779.     end
  780.     /* email forwarding */
  781.     if EMAILCMD <> '' then do    /* using email? */
  782.       call FxLnVout 'FWDEMAIL=' FWDEMAIL 'EMAILCMD=' EMAILCMD
  783.       if FWDEMAIL = 'ALL' | FWDEMAIL = 'VOICE' then do
  784.         cmdstring = EMAILCMD '"'||FxRxIndexToFax( LREC.!ID )||'"' EMAILPARAM
  785.         cmdstring
  786.         call FxLnVout 'rc=' rc 'for' cmdstring
  787.       end
  788.     end
  789.   end
  790.  
  791.   else if mode = 'fax' then do
  792.     /* fax forwarding */
  793.     if FWDFAX <> '' then do
  794.       /* Send with default cover sheet and default "From" information */
  795.       call FxRxQueue LREC.!ID, ,
  796.          'TO='||CALLER||' at fax: '||FWDFAX||',,'||FWDFAX, ,
  797.          'INFO="Forwarded fax is attached.",*,"Forwarding fax...",*,1,2', ,
  798.          'FROM=*,*,*,*'
  799.     end
  800.     /* email forwarding */
  801.     if EMAILCMD <> '' then do    /* using email? */
  802.       call FxLnVout 'FWDEMAIL=' FWDEMAIL 'EMAILCMD=' EMAILCMD
  803.       if FWDEMAIL = 'ALL' | FWDEMAIL = 'FAX' then do
  804.         cmdstring = EMAILCMD '"'||FxRxIndexToFax( LREC.!ID )||'"' EMAILPARAM
  805.         cmdstring
  806.         call FxLnVout 'rc=' rc 'for' cmdstring
  807.       end
  808.     end
  809.  
  810.   end
  811.   return
  812.  
  813.  
  814. DeliverVoice: procedure expose LREC.
  815.   /* given a message (id# or file) and phone number, call the number */
  816.   /* and play message.  Protects LREC record while doing so.         */
  817.   parse arg msg fwdnum
  818.   call FxLnVout 'DELIVERVOICE =' msg fwdnum
  819.   call FxLnMsg 'Voice delivery of' msg 'to' fwdnum
  820.   logtmp = FxRxFormatLog( 'LREC' )    /* save the record */
  821.   do 3   /* retry in case of no dialtone, etc. */
  822.     call FxLnLine 'DIAL' fwdnum
  823.     if result = OK then do
  824.       call FxLnPlay msg
  825.       leave
  826.     end
  827.   end
  828.   call FxRxParseLog logtmp, 'LREC'    /* restore record  */
  829.   call FxLnVout 'Leaving DeliverVoice'
  830.   return
  831.  
  832.  
  833. DeliverBeeps: procedure
  834.   /* Given a phone number, call the number */
  835.   parse arg BeepNum
  836.   call FxLnMsg 'Delivery beeps to' BeepNum
  837.   do 3   /* retry in case of no dialtone, etc. */
  838.     call FxLnLine 'DIAL' BeepNum
  839.     if result = OK then leave
  840.   end
  841.   return
  842.  
  843.  
  844. Paging:
  845.   parse arg mode    /* 'voice' or 'fax' */
  846.  
  847.   call FxLnVout 'PAGING =' mode PAGEFAX PAGEVOICE
  848.   if PAGEFAX <> '' then do
  849.     if mode = 'fax'
  850.     then tmp = 'A fax was received.'
  851.     else tmp = 'A voice message was received.'
  852.     call FxRxQueue 'TO='||CALLER||' at fax: '||PAGEFAX||',,'||PAGEFAX, ,
  853.        'INFO='||'"'||tmp||'"'||',*,"Paging by fax...",*,1,2', ,
  854.        'FROM=*,*,*,*'
  855.   end
  856.  
  857.   if PAGEVOICE <> '' then do
  858.     if mode = 'fax' then do
  859.       call DeliverVoice VOXDIR||'RCVD_FAX.WAV' PAGEVOICE
  860.     end
  861.     else if mode = 'voice' then do
  862.       call DeliverVoice VOXDIR||'RCVD_MSG.WAV' PAGEVOICE
  863.     end
  864.   end
  865.  
  866.   if mode = 'fax' & PAGEBEEPFAX <> '' then do
  867.     call DeliverBeeps PAGEBEEPFAX
  868.   end
  869.   if mode = 'voice' & PAGEBEEPVOICE <> '' then do
  870.     call DeliverBeeps PAGEBEEPVOICE
  871.   end
  872.  
  873.   return
  874.