Main Page Class Hierarchy Compound List File List Compound Members File Members

# wave_client.c

Go to the documentation of this file.

    00001
    00002 /*
    00003  *   THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE
    00004  *   CHECKED IT OUT USING THE COMMAND CHECKOUT.
    00005  *
    00006  *    $Id: wave__client_8c-source.html,v 1.1 2006/05/19 16:55:02 paulf Exp $
    00007  *
    00008  *    Revision history:
    00009  *     $Log: wave__client_8c-source.html,v $
    00009  *     Revision 1.1  2006/05/19 16:55:02  paulf
    00009  *     first inclusion
    00009  *
    00010  *     Revision 1.2  2001/04/17 17:30:42  davidk
    00011  *     added an explicit typecast to get rid of a compiler warning on NT.
    00012  *
    00013  *     Revision 1.1  2000/02/14 18:51:48  lucky
    00014  *     Initial revision
    00015  *
    00016  *
    00017  */
    00018
    00019 /*
    00020    wave_client.c
    00021
    00022    Contains functions for connecting to a wave_server's socket, making
    00023    a request for a time-chunk of waveforms, and writing the requested
    00024    data to a disk file.
    00025    Library routines for talking to the original "wave_server".
    00026
    00027    Returns the number of waveform messages received.
    00028 */
    00029
    00030 #include <stdlib.h>
    00031 #include <errno.h>
    00032 #include <stdio.h>
    00033 #include <string.h>
    00034 #include <earthworm.h>
    00035 #include <kom.h>
    00036 #include "wave_client.h"
    00037
    00038 #define MAX_MSG_LEN  126
    00039
    00040 /* Global variables
    00041  ******************/
    00042 static int      Config_Init = 0;      /* 1=config file has been read        */
    00043 static struct hostent    *Host;       /* Contains host ip address           */
    00044 static struct sockaddr_in Sin;        /* Server's socket address stucture   */
    00045 static unsigned long      Addr;       /* binary form of server's ip address */
    00046
    00047 /*********************************************************
    00048  *                       wave_request                    *
    00049  *     Connects to socket, requests data, writes file    *
    00050  *********************************************************/
    00051 int wave_request( double  ton,       /* start-time of requested waveforms */
    00052                   double  toff,      /* end-time of requested waveforms   */
    00053                   char   *pathfile ) /* where to write file of waveforms  */
    00054 {
    00055    char          request[MAX_MSG_LEN];
    00056    char         *buf, *bufptr;
    00057    FILE         *fp;
    00058    long          maxbuflen;
    00059    long          databuflen;
    00060    long          ntoget;
    00061    long          getatonce;
    00062    int           sd;                   /* Socket descriptor */
    00063    int           ir, nr;
    00064    int           ndatabuf, nbufrec;
    00065    int           length;
    00066    int           ret;
    00067    unsigned char inst, module, type;   /* logo of incoming waveform messages */
    00068    char          c;
    00069    int           i, m, t;
    00070
    00071 /* Make sure configuration file has been read
    00072  ********************************************/
    00073    if ( !Config_Init )
    00074    {
    00075       /*printf("wave_request: Config file has not been read.\n" );*/ /*DEBUG*/
    00076       return( ERR_NOCONFIG );
    00077    }
    00078
    00079 /* Open the file that will contain the trace data
    00080  ************************************************/
    00081    fp = fopen( pathfile, "wb" );
    00082    if ( fp == NULL )
    00083    {
    00084       /*printf("wave_request: Error opening output file <%s>\n",
    00085               pathfile );*/ /*DEBUG*/
    00086       return( ERR_FILEIO );
    00087    }
    00088
    00089 /* Set up socket connection here
    00090  *******************************/
    00091    if ( (sd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 )
    00092    {
    00093       logit( "t", "wave_request: Socket call failed.\n" );
    00094       SocketPerror( "wave_request: Socket call failed" );
    00095       fclose( fp );
    00096       return( ERR_SOCKET );
    00097    }
    00098
    00099    if ( connect( sd, (struct sockaddr *)&Sin, sizeof(Sin) ) == -1 )
    00100    {
    00101       logit( "t", "wave_request: Connect to wave_server host failed.\n" );
    00102       SocketPerror( "wave_request: Connect to wave_server host failed" );
    00103       ret = ERR_SOCKET;
    00104       goto done;
    00105    }
    00106
    00107 /* Build and send a request to the wave_server
    00108  *********************************************/
    00109    sprintf( request, "REQ: %15.2f %15.2f\n", ton, toff );
    00110    length = (int) strlen(request);
    00111    if ( send( sd, request, length, 0 ) == -1 )
    00112    {
    00113       logit( "t", "wave_request: Error sending waveform request.\n" );
    00114       SocketPerror( "wave_request: Error sending waveform request" );
    00115       ret = ERR_SOCKET;
    00116       goto done;
    00117    }
    00118
    00119 /* Start reading the socket, one character at a time
    00120  ***************************************************/
    00121    ir = 0;
    00122    do
    00123    {
    00124       if ( ir == MAX_MSG_LEN ) {        /* stop if there's no more room */
    00125          /*printf("wave_request: wave_server reply too long.\n ");*/ /*DEBUG*/
    00126          ret = ERR_OVRFLW;
    00127          goto done;
    00128       }
    00129       nr = recv( sd, &c, 1, 0 );        /* try to get a char from socket*/
    00130       if ( nr == 1 ) {                  /* got a character; save it     */
    00131          request[ir++] = c;
    00132       }
    00133       else if ( nr == -1 ) {            /* trouble reading socket       */
    00134          logit( "e", "wave_request: Error on socket recv\n" );
    00135          ret = ERR_SOCKET;
    00136          goto done;
    00137       }
    00138    } while( c != '\n' );                /* last char of reply           */
    00139    request[ir] = '\0';                  /* null-terminate the reply     */
    00140
    00141 /* Process inquiry reply from wave_server
    00142  ****************************************/
    00143    if( sscanf( request, "%d %d %d %ld %d",
    00144                &i, &m, &t, &maxbuflen, &ndatabuf ) < 5 )
    00145    {
    00146         logit("e","wave_request: error decoding wave_server reply:\n%s\n",
    00147                request );
    00148         inst     = 0;
    00149         module   = 0;
    00150         type     = 0;
    00151         ndatabuf = 0;
    00152         ret      = ERR_STRIO;
    00153         goto done;
    00154    }
    00155    if ( i<256 && i>0 ) {
    00156         inst = (unsigned char) i;
    00157    }
    00158    else {
    00159         logit( "e", "wave_request: invalid installation id <%d>\n", i );
    00160         inst = 0;
    00161    }
    00162    if ( m<256 && m>0 ) {
    00163         module = (unsigned char) m;
    00164    }
    00165    else {
    00166         logit( "e", "wave_request: invalid module id <%d>\n", m );
    00167         module = 0;
    00168    }
    00169    if ( t<256 && t>0 ) {
    00170         type = (unsigned char) t;
    00171    }
    00172    else {
    00173         logit( "e", "wave_request: invalid msg type <%d>\n", t );
    00174         type = 0;
    00175    }
    00176    /*printf("wave_request: accepting %d msg(s) of logo Inst:%d Mod:%d Type:%d\n",
    00177            ndatabuf, (int) inst, (int) module, (int) type );*/ /*DEBUG*/
    00178
    00179 /* Bail out if there's no data coming
    00180  ************************************/
    00181    if ( ndatabuf == 0 )
    00182    {
    00183       /*printf("wave_request: Requested time period not in tank\n");*/ /*DEBUG*/
    00184       ret = ERR_NODATA;
    00185       goto done;
    00186    }
    00187
    00188 /* Allocate memory for incoming messages
    00189  ***************************************/
    00190    buf = (char *) malloc( (size_t) maxbuflen );
    00191    if ( buf == (char *)NULL )
    00192    {
    00193       /*printf("wave_request: Error allocating memory buffer.\n");*/ /*DEBUG*/
    00194       ret = ERR_ALLOC;
    00195       goto done;
    00196    }
    00197
    00198 /* Loop reading messages from socket
    00199  ***********************************/
    00200    nbufrec = 0;
    00201    do
    00202    {
    00203
    00204    /* Read the size of the next message from the socket
    00205     ***************************************************/
    00206       ir = 0;
    00207       do
    00208       {
    00209          if ( ir == maxbuflen ) {       /* stop if there's no more room */
    00210              ret = ERR_OVRFLW;
    00211              goto almostdone;
    00212          }
    00213          nr = recv( sd, &c, 1, 0 );     /* try to get a char from socket*/
    00214          if ( nr == 1 ) {               /* got a character; save it     */
    00215              buf[ir++] = c;
    00216          }
    00217          else if ( nr == -1 ) {         /* trouble reading socket       */
    00218              logit( "e", "wave_request: Error on socket recv\n" );
    00219              ret = ERR_SOCKET;
    00220              goto almostdone;
    00221          }
    00222       } while( c != '\n' );             /* last char of reply           */
    00223       buf[ir] = '\0';                   /* null-terminate the reply     */
    00224
    00225       sscanf( buf, "%ld", &databuflen );
    00226       /*printf( "wave_request: incoming msg[%ld]\n", databuflen );*/ /*DEBUG*/
    00227
    00228       if( databuflen > maxbuflen )
    00229       {
    00230           logit( "e",
    00231                  "wave_request: Data_buffer:%ld bytes > max_size:%ld\n",
    00232                   databuflen, maxbuflen );
    00233           ret = ERR_OVRFLW;
    00234           goto almostdone;
    00235       }
    00236
    00237    /* Read one waveform message from the server
    00238     *******************************************/
    00239       ntoget = databuflen;
    00240       bufptr = buf;
    00241       while ( ntoget > 0 )
    00242       {
    00243       /* warning: trouble trying to recv 32 kbytes or more at once */
    00244       /*          (recv dies with an "invalid argument" error)     */
    00245          getatonce = ( (ntoget<32000) ? ntoget : 32000 );
    00246          nr = recv( sd, bufptr, getatonce, 0 );
    00247          if ( nr == -1 )
    00248          {
    00249             logit( "t", "wave_request: Error reading socket.\n" );
    00250             SocketPerror( "wave_request: Error reading socket" );
    00251             ret = ERR_SOCKET;
    00252             goto almostdone;
    00253          }
    00254          bufptr += nr;
    00255          ntoget -= nr;
    00256       }
    00257
    00258    /* Get end-of-message flag; make sure it's a newline!
    00259     ****************************************************/
    00260       nr = recv( sd, &c, 1, 0 );
    00261       if ( nr != 1  ||  c != '\n' )
    00262       {
    00263          logit( "e", "wave_request: Error on recv end-of-message flag\n" );
    00264          ret = ERR_SOCKET;
    00265          goto almostdone;
    00266       }
    00267
    00268    /* Write this data buffer to the disk file
    00269     *****************************************/
    00270       if ( fwrite( buf, sizeof(char), databuflen, fp ) != (size_t)databuflen )
    00271       {
    00272          /*printf("wave_request: Error writing to file.\n");*/ /*DEBUG*/
    00273          ret = ERR_FILEIO;
    00274          goto almostdone;
    00275       }
    00276
    00277    } while ( ++nbufrec < ndatabuf );
    00278
    00279 /* Received all the data we requested
    00280  ************************************/
    00281    ret = nbufrec;
    00282
    00283 almostdone:
    00284    free( buf );
    00285
    00286 done:
    00287    SocketClose( sd );
    00288    fclose( fp );
    00289    return( ret );
    00290 }
    00291
    00292
    00293 /********************************************************
    00294  *                       wave_inquire                   *
    00295  *     Asks the wave_server for the time range and      *
    00296  *     and the logo (installation, module and message   *
    00297  *     type) of the data that's stored in the tank      *
    00298  ********************************************************/
    00299 int wave_inquire( double        *tstart, /* start-time of first buffer in tank */
    00300                   double        *tend,   /* start-time of last buffer in tank  */
    00301                   unsigned char *inst,   /* source installation of served data */
    00302                   unsigned char *module, /* source module of served waveforms  */
    00303                   unsigned char *type )  /* type of waveform msg being served  */
    00304 {
    00305    int     sd;                   /* Socket descriptor */
    00306    int     i, m, t;
    00307    char    msg[MAX_MSG_LEN];
    00308    char    c;
    00309    int     length, nrec;
    00310    int     ir;
    00311
    00312 /* Make sure configuration file has been read
    00313  ********************************************/
    00314    if ( !Config_Init )
    00315    {
    00316       /*printf("wave_inquire: Configuration file has not been read.\n");*/ /*DEBUG*/
    00317       return( ERR_NOCONFIG );
    00318    }
    00319
    00320 /* Set up socket connection here
    00321  *******************************/
    00322    if ( (sd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 )
    00323    {
    00324       logit( "t", "wave_inquire: Socket call failed.\n" );
    00325       SocketPerror( "wave_inquire: Socket call failed" );
    00326       return( ERR_SOCKET );
    00327    }
    00328
    00329    if ( connect( sd, (struct sockaddr *)&Sin, sizeof(Sin) ) == -1 )
    00330    {
    00331       logit( "t", "wave_inquire: Connect to wave_server host failed.\n" );
    00332       SocketPerror( "wave_inquire: Connect to wave_server host failed" );
    00333       SocketClose( sd );
    00334       return( ERR_SOCKET );
    00335    }
    00336
    00337 /* Send an inquiry to the wave_server
    00338  ************************************/
    00339    sprintf( msg, "INQ:\n\0" );
    00340    length = (int) strlen( msg );
    00341    if ( send( sd, msg, length, 0 ) == -1 )
    00342    {
    00343       logit( "t", "wave_inquire: Error sending inquiry.\n" );
    00344       SocketPerror( "wave_inquire: Error sending inquiry" );
    00345       SocketClose( sd );
    00346       return( ERR_SOCKET );
    00347    }
    00348
    00349 /* Start reading the socket.
    00350  ***************************/
    00351    nrec = 0;
    00352    do
    00353    {
    00354       if ( nrec == MAX_MSG_LEN ) {      /* stop if there's no more room */
    00355          logit( "e", "wave_inquire: wave_server reply too long.\n " );
    00356          SocketClose( sd );
    00357          return( ERR_OVRFLW );
    00358       }
    00359       ir = recv( sd, &c, 1, 0 );        /* try to get a char from socket*/
    00360       if ( ir == 1 ) {                  /* got a character; save it     */
    00361          msg[nrec++] = c;
    00362       }
    00363       else if ( ir == -1 ) {            /* trouble reading socket       */
    00364          logit( "t", "wave_inquire: Error on socket recv\n" );
    00365          SocketPerror( "wave_inquire: Error on socket recv" );
    00366          SocketClose( sd );
    00367          return( ERR_SOCKET );
    00368       }
    00369    } while( c != '\n' );                /* last char of reply           */
    00370    msg[nrec] = '\0';                    /* null-terminate reply         */
    00371
    00372 /* Process inquiry reply from wave_server
    00373  ****************************************/
    00374    if( sscanf( msg, "%lf %lf %d %d %d", tstart, tend, &i, &m, &t ) < 5 )
    00375    {
    00376         logit( "e", "wave_inquire: error decoding wave_server reply:\n%s\n",
    00377                msg );
    00378        *tstart = 0.;
    00379        *tend   = 0.;
    00380        *inst   = 0;
    00381        *module = 0;
    00382        *type   = 0;
    00383         SocketClose( sd );
    00384         return( ERR_STRIO );
    00385    }
    00386    if ( i<256 && i>0 ) {
    00387        *inst = (unsigned char) i;
    00388    }
    00389    else {
    00390         logit( "e", "wave_inquire: invalid installation id <%d>\n", i );
    00391        *inst = 0;
    00392    }
    00393    if ( m<256 && m>0 ) {
    00394        *module = (unsigned char) m;
    00395    }
    00396    else {
    00397         logit( "e", "wave_inquire: invalid module id <%d>\n", m );
    00398        *module = 0;
    00399    }
    00400    if ( t<256 && t>0 ) {
    00401        *type = (unsigned char) t;
    00402    }
    00403    else {
    00404         logit( "e", "wave_inquire: invalid msg type <%d>\n", t );
    00405        *type = 0;
    00406    }
    00407    SocketClose( sd );
    00408    return( 0 );
    00409 }
    00410
    00411
    00412 /***********************************************************************
    00413  * wave_client_config()  processes command file using kom.c functions  *
    00414  *                    exits if any errors are encountered              *
    00415  ***********************************************************************/
    00416 void wave_client_config( char *configfile )
    00417 {
    00418    int      ncommand;   /* # of required commands you expect to process   */
    00419    char     init[10];   /* init flags, one byte for each required command */
    00420    int      nmiss;      /* number of required commands that were missed   */
    00421    char    *com;
    00422    char    *str;
    00423    int      nfiles;
    00424    int      success;
    00425    int      i;
    00426
    00427 /* Set to zero one init flag for each required command
    00428  *****************************************************/
    00429    ncommand = 2;
    00430    for( i=0; i<ncommand; i++ )  init[i] = 0;
    00431
    00432 /* Open the main configuration file
    00433  **********************************/
    00434    nfiles = k_open( configfile );
    00435    if ( nfiles == 0 ) {
    00436         fprintf( stderr,
    00437                 "wave_client: Error opening command file <%s>; exitting!\n",
    00438                  configfile );
    00439         exit( -1 );
    00440    }
    00441
    00442 /* Process all command files
    00443  ***************************/
    00444    while(nfiles > 0)   /* While there are command files open */
    00445    {
    00446         while(k_rd())        /* Read next line from active file  */
    00447         {
    00448             com = k_str();         /* Get the first token from line */
    00449
    00450         /* Ignore blank lines & comments
    00451          *******************************/
    00452             if( !com )           continue;
    00453             if( com[0] == '#' )  continue;
    00454
    00455         /* Open a nested configuration file
    00456          **********************************/
    00457             if( com[0] == '@' ) {
    00458                success = nfiles+1;
    00459                nfiles  = k_open(&com[1]);
    00460                if ( nfiles != success ) {
    00461                   fprintf( stderr,
    00462                           "wave_client: Error opening command file <%s>; exitting!\n",
    00463                            &com[1] );
    00464                   exit( -1 );
    00465                }
    00466                continue;
    00467             }
    00468
    00469         /* Process anything else as a command
    00470          ************************************/
    00471             /* Read the wave_server's host name
    00472              **********************************/
    00473    /*0*/    if( k_its( "ServerIPAdr" ) )
    00474             {
    00475                 str = k_str();
    00476                 if(str) strcpy( ServerIPAdr, str );
    00477                 init[0] = 1;
    00478             }
    00479             /* Read the port number to find waveform data on
    00480              ***********************************************/
    00481    /*1*/    else if( k_its( "ServerPort" ) )
    00482             {
    00483                 ServerPort = k_int();
    00484                 init[1] = 1;
    00485             }
    00486             /* Command not recognized
    00487              ************************/
    00488             else
    00489             {
    00490                 fprintf(stderr,
    00491                        "wave_client: <%s> unknown command in <%s>.\n",
    00492                         com, configfile );
    00493                 continue;
    00494             }
    00495
    00496         /* See if there were any errors processing the command
    00497          *****************************************************/
    00498             if( k_err() ) {
    00499                fprintf( stderr,
    00500                        "wave_client: Bad <%s> command in <%s>; exitting!\n",
    00501                         com, configfile );
    00502                exit( -1 );
    00503             }
    00504         }
    00505         nfiles = k_close();
    00506    }
    00507
    00508 /* After all files are closed, check init flags for missed commands
    00509  ******************************************************************/
    00510    nmiss = 0;
    00511    for ( i=0; i<ncommand; i++ )  if( !init[i] ) nmiss++;
    00512    if ( nmiss ) {
    00513        fprintf( stderr, "wave_client: ERROR, no " );
    00514        if ( !init[0] )  fprintf( stderr, "<ServerIPAdr> " );
    00515        if ( !init[1] )  fprintf( stderr, "<ServerPort> "   );
    00516        fprintf( stderr, "command(s) in <%s>; exitting!\n", configfile );
    00517        exit( -1 );
    00518    }
    00519
    00520 /* Set up socket address structure for wave_server's machine
    00521  ***********************************************************/
    00522    if((int)(Addr = inet_addr(ServerIPAdr)) == -1)
    00523    {
    00524       fprintf( stderr,
    00525               "wave_client: inet_addr failed for ServerIPAdr <%s>\n",
    00526               ServerIPAdr );
    00527       exit( -1 );
    00528    }
    00529
    00530    Host = gethostbyaddr((char *)&Addr, sizeof(Addr), AF_INET);
    00531    if(Host == NULL)
    00532    {
    00533       fprintf( stderr,
    00534               "wave_client: gethostbyaddr failed for ServerIPAdr <%s>\n",
    00535                ServerIPAdr );
    00536       exit( -1 );
    00537    }
    00538    memset( (char *) &Sin, '\0', sizeof(Sin) );
    00539    memcpy( (char *) &Sin.sin_addr, Host->h_addr, Host->h_length );
    00540    Sin.sin_family = AF_INET;
    00541    Sin.sin_port   = htons( (short)ServerPort );
    00542
    00543 /* Set configuration flag
    00544  ************************/
    00545    Config_Init = 1;
    00546
    00547    return;
    00548 }
    00549
    00550 /***********************************************************************
    00551  * wave_client_setup()  Initializes or resets the global variables     *
    00552  *                      ServerIPAdr & ServerPort used by wave_client   *
    00553  *                      routines to connect to a wave_server           *
    00554  ***********************************************************************/
    00555 int wave_client_setup( char *ipadr,    /* server's IP address    */
    00556                        int   port )    /* server's port number   */
    00557 {
    00558 /* Transfer arguments to wave_client globals
    00559  *******************************************/
    00560      strcpy( ServerIPAdr, ipadr );
    00561      ServerPort = port;
    00562
    00563 /* Set up socket address structure for wave_server's machine
    00564  ***********************************************************/
    00565    if((int)(Addr = inet_addr(ServerIPAdr)) == -1)
    00566    {
    00567       logit( "et",
    00568              "wave_client: inet_addr failed for ServerIPAdr <%s>\n",
    00569               ServerIPAdr );
    00570       return( -1 );
    00571    }
    00572
    00573    Host = gethostbyaddr((char *)&Addr, sizeof(Addr), AF_INET);
    00574    if(Host == NULL)
    00575    {
    00576       logit( "et",
    00577              "wave_client: gethostbyaddr failed for ServerIPAdr <%s>\n",
    00578               ServerIPAdr );
    00579       return( -1 );
    00580    }
    00581    memset( (char *) &Sin, '\0', sizeof(Sin) );
    00582    memcpy( (char *) &Sin.sin_addr, Host->h_addr, Host->h_length );
    00583    Sin.sin_family = AF_INET;
    00584    Sin.sin_port   = htons( (short)ServerPort );
    00585
    00586 /* Set configuration flag
    00587  ************************/
    00588    Config_Init = 1;
    00589
    00590    return( 0 );
    00591 }