
/*
 *   THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE
 *   CHECKED IT OUT USING THE COMMAND CHECKOUT.
 *
 *    $Id: sniffwave.c,v 1.13 2006/03/27 16:57:27 davek Exp $
 *
 *    Revision history:
 *     $Log: sniffwave.c,v $
 *     Revision 1.13  2006/03/27 16:57:27  davek
 *     Added version and quality info to the sniffwave output for each tracebuf.
 *
 *     Revision 1.12  2005/03/30 23:13:26  dietz
 *     Now printing seconds to 4 decimal places.
 *
 *     Revision 1.11  2004/04/13 22:57:32  dietz
 *     modified to work with TYPE_TRACEBUF2 and TYPE_TRACE2_COMP_UA msgs
 *
 *     Revision 1.10  2003/10/31 17:20:43  dietz
 *     Will now sniff both TYPE_TRACEBUF and TYPE_TRACE_COMP_UA msg headers.
 *     Will accept strings "wild", "WILD", and "*" as wildcards in SCN.
 *
 *     Revision 1.9  2002/10/24 22:11:32  dietz
 *     Added message length to printed information
 *
 *     Revision 1.8  2002/07/12 17:49:57  dietz
 *     added #include <time_ew.h>
 *
 *     Revision 1.7  2002/02/02 00:28:58  dietz
 *     Changed to print instid and module on the tracebuf header summary line
 *
 *     Revision 1.6  2001/03/30 01:17:36  dietz
 *     *** empty log message ***
 *
 *     Revision 1.5  2001/03/30 01:10:18  dietz
 *     added newline after every 10 data samples, and an fflush(stdout)
 *     after each tracebuf message.
 *
 *     Revision 1.4  2001/03/29 23:51:03  dietz
 *     Changed ring flush statemnet to while( tport_get... != GET_NONE );
 *
 *     Revision 1.3  2000/08/08 18:18:28  lucky
 *     Lint cleanup
 *
 *     Revision 1.2  2000/05/31 18:29:10  dietz
 *     Fixed to print 4-byte data properly.
 *
 *     Revision 1.1  2000/02/14 19:36:09  lucky
 *     Initial revision
 *
 *
 */


  /*****************************************************************
   *                            sniffwave.c                        *
   *                                                               *
   * Program to read waveform messages from shared memory and      *
   * write to a disk file.                                         *
   *                                                               *
   * Modified by Lucky Vidmar Tue May 11 11:27:35 MDT 1999         *
   *   allows for more arguments which specify                     *
   *     Ring to read from                                         *
   *     SCN of the messages to print                              *
   *     Whether or not trace data should be printed               *
   *                                                               *
   *                                                               *
   * Usage: sniffwave  <Ring> <Sta> <Comp> <Net> <Loc> <Data y/n>  *
   *                                                               *
   *****************************************************************/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <transport.h>
#include <swap.h>
#include <time_ew.h>
#include <trace_buf.h>
#include <earthworm.h>

#define NLOGO 4

int IsWild( char *str )
{
  if( (strcmp(str,"wild")==0)  ) return 1;
  if( (strcmp(str,"WILD")==0)  ) return 1;
  if( (strcmp(str,"*")   ==0)  ) return 1;
  return 0;
}

