From pds@fsl.noaa.gov  Fri Oct  1 22:21:33 1999
Received: from gatekeeper.fsl.noaa.gov (gatekeeper.fsl.noaa.gov [137.75.1.181])
	by brain.fsl.noaa.gov (8.8.5/8.8.5) with ESMTP id WAA02392
	for <albers@brain.fsl.noaa.gov>; Fri, 1 Oct 1999 22:21:33 GMT
Received: from dilbert.fsl.noaa.gov (pds@dilbert.fsl.noaa.gov [137.75.132.102])
	by gatekeeper.fsl.noaa.gov (8.9.1/8.9.1) with ESMTP id WAA26995
	for <albers@mail.fsl.noaa.gov>; Fri, 1 Oct 1999 22:21:33 GMT
Received: (from pds@localhost)
	by dilbert.fsl.noaa.gov (8.9.1/8.9.1) id WAA12384
	for albers; Fri, 1 Oct 1999 22:21:32 GMT
Date: Fri, 1 Oct 1999 22:21:32 GMT
From: PDS Librarian <pds@fsl.noaa.gov>
Message-Id: <199910012221.WAA12384@dilbert.fsl.noaa.gov>
Content-Type: text
Status: OR

/*------------------------------------------------------------------------------
**  NOAA/ERL
**  Forecast Systems Laboratory
**  Facility Division
**  Remote Sensor Systems Branch
**
**  This software and its documentation are in the public domain and are 
**  furnished "as is".  The United States government, its instrumentalities,
**  officers, employees, and agents make no warranty, express or implied, as to
**  the usefullness of the software and documentation for any purpose.  They 
**  assume no responsibility (1) for the use of the software and documentation;
**  or (2) to provide technical support to users.
**
**  ItWsr88dI2RdamLib.c
**
**  This file contains the function which translates internal data structure
**  format WSR-88D wideband data into RDAM format.
**
**  WARNING: This is OPAQUE Facility Division (FD) Software. All OPAQUE FD 
**  Software is subject to change without notice.
**
**  07/19/96    Dell Long    v1.1    Original version
**  03/10/97    Dell Long    v1.2    Fixed assignment of origSource and 
**      origFormat in the RDAM header to operational values;  added code to 
**      fill the fields elevStartTime, volumeStartTime, siteLat, siteLon, and 
**      siteAlt in the RDAM header; Removed hard-coded radar name, etc.  
**      Instead, it uses values from the config file.  Added ray-type string to
**      RDAM key.  Removed ItTimeStr() -- it was put in stdNimbusLib. 
**  06/02/97    Dell Long    v1.3    Added elevation number to ray keys.
**  10/09/97    Laura Heigl  v1.4    Changed strcpy to strncpy to fix mem leak 
**----------------------------------------------------------------------------*/
static char RcsId[] =  "$Id: ItWsr88dI2RdamLib.c,v 1.4 1997/10/09 19:37:10 pds Exp $";

#include "ItXltWsr88d.h"

void fillDamHeader(DamHeader *hdr, getmsg_args *args, unsigned long *AuditId)
    {
    hdr->majorVer = DAM_MAJORVER;
    hdr->minorVer = DAM_MINORVER;
    hdr->auditId  = *AuditId;
    if (*AuditId == ULONG_MAX)
        *AuditId = 0;
    else
        (*AuditId)++;

    return;
    } /* fillDamHeader() */

