[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: 19991202: pqsurf SYN date code problem
- Subject: Re: 19991202: pqsurf SYN date code problem
- Date: Thu, 2 Dec 1999 16:28:28 -0700 (MST)
Art,
It was a bug in pqsurf/surf_split.c, line 33 should be:
set_dtime(time, YY, GG, 0);
I'll attach surf_split.c.
Robb...
On Thu, 2 Dec 1999, Arthur A. Person wrote:
> Rob,
>
> On Thu, 2 Dec 1999, Robb Kambic wrote:
>
> > I don't know for sure what the product ID's look like in pqsurf. Could you
> > enter a command in pqsurf.conf like
> >
> > WMO ^(...... .... ......)
> > EXEC /bin/touch data/IDs/\1
> >
> > This will show the product ID's, then it will be able to check if your
> > pqsurf.conf entries are correct or there is a problem with pqsurf. I
> > suspect that your pqsurf.conf entries need to be changed.
>
> Here's the pqsurf.conf entry that worked:
>
> WMO ^(.*)
> EXEC /bin/touch "data/IDs/\1"
>
> and here's some output. The aaxx and bbxx stuff all have 0202mm while the
> rest have 0217mm.
>
> aaxx 24507 020212 CCA
> aaxx 44203 020215 RRC
> aaxx 44207 020215 RRC
> aaxx 44218 020215 RRC
> aaxx 44230 020215 RRC
> aaxx 44265 020215 RRC
> aaxx 93004 020217
> aaxx 93023 020217
> aaxx 93069 020217
> aaxx 93110 020217
> aaxx 93186 020217
> aaxx 93196 020217
> aaxx 93245 020217
> aaxx 93292 020217
> aaxx 93305 020217
> aaxx 93309 020217
> aaxx 93334 020217
> aaxx 93373 020217
> aaxx 93404 020217
> aaxx 93420 020217
> aaxx 93439 020217
> aaxx 93498 020217
> aaxx 93515 020217
> aaxx 93527 020217
> aaxx 93546 020217
> aaxx 93597 020217
> aaxx 93615 020217
> aaxx 93678 020217
> aaxx 93709 020217
> aaxx 93773 020217
> aaxx 93781 020217
> aaxx 93781 020217
> aaxx 93800 020217
> aaxx 93805 020217
> aaxx 93831 020217
> aaxx 93845 020217
> aaxx 93896 020217
> aaxx 93909 020217
> aaxx 93929 020217
> aaxx 93947 020217
> aaxx 93987 020217
> aaxx 93994 020217
> aaxx 94120 020217 RRE
> aaxx 94150 020217 RRB
> aaxx 94238 020217 RRC
> aaxx 94326 020217 RRF
> aaxx 95322 020217 RRD
> bbxx 46061 020217 RRD
> bbxx 46132 020217
> bbxx 46181 020217
> bbxx 46185 020217
> bbxx 46204 020217
> bbxx 46207 020217
> bbxx 46208 020217
> metar BIKF 021700 RRA
> metar EGAE 021720 RRB
> metar EGHH 021720 RRB
> metar EGMC 021720 RRB
> metar EGNH 021720 RRB
> metar EGNJ 021720 RRB
> metar EGPE 021720 RRB
> metar EGPN 021720 RRB
> metar EGPO 021720 RRB
> metar EGPO 021720 RRB
> metar EGSH 021720 RRB
> metar EHDL 021720 RRB
> metar EHEH 021720 RRB
> metar EHGR 021720 RRB
> metar EHKD 021720 RRB
> metar EHLW 021720 RRB
> metar EHSB 021720 RRB
> metar EHTW 021720 RRB
> metar EHVB 021720 RRB
> metar EICK 021730 RRB
> metar EIDW 021730 RRA
> metar EIKN 021730
> metar EINN 021730 RRC
> metar ENAL 021720 RRB
> metar ENCN 021720 RRB
> metar ENHD 021720 RRB
> metar ENRY 021720 RRB
> metar ENTC 021720 RRB
> metar ESOK 021720 RRA
> metar HKNA 021700 RRA
> metar K3HT 021500 CCI
> metar K3HT 021700 RRG
> metar KADU 021731
> metar KAFJ 021736
> metar KAIO 021730
> metar KAIZ 021736
> metar KALM 021733
> metar KANW 021735
> metar KAPF 021736
> metar KARG 021736
> metar KATS 021733
> metar KATS 021733
> metar KAUH 021735
> metar KAUO 021736
> metar KAWG 021730
> metar KAXA 021730
> metar KBCB 021730
> metar KBHB 021736
> metar KBID 021736
> metar KBIE 021733
> metar KBJI 021736
> metar KBKX 021736
> metar KBLM 021735
> metar KBNW 021730
> metar KBTP 021736
> metar KBVX 021736
> metar KCAV 021730
> metar KCBF 021731
> metar KCCY 021730
> metar KCGZ 021736
> metar KCIN 021730
> metar KCIU 021736
> metar KCNC 021730
> metar KCSQ 021730
> metar KDEH 021731
> metar KDNS 021730
> metar KEBS 021731
> metar KEOK 021731
> metar KFAT 021700 RRC
> metar KFET 021733
> metar KFFL 021730
> metar KGEG 021700 RRC
> metar KHDE 021733
> metar KHDE 021733
> metar KICL 021731
> metar KIKV 021731
> metar KLRJ 021731
> metar KLXN 021733
> metar KMCC 021733
> metar KMSV 021735
> metar KMUT 021730
> metar KMXO 021730
> metar KOGA 021733
> metar KOLZ 021731
> metar KONL 021733
> metar KORC 021730
> metar KOXV 021731
> metar KPIR 021700 RRM
> metar KRDK 021730
> metar KSDA 021730
> metar KSGF 021700 RRC
> metar KSHL 021731
> metar KSLB 021731
> metar KSRR 021735
> metar KSVC 021735
> metar KTNU 021731
> metar KVDI 021735
> metar KWWD 021735
> metar LFBD 021730
> metar LFBO 021730
> metar LFKB 021730
> metar LFKJ 021730
> metar LFLL 021730
> metar LFML 021730
> metar LFMN 021730
> metar LFMN 021730
> metar LFPB 021730
> metar LFPG 021730
> metar LFPO 021730
> metar LFSB 021730
> metar LGAD 021720 RRA
> metar LGAL 021720 RRA
> metar LGAT 021720 RRA
> metar LGEL 021720 RRA
> metar LGKL 021720 RRA
> metar LGKO 021720 RRA
> metar LGKR 021720 RRA
> metar LGLM 021720 RRA
> metar LGMT 021720 RRA
> metar LGPZ 021720 RRA
> metar LGRP 021720 RRA
> metar LGRX 021720 RRA
> metar LGSA 021720 RRA
> metar LGSM 021720 RRA
> metar LGTS 021720 RRA
> metar LHBP 021730
> metar LHBP 021730 CCA
> metar LPFR 021730
> metar LPPR 021730
> metar LPPT 021730
> metar MTPP 021700
> metar NZCM 021700 RRC
> metar PKMJ 021600
> metar RKSS 021730
> metar SARL 021700 RRB
> metar SARP 021700 RRD
> metar SBGL 021700 RRB
> metar SBGL 021700 RRB
> metar SBRF 021700 RRB
> metar SBTT 021700 RRB
> metar SBUG 021700 RRE
> metar SEQU 021700 RRC
> metar UMMS 021730
> metar YPAD 021700 RRB
> metar YPAD 021700 RRD
> sao SA WHP 021731
> sao SA WHY 021700 RRC
> sao SA WIA 021700 RRC
> sao SA WIG 021700 RRC
> sao SA WIP 021700 RRC
> sao SA WIU 021700 RRC
> sao SA WNL 021729
> sao SA WQS 021728
> sao SA WZO 021700 RRC
> sao SA XDE 021700 RRD
> sao SA XHF 021700 RRD
> sao SA XTV 021700 RRD
> speci CWUW 021729
> speci CYGQ 021725
> speci CYGR 021731
> speci CYKL 021731
> speci CYOW 021729
> speci CYOW 021732
> speci CYQT 021732
> speci CYUT 021726 CCA
> speci CYWA 021729
> speci CZBF 021728
> speci KAPC 021733
> speci KBNO 021731
> speci KCSM 021731
> speci KDEW 021730
> speci KFAT 021731
> speci KGEG 021733
> speci KINK 021731
> speci KINK 021732
> speci KKLS 021733
> speci KLKV 021730
> speci KLKV 021732
> speci KLKV 021733
> speci KRND 021730
> speci KSGF 021733
> speci KSSC 021730
> speci KWRL 021732
> speci PACD 021732
> speci PACD 021734
> speci PAEN 021731
> speci PHHI 021733
> speci PHHI 021734
> speci PHLI 021730
> speci PHLI 021732
> speci RJSM 021731
> speci SARE 021731
> speci SEQU 021731
>
>
> Art.
>
> Arthur A. Person
> Research Assistant, System Administrator
> Penn State Department of Meteorology
> email: address@hidden, phone: 814-863-1563
>
===============================================================================
Robb Kambic Unidata Program Center
Software Engineer III Univ. Corp for Atmospheric Research
address@hidden WWW: http://www.unidata.ucar.edu/
===============================================================================
/*
* Copyright 1993, University Corporation for Atmospheric Research
* See ../COPYRIGHT file for copying and redistribution conditions.
*/
/* $Id: surf_split.c,v 1.30 1999/12/02 23:21:26 rkambic Exp $ */
#include <ldmconfig.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "ldm.h"
#include "ulog.h"
#include "wmo_header.h"
#include "tokens.h"
#include "xbuf.h"
#include "surface.h" /* wind_units_t, CALL_SIGN_LEN */
#include "md5.h"
static double md5ctx[16]; /* 88 would be big enough */
static MD5_CTX *md5ctxp = (MD5_CTX *)md5ctx;
static int
get_yygg(xbuf *buf, dtime *time)
{
int status;
int YY = -1;
int GG = -1;
if((status = dget_wnum(buf, &YY, 2)) < 0) return status;
if((status = dget_num(buf, &GG, 2)) < 0) return status;
set_dtime(time, YY, GG, 0);
return status;
}
/* For METAR, check if the HHMMZ time string is present */
static int
whas_yyggZ(xbuf *buf)
{
int ch;
/* skip white space */
do{
ch = nextc(buf);
}while((isascii(ch) && !isgraph(ch)));
unnextc(buf,ch);
if(buf->cnt < 5)
return 0; /* not enough characters */
if(buf->get[4] != 'Z'
|| !isdigit(buf->get[3])
|| !isdigit(buf->get[2])
|| !isdigit(buf->get[1])
|| !isdigit(buf->get[0]))
return 0;
return 1; /* passed */
}
/* For METAR, check if "NIL" */
static int
has_NIL(xbuf *buf)
{
char nilstr[] = "NIL";
char *np = (char *)&buf->base[buf->bufsiz - 1 - (sizeof(nilstr) -1 -1)];
if(strncmp(np, nilstr, sizeof(nilstr) -1) == 0)
return 1;
return 0;
}
/* For METAR, get the bulletin time, if possible */
static void
get_wyyggZ(xbuf *buf, dtime *time)
{
int ch;
if(!whas_yyggZ(buf))
return;
(void)get_yygg(buf, time);
ch = nextc(buf); /* eat the 'Z' */
return;
}
/*
* Takes a WMO format product which is a
* SAO, SYNOP, SHIP, METAR, or SPECI message, splits it into
* individual observations. The observations are each encapsulated in a
* new product which inherits most of its description from the
* original product.
* The new product pkey is derived from the observation type
* and has the following form:
*
* SAO - "sao tt ccc ddhhmm"
* where:
* tt is SA, SP or RS
* ccc is the station ID like SFO, LXV, etc
* ddhhmm is the time stamp.
*
* SYNOP - "aaxx nnnnn ddhhmm"
* where:
* nnnnn is the WMO station id (5 digit number)
*
* SHIP - "bbxx c* ddhhmm"
* where:
* c* is the call sign
*
* METAR - "metar cccc ddhhmm"
* where:
* cccc is the call sign
*
* SPECI - "speci cccc ddhhmm"
*
* The new product sequence number is original sequence number times 1000
* plus the sequence of the individual observation within the product.
*
* 'doit' is called on each of the new products. It is presumed
* this function return zero upon success.
*
* Returns the number of successful calls to 'doit', eg, the
* number of splits. Returns -1 on error.
*/
int
surf_split(const prod_info *infop, const void *datap,
int (*doit)(const prod_info *, const void *))
{
int action = -1;
wmo_header_t hdr;
message_type_t mtype;
dtime dt;
xbuf buf[1];
unsigned char dbuf[8192]; /* TODO */
int nsplit = 0;
enum {
SURFACE_BOGUS ,
AAXX,
US_AAXX,
BBXX,
SAO,
sMETAR,
sSPECI
} subtype = SURFACE_BOGUS;
hdr.time = &dt;
if(infop->sz > sizeof(dbuf))
return -1; /* TODO: too big */
memcpy(dbuf, datap, infop->sz);
if( cbuftoxbuf(buf, (unsigned char *)dbuf,
infop->sz) == NULL)
return -1;
skipline(buf, 4); /* SOH */
skipline(buf, 12); /* start */
if( get_wmo_header(buf, &hdr) == NULL)
{
return -1;
}
#if DEBUG
fputs("\t", stderr);
fprint_wmo_header(stderr, &hdr);
fputs("\n", stderr);
#endif
mtype = decode_type(hdr.TT,hdr.AA);
/* #### */
{
char cbuf[8];
int digit;
dtime time;
wind_units_t wind_units = WIND_UNAVAIL;
time = *hdr.time; /* default the ob time to the time in the header */
/* delve into section 0 */
switch(mtype) {
case SYNOP :
if(get_wstr(buf, cbuf, 1) < 0 ) return -1;
if(cbuf[0] == 'A')
{
subtype = AAXX;
if(get_str(buf, &cbuf[1], 3) < 0 ) return -1;
if( cbuf[3] != 'X' )
{
/* punt */
uerror("surface_split: Unknown type: %s\n",
cbuf);
return 0;
}
if(get_yygg(buf, &time) < 0 ) return -1; /* YYGG */
if(dget_num(buf, &digit, 1) < 0 ) return -1; /* isubw */
if(digit >= 0 && digit <= 4) wind_units =
(wind_units_t)digit;
}
else if(isascii(cbuf[0]) && isdigit(cbuf[0])) /* US Stations
7NNNN */
{
unnextc(buf,cbuf[0]);
subtype = US_AAXX;
/*
* Some US reports leave off AAXX YYGGisubw, so we use
the
* time from the wmo header.
*/
wind_units = KNOTS;
}
else
{
unnextc(buf,cbuf[0]);
return 0; /* ?? */
}
break;
case SHIP :
if(get_wstr(buf, cbuf, 4) < 0 ) return -1;
if(cbuf[0] == 'B')
{
if( cbuf[3] != 'X' )
{
/* punt */
uerror("surface_split: Unknown type: %s\n",
cbuf);
return 0;
}
subtype = BBXX;
/* get time below */
}
else
{
unnextc(buf,cbuf[0]);
return 0;
}
break;
case METAR :
if(whasSTR(buf, "METAR"))
{
subtype = sMETAR;
get_wyyggZ(buf, &time);
}
else
subtype = SAO; /* may actually be a METAR, check below
*/
break;
case SPECI :
if(whasSTR(buf, "SPECI"))
{
subtype = sSPECI;
get_wyyggZ(buf, &time);
}
break;
default :
uerror("surface_split: Can't handle %s",
sMessage_type(mtype) );
return -1;
}
{ /* while block */
static char newkey[KEYSIZE];
xbuf subbuf[1];
prod_info newinfo = *infop;
#define MAX_SURF_LEN 511
#undef MIN
#define MIN(a,b) ((a) <= (b) ? (a) : (b))
char pbuf[MAX_SURF_LEN + 1];
int l1, l2;
static char ident[CALL_SIGN_LEN+1];
static char type[4];
u_int subseq = infop->seqno * 1000;
unsigned char *pp;
while( get_weqxbuf(buf, subbuf) > 0 )
{
(void)memset(newkey,0,KEYSIZE);
(void)memset(pbuf,0,MAX_SURF_LEN + 1);
(void)memset(ident,0,CALL_SIGN_LEN+1);
pp = subbuf->base;
switch(subtype) {
case AAXX :
case US_AAXX :
strcpy(newkey, "aaxx ");
strcpy(pbuf, "AAXX");
sprintf(&pbuf[strlen(pbuf)], " %02d%02d%1d\r\r\n",
time.mday, time.hour, (int)wind_units);
/* WMO station no. */
if(get_wstr(subbuf, ident, 5) < 0)
continue;
strcat(newkey, ident);
break;
case BBXX :
strcpy(newkey, "bbxx ");
strcpy(pbuf, "BBXX\r\r\n");
/* call sign */
if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0)
continue;
strcat(newkey, ident);
if(get_yygg(subbuf, &time) < 0) continue; /* YYGG */
break;
case sSPECI :
/* call sign */
if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0)
continue;
if(strcmp(ident, "SPECI") == 0)
{
/* They package each ob with a tag */
pp = (subbuf->get +1);
if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0)
continue;
}
if(!whas_yyggZ(subbuf))
{
/* Have to insert the date */
sprintf(pbuf, "SPECI\r\r\n%s %02d%02dZ ",
ident, time.hour, time.min);
pp = subbuf->get;
}
else
strcpy(pbuf, "SPECI\r\r\n");
strcpy(newkey, "speci ");
strcat(newkey, ident);
break;
case sMETAR :
if(has_NIL(subbuf))
continue;
/* call sign */
if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0)
continue;
if(strcmp(ident, "METAR") == 0)
{
/* They package each ob with a tag */
pp = (subbuf->get +1);
if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0)
continue;
}
if(!whas_yyggZ(subbuf))
{
/* Have to insert the date */
sprintf(pbuf, "METAR\r\r\n%s %02d%02dZ ",
ident, time.hour, time.min);
pp = subbuf->get;
}
else
strcpy(pbuf, "METAR\r\r\n");
strcpy(newkey, "metar ");
strcat(newkey, ident);
break;
case SAO :
/* call sign */
if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0)
continue;
if(hdr.AA[0] == 'U' && hdr.AA[1] == 'S'
&& strlen(ident) == 6)
{
/* skip 6 char US "AFOS code" */
if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0)
continue;
}
/* SA, SP, RS, USP or XP */
if(get_wstr(subbuf, type, 3) < 0)
continue;
if((type[0] == 'S'
&& (type[1] == 'A' || type[1] == 'P'))
|| (type[0] == 'R' && type[1] == 'S')
|| (type[0] == 'U' && type[1] == 'S'
&& type[2] == 'P')
|| (type[0] == 'X' && type[1] == 'P')
|| (type[0] == 'T' &&
(type[1] == 'A' || type[1] == 'S'))
)
{
strcpy(newkey, "sao ");
strcat(newkey, type);
strcat(newkey, " ");
strcat(newkey, ident);
}
else if(isdigit(type[0]) && isdigit(type[1]))
{
/* it is a METAR really */
subtype = sMETAR;
strcpy(newkey, "metar ");
strcat(newkey, ident);
strcpy(pbuf, "METAR\r\r\n");
}
else
continue; /* don't know what it is, "NIL=" */
break;
}
/* safety net */
if(strlen(ident) == 0)
{
continue;
}
/* else */
sprintf(&newkey[strlen(newkey)], " %02d%02d%02d",
time.mday, time.hour, time.min);
if(hdr.retransmit != ORIGINAL)
sprintf(&newkey[strlen(newkey)], " %s",
sRetransmit(&hdr));
newinfo.ident = newkey;
newinfo.seqno = ++subseq;
l1 = strlen(pbuf);
l2 = MIN(MAX_SURF_LEN - l1 - 4, subbuf->bufsiz - (pp -
subbuf->base));
/* N.B.: silent truncation */
strncat(pbuf, (char *)pp, l2 );
strcat(pbuf,"=\r\r\n");
newinfo.sz = l1 + l2 + 4;
#if DEBUG
fprintf(stderr,"\t\t%s\n", newinfo.ident);
#endif
#if PRINT
{
char *cp = pbuf;
char *end = &cp[newinfo.sz];
while(cp < end)
{
putc(*cp, stderr);
cp++;
}
}
putc('\n', stderr);
#endif
MD5Init(md5ctxp);
MD5Update(md5ctxp, (const unsigned char *)pbuf, newinfo.sz);
MD5Final(newinfo.signature, md5ctxp);
/*
* process the single ob in the requested fashion
*/
if((*doit)(&newinfo, pbuf) == 0)
nsplit++;
} /* end while */
#if PRINT
putc('\n', stderr);
#endif
} /* end while block */
} /* end #### block */
return nsplit;
}