! ----------  RCM Scheduled Routines ---------- !
!      Dale Burns 07/07/97  !
!      Dale burns 25/08/97  Provide extra report without tabs !
!      Dale Burns 28/08/97  Fix bug in reversed lines report  !
!      Dale Burns 10/09/97  Provide info in logfile for menu scan !
!      Dale Burns 17/09/97  Show exchange file open and lrd's in rep !
!      Dale Burns 17/10/97  Change backup OK message !
!                           Change order of CRC reports !

!      Dale Burns 20/10/97  Provide times for backup !
!      Dale Burns 24/10/97  Privide better routine for carrier fail prior to backup !
!      Dale Burns 28/10/97  Provide better scanning for RCM in datagate menu !
!      Dale Burns 03/11/97  Change cascade scan routine to repair bug !
!      Dale Burns 06/03/98  Change datagate menu scan to read PGS "E" numbers
!                           Ignore cascade port without string "TO"
!      Dale Burns 12/03/98  Provide further check for "E" in RCM name
!      Dale Burns 02/04/98  Make further changes for datagate menu scan
!      Dale Burns 03/04/98  Change scan of datagate menu so 6 char pgs ID
!                           is recognised. Saved files will now be in a
!                           different format. eg. E90123 at GEEM will now
!                           create af file GEEME901.23E for exchange side.
!                           GEEM BAMG01 = GEEMBAMG.01E
!                           BELM 9015 = BELM9015.E
!      A. Tennwnt 26/10/98  Output file path changed to working drive & path.
!      A. Tennent 27/10/98  Corrected scanning order of CRC counters.

! ----- Set up ready for polling -----!
  @hide
  @set rcmIndex = 0
  @set rcmCount = 0
  @set poll = "YES"
  @esckey(on)
  @erase(event_file)                       @@ Remove the temp event file
  @include("local.dat")                    @@ Load Ozterm variables
  @set datagateList = region
  @set path = region                       @@ Preserve string "region"
