;+
; Project     : SOHO - CDS     
;                   
; Name        : RD_ENG_PKT
;                                                      
; Purpose     : Read and load Eng A/B packet in tm file. 
;
; Explanation : Reads a packet in a telemetry file, checks the ID for values 
;               which indicate an engineering A or B packet.  Loads the 
;               data structures when these packets are seen. Can be used for
;               realtime or replay mode.
;               
; Use         : Called by EMON_ERROR, EMON_RELAYS etc.
;    
; Inputs      : None
;
; Opt. Inputs : None
;               
; Outputs     : status - equals A or B if read OK, equals '' otherwise
;               time   - time associated with this packet
;               data   - array of data for the parameters
;
;               Other items are communicated in common block
;
; Opt. Outputs: None
;               
; Keywords    : RT - indicates program is in realtime mode
;               A  - means read ONLY Eng A packets
;               B  - means read ONLY Eng B packets
;
; Calls       :
;
; Common      : emon_err.com
;               
; Restrictions: Needs the common block communication.
;               
; Side effects: None
;               
; Category    : Telemetry
;               
; Prev. Hist. : None
;
; Written     : Originally LOOK_4_ERROR, C D Pike, RAL, 8-Mar-95
;               
; Modified    : 
;
; Version     : Version 1, 21-Aug-95
;-            

pro rd_eng_pkt, status, time, data, rt=rt, a=a, b=b

;
;  common for variables
;
@emon_err.com

;
;  array for raw packet data
;
packet=bytarr(306)


;
;  trap i/o errors
;
on_ioerror, err_finish

;
;  which packets A/B?
;
mode = 3
if keyword_set(a) then mode = 1
if keyword_set(b) then mode = 2


;
;  read the file looking for eng packets
;
read_packet:

readu, eng_lun, packet

case  1 of
        (packet(18) eq '0A'x) and (mode eq 1 or mode eq 3): begin
                        load_eng_a, packet, mask, enga, select=wanted_parms
                        load_eng_parms, wanted_parms, enga, time, data
                        status = 'A'
           end

        (packet(18) eq '0B'x) and (mode eq 2 or mode eq 3): begin
                        load_eng_b, packet, mask, engb, select=wanted_parms
                        load_eng_parms, wanted_parms, engb, time, data
                        status = 'B'
           end
         else: status = 'N'
endcase

return

;
;  handle i/o error (hopefully end-of-file)
;
err_finish:

if not keyword_set(rt) then begin

   free_lun, eng_lun
;
;  if there are more files, get the next one
;

   if file_seq_no lt (num_data_files-1) then begin
      file_seq_no = file_seq_no + 1
      openr, eng_lun, tmfiles(file_seq_no), error=err, /get_lun
;
;  the end because of open error, so tidy up and quit
;
      if err ne 0 then begin
         reading = 0
         status = ''
         return
      endif
      goto, read_packet  ; sorry!

   endif else begin
;
;  it really is the end so tidy up and quit
;
      reading = 0
      status = ''
      return
   endelse

endif else begin

;
;  Realtime mode
;

   pkt_read = packet_no + start_pack  
;
;  is it worth trying again? A 10 second timeout is allowed
; 
   waited = 0
   pkt_avail = 0
   while ((pkt_avail - pkt_read) lt 1) and (waited lt 20) do begin
      wait,0.5
      waited = waited + 1
      tm_size = tm_get_size(tmfiles)
      pkt_avail = tm_size/306L
   endwhile

;
;  time out? then probably onto new file
;  if error reading new file or new file is in fact same as old file
;  (ie haven't switched tm files) then treat as unrecoverable error.
;
   if waited eq 20 then begin
      old_file = tmfiles
      free_lun,eng_lun
      tmfiles = concat_dir('$CDS_TM_DATA',gt_rt_file())
      print,'searching for new file ',tmfiles
      if tmfiles eq old_file then begin
         bell
         print,'Fatal error on realtime read.'
         return
      endif
      openr,eng_lun,tmfiles,/get_lun,error=err
      if err ne 0 then begin
         print,'Error opening new realtime file.'
         return
      endif else begin
         start_pack = 0
         packet_no = 0
         goto, read_packet
      endelse        
   endif else begin
;
;  ok more packets have appeared, make sure of file positioning
;  and try again
;
      point_lun, eng_lun, long(pkt_read)*306L
      goto, read_packet
   endelse

endelse

end