void fillRdamHeader(RdamHeader *hdr, stationInfo *s, int msgType)
    {

    hdr->majorVersion = RDAM_MAJORVER;
    hdr->minorVersion = RDAM_MINORVER;
    hdr->origSource = WSR88D_ORIG_SOURCE;
    hdr->origFormat = VRdamOFmtWSR88D_Wideband;

    /* elevStartTime and volumeStartTime are only valid for radial data */
    if (msgType == WSR88D_DRD)
        hdr->elevStartTime = s->elevStartTime;
    else
        hdr->elevStartTime = -1;

    if (msgType == WSR88D_DRD)
        hdr->volumeStartTime = s->volumeStartTime;
    else
        hdr->volumeStartTime = -1;

    /* insert station information */
    if (s->radarName == NULL)
        hdr->radarName = NULL;
    else
        {
        hdr->radarName = (char *)calloc(strlen(s->radarName) + 1, sizeof(char));
        if (hdr->radarName == NULL)
            PANIC;
        strncpy(hdr->radarName, s->radarName, strlen(s->radarName));
        }
        
    if (s->siteName == NULL)
        hdr->siteName = NULL;
    else
        {
        hdr->siteName = (char *)calloc(strlen(s->siteName) + 1, sizeof(char));
        if (hdr->siteName == NULL)
            PANIC;
        strncpy(hdr->siteName, s->siteName,strlen(s->siteName));
        }

    hdr->siteLat = s->siteLat;
    hdr->siteLon = s->siteLon;
    hdr->siteAlt = s->siteAlt;
    
    return;
    } /* fillRdamHeader() */

void xltWsr88dI2Rdam(wsr88d_data *wd, getmsg_args *args, unsigned long *AuditId, 
                     stationInfo *currStation, DamDataStruct *dam)
    {
    RdamDataStruct *rdam;

    fillDamHeader(&dam->damHdr, args, AuditId);

    /* allocate RDAM data structure */
    rdam = (RdamDataStruct *) calloc(1, sizeof(RdamDataStruct));
    if (rdam == (RdamDataStruct *) NULL)
        PANIC;

    dam->damClass = RDAM_CLASS;
    dam->classInstance = (void *)rdam;

    /* fill the RDAM structure */
    /* fill the RDAM header */
    fillRdamHeader(&rdam->hdr, currStation, wd->hdr.msg_type); 

    /* fill wsr88d header info */
    rdam->data.hdr.msg_size = wd->hdr.msg_size;
    rdam->data.hdr.msg_type = wd->hdr.msg_type;
    rdam->data.hdr.id_seq = wd->hdr.id_seq;
    rdam->data.hdr.msg_date = wd->hdr.msg_date;
    rdam->data.hdr.msg_time = wd->hdr.msg_time;
    rdam->data.hdr.num_seg = wd->hdr.num_seg;
    rdam->data.hdr.seg_num = wd->hdr.seg_num;

    /* fill wsr88d data info */
    switch(wd->hdr.msg_type)
        {
        case WSR88D_DRD:
            rdam->data.msg.drd = (wsr88d_drd *) calloc(1, sizeof(wsr88d_drd));
            if (rdam->data.msg.drd == (wsr88d_drd *)NULL)
                PANIC;
            memcpy(rdam->data.msg.drd, wd->msg.drd, sizeof(wsr88d_drd));
            break;

        case WSR88D_RDA:
            rdam->data.msg.rda = (wsr88d_rda *) calloc(1, sizeof(wsr88d_rda));
            if (rdam->data.msg.rda == (wsr88d_rda *)NULL)
                PANIC;
            memcpy(rdam->data.msg.rda, wd->msg.rda, sizeof(wsr88d_rda));
            break;
            
        case WSR88D_CONSOLE_USER:
        case WSR88D_USER_CONSOLE:
            rdam->data.msg.console = (wsr88d_console *) calloc(1, 
                sizeof(wsr88d_console));
            if (rdam->data.msg.console == (wsr88d_console *)NULL)
                PANIC;            
            memcpy(rdam->data.msg.console, wd->msg.console, 
                   sizeof(wsr88d_console));
            break;

        case WSR88D_LOOP_USER:
        case WSR88D_LOOP_RDA:
            rdam->data.msg.loopback = (wsr88d_loopback *) calloc(1, 
                sizeof(wsr88d_loopback));
            if (rdam->data.msg.loopback == (wsr88d_loopback *)NULL)
                PANIC;           
            memcpy(rdam->data.msg.loopback, wd->msg.loopback, 
                   sizeof(wsr88d_loopback));
            break;

        case NSSL_VOL_ID:
            rdam->data.msg.vol_id = (nssl_vol_id *) calloc(1, 
                sizeof(nssl_vol_id));
            if (rdam->data.msg.vol_id == (nssl_vol_id *)NULL)
                PANIC;  
            memcpy(rdam->data.msg.vol_id, wd->msg.vol_id, sizeof(nssl_vol_id));
            break;
            
        default:
            break;
        }
    
    return;
    } /* xltWsr88dI2Rdam() */

