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 2161 2006-05-19 16:55:03Z paulf $
00007  *
00008  *    Revision history:
00009  *     $Log$
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 }

Generated on Tue May 6 09:16:13 2003 for Earthworm Libs by doxygen1.3-rc3