00001 /* 00002 * THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE 00003 * CHECKED IT OUT USING THE COMMAND CHECKOUT. 00004 * 00005 * $Id: sudsputaway_8c-source.html 2161 2006-05-19 16:55:03Z paulf $ 00006 * 00007 * Revision history: 00008 * $Log$ 00008 * Revision 1.1 2006/05/19 16:55:02 paulf 00008 * first inclusion 00008 * 00009 * Revision 1.9 2002/01/08 17:02:29 cjbryan 00010 * In order to accommodate 24-bit broadband data, traces of data of longer than long are now clipped to +/-2147483648 00011 * 00012 * Revision 1.8 2001/04/12 03:47:36 lombard 00013 * Major reorganization of SUDSPA_next to improve efficiency 00014 * Reformatted code; cleaned up lots of comments and logit calls 00015 * Removed mapping of NC component codes (only needed at UW) 00016 * Now traces of data larger than short in are clipped to +/- 32767 00017 * counts; before they were byte-truncated. 00018 * Initializes SUDS structures to zero before filling them. 00019 * 00020 * Revision 1.7 2001/03/27 22:22:51 cjbryan 00021 * ensured that time portion of suds format is hhmmss and not hhmmss.ss as carried by EventTime variable 00022 * 00023 * Revision 1.6 2001/03/22 20:55:12 cjbryan 00024 * deleted now obsolete EventInst variable 00025 * 00026 * Revision 1.5 2001/03/21 23:15:23 cjbryan 00027 * integrated CVO subnet into output filename 00028 * 00029 * Revision 1.4 2001/03/21 16:41:07 alex 00030 * added EventSubnet variable to carry subnet name through to 00031 * filename; deleted now extraneous EventMod variable 00032 * 00033 * Revision 1.3 2001/03/21 02:23:03 alex 00034 * *** empty log message *** 00035 * 00036 * Revision 1.2 2000/03/10 23:23:43 davidk 00037 * changed the sudsputaway routines to match the new PA_XXX 00038 * routines in putaway.c. 00039 * Moved the SUDSPA_XXX function prototypes to pa_other_head.h 00040 * 00041 * Revision 1.1 2000/02/14 18:51:48 lucky 00042 * Initial revision 00043 * 00044 * 00045 */ 00046 00047 /* sudsputaway.c 00048 00049 Routines for writing trace data in PC-SUDS format 00050 00051 00052 Thu Jul 22 14:56:37 MDT 1999 Lucky Vidmar 00053 Major structural changes to accomodate making all putaway routines 00054 into library calls so that they can be shared between trig2disk 00055 and wave2disk. Eliminated global variables set and allocated outside 00056 of this file. We should only have static globals from now on, with 00057 everything else being passed in via the putaway.c calls. 00058 */ 00059 00060 #include <limits.h> 00061 #include <stdio.h> 00062 #include <stdlib.h> 00063 #include <string.h> 00064 #include <errno.h> 00065 #include <earthworm.h> 00066 #include <time.h> 00067 #include <trace_buf.h> 00068 #include <swap.h> 00069 #include <ws_clientII.h> 00070 #include <sudshead.h> 00071 #include <pa_subs.h> 00072 00073 #define TAG_FILE '.tag' /* file containing the last known file tag */ 00074 #define MAXTXT 150 00075 00076 00077 FILE *SUDSfp; /* file pointer for the SUDS file */ 00078 00079 static long *SudsBuffer; /* write out SUDS data as long integers */ 00080 static short *SudsBufferShort; /* write out SUDS data as short integers */ 00081 static char SudsOutputFormat[MAXTXT]; 00082 00083 /* Internal Function Prototypes */ 00084 static int StructMakeLocal (void *, int, char, int); 00085 static int SwapDo (void *, int); 00086 00087 /************************************************************************ 00088 * Initialization function, * 00089 * This is the Put Away startup intializer. This is called when * 00090 * the system first comes up. Here is a chance to look around * 00091 * and see if it's possible to do business, and to complain * 00092 * if not ,BEFORE an event has to be processed. * 00093 * * 00094 * For PCSUDS, all we want to do is to make sure that the * 00095 * directory where files should be written exists. * 00096 *************************************************************************/ 00097 int SUDSPA_init (int OutBufferLen, char *OutDir, char *OutputFormat, 00098 int debug) 00099 { 00107 if ((SudsBuffer = (long *) malloc (OutBufferLen * sizeof (char))) == NULL) 00108 { 00109 logit ("et", "SUDSPA_init: couldn't malloc SudsBuffer\n"); 00110 return EW_FAILURE; 00111 } 00112 if ((SudsBufferShort = (short *) malloc (OutBufferLen * sizeof (char))) == NULL) 00113 { 00114 logit ("et", "SUDSPA_init: couldn't malloc SudsBufferShort\n"); 00115 return EW_FAILURE; 00116 } 00117 00118 /* Make sure that the top level output directory exists */ 00119 if (CreateDir (OutDir) != EW_SUCCESS) 00120 { 00121 logit ("e", "SUDSPA_init: Call to CreateDir failed\n"); 00122 return EW_FAILURE; 00123 } 00124 00125 if(strlen(OutputFormat) >= sizeof(SudsOutputFormat)) 00126 { 00127 logit("","SUDSPA_init: Error: OutputFormat(%s) is too long! Quitting!\n", 00128 OutputFormat); 00129 return(EW_FAILURE); 00130 } 00131 else 00132 { 00133 strcpy(SudsOutputFormat,OutputFormat); 00134 } 00135 return EW_SUCCESS; 00136 } 00137 00138 /************************************************************************ 00139 * This is the Put Away event initializer. It's called when a snippet * 00140 * has been received, and is about to be processed. * 00141 * It gets to see the pointer to the TraceRequest array, * 00142 * and the number of loaded trace structures. * 00143 * * 00144 * For PCSUDS, we need to make sure that the target directory * 00145 * exists, create it if it does not, then open the SUDS file * 00146 * for writing. * 00147 *************************************************************************/ 00148 int SUDSPA_next_ev (char *EventID, TRACE_REQ *ptrReq, int nReq, 00149 char *OutDir, char *EventDate, char *EventTime, 00150 char *EventSubnet, int debug) 00151 00152 { 00153 char SUDSFile[4*MAXTXT]; 00154 char hhmmss[7]; 00155 00156 /* Changed by Eugene Lublinsky, 3/31/Y2K */ 00157 /* There are 2 modes of behavior now: the default one when insmod */ 00158 /* is numeric or the second one when insmod is alphanumeric */ 00159 char tmpEventID[EVENTID_SIZE + 3]; 00160 00161 /* We treat suds file slightly differently - by request 00162 * from Tom Murray. The files are placed directly into the 00163 * top level suds directory, with names as follows: 00164 * 00165 * yyyymmdd_hhmmss_insmod_evid.dmx 00166 */ 00167 00168 /* Changed by Eugene Lublinsky, 3/31/Y2K */ 00169 /* choose which way to go */ 00170 00171 /* Build the file name */ 00172 /* added by murray (and it shows) to set the eventid at 3 characters */ 00173 if (strlen(EventID) < 3) 00174 sprintf (tmpEventID,"000%s",EventID) ; 00175 else 00176 sprintf (tmpEventID,"%s",EventID) ; 00177 00178 /* ensure that time string is of the form hhmmss (revised EventTime 00179 allows a string of the form hhmmss.ss, so truncate it if necessary) */ 00180 if (strlen(EventTime) > 6) 00181 { 00182 strncpy(hhmmss, EventTime, 6); 00183 hhmmss[6] = '\0'; 00184 } 00185 else 00186 strcpy(hhmmss, EventTime); 00187 00188 /* changed by Carol 3/21/01: if no subnet, use network name 00189 in filename */ 00190 if (EventSubnet[0] != '\0') 00191 sprintf (SUDSFile, "%s/%s_%s_%s_%s.dmx", OutDir, 00192 EventDate, hhmmss, EventSubnet, 00193 &tmpEventID[strlen(tmpEventID)-3]); 00194 else 00195 sprintf (SUDSFile, "%s/%s_%s_%s_%s.dmx", OutDir, 00196 EventDate, hhmmss, ptrReq->net, 00197 &tmpEventID[strlen(tmpEventID)-3]); 00198 00199 /* end of changes */ 00200 00201 if (debug == 1) 00202 logit ("t", "Opening SUDS file %s\n", SUDSFile); 00203 00204 /* open file */ 00205 if ((SUDSfp = fopen (SUDSFile, "wb")) == NULL) 00206 { 00207 logit ("e", "SUDSPA_next_ev: unable to open file %s: %s\n", 00208 SUDSFile, strerror(errno)); 00209 return EW_FAILURE; 00210 } 00211 00212 return (EW_SUCCESS); 00213 } 00214 00215 /************************************************************************ 00216 * This is the working entry point into the disposal system. This * 00217 * routine gets called for each trace snippet which has been recovered. * 00218 * It gets to see the corresponding SNIPPET structure, and the event id * 00219 * * 00220 * For PCSUDS, this routine writes to the SUDS file, pointed to by the * 00221 * SUDSfp pointer, all of the received trace data in SUDS format: * 00222 * * 00223 * 1. SUDS tag - indicating what follows * 00224 * 2. SUDS_STATIONCOMP struct - describe the station * 00225 * 3. SUDS tag - indicating what follows * 00226 * 4. SUDS_DESCRIPTRACE struct - describe the trace data * 00227 * 5. trace data * 00228 * * 00229 * One bit of complexity is that we need to write the files in the * 00230 * correct byte-order. Based on the OutputFormat parameter, determine * 00231 * whether or not to swap bytes before writing the suds file. * 00232 * * 00233 * WARNING: we clip trace data to -2147483648 - +2147483647 so it will * 00234 * fit in a long int. Any incoming data that is longer than 32 bits * 00235 * will be CLIPPED. cjb 5/18/2001 * 00236 *************************************************************************/ 00237 /* Process one channel of data */ 00238 int SUDSPA_next (TRACE_REQ *getThis, double GapThresh, 00239 long OutBufferLen, int debug) 00240 { 00241 TRACE_HEADER *wf; 00242 short *s_data; 00243 long *l_data; 00244 float *f_data; 00245 char *msg_p; /* pointer into tracebuf data */ 00246 char datatype; 00247 int data_size; 00248 int j; 00249 int gap_count = 0; 00250 long nsamp, nfill; 00251 long nfill_max = 0l; 00252 long nsamp_this_scn = 0l; 00253 long this_size; 00254 double begintime, starttime, endtime; 00255 double samprate; 00256 long fill = 0l; 00257 long min, max; 00258 int total; 00259 SUDS_STRUCTTAG tag; 00260 SUDS_DESCRIPTRACE dt; 00261 SUDS_STATIONCOMP sc; 00262 00263 /* Check arguments */ 00264 if (getThis == NULL) 00265 { 00266 logit ("e", "SUDSPA_next: invalid argument passed in.\n"); 00267 return EW_FAILURE; 00268 } 00269 00270 /* Start with a clean slate */ 00271 memset(&tag, 0, sizeof(tag)); 00272 memset(&dt, 0, sizeof(dt)); 00273 memset(&sc, 0, sizeof(sc)); 00274 00275 /* Used for computing trace statistics */ 00276 max = 4096; 00277 min = 0; 00278 total = 0; 00279 00280 if ( (msg_p = getThis->pBuf) == NULL) /* pointer to first message */ 00281 { 00282 logit ("e", "SUDSPA_next: Message buffer is NULL.\n"); 00283 return EW_FAILURE; 00284 } 00285 wf = (TRACE_HEADER *) msg_p; 00286 00287 /* Look at the first TRACE_HEADER and get set up of action */ 00288 if (WaveMsgMakeLocal(wf) < 0) 00289 { 00290 logit("e", "SUDSPA_next: unknown trace data type: %s\n", 00291 wf->datatype); 00292 return( EW_FAILURE ); 00293 } 00294 00295 nsamp = wf->nsamp; 00296 starttime = wf->starttime; 00297 endtime = wf->endtime; 00298 samprate = wf->samprate; 00299 if (samprate < 0.01) 00300 { 00301 logit("et", "unreasonable samplerate (%f) for <%s.%s.%s>\n", 00302 samprate, wf->sta, wf->chan, wf->net); 00303 return( EW_FAILURE ); 00304 } 00305 begintime = starttime; 00306 datatype = 'n'; 00307 if (wf->datatype[0] == 's' || wf->datatype[0] == 'i') 00308 { 00309 if (wf->datatype[1] == '2') datatype = 's'; 00310 else if (wf->datatype[1] == '4') datatype = 'l'; 00311 } 00312 else if (wf->datatype[0] == 't' || wf->datatype[0] == 'f') 00313 { 00314 if (wf->datatype[1] == '4') datatype = 'f'; 00315 } 00316 if (datatype == 'n') 00317 { 00318 logit("et", "SUDSPA_next: unsupported datatype: %s\n", datatype); 00319 return( EW_FAILURE ); 00320 } 00321 00322 if (debug == 1) 00323 logit("et", "SUDSPA_next: working on <%s/%s/%s> datatype: %c \n", 00324 wf->sta, wf->chan, wf->net, datatype); 00325 00326 /* loop through all the messages for this s-c-n */ 00327 while (1) 00328 { 00329 /* advance message pointer to the data */ 00330 msg_p += sizeof(TRACE_HEADER); 00331 00332 /* check for sufficient memory in output buffer */ 00333 this_size = (nsamp_this_scn + nsamp ) * sizeof(long); 00334 if ( OutBufferLen < this_size ) 00335 { 00336 logit( "e", "out of space for <%s.%s.%s>; saving long trace.\n", 00337 wf->sta, wf->chan, wf->net); 00338 break; 00339 } 00340 00341 /* if data are floats, clip to longs cjb 5/18/2001 */ 00342 switch( datatype ) 00343 { 00344 case 's': 00345 s_data = (short *)msg_p; 00346 for ( j = 0; j < nsamp ; j++, nsamp_this_scn++ ) 00347 SudsBuffer[nsamp_this_scn] = (long) s_data[j]; 00348 msg_p += sizeof(short) * nsamp; 00349 break; 00350 case 'l': 00351 l_data = (long *)msg_p; 00352 for ( j = 0; j < nsamp; j++, nsamp_this_scn++ ) 00353 SudsBuffer[nsamp_this_scn] = l_data[j]; 00354 msg_p += sizeof(long) * nsamp; 00355 break; 00356 case 'f': 00357 f_data = (float *)msg_p; 00358 /* CLIP the data to long int */ 00359 for ( j = 0; j < nsamp; j++, nsamp_this_scn++ ) 00360 { 00361 if (l_data[j] < (float)LONG_MIN) 00362 SudsBuffer[nsamp_this_scn] = LONG_MIN; 00363 else if (l_data[j] > (float) LONG_MAX) 00364 SudsBuffer[nsamp_this_scn] = LONG_MAX; 00365 else 00366 SudsBuffer[nsamp_this_scn] = (long) l_data[j]; 00367 } 00368 msg_p += sizeof(float) * nsamp; 00369 break; 00370 } 00371 00372 /* End-check based on length of snippet buffer */ 00373 if ((long) msg_p >= ((long) getThis->actLen + (long) getThis->pBuf)) 00374 { 00375 if (debug == 1) 00376 logit ("", "Setting done for <%s.%s.%s>\n", wf->sta, wf->chan, 00377 wf->net); 00378 break; /* Break out of the while(1) loop 'cuz we're done */ 00379 } 00380 00381 /* msg_p has been advanced to the next TRACE_BUF; localize bytes * 00382 * and check for gaps. */ 00383 wf = (TRACE_HEADER *) msg_p; 00384 if (WaveMsgMakeLocal(wf) < 0) 00385 { 00386 logit("e", "SUDSPA_next: unknown trace data type: %s\n", 00387 wf->datatype); 00388 return( EW_FAILURE ); 00389 } 00390 nsamp = wf->nsamp; 00391 starttime = wf->starttime; 00392 /* starttime is set for new packet; endtime is still set for old packet */ 00393 if ( endtime + ( 1.0/samprate ) * GapThresh < starttime ) 00394 { 00395 /* there's a gap, so fill it */ 00396 logit("e", "gap in %s.%s.%s: %lf: %lf\n", wf->sta, wf->chan, wf->net, 00397 endtime, starttime - endtime); 00398 nfill = (long) (samprate * (starttime - endtime) - 1); 00399 if ( (nsamp_this_scn + nfill) * (long)sizeof(long) > OutBufferLen ) 00400 { 00401 logit("e", 00402 "bogus gap (%d); skipping\n", nfill); 00403 return(EW_FAILURE); 00404 } 00405 /* do the filling */ 00406 for ( j = 0; j < nfill; j++, nsamp_this_scn ++ ) 00407 SudsBuffer[nsamp_this_scn] = fill; 00408 /* keep track of how many gaps and the largest one */ 00409 gap_count++; 00410 if (nfill_max < nfill) 00411 nfill_max = nfill; 00412 } 00413 /* Advance endtime to the new packet; * 00414 * process this packet in the next iteration */ 00415 endtime = wf->endtime; 00416 } /* while(1) */ 00417 00418 /* figure out min, max, and "noise" */ 00419 for (j = 0; j < 200 && j < nsamp_this_scn; j++) 00420 { 00421 if (SudsBuffer[j] > max) 00422 max = SudsBuffer[j]; 00423 if (SudsBuffer[j] < min) 00424 min = SudsBuffer[j]; 00425 total += SudsBuffer[j]; 00426 } 00427 dt.avenoise = ((float)total)/ (float)j; /* Mean of the first 200 samples */ 00428 for (; j < nsamp_this_scn; j++) 00429 { 00430 if (SudsBuffer[j] > max) 00431 max = SudsBuffer[j]; 00432 if (SudsBuffer[j] < min) 00433 min = SudsBuffer[j]; 00434 } 00435 00436 /* If the incoming data were originally short integers, copy the values 00437 back to an array of shorts; disk space saving feature requested 00438 by Gabriel Reyes cjb 6/11/01 */ 00439 if (datatype == 's') 00440 { 00441 for (j = 0; j < nsamp_this_scn; j++) 00442 SudsBufferShort[j] = (short)SudsBuffer[j]; 00443 } 00444 00445 /* Convert to the appropriate output format */ 00446 #if defined (_INTEL) 00447 /* we are on intel, data will be read on sparc */ 00448 if (strcmp (SudsOutputFormat, "sparc") == 0) 00449 for (j = 0; j < nsamp_this_scn; j++) 00450 { 00451 if (datatype == 's') 00452 SwapShort(&SudsBufferShort[j]); 00453 else 00454 SwapLong(&SudsBuffer[j]); 00455 } 00456 #elif defined (_SPARC) 00457 /* we are on sparc, data will be read on intel */ 00458 if (strcmp (SudsOutputFormat, "intel") == 0) 00459 for (j = 0; j < nsamp_this_scn; j++) 00460 { 00461 if (datatype == 's') 00462 SwapShort(&SudsBufferShort[j]); 00463 else 00464 SwapLong(&SudsBuffer[j]); 00465 } 00466 #else 00467 logit ("e", "SUDSPA_next: Can't determine my platform - please compile with either _INTEL or _SPARC set\n"); 00468 return EW_FAILURE; 00469 #endif 00470 00471 /* Write out to the SUDS file */ 00472 /* Fill and write TAG for the STATIONCOMP struct */ 00473 00474 tag.id_struct = STATIONCOMP; /* what follows is STATIONCOMP */ 00475 tag.len_struct = sizeof (SUDS_STATIONCOMP); 00476 tag.len_data = 0; 00477 tag.sync = 'S'; 00478 00479 if (debug == 1) 00480 logit ("", "Writing tag for %d (%d)\n", tag.id_struct, tag.len_struct); 00481 00482 if (strcmp (SudsOutputFormat, "sparc") == 0) 00483 tag.machine = '1'; 00484 else if (strcmp (SudsOutputFormat, "intel") == 0) 00485 tag.machine = '6'; 00486 00487 if (StructMakeLocal ((void *) &tag, STRUCTTAG, tag.machine, debug) 00488 != EW_SUCCESS) 00489 { 00490 logit ("et", "SUDSPA_next: Call to StructMakeLocal failed. \n"); 00491 return EW_FAILURE; 00492 } 00493 00494 if (fwrite ((void *) &tag, sizeof (SUDS_STRUCTTAG), 1, SUDSfp) != 1) 00495 { 00496 logit ("et", "SUDSPA_next: error writing SUDS tag. \n"); 00497 return EW_FAILURE; 00498 } 00499 00500 /* Fill and write STATIONCOMP struct */ 00501 /* in SUDS_STATIDENT structure, char st_name[5], 00502 char network[4], char component where component = v,n,e 00503 cjb 5/18/2001 */ 00504 if (strlen(wf->sta) > 5) { 00505 strncpy(sc.sc_name.st_name, wf->sta, 4); 00506 sc.sc_name.st_name[4] = '\0'; 00507 } 00508 else 00509 strcpy (sc.sc_name.st_name, wf->sta); 00510 00511 if (strlen(wf->net) > 4) { 00512 strncpy(sc.sc_name.network, wf->net, 3); 00513 sc.sc_name.network[3] = '\0'; 00514 } 00515 else 00516 strcpy (sc.sc_name.network, wf->net); 00517 00518 if (strlen(wf->chan) >= 3) 00519 sc.sc_name.component = wf->chan[2]; 00520 else 00521 sc.sc_name.component = wf->chan[0]; 00522 00523 if ((sc.sc_name.component == 'Z') || (sc.sc_name.component == 'z')) 00524 sc.sc_name.component = 'V'; 00525 00526 if ((sc.sc_name.component != 'N') && (sc.sc_name.component != 'n') 00527 && (sc.sc_name.component != 'E') && (sc.sc_name.component != 'e') 00528 && (sc.sc_name.component != 'V') && (sc.sc_name.component != 'v') 00529 && (sc.sc_name.component != 'T') && (sc.sc_name.component != 't')) 00530 logit("et", "SUDSPA_next: unknown station component %c \n", 00531 sc.sc_name.component); 00532 00533 if (datatype == 's') 00534 sc.data_type = 's'; 00535 else 00536 sc.data_type = 'l'; 00537 sc.data_units = 'd'; 00538 00539 if (debug == 1) 00540 logit ("", "Writing STATIONCOMP struct for %s.%s.%c\n", 00541 sc.sc_name.st_name, 00542 sc.sc_name.network, 00543 sc.sc_name.component); 00544 00545 if (StructMakeLocal ((void *) &sc, STATIONCOMP, tag.machine, debug) 00546 != EW_SUCCESS) 00547 { 00548 logit ("et", "SUDSPA_next: Call to StructMakeLocal failed. \n"); 00549 return EW_FAILURE; 00550 } 00551 00552 if (fwrite ((void *) &sc, sizeof (SUDS_STATIONCOMP), 1, SUDSfp) != 1) 00553 { 00554 logit ("et", "SUDSPA_next: error writing SUDS_STATIONCOMP struct. \n"); 00555 return EW_FAILURE; 00556 } 00557 00558 /* Fill and write TAG for the DESCRIPTRACE struct */ 00559 if (datatype == 's') 00560 data_size = nsamp_this_scn * sizeof (short); 00561 else 00562 data_size = nsamp_this_scn * sizeof (long); 00563 tag.id_struct = DESCRIPTRACE; /* what follows is DESCRIPTRACE */ 00564 tag.len_struct = sizeof (SUDS_DESCRIPTRACE); 00565 tag.len_data = (long) data_size; 00566 00567 if (debug == 1) 00568 logit ("", "Writing tag for %d (%d)\n", tag.id_struct, tag.len_struct); 00569 00570 if (StructMakeLocal ((void *) &tag, STRUCTTAG, tag.machine, debug) != EW_SUCCESS) 00571 { 00572 logit ("et", "SUDSPA_next: Call to StructMakeLocal failed. \n"); 00573 return EW_FAILURE; 00574 } 00575 00576 if (fwrite ((void *) &tag, sizeof (SUDS_STRUCTTAG), 1, SUDSfp) != 1) 00577 { 00578 logit ("et", "SUDSPA_next: error writing SUDS tag. \n"); 00579 return EW_FAILURE; 00580 } 00581 00582 /* Fill and write DESCRIPTRACE struct */ 00583 /*strcpy (dt.dt_name.st_name, wf->sta); 00584 strcpy (dt.dt_name.network, wf->net); 00585 dt.dt_name.component = wf->chan[0]; 00586 */ 00587 /* in SUDS_STATIDENT structure, char st_name[5], 00588 char network[4], char component where component = v,n,e 00589 cjb 5/18/2001 */ 00590 if (strlen(wf->sta) > 5) { 00591 strncpy(dt.dt_name.st_name, wf->sta, 4); 00592 dt.dt_name.st_name[4] = '\0'; 00593 } 00594 else 00595 strcpy (dt.dt_name.st_name, wf->sta); 00596 00597 if (strlen(wf->net) > 4) { 00598 strncpy(dt.dt_name.network, wf->net, 3); 00599 dt.dt_name.network[3] = '\0'; 00600 } 00601 else 00602 strcpy (dt.dt_name.network, wf->net); 00603 00604 if (strlen(wf->chan) >= 3) 00605 dt.dt_name.component = wf->chan[2]; 00606 else 00607 dt.dt_name.component = wf->chan[0]; 00608 00609 if ((dt.dt_name.component == 'Z') || (dt.dt_name.component == 'z')) 00610 dt.dt_name.component = 'V'; 00611 00612 if ((dt.dt_name.component != 'N') && (dt.dt_name.component != 'n') 00613 && (dt.dt_name.component != 'E') && (dt.dt_name.component != 'e') 00614 && (dt.dt_name.component != 'V') && (dt.dt_name.component != 'v') 00615 && (dt.dt_name.component != 'T') && (dt.dt_name.component != 't')) 00616 logit("et", "SUDSPA_next: error with station component %c \n", 00617 dt.dt_name.component); 00618 00619 00620 if (datatype == 's') 00621 dt.datatype = 's'; 00622 else 00623 dt.datatype = 'l'; 00624 dt.begintime = begintime; 00625 dt.length = nsamp_this_scn; 00626 dt.rate = (float) wf->samprate; 00627 dt.mindata = (float) min; 00628 dt.maxdata = (float) max; 00629 00630 /* Ignore the rest for now - see how it works */ 00631 00632 if (debug == 1) 00633 logit ("", "Writing DESCRIPTRACE - %d samples (%d,%d) \n", 00634 nsamp_this_scn, min, max); 00635 00636 if (StructMakeLocal ((void *) &dt, DESCRIPTRACE, tag.machine, debug) != EW_SUCCESS) 00637 { 00638 logit ("et", "SUDSPA_next: Call to StructMakeLocal failed. \n"); 00639 return EW_FAILURE; 00640 } 00641 00642 if (fwrite ((void *) &dt, sizeof (SUDS_DESCRIPTRACE), 1, SUDSfp) != 1) 00643 { 00644 logit ("et", "SUDSPA_next: error writing DESCRIPTRACE struct. \n"); 00645 return EW_FAILURE; 00646 } 00647 00648 /* write TRACE data - SudsBuffer holds long data; 00649 SudsBufferShort holds short data */ 00650 if (debug == 1) 00651 logit ("", "Writing %d bytes of DESCRIPTRACE data\n", data_size); 00652 if (datatype == 's') 00653 { 00654 if ((long)fwrite ((void *) SudsBufferShort, sizeof (char), data_size, SUDSfp) 00655 != data_size) 00656 { 00657 logit ("et", "SUDSPA_next: error writing short TRACE data. \n"); 00658 return EW_FAILURE; 00659 } 00660 } 00661 else 00662 { 00663 if ((long)fwrite ((void *) SudsBuffer, sizeof (char), data_size, SUDSfp) 00664 != data_size) 00665 { 00666 logit ("et", "SUDSPA_next: error writing long TRACE data. \n"); 00667 return EW_FAILURE; 00668 } 00669 } 00670 return EW_SUCCESS; 00671 } 00672 00673 00674 /************************************************************************ 00675 * This is the Put Away end event routine. It's called after we've * 00676 * finished processing one event * 00677 * * 00678 * For PC-SUDS - close the SUDS file, pointed to by SUDSfp * 00679 * free SudsBuffer memory to be nice to everyone else * 00680 *************************************************************************/ 00681 int SUDSPA_end_ev(int debug) 00682 { 00683 fclose (SUDSfp); 00684 00685 if (debug == 1) 00686 logit("t", "Closing SUDS file \n"); 00687 00688 return( EW_SUCCESS ); 00689 } 00690 00691 00692 /************************************************************************ 00693 * This is the Put Away close routine. It's called after when * 00694 * we're being shut down. * 00695 *************************************************************************/ 00696 int SUDSPA_close(int debug) 00697 { 00698 00699 free ((char *) SudsBufferShort); 00700 free ((char *) SudsBuffer); 00701 return( EW_SUCCESS ); 00702 } 00703 00704 00705 /* 00706 * 00707 * Byte swapping functions 00708 */ 00709 00710 /* swap bytes if necessary, depending on what machine */ 00711 /* we have been compiled, and what machine the data */ 00712 /* is being read from/being written to */ 00713 00714 static int StructMakeLocal(void *ptr, int struct_type, char data_type, 00715 int debug) 00716 { 00717 if (ptr == NULL) 00718 { 00719 logit ("e", "StructMakeLocal: NULL pointer passed in\n"); 00720 return EW_FAILURE; 00721 } 00722 00723 #if defined (_INTEL) 00724 if (data_type != '6') 00725 { 00726 if (debug == 1) 00727 logit ("", "Swapping from Intel to Sun \n"); 00728 00729 /* if we are on intel, and target data is not intel */ 00730 if (SwapDo (ptr, struct_type) != EW_SUCCESS) 00731 { 00732 logit ("e", "StructMakeLocal: Call to SwapDo failed \n"); 00733 return EW_FAILURE; 00734 } 00735 } 00736 00737 #elif defined (_SPARC) 00738 if (data_type == '6') 00739 { 00740 if (debug == 1) 00741 logit ("", "Swapping from Sun to Intel \n"); 00742 00743 /* if we are on solaris, and target data is not solaris */ 00744 if (SwapDo (ptr, struct_type) != EW_SUCCESS) 00745 { 00746 logit ("e", "StructMakeLocal: Call to SwapDo failed \n"); 00747 return EW_FAILURE; 00748 } 00749 } 00750 00751 #endif 00752 return EW_SUCCESS; 00753 } 00754 00755 00756 /* Do the dirty work by swapping the innards of SUDS */ 00757 /* structures that are of interest to us */ 00758 static int SwapDo( void *ptr, int struct_type) 00759 { 00760 SUDS_STRUCTTAG *tag; 00761 SUDS_STATIONCOMP *sc; 00762 SUDS_DESCRIPTRACE *dt; 00763 SUDS_TRIGGERS *tr; 00764 SUDS_DETECTOR *de; 00765 SUDS_TIMECORRECTION *tc; 00766 00767 if (ptr == NULL) 00768 { 00769 logit ("e", "SwapDo: NULL pointer passed in.\n"); 00770 return EW_FAILURE; 00771 } 00772 00773 switch( struct_type ) 00774 { 00775 case STRUCTTAG: 00776 tag = (SUDS_STRUCTTAG *) ptr; 00777 SwapShort (&tag->id_struct); 00778 SwapLong (&tag->len_struct); 00779 SwapLong (&tag->len_data); 00780 break; 00781 case STATIONCOMP: 00782 sc = (SUDS_STATIONCOMP *) ptr; 00783 SwapShort (&sc->sc_name.inst_type); 00784 SwapShort (&sc->azim); 00785 SwapShort (&sc->incid); 00786 SwapDouble (&sc->st_lat); 00787 SwapDouble (&sc->st_long); 00788 SwapFloat (&sc->elev); 00789 SwapShort (&sc->rocktype); 00790 SwapFloat (&sc->max_gain); 00791 SwapFloat (&sc->clip_value); 00792 SwapFloat (&sc->con_mvolts); 00793 SwapShort (&sc->channel); 00794 SwapShort (&sc->atod_gain); 00795 SwapLong (&sc->effective); 00796 SwapFloat (&sc->clock_correct); 00797 SwapFloat (&sc->station_delay); 00798 break; 00799 case DESCRIPTRACE: 00800 dt = (SUDS_DESCRIPTRACE *) ptr; 00801 SwapShort (&dt->dt_name.inst_type); 00802 SwapDouble (&dt->begintime); 00803 SwapShort (&dt->localtime); 00804 SwapShort (&dt->digi_by); 00805 SwapShort (&dt->processed); 00806 SwapLong (&dt->length); 00807 SwapFloat (&dt->rate); 00808 SwapFloat (&dt->mindata); 00809 SwapFloat (&dt->maxdata); 00810 SwapFloat (&dt->avenoise); 00811 SwapLong (&dt->numclip); 00812 SwapDouble (&dt->time_correct); 00813 SwapFloat (&dt->rate_correct); 00814 break; 00815 case TRIGGERS: 00816 tr = (SUDS_TRIGGERS *) ptr; 00817 SwapShort (&tr->tr_name.inst_type); 00818 SwapShort (&tr->sta); 00819 SwapShort (&tr->lta); 00820 SwapShort (&tr->abs_sta); 00821 SwapShort (&tr->abs_lta); 00822 SwapShort (&tr->trig_value); 00823 SwapShort (&tr->num_triggers); 00824 SwapDouble (&tr->trig_time); 00825 break; 00826 case DETECTOR: 00827 de = (SUDS_DETECTOR *) ptr; 00828 SwapFloat (&de->versionnum); 00829 SwapLong (&de->event_number); 00830 SwapLong (&de->spareL); 00831 break; 00832 case TIMECORRECTION: 00833 tc = (SUDS_TIMECORRECTION *) ptr; 00834 SwapShort (&tc->tm_name.inst_type); 00835 SwapDouble (&tc->time_correct); 00836 SwapFloat (&tc->rate_correct); 00837 SwapLong (&tc->effective_time); 00838 SwapShort (&tc->spareM); 00839 break; 00840 default: 00841 logit ("e", "SwapDo: Don't know about type %d\n", struct_type); 00842 return EW_FAILURE; 00843 } 00844 00845 return EW_SUCCESS; 00846 } 00847