/*************************************************************************
 CID.rexx (c) 1992 by Doug McLean

 Get caller ID info from TrapDoor

 This is for the SupraFax modem, using the caller ID system in New
 Brunswick, Canada.

 YOU WILL HAVE TO CHANGE PARTS OF THIS SCRIPT FOR YOUR SYSTEM!!! See the
 comments below...

 Use AT#CID=1&W to set the SupraFax for this script.

 PLEASE NOTE that I am NOT an ARexx programmer. I am MUCH more comfortable
 with C. This is only my second ARexx script (the first was call.rexx), and
 it could probably be greatly improved. If you do improve it, or find an
 improved version somewhere, PLEASE file attach or upload a copy to me!
 I don't think that is too much to ask, do you??? 

 Doug McLean
 The Mad Scientist's BBS

 Fido     -> 1:255/9.0
 AmigaNet -> 40:940/1.0
 BBS      -> (506) 636-9117
             CM V32bis FREQ

 Some of the reasons that ARexx is better than C for this project are:

 - I didn't have to write serial stuff to get the ID info directly :-)
 - You can modify it so that it works with your phone companies caller
   ID system,
 - It allows TrapDoor to do other things too, like call out, quit, and
   process other ARexx commands (you might have to wait up to 20
   seconds for these).

 PS: Special thanks to Mike Mossman for explaining that"Yes, Arexx really
     does work, and it is a good language as long as to use it right, and
     ARexx is better for this than C".

 Ok Mike, you were right! :-)

 I've tried to put LOTS of comments in this script, since you WILL have
 to modify it. There are more comments than code (another first for me :-).

 If you do not run DLG BBS/OS, and do not wish to upgrade yet, this script
 should still produce a file with the phone number, but you will have to
 find something (perhaps an ARexx script) to use the info from within
 your BBS software.
*************************************************************************/

options results          /*** gotta have results!!! ***/

SIGNAL ON BREAK_C        /*** in case the user wants to break ***/
SIGNAL ON SYNTAX         /*** only way to handle when TD goes down?
                              see SYNTAX: label at end of script. comment
                              SIGNAL ON SYNTAX out when you are testing
                              this script. */

vers = 'CID.rexx v0.2 (c) 1992 by Doug McLean'
logfile = 'logs:cid.log' /*** the log file for a continuous log */
cidfile = 't:tr0.cid'    /*** the file that will contain the phone number
                              for DLG to use from login.dlgbatch */
calls = 0                /*** might as well count calls while we are at it */
say vers
                         /*** tell the log file we are running. *sigh* in
                              C, if we open a file in append mode, it will
                              get created if it doesn't exist. arexx doesn't
                              seem to work that way, so we better open it in
                              write mode if it doesn't exist. we'll assume
                              you don't delete the log while the script is
                              running, and open it in append mode the rest
                              of the time. it took me a while to
                              figure this one out... */

if exists(logfile) ~= 0 then do
   call open('log',logfile,'append')
end
else do
   call open('log',logfile,'write')
end
call writeln('log',' ')
call writeln('log','[ 'vers' ]')
call writeln('log',' ')
call close('log')

START:                /*** a label to use with SIGNAL in the routine to
                           handle when TD goes down (SYNTAX at the end
                           of the script) */
do forever
   call CheckAllow    /*** we may want to temporarily disable this script */
   call FindTd        /*** function below to make sure TD is running */
   address 'TrapDoor' /*** select TDs arexx port */
   STIMEOUT 20        /*** Tell TrapDoor to wait a bit. We don't want
                           to wait too long, because TD might have other
                           things to do... */
   SWAIT 'TIME'       /*** wait till TD gets TIME from the modem. This is
                           the 2nd line that the modem returns. The modem
                           returns DATE, TIME, NMBR, NAME but Arexx doesn't
                           seem to be able to get all four lines at 38400,
                           so we will wait till the second and get the
                           third. NAME is not supported where I live. */
   if result = 'TIME' then do    /*** if we got 'TIME', then get and process
                                      the caller's number. If we didn't get
                                      TIME, then the STIMEOUT must have
                                      expired and we jump back to the top.
                                      If another arexx command arrived while
                                      we were SWAITing (maybe a CALL from
                                      DLGMail, or a QUIT, or whatever) then
                                      it will be processed before the
                                      STIMEOUT at the top of the loop */
      SLINE           /*** we got here, so we must have gotten 'TIME' from
                           SWAIT. The next line of info should be the
                           caller's phone number, we get this with SLINE */
      num = result             /*** and save the string to process later */
  /*  ANSWER IMMEDIATE */      /*** It seems to work better is we let TD
                                    answer on the 2nd ring */
      address command          /*** done with TD now, and we want DOS */

