head 1.1; access ; symbols ; locks oasisa:1.1; strict; comment @ * @; 1.1 date 2001.06.19.13.03.04; author oasisa; state Exp; branches ; next ; desc @Periodic Update w/ changes to utils plus new utils 6/19/2001 (klh) @ 1.1 log @Initial revision @ text @/****************************************************************************/ /* Copyright 1992 MBARI */ /****************************************************************************/ /* $Header: getoasis.c,v 1.2 99/07/28 15:27:09 teto Exp $ */ /* Summary : Program to download OASIS data */ /* Filename : getoasis.c */ /* Author : Robert Herlien (rah) */ /* Project : OASIS Mooring */ /* $Revision: 1.2 $ */ /* Created : 02/22/92 */ /* */ /* MBARI provides this documentation and code "as is", with no warranty, */ /* express or implied, of its quality or consistency. It is provided without*/ /* support and without obligation on the part of the Monterey Bay Aquarium */ /* Research Institute to assist in its use, correction, modification, or */ /* enhancement. This information should not be published or distributed to */ /* third parties without specific written permission from MBARI. */ /* */ /****************************************************************************/ /* Modification History: */ /* 22feb92 rah - created, from gps.c */ /* $Log: getoasis.c,v $ * Revision 1.2 99/07/28 15:27:09 15:27:09 teto (Tom Tengdin) * As found. About to change the port * T3 * * Revision 1.1 99/07/27 16:14:37 16:14:37 teto (Tom Tengdin) * Initial revision * * Revision 3.0 99/05/12 10:11:28 10:11:28 bobh (Bob Herlien) * Added tstring, misc changes * * Revision 2.9 98/08/24 13:45:56 13:45:56 bobh (Bob Herlien) * Archiving sources after M2/M3 & Eqpac deployments of 1998 * * Revision 2.8 98/03/17 11:11:43 11:11:43 bobh (Bob Herlien) * Archiving sources prior to porting to DOS/Windows * * Revision 2.7 97/09/09 09:52:48 09:52:48 bobh (Bob Herlien) * Archiving various changes * * Revision 1.5 94/01/17 11:07:42 11:07:42 hebo (Bob Herlien) * Misc changes * * Revision 1.4 92/06/22 14:48:11 14:48:11 hebo (Bob Herlien) * Fixed timeout bug in wait_for_prompt() that caused early abort. * * Revision 1.3 92/06/22 10:20:22 10:20:22 hebo (Bob Herlien) * Fixed bug in tnc_cmd_mode. Added error message if release_port() fails. * * Revision 1.2 92/05/29 09:13:14 09:13:14 hebo (Bob Herlien) * Changed restore parameters to delete "M OFF", add "EC ON" * Deleted #define _HPUX_SOURCE. It's now defined in Makefile. * * Revision 1.1 92/03/16 15:44:43 15:44:43 hebo (Bob Herlien) * First working version * * Revision 1.0 92/03/12 13:59:22 13:59:22 hebo (Bob Herlien) * Initial revision */ /****************************************************************************/ #include /* Standard I/O */ #include /* For exit() */ #include /* For FD_ISSET, etc */ #include /* MBARI type definitions */ #include /* MBARI constants */ #include /* For timeout */ #include /* For terminal I/O stuff */ #include /* For open() stuff */ #include /* For signal() */ #include /* For ioctl() */ #include /* For NOFILE */ #include /* For toupper() */ #include /* For strchr() */ #include "decode.h" /* For LogStruct */ #define TNC_DEV "tty0p1" /* Default radio device file */ #define BUFSIZE 1023 /* Size of line buffer */ #define OPROMPT "OASIS>" /* OASIS prompt */ #define CAN_NAME "m4" /* Can name */ #define ARG_ERR 1 /* Bad command line arg exit() code */ #define PORT_ERR 2 /* Serial port error exit() code */ #define CONNECT_ERR 3 /* Can't connect exit() code */ #define DOWNLOAD_ERR 4 /* Download error exit() code */ #define ABORT_ERR 5 /* Aborted exit() code */ /********************************/ /* External Functions */ /********************************/ /* From port.c */ Extern MBool set_baud( struct termio *tp, Int baud ); Extern Int get_port( char *name, Int mode, struct termio *setup, struct termio *save ); Extern Status release_port( char *name, Int fd, struct termio *parms ); Extern Void rcdInit( LogStruct *lp ); Extern MBool readRcd( char *can, LogStruct *lp ); Extern MBool getMissingRcd( LogStruct *lp, Nat32 lognum, Nat32 last, RcdRange *rcd ); /********************************/ /* External Data */ /********************************/ Extern char *optarg; /* Option argument from getopt() */ Extern Int optind; /* Option index from getopt() */ Extern Int opterr; /* getopt() error flag */ Extern char *rcdfile; /* File of record numbers */ /********************************/ /* Module Local Data */ /********************************/ MLocal char *tncfile = TNC_DEV; /* Radio TNC device file */ MLocal time_t timeout = 660; /* 11 minute timeout by default */ MLocal MBool get_rcds = FALSE; /* TRUE to get missing records */ MLocal Int32 tfd = ERROR; /* TNC file descriptor */ MLocal MBool echo = FALSE; /* TRUE to echo tnc reads to stdout */ MLocal MBool aborted = FALSE; /* Set from signal handler */ MLocal char rbuf[BUFSIZE+1]; /* Read line buffer */ MLocal Nat32 rcnt = 0; /* # chars in rbuf */ MLocal LogStruct logs; /* Which records have been read */ MLocal char *can_name = CAN_NAME; /* Can name */ MLocal struct termio tnc_term = /* Termio characteristics for TNC */ { IGNPAR, /* c_iflag */ 0, /* c_oflag */ B9600 | CS8 | CREAD | CLOCAL, /* c_cflag */ NOFLSH, /* c_lflag */ 0, /* c_line, HP has no line disciplines*/ {0, 0, 0, 0, 0, 10, 0, 0} /* control chars (1 second timeout) */ }; MLocal struct termio tnc_save; /* Place to save terminal charac. */ /********************************/ /* Forward Declarations */ /********************************/ MBool process_command_line ( Int argc, char **argv ); Void use_msg( char *s ); Status wait_for_output( char *matchStr, char sendChar ); Status connect_tnc( Void ); Status write_tnc( char *s ); Status get_missing_records( Void ); Status get_data( Void ); Void quit( Int sig ); /************************************************************************/ /* Function : main */ /* Purpose : Main routine */ /* Inputs : argc, argv */ /* Outputs : none */ /************************************************************************/ Void main( Int argc, char **argv ) { Int rtn; /* exit() code */ printf("OASIS download program $Revision: 1.2 $\n"); if ( !process_command_line(argc, argv) ) { use_msg(argv[0]); exit( ARG_ERR ); } signal(SIGTERM, quit); /* Catch terminate signals */ signal(SIGHUP, quit); signal(SIGINT, quit); signal(SIGQUIT, quit); if ( (tfd = get_port(tncfile, O_RDWR, &tnc_term, &tnc_save)) == ERROR ) { printf( "Couln't acquire serial port %s\n", tncfile ); exit( PORT_ERR ); } printf("Acquired serial port %s\n", tncfile); if ( connect_tnc() == OK ) { rtn = wait_for_output(OPROMPT, '\r'); if ( rtn == OK ) rtn = get_data(); if ( get_rcds && (rtn == OK) ) rtn = get_missing_records(); write_tnc( "quit\r" ); sleep( 3 ); } else { printf( "Couldn't establish radio communication\n" ); rtn = CONNECT_ERR; } printf("\n"); if ( release_port(tncfile, tfd, &tnc_save) == ERROR ) printf( "Error in releasing serial port %s\n", tncfile ); exit( aborted ? ABORT_ERR : rtn ); } /* main() */ /************************************************************************/ /* Function : use_msg */ /* Purpose : Print Usage Message */ /* Inputs : Name of program */ /* Outputs : None */ /************************************************************************/ Void use_msg( char *s ) { fprintf( stderr, "Usage: %s [-b baud] [-c can] [-p port] ", s ); fprintf( stderr, "[-r rcd_file] [-t timeout]\n"); } /* use_msg() */ /************************************************************************/ /* Function : process_command_line */ /* Purpose : Read the arguments from the command line */ /* Inputs : argc, argv from main() routine */ /* Outputs : TRUE if arguments OK, else FALSE */ /************************************************************************/ MBool process_command_line ( Int argc, char **argv ) { Int i, baud; while ( (i = getopt(argc, argv, "b:c:p:r:t:")) != EOF ) switch( i ) { case 'b': if ( !set_baud(&tnc_term, atoi(optarg)) ) return( FALSE ); break; case 'c': can_name = optarg; get_rcds = TRUE; break; case 'p': tncfile = optarg; break; case 'r': rcdfile = optarg; get_rcds = TRUE; break; case 't': timeout = 60 * atoi(optarg); break; default: return( FALSE ); } return( TRUE ); } /* process_command_line() */ /****************************************************************************/ /* Function : find_str */ /* Purpose : Find target string embedded in source string, case insens */ /* Inputs : Source string ptr, Target string ptr */ /* Outputs : NULL if strings don't match, else ptr to next char of source*/ /****************************************************************************/ char * find_str( char *src, char *tgt ) { Reg char *p, *p1, *q; for ( p1 = src; *p1; p1++ ) { for( p = p1, q = tgt; ; p++, q++ ) { if ( *q == '\0' ) return( p ); if ( *p == '\0' ) return( NULL ); if ( toupper(*p) != toupper(*q) ) break; } } return( NULL ); } /* find_str() */ /************************************************************************/ /* Function : gets_tnc_tmout */ /* Purpose : Read one line from TNC with timeout */ /* Inputs : Buffer, length, timeout (seconds) */ /* Outputs : Number of characters read, or ERROR */ /* Comment : Needs a buffer of length len+1 (for '\0') */ /************************************************************************/ Int gets_tnc_tmout( char *buf, Int len, Int tmout ) { time_t start, curtime; Int i, rtn; char c; time( &start ); /* Get start time */ for ( rtn = 0; rtn < len; ) { if ( (i = read(tfd, &buf[rtn], 1)) < 0 ) /* Read one character */ break; if ( i > 0 ) /* If got character, */ { c = buf[rtn++]; /* increment char count */ if ( c == '\n' ) /* look for end of line */ break; if ( c == '\r' ) { /* If CR, */ buf[rtn++] = '\n'; /* insert LF */ break; } } time( &curtime ); /* Get time */ if ( curtime > start + tmout ) /* If timed out, return */ break; } buf[rtn] = '\0'; /* Insert EOS */ if ( rtn > 0 ) { /* Echo to stdout */ printf( "%s", buf ); fflush( stdout ); } return( rtn ); /* Return # chars */ } /* gets_tnc_tmout() */ /************************************************************************/ /* Function : write_tnc */ /* Purpose : Write a line to the TNC, echo to stdout */ /* Inputs : String to write */ /* Outputs : OK or ERROR */ /************************************************************************/ Status write_tnc( char *s ) { Reg Nat32 rtn; Reg char *p, *q; rtn = write( tfd, s, strlen(s) ); if ( (p = strdup(s)) != NULL ) { while ( (q = strchr(p, '\r')) != NULL ) *q = '\n'; printf( "%s", p ); fflush( stdout ); free(p); } return( (rtn == strlen(s)) ? OK : ERROR ); } /* write_tnc() */ /************************************************************************/ /* Function : wait_for_output */ /* Purpose : Wait for specific output sequence */ /* Inputs : String to look for, char to send while waiting */ /* Outputs : OK or ERROR */ /* Comments : Error if no data for timeout seconds */ /************************************************************************/ Status wait_for_output( char *matchStr, char sendChar ) { time_t datatime, curtime; Int i, j; char c; time( &datatime ); /* Get start time */ j = 0; while ( !aborted && (time(&curtime) <= datatime + timeout) ) { if ( (i = read(tfd, &c, 1)) > 0 ) /* Read one character */ { /* If got character, */ rbuf[j++] = c; /* Store it */ rbuf[j] = '\0'; /* Mark end of string */ if ( c != '\r' ) putchar( c ); /* Echo it to stdout */ datatime = curtime; /* Save time of last data*/ if ( find_str(rbuf, matchStr) != NULL ) { /* Look for prompt */ while ( read(tfd, &c, 1) > 0 ) /* If got it, throw away*/ ; /* extra chars (spaces)*/ return( OK ); /* and return OK */ } if ( (c == '\r') || (c == '\n') || (j > BUFSIZE) ) { j = 0; fflush(stdout); } } else if ( sendChar ) write( tfd, &sendChar, 1 ); } /* while */ return( DOWNLOAD_ERR ); } /* wait_for_output() */ /************************************************************************/ /* Function : connect_tnc */ /* Purpose : Connect to OASIS, look for "OASIS" connect string */ /* Inputs : None */ /* Outputs : OK or ERROR */ /************************************************************************/ Status connect_tnc( Void ) { return( wait_for_output("OASIS", ' ') ); } /* connect_tnc() */ /************************************************************************/ /* Function : wait_for_prompt */ /* Purpose : Wait for OASIS prompt */ /* Inputs : None */ /* Outputs : OK or ERROR */ /* Comments : Error if no data for timeout seconds */ /************************************************************************/ Status wait_for_prompt( Void ) { return( wait_for_output(OPROMPT, 0) ); } /* wait_for_prompt() */ /************************************************************************/ /* Function : get_data */ /* Purpose : Get data from mooring, copy to stdout */ /* Inputs : None */ /* Outputs : Return code for exit() */ /************************************************************************/ Status get_data( Void ) { if ( write_tnc("logs\r") != OK ) /* Send "logs" command */ return( DOWNLOAD_ERR ); sleep( 20 ); if ( wait_for_prompt() != OK ) /* Wait for end of "logs"*/ return( DOWNLOAD_ERR ); printf("\n"); /* Echo newline to output*/ if ( write_tnc("getdata\r") != OK ) /* Send "getdata" command*/ return( DOWNLOAD_ERR ); if ( wait_for_prompt() != OK ) /* Wait for end of data */ return( DOWNLOAD_ERR ); return( OK ); } /* get_data() */ /************************************************************************/ /* Function : get_missing_records */ /* Purpose : Look for and download missing data records */ /* Inputs : None */ /* Outputs : Return code for exit() */ /************************************************************************/ Status get_missing_records( Void ) { Reg Int32 lognum; Reg Nat32 rcd; RcdRange range; MBool changedToBin; rcdInit( &logs ); /* Init LogStructs */ if ( !readRcd(can_name, &logs) ) /* Read record file */ return( OK ); changedToBin = FALSE; for ( lognum = logs.firstLog; lognum < logs.nLogs; lognum++ ) for (rcd = 0; getMissingRcd(&logs, lognum, rcd, &range); ) { if ( !changedToBin ) { printf("\n"); if ( write_tnc("parm ascii 0\r") != OK ) return( DOWNLOAD_ERR ); if ( wait_for_prompt() != OK ) return( DOWNLOAD_ERR ); changedToBin = TRUE; } printf("\n"); /* Echo newline to output*/ sprintf(rbuf, "getlog %d %d %d\r", lognum, range.min, range.max - range.min +1); if ( write_tnc(rbuf) != OK ) return( DOWNLOAD_ERR ); if ( wait_for_prompt() != OK ) return( DOWNLOAD_ERR ); rcd = range.max + 1; } return( OK ); } /* get_missing_records() */ /************************************************************************/ /* Function : quit */ /* Purpose : SIGTERM handler */ /* Inputs : Signal number received */ /* Outputs : None */ /************************************************************************/ Void quit( Int sig ) { aborted = TRUE; } /* quit() */ @