!  @set path = ("{_workdrv}{_workpath}\")   @@ write reports to ..\SESSx directory
  @gosub ReleaseNasi                       @@ Disconnect NASI session first

! ----- Now we must remove the filename from path variable -----!
!       (this is not necessary, now that path is not derived from region)
@label GetPath
  @set pathLen = length(path)              @@ Find the last "\" character
  @if copy(path,pathLen,1) = "\" then goto HavePath
  @dec(pathLen)
  @set path = copy(path,1,pathLen)         @@ The remove everything after it
  @goto GetPath

! ----- Now we can prepare files -----!
@label HavePath
  @set logfile = concat(path,"connect.log")
  @set report = concat(path,"connect.rep")
  @set tabReport = concat(path,"connect.tab")
  @erase(tabReport)
  @erase(report)
  @erase(logfile)                          @@ Remove old logfile
  @log(logfile)
  @fileclose(datagateList)                 @@ Force file closed
  @set datagateNumber = 0                  @@ Reset datagate counter
  @openread(datagateList)                  @@ Open file to build new list
  @iferror then write(report,"Can't open {datagateList}")
  @else write(report,"{datagateList} opened OK")
  @window

@label GetDatagate
  @check(off)
  @read(line)                              @@ Read the next line
  @check(on)
  @iferror then goto EndDatagateList       @@ Finish reading if EOF found
  @comment(line)
  @if copy(line,1,1) = "!" then goto GetDatagate
  @if copy(line,16,3) = "END" then goto GetDatagate
  @inc(datagateNumber)
  @set datagate[{datagateNumber}] = trim(copy(line,16,_lncdsize))
  @write(report,"Datagate: {datagate[{datagateNumber}]} found.")
  @goto GetDatagate

@label EndDatagateList
  @write(report,"{datagateNumber} Datagates in list")
  @fileclose(datagateList)                 @@ Force the file closed
  @set datagatePointer = 0                 @@ Reset the pointer
  @windowend                               @@ Clear the comments window

! ----- Get the next Datagate LNCD (LRD) from the list ----- !
@label DatagateLoop
  @inc(datagatePointer)
  @if datagatePointer > datagateNumber then goto LastDatagate
  @set lncd = datagate[{datagatePointer}]
  @set scanned = "NO"                      @@ This is a new datagate connection
                                           @@ so we must scan the menus

! ----- Connecting to a new Datagate ----- !
! ----- This is the main routine for connection & controlling routines ----- !
@label DatagateConnection
   @window
   @set connectCounter = 3                 @@ We will attempt connection three
                                           @@ times before giving up
@label RetryConnection
  @gosub GetDate
  @gosub ConnectDatagate                   @@ Use connect subroutine
  @setdest("        ")
  @if lrderror <> "FAIL" then goto DatagateConnected
  @dec(connectCounter)                     @@ Retry connection if failed
  @if connectCounter > 0 then goto RetryConnection
  @write(tabReport,"E001",#9,"{lncd}",#9,#9,#9,#9,"{date}",#9,"Datagate not connected")
  @write(report,"")
  @write(report,"{lncd}"," {date} Datagate not connected")
  @goto DatagateLoop                       @@ If we fall through to here, all
                                           @@ has failed and we must provide
                                           @@ error message

! ----- Last datagate has been polled. We can now make a report ----- !
@label LastDatagate
  @fileclose(datagateList)
  @gosub GetDate
  @write(tabReport,#9,#9,#9,#9,#9,"{date}",#9,"Routine completed")
  @write(report,"")
  @write(report,"{date}",#9,"Routine completed")
  @mode("FD")
  @flushvar(error)
  @close
  @gosub ReleaseNasi
  @stop


!--------------------------------------------------------------------------!


@label DatagateConnected
  @setdest("{lncd}")
  @gosub GetDate
  @write(report,"")
  @write(report,"{lncd} Datagate connected at {date}")
  @if scanned = "YES" then goto ConnectRcm
  @set scanned = "YES"
  @gosub GetDate

! ----- Now we scan the datagate main menu ----- !
  @delaysec(5)                             @@ Wait 5 seconds to settle down
  @mark                                    @@ Mark start for scan
  @send(#13)                               @@ Get menu again
  @waitfor("Option #",30)
  @iferror then goto RetryConnection
  @delaysec(1)
  @set rcmCount = 0                        @@ Reset RCM counter
  @set lineNumber = 1                      @@ Start a first line
  @set cascadeCount = 0                    @@ Reset cascade counter

@label MenuScanLoop
  @set cascade = "0"                       @@ Default cascade port 0
  @inc(lineNumber)                         @@ Scan next line
  @if lineNumber > 60 then goto MainMenuScanned
  @set line = reply(lineNumber)
  @if pos("Option #",line) <> 0 then goto MainMenuScanned
  @if pos("RCM ",line) = 9 then gosub StoreRcm
  @if pos("CASCADE",line) = 9 then gosub StoreCascade
  @goto MenuScanLoop

@label StoreRcm                            @@ Store the RCM details from menu
  @if pos("RCM",line) > 11 then return     @@ Not valid, must be future RCM
  @windend
  @window
  @if pos("Busy",line) = 0 then goto RcmPortFree
  @gosub GetDate
  @write(tabReport,"E007",#9,"{lncd}",#9,"{cascade}",#9,trim(copy(line,5,2)),#9,#9,"{date}",#9,"RCM port busy on datagate")
  @write(report,"")
  @write(report,"{lncd} {cascade} ,trim(copy(line,5,2))",#9,"{date}",#9,"RCM port busy on datagate")
  @return

@label RcmPortFree
  @inc(rcmCount)
  @set rcmCascade[{rcmCount}] = cascade
  @set rcmPort[{rcmCount}] = trim(copy(line,5,2))
  @set rcmPgs1 = trim(copy(line,34,6))
  @set rcmPgs[{rcmCount}] = rcmPgs1
  @close
  @comment("LRD {lncd} Cascade {rcmCascade[{rcmCount}]} Port {rcmPort[{rcmCount}]} PGS {rcmPgs[{rcmCount}]}")
  @write(logfile,"")
  @write(logfile,"LRD {lncd} Cascade {rcmCascade[{rcmCount}]} Port {rcmPort[{rcmCount}]} PGS {rcmPgs[{rcmCount}]}")
  @log(logfile)
  @delaysec(1)
  @return

@label StoreCascade                        @@ Store the cascade port
  @if pos("Busy",line) = 0 then goto CascadeFree
  @gosub GetDate
  @write(tabReport,"E007",#9,"{lncd}",#9,trim(copy(line,5,2)),#9,#9,#9,"{date}",#9,"Cascade port busy on datagate")
  @write(report,"")
  @write(report,"{lncd}",#9,trim(copy(line,5,2)),#9,"{date}",#9,"Cascade port busy on datagate")
  @return

@label CascadeFree
  @if pos(" TO ",line) = 0 then return        @@ ignore port without "TO" in line
  @inc(cascadeCount)
  @set cascadePort[{cascadeCount}] = trim(copy(line,5,2)
  @close
  @write(logfile,"")
  @write(logfile,"Storing cascade on port {cascadePort[{cascadeCount}]}")
  @comment("Storing cascade on port {cascadePort[{cascadeCount}]}")
  @log(logfile)
  @return

@label ScanCascade                         @@ Scan cascade menu for RCM
  @set cascade = trim(cascadePort[{cascadeCount}])
  @comment("Scanning port {cascade}")
  @close
  @write(logfile,"")
  @write(logfile,"Scanning port {cascade}")
  @log(logfile)
  @mark
  @send(cascade,#13)
  @waitfor("Option #",30)
  @set lineNumber = 1

@label ScanCascadeLoop
  @inc(lineNumber)
  @if lineNumber > 50 then goto ScanCascadeEnd
  @set line = reply(lineNumber)
  @if pos("Option #",line) <> 0 then goto ScanCascadeEnd
  @if pos("RCM ",line) = 9 then gosub StoreRcm
  @goto ScanCascadeLoop

@label ScanCascadeEnd
  @dec(cascadeCount)
  @send("0",#13)
  @waitfor("Option #",30)

! ----- The main menu has now been scanned, check cascades ----- !
@label MainMenuScanned
  @if cascadeCount > 0 then goto ScanCascade

! ----- The datagate menu has been scanned with list of RCM/CASCADE ----- !
@label DatagateScanned
  @set rcmIndex = 0

@label ConnectRcm
! The current variables are:
! lncd                             lrd code for current datagate
! datagatePointer                 points to current datagate
! datagateNumber                   total number of datagates
! datagate[{datagatePointer}]     current datagate lncd code
! rcmCount                        total rcm's found on datagate
! rcmIndex                        current rcm counter
! rcmCascade[{rcmIndex}]         cascade port for current rcm (0 for main)
! rcmPort[{rcmIndex}]            port for current rcm on main or cascade
! rcmPgs[{rcmIndex}]             pgs for current rcm
! error                            error status for polling
  @inc(rcmIndex)
  @if rcmIndex > rcmCount then send("0",#13)
  @if rcmIndex > rcmCount then delaysec(5)
  @if rcmIndex > rcmCount then goto DatagateLoop
  @set error = ""                          @@ start with no errors
  @if rcmCascade[{rcmIndex}] = "0" then goto CascadeConnected
  @set port = trim(rcmCascade[{rcmIndex}])
  @send(port,#13)
  @waitfor("Option #",30)

@label CascadeConnected
  @set port = trim(rcmPort[{rcmIndex}])
  @send(port,#13)
!                                                                     !
! ----- WE HAVE NOW CONNECTED TO THE RCM READY FOR THE ROUTINES ----- !
!                                                                     !
! If we have any problems at this point, we know where to return to   !
! and re-do the entire routine. The cascade & rcm number will change  !
! as we go, so they will not be repeated if successful.               !
! @windend                                                                    !
  @window
  @gosub GetDate
  @close
  @log(logfile)
  @set connection = concat(lncd,#9)
  @set connection = concat(connection,rcmCascade[{rcmIndex}])
  @set connection = concat(connection,#9)
  @set connection = concat(connection,rcmPort[{rcmIndex}])
  @set connection = concat(connection,#9)
  @set connection = concat(connection,rcmPgs[{rcmIndex}])
  @set connection = concat(connection,#9)
  @set connection = concat(connection,date)
  @set connection = concat(connection,#9)
  @set conDet = ("{lncd} {rcmCascade[{rcmIndex}]},{rcmPort[{rcmIndex}]} ")
  @set conDet = ("{conDet} {rcmPgs[{rcmIndex}]} {date}")

  @setdest("{lncd}{rcmPgs[{rcmIndex}]}")
  @comment("Connecting to Datagate at {lncd}, via cascade port {rcmCascade[{rcmIndex}]}")
  @comment("RCM port {rcmPort[{rcmIndex}]}  RCM PGS {rcmPgs[{rcmIndex}]}")
  @delaysec(5)
  @send(#13)
  @waitfor(">",10)
  @iferror then set error = "E002"
  @if length(error) < 2 then goto routine
  @write(tabReport,"E002",#9,connection,"Could not connect RCM")
  @write(report,"")
  @write(report,conDet," Could not connect RCM")


! ----- disconnect rcm port ----- !
@label DisconnectRcm
  @set name = ""
  @send("RECALL!!")
  @waitfor("Option #",30)
  @if rcmCascade[{rcmIndex}] <> "0" then send("0",#13)
  @if rcmCascade[{rcmIndex}] <> "0" then waitfor("Option #",30)
  @if schedule_b <> "Y" then goto ConnectRcm
  @if (rcmIndex + 1) > rcmCount then goto ConnectRcm

! ----- We will re-connect the datagate now to prevent timeout ----- !

  @gosub ReleaseNasi
  @goto DatagateConnection

@label routine

! ----- Start with local RCM ----- !
  @set name = concat(trim(copy(lncd,1,4)),trim(copy(rcmPgs[{rcmIndex}],1,4)))
  @set name = concat(name,".")
  @set name = concat(name,copy(rcmPgs[{rcmIndex}],5,2))
  @set name = concat(name,"E")
  @set alarm = ""
  @set message = ""
  @set reversals = "Reversals: "
  @set es = ""
  @set ses = ""
  @set dm = ""
  @gosub GetDate
  @write(report,conDet," Connected")
  @set back_OK = "No Backup"
  @set timer = ""
  @mark
  @send("LOC",#13)
  @waitfor(">",120)
  @iferror then set error = "E002"
  @if scan("NO CARRIER") then set error = "E003"
  @if scan("NASI") then set error = "E003"
  @if scan("Busy") then set error = "E004"
  @if length(error) > 1 then goto EndLocal
  @write(report,"{name} connected")
  @if schedule_a = "Y" then gosub AlarmCommand
  @if error = "E003" then goto EndLocal
  @if schedule_s = "Y" then gosub CrcCommand
  @if error = "E003" then goto EndLocal
  @set timer = ""
  @gosub GetDate
  @if schedule_r = "Y" then gosub CustCommand
  @gosub CheckTime
  @if schedule_r = "Y" then write(report,"Reversals{timer}")
  @set timer = ""
  @if length(error) > 1 then goto EndLocal
  @gosub GetDate
  @if schedule_b = "Y" then include(concat(dir0,"rcm\rcm_back.inc")
  @gosub CheckTime

@label EndLocal
  @gosub WriteReport
  @if error = "E003" then goto DatagateConnection

! ----- Now go to remote RCM ----- !
  @set name = concat(trim(copy(lncd,1,4)),trim(copy(rcmPgs[{rcmIndex}],1,4)))
  @set name = concat(name,".")
  @set name = concat(name,copy(rcmPgs[{rcmIndex}],5,2))
  @set name = concat(name,"R")
  @set alarm = ""
  @set message = ""
  @set reversals = "Reversals: "
  @set es = ""
  @set ses = ""
  @set dm = ""
  @set back_OK = "No Backup"
  @set timer = ""
  @send("REM",#13)
  @waitfor(">",120)
  @iferror then set error = "E002"
  @if scan("NO CARRIER") then set error = "E003"
  @if scan("NASI") then set error = "E003"
  @if scan("Busy") then set error = "E004"
  @if length(error) > 1 then goto EndRemote
  @write(report,"{name} connected")
  @if schedule_a = "Y" then gosub AlarmCommand
  @if error = "E003" then goto EndRemote
  @if schedule_s = "Y" then gosub CrcCommand
  @if error = "E003" then goto EndRemote
  @set timer = ""
  @gosub GetDate
  @if schedule_r = "Y" then gosub CustCommand
  @gosub CheckTime
  @if schedule_r = "Y" then write(report,"Reversals{timer}")
  @set timer = ""
  @if length(error) > 1 then goto EndRemote
  @gosub GetDate
  @if schedule_b = "Y" then include(concat(dir0,"rcm\rcm_back.inc")
  @gosub CheckTime
  @send("LOC",#13)
  @waitfor(">",30)
@label EndRemote
  @gosub WriteReport
  @goto DisconnectRcm
  @if error = "E003" then goto Releasenasi

! ----- Write line to connect.rep file ----- !
@label WriteReport
  @gosub GetDate
  @if ((length(alarm) > 1) and (length(error) < 2)) then set error = "E005"
  @if error = "E004" then set message = "RCM Busy"
  @if error = "E004" then write(report,"RCM Busy")
  @set line = concat(error,#9)
  @set line = concat(line,lncd)
  @set line = concat(line,#9)
  @set line = concat(line,rcmCascade[{rcmIndex}])
  @set line = concat(line,#9)
  @set line = concat(line,rcmPort[{rcmIndex}])
  @set line = concat(line,#9)
  @set line = concat(line,copy(name,5,8))
  @set line = concat(line,#9)
  @set line = concat(line,date)
  @set line = concat(line,#9)
  @if error = "E003" then set line = concat(line,"Carrier fail: ")
  @set back_OK = concat(back_OK,timer)
  @if (schedule_b = "Y") then set line = concat(line,back_OK)
  @if error = "E003" then write(report,"Carrier Fail {date}")
  @if (schedule_b = "Y") then write(report,back_OK)
  @if length(error) > 1 then set line = concat("{line} ",message)
  @comment(alarm)
  @if length(alarm) > 1 then set line = ("{line} {alarm}")
  @set line = concat(line,#9)
  @set line = concat(line,es)
  @set line = concat(line,#9)
  @set line = concat(line,ses)
  @set line = concat(line,#9)
  @set line = concat(line,dm)
  @set line = concat(line,#9)
  @set line = concat(line,reversals)
  @write(tabReport,line)
  @return



! ----- Release the NASI connection ----- !
@label ReleaseNasi
  @set direct = "YES"
  @set autofile = "YES"
  @set lrderror = ""
  @set finished = "HIDE"
  @mode("FD")
  @include(concat(dir0,"disconnt.cmd"))
  @return

! ----- Connect Datagate Modem ----- !
@label ConnectDatagate
  @set direct = "YES"
  @set autofile = "YES"
  @set lrderror = ""
  @set finished = "HIDE"
  @mode("FD")
  @include(concat(dir0,"connect.cmd"))
  @return

! ------ Get the current time and date ----- !
@label GetDate
  @getdate(now)
  @set year = copy(now,1,2)
  @set month = copy(now,3,2)
  @set day = copy(now,5,2)
  @set hour = copy(now,7,2)
  @set minute = copy(now,9,2)
  @set second = copy(now,11,2)
  @set date = ("{hour}:{minute} {day}/{month}/19{year}")
  @return

! ----- Get current alarms ----- !
@label AlarmCommand
  @mark
  @set error = ""
  @set alarm = ""
  @send("STAT",#13)
  @waitfor(">",120)
  @iferror then set error = "E002"
  @if scan("NO CARRIER") then set error = "E003"
  @if scan("NASI") then set error = "E003"
  @if length(error) > 1 then return
  @if scan("No Alarms") then write(report,"No Alarms")
  @if scan("No Alarms") then return
  @set lineNum = scan("STAT")

@label AlarmLoop
  @inc(lineNum)
  @set line = reply(lineNum)
  @if pos(">",line) <> 0 then return
  @if pos("REM Operation",line) <> 0 then goto AlarmLoop
  @set alarm = concat("{alarm} ",trim(line))
  @write(report,trim(line))
  @if lineNum > 10 then return
  @goto AlarmLoop

! ----- Get ES SES and DM values from CRC command. The clear with CLRC ----- !
@label CrcCommand
  @mark
  @set error = ""
  @set ses = ""
  @set dm = ""
  @set es = ""
  @send("CRC",#13)
  @waitfor(">",120)
  @iferror then set error = "E002"
  @if scan("NO CARRIER") then set error = "E003"
  @if scan("NASI") then set error = "E003"
  @if length(error) > 1 then return
  @set lineNum = scan("ES  =")
  @if lineNum > 0 then set line = trim(reply(lineNum))
  @if lineNum > 0 then set es = trim(line)
  @if lineNum > 0 then write(report,line)
  @set lineNum = scan("SES")
  @if lineNum > 0 then set line = trim(reply(lineNum))
  @if lineNum > 0 then set ses = trim(line)
  @if lineNum > 0 then write(report,line)
  @set lineNum = scan("DM")
  @if lineNum > 0 then set line = trim(reply(lineNum))
  @if lineNum > 0 then set dm = trim(line)
  @if lineNum > 0 then write(report,line)
  @send("CLRC",#13)
  @waitfor(">",120)
  @iferror then set error = "E002"
  @if scan("NO CARRIER") then set error = "E003"
  @if scan("NASI") then set error = "E003"
  @return

! ----- Check each channel for reversed lines ----- !
@label CustCommand
  @set error = ""
  @set reversals = "Reversals: "
  @set a = 0
@label ReversalLoop
  @inc(a)
  @if a > 30 then return
  @mark
  @set line = "CUST {a}"
  @set message = line
  @send(line,#13)
  @waitfor(">",120)
  @iferror then set error = "E002"
  @if scan("NO CARRIER") then set error = "E003"
  @if scan("NASI") then set error = "E003"
  @if length(error) > 1 then return
  @if scan("REV") then set reversals = concat(reversals,"{a} ")
  @if scan("REV") then set linePtr = scan("REV")
  @else goto ReversalLoop
  @set line = concat("{a} ",trim(reply(linePtr)))
  @write(report,line)
  @goto ReversalLoop



@label CheckTime                     @@ we already have start day,hour,minute
  @getdate(now)
  @set dayEnd = copy(now,5,2)
  @set hourEnd = copy(now,7,2)
  @set minuteEnd = copy(now,9,2)
  @set secondEnd = copy(now,11,2)
  @if day <> dayEnd then set hourEnd = hourEnd + 24   @@ adjst for next day
  @set startSecond = ((hour * 3600) + (minute * 60) + second)
  @set endSecond = ((hourEnd * 3600) + (minuteEnd * 60) + secondEnd)
  @set seconds = endSecond - startSecond
  @set hours = seconds / 3600
  @set seconds = seconds - (hours * 3600)
  @set minutes = seconds / 60
  @set seconds = seconds - (minutes * 60)
  @if length(hours) < 2 then set hours = concat("0",hours)
  @if length(minutes) < 2 then set minutes = concat("0",minutes)
  @if length(seconds) < 2 then set seconds = concat("0",seconds)
  @set timer = (" in {hours}:{minutes}:{seconds}")
  @return