int main( int argc, char **argv )
{
   SHM_INFO        region;
   long            RingKey;         /* Key to the transport ring to read from */
   MSG_LOGO        getlogo[NLOGO], logo;
   long            gotsize;
   char            msg[MAX_TRACEBUF_SIZ];
   char           *getSta, *getComp, *getNet, *getLoc, *inRing;
   char            wildSta, wildComp, wildNet, wildLoc;
   unsigned char   Type_TraceBuf,Type_TraceBuf2;
   unsigned char   Type_TraceComp, Type_TraceComp2;
   unsigned char   InstWildcard, ModWildcard;
   short          *short_data;
   long           *long_data;
   TRACE2_HEADER  *trh;
   char	           stime[256];
   char	           etime[256];
   int             dataflag;
   int             i;
   int             rc;

  /* Initialize pointers
  **********************/
  trh  = (TRACE2_HEADER *) msg;
  long_data  =  (long *)( msg + sizeof(TRACE2_HEADER) ); 
  short_data = (short *)( msg + sizeof(TRACE2_HEADER) );

  /* Check command line argument 
  *****************************/
  if ( argc != 7 )
  {
     fprintf(stderr,"Usage:   %s <ring name> <station> <component> <network> <loc> <data flag y/n>\n", argv[0]);
     fprintf(stderr,"Example: %s WAVE_RING PHOB wild NC wild n\n", argv[0] );
     exit( 1 );
  }
  inRing  = argv[1];
  getSta  = argv[2];
  getComp = argv[3];
  getNet  = argv[4];
  getLoc  = argv[5];

  wildSta  = IsWild( getSta  );
  wildComp = IsWild( getComp );
  wildNet  = IsWild( getNet  );
  wildLoc  = IsWild( getLoc  );

  if(strcmp (argv[6], "y") == 0)
     dataflag = 1;
  else if(strcmp (argv[6], "n") == 0)
     dataflag = 0;
  else
  {
    fprintf(stderr, "sniffwave: specify data flag - y or n\n");
    exit (1);
  }

  fprintf(stdout, "Sniffing %s for %s.%s.%s.%s\n", 
          inRing, getSta, getComp, getNet, getLoc);
  
  /* Open log file
  ****************/
  logit_init( "sniffwave", 99, 100, 1 );

  /* Attach to ring
  *****************/
  if ((RingKey = GetKey( inRing )) == -1 )
  {
    logit( "e", "Invalid RingName; exiting!\n" );
    exit( -1 );
  }
  tport_attach( &region, RingKey );

  /* Specify logos to get
  ***********************/
  if ( GetType( "TYPE_TRACEBUF", &Type_TraceBuf ) != 0 ) {  
     logit("e","%s: Invalid message type <TYPE_TRACEBUF>!\n", argv[0] );
     exit( -1 );
  }
  if ( GetType( "TYPE_TRACEBUF2", &Type_TraceBuf2 ) != 0 ) {  
     logit("e","%s: Invalid message type <TYPE_TRACEBUF2>!\n", argv[0] );
     exit( -1 );
  }
  if ( GetType( "TYPE_TRACE_COMP_UA", &Type_TraceComp ) != 0 ) {  
     logit("e","%s: Invalid message type <TYPE_TRACE_COMP_UA>!\n", argv[0] );
     exit( -1 );
  }
  if ( GetType( "TYPE_TRACE2_COMP_UA", &Type_TraceComp2 ) != 0 ) {  
     logit("e","%s: Invalid message type <TYPE_TRACE2_COMP_UA>!\n", argv[0] );
     exit( -1 );
  }
  if ( GetModId( "MOD_WILDCARD", &ModWildcard ) != 0 ) {  
     logit("e","%s: Invalid moduleid <MOD_WILDCARD>!\n", argv[0] );
     exit( -1 );
  }
  if ( GetInst( "INST_WILDCARD", &InstWildcard ) != 0 ) {  
     logit("e","%s: Invalid instid <INST_WILDCARD>!\n", argv[0] );
     exit( -1 );
  } 

  for( i=0; i<NLOGO; i++ ) {
      getlogo[i].instid = InstWildcard;
      getlogo[i].mod    = ModWildcard;
  }
  getlogo[0].type = Type_TraceBuf2;
  getlogo[1].type = Type_TraceComp2;
  getlogo[2].type = Type_TraceBuf;
  getlogo[3].type = Type_TraceComp;

  /* Flush the ring
  *****************/
  while ( tport_getmsg( &region, getlogo, NLOGO, &logo, &gotsize,
			(char *)&msg, MAX_TRACEBUF_SIZ ) != GET_NONE );
  logit( "et", "sniffwave: inRing flushed.\n");
                          
  while ( tport_getflag( &region ) != TERMINATE )
  {
    rc = tport_getmsg( &region, getlogo, NLOGO,
		       &logo, &gotsize, msg, MAX_TRACEBUF_SIZ );

    if ( rc == GET_NONE )
    {
      sleep_ew( 200 );
      continue;
    }

    if ( rc == GET_TOOBIG )
    {
      logit( "et", "sniffwave: retrieved message too big (%d) for msg\n",
	    gotsize );
      continue;
    }

    if ( rc == GET_NOTRACK )
      logit( "et", "sniffwave: Tracking error.\n");

    if ( rc == GET_MISS_LAPPED )
      logit( "et", "sniffwave: Got lapped on the ring.\n");

    if ( rc == GET_MISS_SEQGAP )
      logit( "et", "sniffwave: Gap in sequence numbers\n");

    if ( rc == GET_MISS )
      logit( "et", "sniffwave: Missed messages\n");

    /* Check SCNL of the retrieved message */
	
    if ( (wildSta  || (strcmp(getSta,trh->sta)  ==0)) &&
         (wildComp || (strcmp(getComp,trh->chan)==0)) &&
	 (wildNet  || (strcmp(getNet,trh->net)  ==0)) && 
         (wildLoc  || (strcmp(getLoc,trh->loc)  ==0)  
                   || logo.type == Type_TraceBuf  
                   || logo.type == Type_TraceComp   )    ) 
    {
      WaveMsg2MakeLocal( trh );

      datestr23 (trh->starttime, stime, 256);
      datestr23 (trh->endtime,   etime, 256);

      if( logo.type == Type_TraceBuf2  || 
          logo.type == Type_TraceComp2    ) {
          fprintf( stdout, "%s.%s.%s.%s (0x%x 0x%x) ",
                   trh->sta, trh->chan, trh->net, trh->loc, trh->version[0], trh->version[1] );
      } else {
          fprintf( stdout, "%s.%s.%s ",
                   trh->sta, trh->chan, trh->net );
      }
      fprintf( stdout, "%d %s %d %.1f %s (%.4f) %s (%.4f) %c%c i%d m%d t%d len%d\n",
               trh->pinno, trh->datatype, trh->nsamp, trh->samprate,
               stime, trh->starttime,
               etime, trh->endtime, trh->quality[0], trh->quality[1],
               (int)logo.instid, (int)logo.mod, (int)logo.type, gotsize );

      if (dataflag == 1)
      {
        if( logo.type == Type_TraceBuf2 ||
            logo.type == Type_TraceBuf     ) 
        {
          if ( (strcmp (trh->datatype, "s2")==0) || 
               (strcmp (trh->datatype, "i2")==0)    )
          {
            for ( i = 0; i < trh->nsamp; i++ ) {
              fprintf ( stdout, "%6hd ", *(short_data+i) ); 
              if(i%10==9) fprintf ( stdout, "\n" );
            }
          }
          else if ( (strcmp (trh->datatype, "s4")==0) || 
                    (strcmp (trh->datatype, "i4")==0)    )
          {
            for ( i = 0; i < trh->nsamp; i++ ) {
              fprintf ( stdout, "%6ld ", *(long_data+i) );
              if(i%10==9) fprintf ( stdout, "\n" ); 
            }
          }
          else
          {
             fprintf (stdout, "Unknown datatype %s\n", trh->datatype);
          }
        } else {
             fprintf (stdout, "Data values compressed\n");
        }
        fprintf (stdout, "\n");
        fflush (stdout);
      }
 
    }
  }

  exit (0);
}