char *createRdamDataKey(RdamDataStruct *r)
    {
    char *buf;
    int keyLen;
    char *timeStr;
    char productStr[PRODUCT_STR_LEN];
    char rayStatus[RAY_STAT_LEN];
    time_t t;

    /**********************************************************************/
    /* make sure there's something to make a key out of                   */
    /**********************************************************************/
    if (r == (RdamDataStruct *)NULL)
        return NULL;
    if (r->hdr.radarName == NULL)
        return NULL;

    /**********************************************************************/
    /* allocate memory for key                                            */      
    /**********************************************************************/
    keyLen = strlen(RDAM_BASE_KEY) + strlen(WSR88D_BASE_KEY) + 
             strlen(r->hdr.radarName) + PRODUCT_STR_LEN + RAY_STAT_LEN + 
             strlen(".....yyyyjjjhhmmss.*") + 1;
    buf = (char *)calloc(keyLen, sizeof(char));
    if (buf == (char *)NULL)
        PANIC;

    /**********************************************************************/
    /* build key                                                          */
    /**********************************************************************/
    /* time string */
    timeStr = ItTimeStr(RadarTimeToUTC(r->data.hdr.msg_date, 
                                       r->data.hdr.msg_time));

    rayStatus[0] = '\0';
    /* product string */
    switch(r->data.hdr.msg_type)
        {
        case WSR88D_DRD:
            strcpy(productStr, WSR88D_DRD_KEY);
            switch(r->data.msg.drd->ray_status)
                {
                case INTERMEDIATE_RAY:
                    strcpy(rayStatus, INTERMEDIATE_RAY_STR);
                    break;
                case BAD_INTERMEDIATE_RAY: 
                    strcpy(rayStatus, BAD_INTERMEDIATE_RAY_STR);
                    break;
                case NEW_ELEVATION: 
                    strcpy(rayStatus, NEW_ELEVATION_STR);
                    break;
                case BAD_NEW_ELEVATION: 
                    strcpy(rayStatus, BAD_NEW_ELEVATION_STR);
                    break;
                case NEW_VOLUME_SCAN: 
                    strcpy(rayStatus, NEW_VOLUME_SCAN_STR);
                    break;
                case BAD_NEW_VOLUME_SCAN:
                    strcpy(rayStatus, BAD_NEW_VOLUME_SCAN_STR);
                    break;
                case END_ELEVATION: 
                    sprintf(rayStatus, "%s.elev%s%d",
                            END_ELEVATION_STR,
                            r->data.msg.drd->elev_num < 10 ? "0" : "",
                            r->data.msg.drd->elev_num);
                    break;
                case BAD_END_ELEVATION:
                    sprintf(rayStatus, "%s.elev%s%d",
                            BAD_END_ELEVATION_STR,
                            r->data.msg.drd->elev_num < 10 ? "0" : "",
                            r->data.msg.drd->elev_num);
                    break;
                case END_VOLUME_SCAN: 
#if 0
                    sprintf(rayStatus, "%s.elev%s%d",
                            END_VOLUME_SCAN_STR,
                            r->data.msg.drd->elev_num < 10 ? "0" : "",
                            r->data.msg.drd->elev_num);
#else
                    strcpy(rayStatus, END_VOLUME_SCAN_STR);
#endif
                    break;
                case BAD_END_VOLUME_SCAN:
#if 0
                    sprintf(rayStatus, "%s.elev%s%d",
                            BAD_END_VOLUME_SCAN_STR,
                            r->data.msg.drd->elev_num < 10 ? "0" : "",
                            r->data.msg.drd->elev_num);
#else
                    strcpy(rayStatus, BAD_END_VOLUME_SCAN_STR);
#endif
                    break;

                default:
                    strcpy(rayStatus, UNKNOWN_RAY_STR);
                    break;
                }
            break;

        case WSR88D_RDA:
            strcpy(productStr, WSR88D_RDA_KEY);
            break;
            
        case WSR88D_CONSOLE_USER:
            strcpy(productStr, WSR88D_CONSOLE_USER_KEY);
            break;

        case WSR88D_USER_CONSOLE:
            strcpy(productStr, WSR88D_USER_CONSOLE_KEY);
            break;

        case WSR88D_LOOP_USER:
            strcpy(productStr, WSR88D_LOOP_USER_KEY);
            break;

        case WSR88D_LOOP_RDA:
            strcpy(productStr, WSR88D_LOOP_RDA_KEY);
            break;

        case NSSL_VOL_ID:
            strcpy(productStr, NSSL_VOL_ID_KEY);
            break;
            
        default:
            strcpy(productStr, "UNKNOWN");
            break;
        }

    sprintf(buf, "%s.%s.%s.%s%s%s.%s.*", RDAM_BASE_KEY, WSR88D_BASE_KEY, 
            r->hdr.radarName, productStr, 
            rayStatus[0] == '\0' ? "" : ".", rayStatus, timeStr);

    free(timeStr);

    return buf;
    } /* createRdamDataKey() */

