SUBROUTINE AF_DCOD ( cldt, pnvtbl, awptbl, bufrtb, nhours, + iret ) C************************************************************************ C* AF_DCOD * C* * C* This routine decodes aircraft bulletins into BUFR format. * C* * C* AF_DCOD ( CLDT, PNVTBL, AWPTBL, BUFRTB, NHOURS, IRET ) * C* * C* Input parameters: * C* CLDT CHAR* Date-time from command line * C* PNVTBL CHAR* PIREP navaids table * C* AWPTBL CHAR* AIREP waypoints table * C* BUFRTB CHAR* BUFR tables file * C* NHOURS INTEGER Max # of hours before run time * C* for creating BUFR output * C* * C* Output parameters: * C* IRET INTEGER Return code: * C* 0 = normal return. * C* * C** * C* Log: * C* J. Ator/NP12 09/96 * C* J. Ator/NP12 11/96 Decode bulletin day/hour from header * C* for AMDAR, add logic to decode RECCO * C* J. Ator/NP12 01/97 Create BUFR only for reports <= 5 days * C* old, reduce decoder log output * C* J. Ator/NP12 02/97 Reduce decoder log output * C* J. Ator/NP12 08/97 New interface format, style changes * C* J. Ator/NCEP 01/98 Remove BUFR output from decoder log * C* J. Ator/NCEP 03/98 Check ierbif before storing RECCO RPID * C* J. Ator/NCEP 04/98 AF_TMCK -> DC_TMCK * C* D. Kidwell/NCEP 10/98 Added intf mnemonics to call sequences * C* J. Ator/NCEP 12/98 Move init. of mbstr, lmbstr into code, * C* don't decode RECCO ID from 2nd hdr line * C* J. Ator/NCEP 04/99 Added AF_FARP for UAXX10 EGRR bulletins * C* J. Ator/NCEP 08/99 Moved irptr argument elsewhere * C* J. Ator/NCEP 07/00 Added check of iahday vs. ibuldt, * C* restructured some logic * C* J. Ator/NCEP 06/01 Use UT_WBFR, use 'NUL' in call to OPENBF* C* J. Ator/NCEP 08/04 SS_GTIM -> CSS_GTIM * C* J. Cahoon/NCEP 10/11 Added in HDOBB coverage * C************************************************************************ INCLUDE 'GEMPRM.PRM' INCLUDE 'BRIDGE.PRM' INCLUDE 'afcmn.cmn' C* CHARACTER*(*) cldt, pnvtbl, awptbl, bufrtb C* CHARACTER bull*(DCMXBF), bullx*(DCMXBF), report*(DCMXBF), + seqnum*8, buhd*8, cborg*8, bulldt*8, bbb*8, + rundt*12, sysdt*12, + rimnem(NRIMN)*8, cimnem(NCIMN)*8, + chcrid*8 C* REAL*8 GETBMISS C* INTEGER irundt (5), ibuldt (5), irptdt (5) C* LOGICAL bullok, rptok C----------------------------------------------------------------------- iret = 0 C C* Set the pointers for the interface arrays. C CALL AF_IFSP ( rimnem, cimnem, ierfsp ) IF ( ierfsp .ne. 0 ) THEN RETURN END IF C C* Read the PIREP navaids table. C CALL AF_PTOR ( pnvtbl, ierpto ) IF ( ierpto .ne. 0 ) THEN RETURN END IF C C* Read the AIREP waypoints table. C CALL AF_ATOR ( awptbl, ierato ) IF ( ierato .ne. 0 ) THEN RETURN END IF C C* Open the BUFR tables file. C CALL FL_SOPN ( bufrtb, iunbft, ierspn ) IF ( ierspn .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', ierspn, bufrtb, ierwlg ) RETURN END IF C C* Open the BUFR output file. C CALL FL_GLUN ( iunbfo, iergln ) IF ( iergln .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', iergln, ' ', ierwlg ) RETURN END IF C C* Connect the BUFR tables and output files to the C* BUFR interface. C CALL OPENBF ( iunbfo, 'NUL', iunbft ) r8bfms = GETBMISS() C C* Close the BUFR tables file. C CALL FL_CLOS ( iunbft, iercls ) IF ( iercls .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', iercls, ' ', ierwlg ) END IF C DO WHILE ( .true. ) C C* Get a new bulletin from the input pipe. C CALL DC_GBUL ( bull, lenb, ifdtyp, iergbl ) IF ( iergbl .ne. 0 ) THEN C C* A time-out occurred while waiting for a new bulletin C* on the input pipe. Shut down the decoder and exit. C CALL DC_WLOG ( 0, 'DC', iergbl, ' ', ierwlg ) CALL CLOSBF ( iunbfo ) CALL FL_CLAL ( iercal ) RETURN END IF bullok = .true. C C* Decode the header information from this bulletin. C IF ( ifdtyp .eq. 0 ) THEN C C* Decode WMO products. C CALL DC_GHDR ( bull, lenb, seqnum, buhd, cborg, + bulldt, bbb, ibptr, ierghd ) IF ( ierghd .ne. 0 ) THEN CALL DC_WLOG ( 2, 'DC', ierghd, ' ', ierwlg ) bullok = .false. ELSE C C* Start an entry for this bulletin in the decoder log. C logmsg = '####################' // + '####################' CALL DC_WLOG ( 2, 'AF', 1, logmsg, ierwlg ) logmsg = seqnum // buhd // cborg // bulldt // bbb CALL DC_WLOG ( 2, 'AF', 1, logmsg, ierwlg ) END IF ELSE C C* Do not decode AFOS products. C bullok = .false. END IF IF ( bullok ) THEN C C* What type of bulletin is this? C CALL AF_BLTP ( buhd, cborg, ierbtp ) IF ( bultyp .eq. LEMON ) THEN logmsg = 'Invalid bulletin' CALL DC_WLOG ( 2, 'AF', 1, logmsg, ierwlg ) bullok = .false. END IF END IF IF ( bullok ) THEN C C* Remove unprintable characters from this bulletin. C lenbxo = lenb - ibptr CALL ST_UNPR ( bull ( ibptr + 1 : lenb ), lenbxo, + bullx, lenbxn, ierunp ) lenbx = lenbxn ibxptr = 1 C C* Get the system time. C itype = 1 CALL CSS_GTIM ( itype, sysdt, iergtm ) IF ( iergtm .ne. 0 ) THEN CALL DC_WLOG ( 2, 'SS', iergtm, ' ', ierwlg ) bullok = .false. END IF END IF IF ( bullok ) THEN C C* If a date-time was entered on the command line, then C* use it as the run date-time. Otherwise, use the C* system time as the run date-time. C IF ( cldt .eq. 'SYSTEM' ) THEN rundt = sysdt ELSE CALL TI_STAN ( cldt, sysdt, rundt, ierstn ) IF ( ierstn .ne. 0 ) THEN CALL DC_WLOG ( 2, 'TI', ierstn, ' ', ierwlg ) bullok = .false. END IF END IF END IF IF ( bullok ) THEN C C* Convert the run date-time to integer. C CALL TI_CTOI ( rundt, irundt, iercto ) IF ( iercto .ne. 0 ) THEN CALL DC_WLOG ( 2, 'TI', iercto, ' ', ierwlg ) bullok = .false. END IF END IF IF ( bullok ) THEN C C* Get and decode the bulletin day, bulletin hour, and C* bulletin minute from the bulletin header. C CALL AF_OBDH ( bulldt, ibday, ibhr, ibmin, ierodh ) IF ( ierodh .ne. 0 ) THEN CALL UT_EMSG ( 2, 'AF_OBDH', ierodh ) bullok = .false. END IF END IF IF ( bullok ) THEN C C* Use the run date-time, bulletin day, bulletin hour, and C* bulletin minute to construct a bulletin date-time. C CALL DC_RTIM ( irundt, ibday, ibhr, ibmin, 10, ibuldt, + ierrtm ) IF ( ierrtm .ne. 0 ) THEN CALL UT_EMSG ( 2, 'DC_RTIM when computing ibuldt', + ierrtm ) bullok = .false. END IF END IF IF ( bullok ) THEN C C* Decode any extra information from the beginning of C* the bulletin. C CALL AF_XBIF ( bullx, lenbx, ibxptr, iahday, chcrid, + ihyear, ihmnth, ihhday, ierbif ) IF ( ierbif .ne. 0 ) THEN CALL UT_EMSG ( 2, 'AF_XBIF', ierbif ) bullok = .false. END IF END IF IF ( ( bullok ) .and. ( bultyp .eq. AMDAR ) ) THEN C C* Check that the AMDAR header day is within one day of C* the bulletin date-time. C CALL DC_RTIM ( ibuldt, iahday, 0, 0, 1, irptdt, + ierrtm ) IF ( ierrtm .ne. 0 ) THEN WRITE ( UNIT = logmsg, + FMT = '( A, I4.4, 4I2.2, 2A, I2.2 )' ) + 'ibuldt ', ( ibuldt (ii), ii = 1, 5 ), '; ', + 'iahday ', iahday CALL DC_WLOG ( 2, 'AF', 1, logmsg, ierwlg ) bullok = .false. END IF END IF C DO WHILE ( bullok ) C C* Get the next report from this bulletin. C IF ( ( buhd (1:6) .eq. 'UAXX10' ) .and. + ( cborg (1:4) .eq. 'EGRR' ) ) THEN C C* Reports within this bulletin do not end with '='. C CALL AF_FARP ( bullx, lenbx, ibxptr, + report, lenr, ierrpt ) ELSE IF ( bultyp .eq. HDOBB ) THEN CALL AF_HRPT ( bullx, lenbx, ibxptr, + report, lenr, ierrpt ) ELSE CALL AF_GRPT ( bullx, lenbx, ibxptr, + report, lenr, ierrpt ) END IF IF ( ierrpt .ne. 0 ) THEN C C* There are no more reports in this bulletin. C bullok = .false. C C* Make sure that all BUFR output for this bulletin C* has been written out before going back to DC_GBUL C* and waiting for a new bulletin on the input pipe. C CALL UT_WBFR ( iunbfo, 'aircraft', 1, ierwbf ) END IF IF ( bullok ) THEN CALL AF_IFIV ( ierifi ) C C* Write the report to the decoder log. C logmsg = '--------------------' CALL DC_WLOG ( 2, 'AF', 1, logmsg, ierwlg ) CALL DC_WLOG ( 2, ' ', 1, report (1:lenr), ierwlg ) C C* Based upon the bulletin type, decode the report. C IF ( bultyp .eq. AMDAR ) THEN CALL AF_DADR ( report, lenr, ieradr ) ELSE IF ( bultyp .eq. AIREP ) THEN CALL AF_DARP ( report, lenr, cborg, ierarp ) ELSE IF ( bultyp .eq. HDOBB ) THEN CALL AF_DHDO ( report, lenr, chcrid, ierhdo ) ELSE IF ( bultyp .eq. PIREP ) THEN CALL AF_DPRP ( report, lenr, ierprp ) ELSE IF ( bultyp .eq. RECCO ) THEN CALL AF_DRCO ( report, lenr, ierrco ) END IF rptok = .true. C C* Use the run date-time, bulletin date-time, report C* day (if it exists), report hour, and report minute C* to construct a report date-time unless HDOB then C* then use bulletin header info. C IF ( bultyp .eq. HDOBB ) THEN IF ( ( irpthr .eq. IMISSD ) .or. + ( irptmn .eq. IMISSD ) ) THEN rptok = .false. ELSE irptdt ( 1 ) = ihyear irptdt ( 2 ) = ihmnth irptdt ( 3 ) = ihhday irptdt ( 4 ) = INT ( rivals ( irhour ) ) irptdt ( 5 ) = INT ( rivals ( irminu ) ) rivals ( iryear ) = FLOAT ( ihyear ) rivals ( irmnth ) = FLOAT ( ihmnth ) rivals ( irdays ) = FLOAT ( ihhday ) END IF ELSE CALL AF_RTIM ( irundt, ibuldt, irptdt, ierrtm ) IF ( ierrtm .ne. 0 ) THEN rptok = .false. END IF END IF IF ( rptok ) THEN C C* Write data for this report to the decoder log. C CALL AF_IFPT ( rimnem, cimnem, ierfpt ) C C* Do not create BUFR output for reports that C* are more than NHOURS hours before or more than C* 90 minutes after the run time. C CALL DC_TMCK ( 2, irundt, irptdt, nhours, 90, + iertmk ) IF ( iertmk .eq. 0 ) THEN C C* Convert data for this report to BUFR format C* and then write it to the BUFR output file. C CALL AF_BUFR ( iunbfo, irundt, irptdt, + seqnum, buhd, cborg, bulldt, bbb, + report, lenr, ierbfr ) END IF END IF END IF END DO C END DO C* RETURN END