/* Dialin.REXX                                                               */
/*                                                                           */
/* Adapted from SLIPUP.REXX by P.J.Rovero for use with Demon Internet Servs. */
/*                                                                           */
/* Version 1.0, 24 February 1994, by A.J.Tucker -- alex@warp.demon.co.uk     */
/*                                                                           */
/* An ARexx script that will dial Demon Internet Services, set up a slip     */
/* connection and start AmiTCP                                               */
/*                                                                           */
/* Error checking is minimal.  The program will redial until a successful    */
/* connection is made.  A logfile is built in AmiTCP:log/calls -- in future  */
/* this will be compatible with PhoneBill, a call costing program.           */
/*                                                                           */
/* ------------------------------------------------------------------------- */

/* Your configuration */

   dialstring   = 'ATD0813434848' /* The London PoP                    */
   nodename     = 'yourmc'        /* your node name goes here          */
   password     = 'secret'        /* password goes here                */
   baud         = 38400           /* these values must tie in with the */
   device       = 'serial.device' /* ones used with amitcp: i.e. in    */
   unit         = 0               /* env:sana2/slip?.config & startnet */

/* Start the required libraries */

if ~show('L',"rexxsupport.library") then do
   if addlib('rexxsupport.library', 0, -30, 0) then
      say 'added rexxsupport.library'
   else do;
      say 'rexxsupport.library not available'
      exit 10
      end
   end

if ~show( 'L', "rexxserdev.library" ) then do
   if addlib( 'rexxserdev.library', 0, -30, 0 ) then
      say 'added rexxserdev.library'
   else do;
      say 'rexxserdev.library not available'
      exit 10
      end
   end

/* Define modem strings and other initialization stuff     */
   cr               = '0d'x
   crlf             = '0d0a'x
   buffer           = allocmem( 512 )
   junk             = c2d( buffer )

/* Open the serial device and talk to the modem                         */
   signal on halt
   signal on failure
   say 'Opening serial device.....'
   serhandle = SerOpen(device, unit)

/* Hangup? */

   if upper(arg(1))='HANGUP' then call hangup()

/* Check to see if modem is already online */
   status=SerQuery(serhandle)
   parse upper var status valid bytes_read status_bits
   if ~(bittst(d2c(status_bits),5)) then signal already_connected

   call SerClear(serhandle)
   call SerSetParms( serhandle, baud, 8, N, 1, 0 )
   call send('ATZ'||crlf)
   call delay(10)
   sofar=get()
   do until (pos('OK',sofar)>0)
      call delay(50)
      sofar=sofar||get()
   end
   call send('AT&D0'||crlf)
   call delay(10)
   sofar=get()
   do until (pos('OK',sofar)>0)
      call delay(50)
      sofar=sofar||get()
   end

   res=dialwait()
   do while res>1
      if res=2 then say 'Busy, redialing'
      if res=3 then do
         say 'No carrier, redialing'
         call log('online :'||ctime)
         call log('offline:'||date()||' - '||time())
      end
      if res=4 then do
         say 'Timed out while dialing'
         call log('online :'||ctime)
         call log('offline:'||date()||' - '||time())
      end
      call delay(100)
      res=dialwait()
   end
   call log('online :'||ctime)
   say 'Modem connected'
   call login()
already_connected:
   call SerClose( serhandle )
   call freemem( buffer,512)
   address command 'startnet'
return 0

/* Send a string to the modem */
send:
   sendstr=arg(1)
return (SerWrite( serhandle, sendstr, length( sendstr ) ))

/* Get latest string from modem */

get:
   status = SerQuery( serhandle )
   parse upper var status valid bytes_read status_bits
   got=SerRead( serhandle, junk, bytes_read )
   writech(stdout,got)
return (got)

/* Dial Demon & wait for CONNECT/BUSY/NO CARRIER */

dialwait:
   res = 0
   say 'Dialing Demon'
   call send(dialstring||crlf)
   call get()
   sofar=''
   delay(15*50) /* The time it takes to dial */
   ctime=date()||' - '||time()
   call time(r)
   do while res=0
      call delay(50)
      sofar=sofar||get()
      if pos('CONNECT',sofar)>0 then res=1
      if pos('BUSY',sofar)>0 then res=2
      if pos('NO CARRIER',sofar)>0 then res=3
      if time(e)>60 then do /* Timed out for some reason... */
         res=4
         call delay(50)
         call send('+++')
         call delay(50)
         call send('ATH')
      end
   end
return(res)

/* Login */

login:
   sofar=sofar||get()
   do until (pos('ogin:',sofar)>0)
      call delay(50)
      sofar=sofar||get()
   end
   call delay(50)
   say 'Sending nodename'
   call send(nodename||cr)
   sofar=get()
   do until (pos('word:',sofar)>0)
      call delay(50)
      sofar=sofar||get()
   end
   sofar=get()
   say 'Sending password'
   call send(password||cr)
   do until (pos('ocol:',sofar)>0)
      call delay(50)
      sofar=sofar||get()
   end
   say 'Negotiating protocol'
   sofar=get()
   call send('SLIP'||cr)
   do until (pos('HELLO',sofar)>0)
      call delay(50)
      sofar=sofar||get()
   end
return

/* Append information to a log file */

log:
   if ~exists('amitcp:log/calls') then
      if open(.logfile,'amitcp:log/calls','w') then
         close(.logfile)
   call open(.logfile,'amitcp:log/calls','a')
   writeln(.logfile,arg(1))
   close(.logfile)
return

hangup:
   say 'Hanging up...'
   call SerClear(serhandle)
   call SerSetParms( serhandle, baud, 8, N, 1, 0 )
   call delay(100)
   call send('+++')
   call delay(50)
   call get()
   call send('AT&D2'||crlf)
   call delay(50)
   call get()

failure:
halt:
   call SerClose(serhandle)
   call freemem(buffer,512)
   exit
