SUBROUTINE MA_DCOD ( curtim, stntblm, stntblt, + bufrtb, rshpfl, nhours, iret ) C************************************************************************ C* MA_DCOD * C* * C* This subroutine reads bulletins containing marine reports in WMO * C* FM13 format, decodes the report data, and create BUFR output from * C* the decoded data. * C* * C* MA_DCOD ( CURTIM, STNTBLM, STNTBLT, BUFRTB, RSHPFL, NHOURS, IRET ) * C* * C* INPUT PARAMETERS: * C* CURTIM CHAR* Date/time from command line * C* STNTBLM CHAR* Surface marine station table * C* STNTBLT CHAR* Tide gauge station table * C* BUFRTB CHAR* BUFR tables file * C* RSHPFL CHAR* List of WMO bulletins which * C* contain restricted ship data * C* NHOURS INTEGER Max number of hours before run * C* time for creating BUFR output * C* * C* Output parameters: * C* IRET INTEGER Return code * C* 0 = Normal return * C* * C** * C* Log: * C* R. Hollern/NCEP 6/96 * C* R. Hollern/NCEP 2/97 Added code to display program version * C* number in LOG file * C* K. Tyle/GSC 4/97 Cleaned up * C* D. Kidwell/NCEP 4/97 Changed interface * C* K. Tyle/GSC 5/97 Additional error logging * C* D. Kidwell/NCEP 10/97 New interface, cleaned up, merged MADBLT* C* R. Hollern/NCEP 12/97 Removed GEMPAK calls, Added BUFR calls * C* R. Hollern/NCEP 1/98 Added code to close BUFR files * C* R. Hollern/NCEP 8/98 Added the version number to log file * C* R. Hollern/NCEP 1/99 Renamed INCLUDE block ma.bufr.prm to * C* mabufr.cmn * C* R. Hollern/NCEP 12/99 Made a major revision to the program by * C* removing the code which processes * C* drifting buoy reports. * C* R. Hollern/NCEP 3/00 Modified routine to make it conform to * C* the standards for the NWS/IWT decoders. * C* C. Caruso Magee/NCEP 06/01 Replace calls to STATUS, WRITSA, and * C* DBN_BUFR with new s/r UT_WBFR. * C* C. Caruso Magee/NCEP 02/02 Replace orign with cborg. * C* J. Ator/NCEP 08/04 SS_GTIM -> CSS_GTIM * C* C. Caruso Magee/NCEP 03/05 Add code to read tide gauge station tbl.* C* C. Caruso Magee/NCEP 04/08 Change code so that KWNB and KWBC are * C* the only originators we'll accept SXUS20* C* bulletins from. * C* J. Ator/NCEP 07/09 Added rshpfl argument and processing * C* M. Weiss/IMSG 05/18 Added 22 stations to msfc.tbl * C************************************************************************ INCLUDE 'GEMPRM.PRM' INCLUDE 'BRIDGE.PRM' INCLUDE 'macmn.cmn' INCLUDE 'macmn_bufr.cmn' C* CHARACTER*(*) curtim, stntblm, stntblt, bufrtb, rshpfl C* INTEGER istarr(5) C CHARACTER bulltn*(DCMXBF), sysdt*12, dattmp*12, + errstr*80, marrpt*(DCMXBF), + icmand*5, cmdif*8, cdate*8, ctime*4, cdattm*15, + rimnem ( NRIMN )*8, cimnem ( NCIMN )*8 C LOGICAL more, good, ibufr, last C DATA last / .false. / C----------------------------------------------------------------------- iret = 0 C C* Open, read, and close the file of restricted bulletin headers. C CALL FL_TBOP ( rshpfl, 'rshp', irshpfl, iertop ) IF ( iertop .ne. 0 ) THEN CALL DC_WLOG ( 0, 'FL', iertop, rshpfl, ierr ) RETURN END IF C iostat = 0 nrshpb = 0 DO WHILE ( ( nrshpb .lt. MXRSHPB ) .and. ( iostat .eq. 0 ) ) READ ( irshpfl, FMT = '(A)', IOSTAT = iostat ) + crshpb ( nrshpb + 1 ) IF ( iostat .eq. 0 ) THEN nrshpb = nrshpb + 1 END IF END DO C CALL FL_CLOS ( irshpfl, iercls ) C C* Open and read the surface marine station table file. C CALL MA_MTOR ( stntblm, iermat ) C C* Open and read the tide gauge station table file. C CALL MA_TTOR ( stntblt, iertgt ) C C* Exit if there was a problem opening or reading either of the C* station tables. C IF ( ( iermat .ne. 0 ) .or. ( iertgt .ne. 0 ) ) THEN RETURN END IF C C* Set the pointers for the interface arrays. C CALL MA_IFSP ( rimnem, cimnem, ier ) IF ( ier .ne. 0 ) THEN CALL DC_WLOG ( 0, 'DCMSFC', -8, ' ', ierr ) RETURN END IF C C* Loop until a timeout occurs. C iperr = 0 ibufr = .false. C DO WHILE ( iperr .eq. 0 ) C C* Get the bulletin. C CALL DC_GBUL( bulltn, lenb, ifdtyp, iperr ) IF ( iperr .eq. 0 ) THEN C C* Parse the header info from the bulletin. C more = .true. CALL DC_GHDR ( bulltn, lenb, seqnum, buhd, cborg, + btime, bbb, nchrd, ierr ) IF ( ierr .ne. 0 ) THEN CALL DC_WLOG ( 2, 'DC', ierr, ' ', ier ) CALL ST_UNPR ( bulltn(:72), 72, errstr, len1, ier ) CALL DC_WLOG ( 2, 'DCMSFC', 2, errstr, ier ) more = .false. ELSE IF ( ( buhd (1:6) .eq. 'SXUS20' ) .and. + ( cborg(1:4) .ne. 'KWBC' ) .and. + ( cborg(1:4) .ne. 'KWNB' ) ) THEN C C* Reject SXUS20 bulletin if originator is anything other C* than KWBC or KWNB. C CALL DC_WLOG ( 4, 'DC', ierr, ' ', ier ) CALL ST_UNPR ( bulltn(:72), 72, errstr, len1, ier ) CALL DC_WLOG ( 4, 'DCMSFC', 2, errstr, ier ) more = .false. END IF ELSE C C* Write out timeout message to the log. C CALL DC_WLOG ( 0, 'DC', iperr, ' ' , ier ) more = .false. END IF IF ( more ) THEN C C* Get the system time, and make a standard GEMPAK time C* from the "current" time. C itype = 1 CALL CSS_GTIM ( itype, sysdt, ier ) IF ( curtim .eq. 'SYSTEM' ) THEN dattmp = sysdt ELSE CALL TI_STAN ( curtim, sysdt, dattmp, ier ) END IF CALL TI_CTOI ( dattmp, istarr, ier ) C C* Set receipt time significance to 0. C rctim (1) = 0.0 C C* Save receipt time in macmn.cmn. C DO i = 1, 5 rctim ( i+1 ) = FLOAT ( istarr ( i ) ) END DO C C* Remove control characters from bulletin. C CALL ST_UNPR ( bulltn, lenb, bulltn, lennew, ier ) lenb = lennew C IF ( lenb .ge. 60 ) THEN C C* Get bulletin type -- BBXX or CMAN C CALL MA_BTYP ( lenb, bulltn, jpos, icmand, jret ) IF ( ibrtyp .ge. 1 .and. ibrtyp .le. 2 ) THEN C C* Write bulletin header data to decoder log. C logmsg = seqnum // buhd // cborg // btime // bbb CALL DC_WLOG (2, 'DCMSFC', 2, logmsg(1:36),ier) ELSE more = .false. END IF ELSE C C* Reject bulletins less than 60 characters long. C more = .false. END IF END IF C C* Loop through reports. C DO WHILE ( more ) good = .true. C C* Get next report from bulletin. C CALL MA_GRPT ( lenb, bulltn, jpos, mszrpt, marrpt, jret) C nszrpt = mszrpt C IF ( jret .eq. 2 ) THEN C C* No more reports in bulletin. C 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 IF ( ibufr ) THEN C CALL UT_WBFR ( iunbfo, 'msfc', 1, ierwbf ) C ENDIF C more = .false. good = .false. ELSE IF ( jret .ne. 0 ) THEN good = .false. ELSE C C* Write raw report to LOG file. C isz = MIN ( 40, mszrpt ) loglvl = 2 CALL DC_WLOG ( loglvl, ' ', 1, marrpt ( 1:isz ), + ierwlg ) C C* Initialize report parameters to missing. C CALL MA_IFIV ( jret ) CALL MA_INIT ( jret ) C C* Set igrsz to the maximum number of characters C* allowed for any individual group in this report. C IF ( ibrtyp .eq. 1 ) THEN igrsz = 6 ELSE igrsz = 8 END IF C C* Check length of groups in report. C CALL MA_CKRP ( marrpt, igrsz, mszrpt, kret) IF ( kret .ne. 0 ) THEN good = .false. ELSE IF ( ibrtyp .eq. 1 ) THEN C C* Decode section 0 of BBXX report. C CALL MA_BST0 ( marrpt, istarr, ipt, jret ) ELSE IF ( ibrtyp .eq. 2 ) THEN C C* Decode section 0 of CMAN report. C* Set flag that report is from US or Canada. C iflgco = 1 CALL MA_CST0 ( marrpt, istarr, icmand, ipt, + jret) END IF IF ( jret .ne. 0 ) good = .false. END IF END IF C IF ( good ) THEN C C* Compute difference between observation C* and system times. C CALL TI_MDIF ( irptdt, istarr, imdif, ier1) C C* Check that the time is within NHOURS before the C* system time. C C* Report time for BUFR must not be more than nhours C* before the system time, and not more than C* 60 minutes after. C IF ( ( ier1 .ne. 0 ) .or. ( imdif .gt. 60 ) + .or. ( imdif .lt. -60 * nhours ) ) THEN good = .false. errstr = buhd // cborg // btime CALL DC_WLOG ( 2, 'DCMSFC', 3, errstr, ier ) CALL ST_INCH ( imdif, cmdif, ier ) idate = irptdt(1) * 10000 + irptdt(2) * 100 + + irptdt(3) itime = irptdt(4)*100 + irptdt(5) CALL ST_INCH ( idate, cdate, ier ) CALL ST_INCH ( itime, ctime, ier ) cdattm = cdate(3:) // '/' // ctime errstr = cdattm // dattmp // cmdif CALL DC_WLOG ( 2, 'DCMSFC', 4, errstr, ier ) C END IF C IF ( good ) THEN C C* Decode the bulletin report and write the data C* to the output file. C IF ( ibrtyp .eq. 1 .or. ibrtyp .eq. 2 ) THEN CALL MA_DCD1 ( mszrpt, marrpt, ipt, jret ) END IF C C* Output decoded report. C IF ( jret .eq. 0 ) THEN C C* Output decoded report to LOG file C loglvl = 3 logmsg ='<-----BEGIN INTERFACE OUTPUT----->' CALL DC_WLOG ( loglvl, 'DC', 2, + logmsg (1:50), ierwlg ) C C C* Print the raw report. C CALL DC_WLOG ( loglvl, 'DC', 2, + 'RAW REPORT:', ierw ) DO i = 1, mszrpt, 50 msz = MIN ( mszrpt, i+49 ) CALL DC_WLOG ( loglvl, 'DC', 2, + marrpt ( i:msz ), ierw ) END DO C CALL MA_IFPT ( rimnem, cimnem, ierr ) C logmsg = '<-----END INTERFACE OUTPUT----->' CALL DC_WLOG ( loglvl, 'DC', 2, + logmsg (1:50), ierwlg ) C C* Convert current report data to BUFR format C CALL MA_BUFR( bufrtb, last, marrpt, + mszrpt, jret ) ibufr = .true. END IF END IF END IF END DO END DO C C* Close BUFR files C IF ( ibufr ) THEN last = .true. CALL MA_BUFR( bufrtb, last, marrpt, mszrpt, jret ) END IF C* RETURN END