home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / voice2.zip / V_MBX4.CMD < prev    next >
OS/2 REXX Batch file  |  1997-06-19  |  33KB  |  935 lines

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