/**********************************************************************
 here is where we change what we got for caller ID info into a regular
 number, and write it to a file. Since the string is sent differently
in my area then yours (probably), you will have to change this section.
**********************************************************************/

      pflag = substr(num,8,1)        /*** if we don't get a 0 at character 8
                                          of the ID string, then we probably
                                          didn't get ID info (perhaps the
                                          exchange the call came from doesn't
                                          support it, or it is a long distance
                                          number, or an unlisted one). we
                                          check this character and take
                                          acion depending on what we get.
                                          Again, this will work differently
                                          on different phone systems. */
      select

        when pflag = 'P' then do     /*** we got a P, the number isn't
                                          available */
          cid = 'PRIVATE'
        end

        when pflag = 'O' then do     /*** other country??? */
          cid = 'OTHER'
        end

        when pflag = '0' then do     /*** We have a phone number! Here, it
                                          returns the hex digits for the
                                          ASCII equiv of the number, so
                                          6369117 would be returned as
                                          36333639313137 */

          cidtemp = substr(num,12) || 'xx' /*** add 'xx' to the end of the
                                                number string and take
                                                everything from the 12th
                                                position on. This is
                                                because the actual number
                                                has 0307 before it. The
                                                modem returns
                                                MESG = 030736333639313137
                                                as the entire string for
                                                the above number (6369117)
                                                After the above line, cidtemp
                                                should read: 
                                                36333639313137xx */

          i = 2            /*** we want every 2nd digit */
          cid = ''         /*** and we want cid empty at first */

          do until substr(cidtemp,i,1) = 'x' /*** add every 2nd char to cid
                                                  till we get 'x' */
            cid = cid || substr(cidtemp,i,1)
            i = i + 2
          end
          /***** cid now contains the phone number, for example 6369117 */
        end

        otherwise do       /*** got a pflag we didn't expect. */
          cid = '?????'
        end
      end

/**********************************************************************
The above was the main stuff you had to change. the variable cid should
now contain the phone number:
6369117
**********************************************************************/

      calls = calls + 1     /*** add 1 to calls */

      /*** save some of this info in a seperate log. this is REALLY
           HANDY when you are trying to figure out what your phone
           company is sending for caller ID strings */

      'date >>'logfile
      call open('log',logfile,'append')
      call writeln('log','    CALL # : 'calls)
      call writeln('log','    RAW STR: 'num)
      call writeln('log','    NUMBER : 'cid)
      call close('log')

      /*** and create the file for DLG to use. You can add stuff at the
           end, but the first line should contain the string in cid. */

      call open('cfile',cidfile,'write')
      call writeln('cfile',cid)
      call close('cfile')

      /*** and put the info to the CLI too */

      say ' '
      say 'CALL # : 'calls
      say 'RAW STR: 'num
      say 'NUMBER : 'cid

      /*** here we have to wait a bit or TD will get another STIMEOUT and
           SWAIT before it answers the phone, and we will be in an endless
          loop (not good). This is to give TD time to get the next RING and
           answer the phone. Once TD does this, it is safe to start sending
           commands again, because they won't be executed till TD hangs up. */

      call delay(300)

   end
end

/*******************Make sure trapdoor is up and running *****************
     make sure trapdoor is running. this function will not return
     until TD is present. However, if TrapDoor disappears while the
     script is running, you will get a "host environment not found"
     error... */

FindTd:
address command
do while show(Ports,'TrapDoor','') = 0    /*** if the TD port isn't there
                                               we just wait a bit and check
                                               again */
   call delay(60)
   end
return    /*** once the port is there, we can return to the main part
               of the script */
end


/**** check to see if there is an environment variable telling
      us to stop for a bit, useful when you don't want this
      script on the TD port (maybe you have another script that wants
      the TD port, like I do). As long as the environment variable CID
      is OFF, this script will not return. So, so disable the script use
         setenv CID OFF 
      and to enable it use
         setenv CID ON (or anything not starting with OFF */

CheckAllow:
address command
sflag = 0
do while open('envfile','env:cid','read') = 1
   envstr = upper(readln('envfile'))
   call close('envfile')
   
   if left(envstr,3) ~= 'OFF' then do
      if sflag = 1 then say 'CID.rexx enabled again'
      return
   end
   if sflag = 0 then say 'CID.rexx disabled by env var'
   sflag = 1
   call delay(60 * 10)
end
if sflag = 1 then say 'CID.rexx enabled again'
return


/**************** handle control c breaking ********************************/
BREAK_C:
say ' * BREAK * '
exit


/**************** when TrapDoor goes down *********************************
     When TrapDoor goes down, we get a syntax/command error because the
     trapdoor host environment isn't there any more. since we have SIGNAL
     ON SYNTAX set at the top, here is where we go when that happens...
     We will assume we got this error due to TD going down and it isn't
     a real syntax error, because we know there are no real syntax errors
     in the script. */

SYNTAX:
address command       /*** TD ain't here, so we better switch environments */
say '[ TrapDoor Down ]' /*** Tell the sysop that TD went down. you will also
                             get a message in the window the script runs in,
                             THIS ERROR MESSAGE IS NORMAL AND SHOULD BE
                             IGNORED */
call FindTD             /*** wait till TD is back up again */
say '[ TrapDoor Up ]'   /*** tell sysop that TD is back */
SIGNAL ON SYNTAX        /*** reset our signal. the script seems to crash
                             the second time we take TD down if we don't
                             do this */
signal START:       /*** and finally, a signal to re-start the main loop */


/*** that's all folks! I'll try to do better once I learn a bit more arexx.
     I will be happy to answer any questions about this script, but please
     remember that I am not an arexx programmer and thus can't answer
     complicated questions about arexx. */