int createRdamXltNotify(char **buffer, u_long *len, RdamData *rdam,
                        time_t elevStartTime, char *origKey, char *xltKey, 
                        char *origHost, char *origProc)
    {
    NotifyArgs    *nty;    /* notification structure */
    int           status;
    int           ray_num;
    int           elev_num;

    /*--------------------------------------------------------------------------
    ** allocate structure for notification and assign fixed elements
    **------------------------------------------------------------------------*/
    nty = (NotifyArgs *) calloc(1, sizeof(NotifyArgs));
    if (nty == (NotifyArgs *)NULL)
        PANIC;
    
    nty->Notify.Type = XLT_NOTIFY;
    nty->Notify.Time = time((time_t *)NULL);

    nty->Var.Xlt.xltKey = (char *) malloc(strlen(xltKey) + 1);
    if (nty->Var.Xlt.xltKey == (char *) NULL)
        PANIC;
    strcpy(nty->Var.Xlt.xltKey, xltKey);

    nty->Var.Xlt.origKey = (char *) malloc(strlen(origKey) + 1);
    if (nty->Var.Xlt.origKey == (char *) NULL)
        PANIC;
    strcpy(nty->Var.Xlt.origKey, origKey);

    if (origHost == (char *) NULL)
        AddProductDesc(&nty->Var.Xlt.prodDesc, String, ORIG_HOST_NAME, 
                       NOT_AVAILABLE);
    else
        AddProductDesc(&nty->Var.Xlt.prodDesc, String, ORIG_HOST_NAME, 
                       origHost);

    AddProductDesc(&nty->Var.Xlt.prodDesc, String, ORIG_PROC_NAME, 
                   origProc);

    switch(rdam->hdr.msg_type)
        {
        case WSR88D_DRD: /* Radial data */
            /* convert elev_num and ray_num to int for AddProductDesc() */
            elev_num = (int)rdam->msg.drd->elev_num;
            ray_num = (int)rdam->msg.drd->ray_num;
            /* add elevation and ray number to product descriptions */
            AddProductDesc(&nty->Var.Xlt.prodDesc, Int, "Elevation Number",
                           (char *) &elev_num);
            AddProductDesc(&nty->Var.Xlt.prodDesc, Int, "Ray Number",
                           (char *) &ray_num);
            /* add elevation start time */
            AddDataTime(&nty->Var.Xlt.dataTimes, "Elevation Start Time", 
                        elevStartTime);
            break;

        case WSR88D_RDA:
        case WSR88D_CONSOLE_USER:
        case WSR88D_USER_CONSOLE:
        case WSR88D_LOOP_USER:
        case WSR88D_LOOP_RDA:
        case NSSL_VOL_ID:
            break;
            
        default:
            break;
        }

    /* XDR encode the notification */
    if (EncodeNotify(nty, buffer, len) == EXIT_FAILURE)
        {
        PdsAdvise(Targ, PdsError, "EncodeNotify failed");
        FreeNotify(nty);
        return EXIT_FAILURE;
        }

    FreeNotify(nty);
    return EXIT_SUCCESS;
    } /* createRdamXltNotify() */

char *createRdamXltNotifyKey(RdamDataStruct *r)
    {
    char *curTimeStr;
    char productStr[PRODUCT_STR_LEN];
    char *key = NULL;
    char rayStatus[RAY_STAT_LEN];

    /* allocate and set current time string in IT format */
    curTimeStr = ItTimeStr(time((time_t *) NULL));

    rayStatus[0] = '\0';
    /* get product type string */
    switch(r->data.hdr.msg_type)
        {
        case WSR88D_DRD:
            strcpy(productStr, WSR88D_DRD_KEY);
            /* put ray type string here!!!!! */
            switch(r->data.msg.drd->ray_status)
                {
                case INTERMEDIATE_RAY:
                    strcpy(rayStatus, INTERMEDIATE_RAY_STR);
                    break;
                case BAD_INTERMEDIATE_RAY: 
                    strcpy(rayStatus, BAD_INTERMEDIATE_RAY_STR);
                    break;
                case NEW_ELEVATION: 
                    strcpy(rayStatus, NEW_ELEVATION_STR);
                    break;
                case BAD_NEW_ELEVATION: 
                    strcpy(rayStatus, BAD_NEW_ELEVATION_STR);
                    break;
                case NEW_VOLUME_SCAN: 
                    strcpy(rayStatus, NEW_VOLUME_SCAN_STR);
                    break;
                case BAD_NEW_VOLUME_SCAN:
                    strcpy(rayStatus, BAD_NEW_VOLUME_SCAN_STR);
                    break;
                case END_ELEVATION: 
                    strcpy(rayStatus, END_ELEVATION_STR);
                    break;
                case BAD_END_ELEVATION:
                    strcpy(rayStatus, BAD_END_ELEVATION_STR);
                    break;
                case END_VOLUME_SCAN: 
                    strcpy(rayStatus, END_VOLUME_SCAN_STR);
                    break;
                case BAD_END_VOLUME_SCAN:
                    strcpy(rayStatus, BAD_END_VOLUME_SCAN_STR);
                    break;

                default:
                    strcpy(rayStatus, UNKNOWN_RAY_STR);
                    break;
                }
            break;
        case WSR88D_RDA:
            strcpy(productStr, WSR88D_RDA_KEY);
            break;
        case WSR88D_CONSOLE_USER:
            strcpy(productStr, WSR88D_CONSOLE_USER_KEY);
            break;
        case WSR88D_USER_CONSOLE:
            strcpy(productStr, WSR88D_USER_CONSOLE_KEY);
            break;
        case WSR88D_LOOP_USER:
            strcpy(productStr, WSR88D_LOOP_USER_KEY);
            break;
        case WSR88D_LOOP_RDA:
            strcpy(productStr, WSR88D_LOOP_RDA_KEY);
            break;
        case NSSL_VOL_ID:
            strcpy(productStr, NSSL_VOL_ID_KEY);
            break;
            
        default:
            PdsAdvise(Targ, PdsError, "createRdamXltNotifyKey: bad message type");
            free(curTimeStr);
            return (char *)NULL;
            break;
        }

    /* allocate and set Notify key */
    key = MakeTarget("%s.%s.Xlt.%s.%s.%s.%s.%s.*", RDAM_NOTIFY_BASE_KEY, 
                     PdsProgname, WSR88D_BASE_KEY, r->hdr.radarName, productStr, 
                     rayStatus, curTimeStr);

    free(curTimeStr);
    return key;
    } /* createRdamXltNotifyKey() */