#include /* Unix standard I/O */ #include /* Unix standard library */ #include /* MBARI standard types */ #include /* MBARI standard constants */ #include /* OASIS data definitions */ #include /* Unix string library */ #include #include #include "argtest.h" /* argtest.c: Prototype of new ARGOS buffer management code. The original code used a scheme that was 'info centric'; the naming scheme for the buffers and associated data structures was based on the information contained within them. The drawback to this scheme is that to rearrange the buffer content required either that the a lot of code changes had to take place to rename buffers (yuck) or data had to be put in data structures with names that didn't match (bad idea). The new scheme adopts the paradigm that the buffers are just containers for data bytes, and to insert or extract data requires only that the correct mapping be known both the writer and reader of the buffers. A data writer (OASIS can) need only know which offset into which buffer should be used for each item of data. A data reader (data extraction program) needs to know both the number of location of data items in each buffer, as well as which extraction routine should be used for each item. Currently there are 10 buffers used for ARGOS data, each with a mapping, or organization scheme. For a given deployment, a 'major key' is used to select a set of indices into a table of buffer mappings. By using this doubly indexed system, less memory is wasted since it eliminates the need for buffer scheme tables to contain empty entries each time one buffer changes its organization. Data extraction functions are broken out into individual functions for each data item; this makes better logical sense, is more extensible and still allows for similar data to be processed by the same function if desired. With an eye toward integrating ARGOS processing with local data processing and screen decoding functions, output functions will be separated from extraction and sent to a central function that will be able to send output to the screen as well as to the appropriate files. The new system makes the system flexible and easy to configure; only minimal code changes are required (editing a few tables) to rearrange the ARGOS buffers, making it a configuration task rather than a code rewrite. */ /********************************/ /* External Functions */ /********************************/ Extern double decode_prr_chan( Int16 ival, SpecChanCal *sccp ); Extern Status read_cfg( char **cfgname ); /********************************/ /* External Data */ /********************************/ Extern char *optarg; /* Option argument from getopt() */ Extern Int optind; /* Option index from getopt() */ Extern Int32 gmt_offset; Extern Analog analog[ANALOG_CHANS]; /* Analog calibration */ /*******************************************/ /* Local Function Forward Declarations */ /*******************************************/ Flt64 fileDate( time_t timeToConvert ); Void decodeFile( char *filename ); MBool processCommandLine ( Int32 argc, char **argv ); Void getMessages( FILE *fp, char *buffer ); MsgRtn getSvcArgosMsg( FILE *fp, char *buffer, WordMsg *msgp, struct tm *tmPtr, Int32 *nmsgs ); MsgRtn getLine( FILE *fp, char * buffer ); Int32 findMatchingMessage( ByteMsg *msgp ); MBool msgMatch( ByteMsg *msgp1, ByteMsg *msgp2 ); MBool checkCRC( WordMsg *msgp ); Nat16 crcOneWord( Nat16 initCRC, Nat16 wordToCheck ); void exPCO2( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key); void exPRRPitch( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key); void exPRRRoll( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key); void exPRRTemp( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key); void exPRRDepth( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key); void exISUS( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key); void exSpecLu( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key); void exSpecEd( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key); void exSpecErrorCount( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key); void exOASIS( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key); void exFluor( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key); void exNull( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key); void prRawBuffer(ArgosInMsg *pMsg, Nat32 oflags, Nat32 options); void prNullFunc( struct _ItemInfo *pItem, Nat32 oflags, Nat32 options); void prNULL( ArgosInMsg *pMsg, struct _BufferMap *pMap, Nat32 oflags, Nat32 options); void prMapDefault( ArgosInMsg *pMsg,struct _BufferMap *pMap, Nat32 oflags, Nat32 options); void prMap0_0( ArgosInMsg *pMsg,struct _BufferMap *pMap, Nat32 oflags, Nat32 options); void prMap0_1( ArgosInMsg *pMsg,struct _BufferMap *pMap, Nat32 oflags, Nat32 options); void prMap1_0( ArgosInMsg *pMsg,struct _BufferMap *pMap, Nat32 oflags, Nat32 options); void prMap2_0( ArgosInMsg *pMsg,struct _BufferMap *pMap, Nat32 oflags, Nat32 options); void prMap2_1( ArgosInMsg *pMsg,struct _BufferMap *pMap, Nat32 oflags, Nat32 options); void prMap3_0( ArgosInMsg *pMsg,struct _BufferMap *pMap, Nat32 oflags, Nat32 options); void prMap4_0( ArgosInMsg *pMsg,struct _BufferMap *pMap, Nat32 oflags, Nat32 options); void prMap5_0( ArgosInMsg *pMsg,struct _BufferMap *pMap, Nat32 oflags, Nat32 options); /********************************/ /* Local Data */ /********************************/ Nat32 gKey = DEFAULT_KEY; MLocal MBool decode_msg[kMAXBUFFERS]; MLocal char *pConfigFile = NULL; /* Ptr to name of OASIS config file */ MLocal MBool decode_all = TRUE; MLocal Nat32 nMessages = 0; MLocal Nat32 messageCount = 0; MLocal ArgosInMsg messages[kMAXMESSAGES]; MLocal CSUnion csUnion; Global Nat32 gPrintOptions; Global Nat32 gOutputFlags; Global Byte dataOut[kMAXBUFFERITEMS][kMAXCONTAINER]; /* This is the table is indexed with the key and buffer number, returning the mapping to be used to decode the buffer. */ Nat16 bufferMapping[kMAXKEY][kMAXBUFFERS]= { {0,0,0,0,0,0,0,0,0,0}, {1,0,1,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0} }; BufferMap bufferMap[kMAXBUFFERS][kMAXKEY] = { {/* Buffer 0 */ {/* Mapping 0 */ prMap0_0, { {PCO2_12BIT, 0,12, dataOut[0], exPCO2, prNullFunc}, {_0M_1200_PRR620_PITCH,12, 2, dataOut[1], exPRRPitch, prNullFunc}, {_0M_1200_PRR620_ROLL, 14, 2, dataOut[2], exPRRRoll, prNullFunc}, {_0M_1200_PRR600_TEMP, 16, 2, dataOut[3], exPRRTemp, prNullFunc}, {_0M_1200_PRR600_DEPTH,18, 2, dataOut[4], exPRRDepth, prNullFunc}, {_0M_1230_PRR620_PITCH,20, 2, dataOut[5], exPRRPitch, prNullFunc}, {_0M_1230_PRR620_ROLL, 22, 2, dataOut[6], exPRRRoll, prNullFunc}, {_0M_1230_PRR600_TEMP, 24, 2, dataOut[7], exPRRTemp, prNullFunc}, {_0M_1230_PRR600_DEPTH,28, 2, dataOut[8], exPRRDepth, prNullFunc}, {NOTYPE} } }, {/* Mapping 1 */ prMap0_1, { {PCO2_12BIT, 0,12, dataOut[0], exPCO2, prNullFunc}, {_0M_1200_PRR600_TEMP, 12, 2, dataOut[1], exPRRTemp, prNullFunc}, {_0M_1200_PRR600_DEPTH,14, 2, dataOut[2], exPRRDepth, prNullFunc}, {_0M_ISUS_REC0_NO3, 16,14, dataOut[3], exISUS, prNullFunc}, {NOTYPE} } } }, { /* Buffer 1 */ { /* Mapping 0 */ prMap1_0, { {_0M_1200_PRR620_ED, 0,14, dataOut[0], exSpecEd, prNullFunc}, {_0M_1200_SATA_LU, 14,14, dataOut[1], exSpecLu, prNullFunc}, {_0M_PRR_ERRCNT0, 28, 2, dataOut[2], exSpecErrorCount, prNullFunc}, {NOTYPE} } } }, { /* Buffer 2 */ { /* Mapping 0 */ prMap2_0, { {_0M_1230_PRR620_ED, 0,14, dataOut[0], exSpecEd, prNullFunc}, {_0M_1230_SATA_LU, 14,14, dataOut[1], exSpecLu, prNullFunc}, {_0M_PRR_CHCNT, 28, 2, dataOut[2], exSpecErrorCount, prNullFunc}, {NOTYPE} } }, { /* Mapping 1 */ prMap2_1, { {_0M_1230_PRR620_ED, 0,14, dataOut[0], exSpecEd, prNullFunc}, {_0M_ISUS_REC1_NO3, 14,14, dataOut[1], exISUS, prNullFunc}, {_0M_PRR_CHCNT, 28, 2, dataOut[2], exSpecErrorCount, prNullFunc}, {NOTYPE} } } }, { /* Buffer 3 */ { /* Mapping 0 */ prMap3_0, { {PCO2_CAL_12BIT, 0, 2, dataOut[0], exPCO2, prNullFunc}, {OASIS_DAT, 2, 4, dataOut[1], exOASIS, prNullFunc}, {_0M_WETSTAR_FLUOR, 6, 12, dataOut[2], exFluor, prNullFunc}, {_20M_WETSTAR_FLUOR, 18, 12, dataOut[3], exFluor, prNullFunc}, {NOTYPE} } } }, { /* Buffer 4 */ { /* Mapping 0 */ prMap4_0, { {_20M_1200_PRR600_ED, 0,14, dataOut[0], exSpecEd, prNullFunc}, {_20M_1200_PRR600_LU, 14,14, dataOut[1], exSpecLu, prNullFunc}, {NOTYPE} } } }, { /* Buffer 5 */ { /* Mapping 0 */ prMap5_0, { {_20M_1230_PRR600_ED, 0,14, dataOut[0], exSpecEd, prNullFunc}, {_20M_1230_PRR600_LU, 14,14, dataOut[1], exSpecLu, prNullFunc}, {NOTYPE} } } }, { /* Buffer 6 */ { /* Mapping 0 */ prNULL, { {NOTYPE} } } }, { /* Buffer 7 */ { /* Mapping 0 */ prNULL, { {NOTYPE} } } }, { /* Buffer 8 */ { /* Mapping 0 */ prNULL, { {NOTYPE} } } }, { /* Buffer 9 */ { /* Mapping 0 */ prNULL, { {NOTYPE} } } } }; /* The specAddressMap table is used to track the history of PRR address tags and channel numbers. It is indexed by data item ID and contains one address-channel pair per data item ID for each key. To retrieve an address-channel pair, the item ID is looked up and the key value used to index the array of address-channel pairs. */ eSpecInfo specAddressMap[]= { {_0M_1200_PRR620_ED, {{0,0},{0,0},{0,0},{0,0},{0,0}}}, {_0M_1200_SATA_LU, {{1,0},{1,0},{1,0},{1,0},{1,0}}}, {_0M_1030_PRR620_ED, {{0,0},{0,0},{}, {}, {} }}, {_0M_1030_PRR620_LU, {{1,8},{1,8},{}, {}, {} }}, {_0M_1000_PRR620_ED, {{}, {}, {}, {}, {0,0}}}, {_0M_1230_PRR620_ED, {{}, {}, {0,0},{0,0},{} }}, {_0M_1230_SATA_LU, {{}, {}, {1,8},{1,0},{} }}, {_20M_1200_PRR600_ED,{{2,0},{2,0},{2,0},{2,0},{2,0}}}, {_20M_1200_PRR600_LU,{{3,0},{3,0},{3,0},{3,0},{3,0}}}, {_10M_1200_MCP_ED, {{}, {}, {}, {}, {} }}, {_20M_1230_PRR600_ED,{{2,0},{2,0},{2,0},{2,0},{} }}, {_20M_1230_PRR600_LU,{{3,0},{3,0},{3,0},{3,0},{} }}, {_20M_1000_PRR600_ED,{{}, {}, {}, {}, {2,0}}}, {_20M_1000_PRR600_LU,{{}, {}, {}, {}, {3,0}}}, {_30M_1200_MCP_ED, {{}, {}, {}, {}, {} }}, {_0M_0000_SATB_LU, {{}, {}, {1,8},{1,8},{1,8}}}, {_0M_0000_PRR620_ED, {{}, {}, {0,0},{0,0},{0,0}}}, {_0M_0000_SATA_LU, {{}, {}, {1,0},{1,0},{1,0}}}, {_20M_0000_PRR600_ED,{{}, {}, {2,0},{2,0},{2,0}}}, {_20M_0000_PRR600_LU,{{}, {}, {3,0},{3,0},{3,0}}}, {_0M_1200_SATB_LU, {{}, {}, {1,8},{1,8},{1,8}}}, {_0M_1230_SATB_LU, {{}, {}, {1,8},{1,8},{1,8}}}, {NOTYPE} }; /************************************************************************/ /* Function : printDebug */ /* Purpose : Print Degub Message */ /* Inputs : format, args */ /* Outputs : None */ /************************************************************************/ Void printDebug( const char *fmt , ... ) { #ifdef _DEBUG_ va_list ap; /* Argument pointer */ va_start( ap, fmt ); vprintf( fmt, ap ); va_end( ap ); #endif return; } /* printDebug() */ /************************************************************************/ /* Function : use_msg */ /* Purpose : Print Usage Message */ /* Inputs : Name of program */ /* Outputs : None */ /************************************************************************/ Void use_msg( char *s ) { fprintf( stderr, "\n\tUsage: %s [-c cfg_file] [-i msg_number]\n" ); fprintf( stderr, "\t-c specifies a configuration file\n" ); fprintf( stderr, "\t-i decodes a specified message number\n\n" ); fprintf( stderr, "\tDefault is for data from Service Argos\n\n"); } /* use_msg() */ /************************************************************************/ /* Function : processCommandLine */ /* Purpose : Read the arguments from the command line */ /* Inputs : argc, argv from main() routine */ /* Outputs : TRUE if arguments OK, else FALSE */ /************************************************************************/ MBool processCommandLine ( Int32 argc, char **argv ) { Int32 c, i; char *cp; gOutputFlags = fCONSOLE; gPrintOptions = fNOOPTIONS; for ( i = 0; i < kMAXBUFFERS; i++ ) decode_msg[i] = FALSE; while ( (c = getopt(argc, argv, "c:i:k:o:")) != EOF ) switch( c ) { case 'c': pConfigFile = optarg; break; case 'i': decode_all = FALSE; decode_msg[atoi(optarg)] = TRUE; break; case 'k': gKey = atoi(optarg); break; case 'o': cp=optarg; while(*cp++ != '\0'){ if(toupper(*cp)=='C') gOutputFlags |= fCONSOLE; if(toupper(*cp)=='A') gOutputFlags |= fARCHIVE; if(toupper(*cp)=='H') gOutputFlags |= fHTML; } break; default: use_msg( argv[0] ); return( FALSE ); } return( TRUE ); } /* processCommandLine() */ /************************************************************************/ /* Function : main */ /* Purpose : Main routine */ /* Inputs : argc, argv */ /* Outputs : Integer, 0 for success, 1 for failure */ /************************************************************************/ Int32 main( Int32 argc, char **argv ) { char *filename, *cp; Reg Int32 i; if ( argc < 2 ){ use_msg(argv[0]); /*exit( 1 );*/ } if ( !processCommandLine(argc, argv) ) exit( 1 ); putenv( "TZ=GMT0" ); for ( i = optind; i < argc; i++ ) { filename = argv[i]; get_can_name( filename ); cp = pConfigFile; if ( read_cfg(&cp) != OK ) printf("Can't read configuration file \"%s\"\n", cp); else decodeFile( filename ); } return 0; }/* end main */ /************************************************************************/ /* Function : fileDate */ /* Purpose : Convert Unix time_t to file date spec */ /* Inputs : Time of first ARGOS hit */ /* Outputs : Decimal year, e.g. 97.003 for Jan 2, 1997 */ /************************************************************************/ Flt64 fileDate( time_t timeToConvert ) { time_t adjustedTime; struct tm *tmPtr; Int32 year; Flt64 daysPerYear; adjustedTime = timeToConvert + (3600 * gmt_offset) - (24 * 3600); tmPtr = gmtime( &adjustedTime ); /* year = tmPtr->tm_year + 1900;*/ year = tmPtr->tm_year; daysPerYear = ((year % 4) == 0) ? 366.0 : 365.0; return( (Flt64)year + ((Flt64)tmPtr->tm_yday / daysPerYear) ); } /* fileDate() */ /************************************************************************/ /* Function : exNull */ /* Purpose : Dummy extract function */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void exNull( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key){ DEBUG(("exNull\n")); return; }/* exNull() */ /************************************************************************/ /* Function : exISUS */ /* Purpose : Extract ISUS data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void exISUS( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key){ Nat16 i; Nat16 ival; char *pIn,*pOut; DEBUG(("exISUS\n")); pIn = (char *)&pMsg->msg.hd.data[pItem->offset]; pOut = (char *)pItem->pData; switch(pItem->id){ case _0M_ISUS_REC0_NO3: for(i=0;i<(ISUS0_BYTES);i++,pOut++,pIn++){ if( (*pIn) < 0x20 || (*pIn) >= 0x7f) sprintf(pOut,"?"); else sprintf(pOut,"%c",*pIn); *(pOut+1)='\0'; } strcat(pOut," C"); break; case _0M_ISUS_REC1_NO3: for(i=0;i<(ISUS1_BYTES);i++,pOut++,pIn++){ if( (*pIn) < 0x20 || (*pIn) >= 0x7f) sprintf(pOut,"?"); else sprintf(pOut,"%c",*pIn); *(pOut+1)='\0'; } strcat(pOut," S"); break; default: break; }/* end switch */ return; }/* exISUS() */ /************************************************************************/ /* Function : exPCO2 */ /* Purpose : Extract pCO2 data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void exPCO2( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key){ Reg Byte *pIn; Nat32 *pOut; Nat32 i; Flt64 day; Int32 co2; Nat32 val; DEBUG(("exPCO2\n")); day = DAY(pMsg->first_msg); pIn = (Byte *)&pMsg->msg.hd.data[pItem->offset]; pOut = (Nat32 *)pItem->pData; switch(pItem->id){ case PCO2_12BIT: for ( i = 0; i < CHEM_SAMPLES; i+=2 ) { co2 = *pIn++ << 4; co2 |= ((*pIn >> 4) & 0x0f); if ( co2 & 0x800 ) co2 |= 0xfffff000; /* Sign extend */ *(pOut+i) = co2; co2 = ((*pIn++ & 0x0f) << 8); co2 |= *pIn++; if ( co2 & 0x800 ) co2 |= 0xfffff000; /* Sign extend */ *(pOut+i+1) = co2; } break; case PCO2_CAL_10BIT: val = getIntelword( (Byte *)pIn ); co2 = val & 0x3ff; if ( co2 & 0x200 ) co2 |= ~0x3ff; /* Sign extend */ *pOut = co2; *(pOut+1) = (((val >> 10) & 7) * 3); break; case PCO2_CAL_12BIT: val = getIntelword( (Byte *)pIn ); co2 = val & 0xfff; if ( co2 & 0x800 ) co2 |= ~0xfff; /* Sign extend */ *pOut = co2; *(pOut+1) = (((val >> 12) & 7) * 3); break; default: break; }/*end switch*/ }/*end exPCO2()*/ /************************************************************************/ /* Function : exPPitch */ /* Purpose : Extract PRR Pitch data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void exPRRPitch( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key){ Nat16 *pIn,ipitch; Flt64 day,*pOut; DEBUG(("exPRRPitch\n")); pIn = (Nat16 *)&pMsg->msg.hd.data[pItem->offset]; pOut = (Flt64 *)pItem->pData; ipitch = getIntelword( (Byte *)pIn ); *pOut=decode_prr_chan(ipitch, &spec_cal.spc_cal[0][10]); }/*end exPRRPitch()*/ /************************************************************************/ /* Function : exPRRRoll */ /* Purpose : Extract PRR Roll data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void exPRRRoll( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key){ Nat16 *pIn,iroll; Flt64 day,*pOut; DEBUG(("exPRRROLL\n")); pIn = (Nat16 *)&pMsg->msg.hd.data[pItem->offset]; pOut = (Flt64 *)pItem->pData; iroll = getIntelword( (Byte *)pIn ); *pOut = decode_prr_chan(iroll, &spec_cal.spc_cal[0][11]); }/*end exPRRROLL()*/ /************************************************************************/ /* Function : exPRRTemp */ /* Purpose : Extract PRR Temp data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void exPRRTemp( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key){ Nat16 *pIn,itemp; Flt64 day,*pOut; DEBUG(("exPRRTEMP\n")); pIn = (Nat16 *)&pMsg->msg.hd.data[pItem->offset]; pOut = (Flt64 *)pItem->pData; itemp = getIntelword( (Byte *)pIn ); *pOut = decode_prr_chan(itemp, &spec_cal.spc_cal[2][8]); }/*end exPRRTemp()*/ /************************************************************************/ /* Function : exPRRDepth */ /* Purpose : Extract PRR Depth data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void exPRRDepth( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key){ Nat16 *pIn,idepth; Flt64 day,*pOut; DEBUG(("exPRRDEPTH\n")); pIn = (Nat16 *)&pMsg->msg.hd.data[pItem->offset]; pOut = (Flt64 *)pItem->pData; idepth = getIntelword( (Byte *)pIn ); *pOut = decode_prr_chan(idepth, &spec_cal.spc_cal[2][9]); }/*end exPRRDepth()*/ /************************************************************************/ /* Function : getSpecAddress */ /* Purpose : Get auxiliary data for PRR */ /* Inputs : Item ID, pointer to AuxSpec struct */ /* Outputs : None */ /************************************************************************/ Nat16 getSpecAddress(int id,Nat32 key) { eSpecInfo *pInfo; pInfo = (&specAddressMap[0]); while(pInfo->id != NOTYPE){ if(pInfo->id == id){ return pInfo->data[key].address; } pInfo++; } return(0); }/* getSpecAddress() */ /************************************************************************/ /* Function : getSpecChannel */ /* Purpose : Get auxiliary data for PRR */ /* Inputs : Item ID, pointer to AuxSpec struct */ /* Outputs : None */ /************************************************************************/ Nat16 getSpecChannel(int id,Nat32 key) { eSpecInfo *pInfo; pInfo = (&specAddressMap[0]); while(pInfo->id != NOTYPE){ if(pInfo->id == id){ return pInfo->data[key].channel; } pInfo++; } return(0); }/* getSpecChannel() */ /************************************************************************/ /* Function : exSpecEd */ /* Purpose : Extract PRR Ed data (from printSpecR5) */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void exSpecEd( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key) { Reg Int32 i; Reg Nat16 ival; Flt64 ed; Nat16 *pIn; Flt64 *pOut; Int32 edAdr,edChan; DEBUG(("exSpecED\n")); pIn = (Nat16 *)&pMsg->msg.hd.data[pItem->offset]; pOut = (Flt64 *)pItem->pData; edAdr = getSpecAddress(pItem->id,key); edChan = getSpecChannel(pItem->id,key); for ( i = 0; i < ASPEC_CHANS; i++ ) { ival = getIntelword( (Byte *)&pIn[i] ); #if SPEC_VOLTS ed = decode_prr_chan( ival, NULL ); #else ed = decode_prr_chan( ival, &spec_cal.spc_cal[edAdr][i+edChan] ); #endif *(pOut+i)=ed; } } /* exSpecEd() */ /************************************************************************/ /* Function : exSpecLu */ /* Purpose : Print PRR Lu data (from printSpecR5) */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void exSpecLu( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key) { Reg Int32 i; Reg Nat16 ival; Flt64 lu; Nat16 *pIn; Flt64 *pOut; Int32 luAdr,luChan; DEBUG(("exSpecLU\n")); pIn = (Nat16 *)&pMsg->msg.hd.data[pItem->offset]; pOut = (Flt64 *)pItem->pData; luAdr = getSpecAddress(pItem->id,key); luChan = getSpecChannel(pItem->id,key); for ( i = 0; i < ASPEC_CHANS; i++ ){ ival = getIntelword( (Byte *)&pIn[i] ); #if SPEC_VOLTS lu = decode_prr_chan( ival, NULL ); #else lu = decode_prr_chan( ival, &spec_cal.spc_cal[luAdr][i+luChan] ); #endif *(pOut+i)=lu; } } /* exSpecLu() */ /************************************************************************/ /* Function : exSpecErrorCount */ /* Purpose : Print PRR Error Count */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void exSpecErrorCount( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key) { int i; Nat16 misc; Reg Byte *pIn; Nat16 *pOut; DEBUG(("exSpecErr\n")); pIn = (Byte *)&pMsg->msg.hd.data[pItem->offset]; pOut = (Nat16 *)pItem->pData; misc = getIntelword( (Byte *)pIn); *pOut = misc; } /* exSpecErrorCount() */ void exOASIS( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key){ Byte *pIn; Flt64 *pOut,*pOTemp,*pOBat,*pABat; Nat32 val; DEBUG(("exOASIS\n")); pIn = (Byte *)&pMsg->msg.hd.data[pItem->offset]; pOut = (Flt64 *)pItem->pData; pOTemp = pOut; pOBat = pOut+1; pABat = pOut+2; val = getIntellong( (Byte *)pIn ); *pOTemp = (((analog[TEMP_CHAN].a * (Flt32)(val & 0x3ff)) + analog[TEMP_CHAN].b) * analog[TEMP_CHAN].c) + analog[TEMP_CHAN].d; *pOBat = ((analog[OBATT_CHAN].a * (Flt32)((val >> 10) & 0x3ff)) + analog[OBATT_CHAN].b) * analog[OBATT_CHAN].c; *pABat = ((analog[ABATT_CHAN].a * (Flt32)((val >> 20) & 0x3ff)) + analog[ABATT_CHAN].b) * analog[ABATT_CHAN].c; }/* exOASIS() */ void exFluor( ArgosInMsg *pMsg, struct _ItemInfo *pItem, Nat32 key){ Byte *pIn; Flt64 *pOut; Nat32 i,j; Nat32 ifluor; Flt64 ffluor; DEBUG(("exFluor\n")); pIn = (Byte *)&pMsg->msg.hd.data[pItem->offset]; pOut = (Flt64 *)pItem->pData; switch(pItem->id){ case _0M_WETSTAR_FLUOR: for ( i = 0; i < CHEM_SAMPLES; i++ ) { if ( i & 1 ) { ifluor = (*pIn++ & 0x0f) << 8; ifluor |= *pIn++; } else { ifluor = *pIn++ << 4; ifluor |= ((*pIn >> 4) & 0x0f); } *(pOut+i) = (((analog[FLUOR_CHAN].a * (Flt64)(ifluor>>2)) + analog[FLUOR_CHAN].b) * analog[FLUOR_CHAN].c) + analog[FLUOR_CHAN].d; } break; case _20M_WETSTAR_FLUOR: for ( i = j = 0; i < CHEM_SAMPLES; i++ ) { if ( (i != 1) && (i != 7) ) { ifluor = getIntelword( (Byte *)&pIn[j++] ); ffluor = decode_prr_chan(ifluor, &spec_cal.spc_cal[2][11]); if ( ffluor < 20.0 ) *(pOut++) = ffluor; j++; } } break; default: break; }/* end switch */ }/* exFluor() */ /************************************************************************/ /* Function : getMapItem */ /* Purpose : Get Data Item from Map by Name */ /* Inputs : Map, Item ID */ /* Outputs : pointer to Item, NULL on failure */ /************************************************************************/ ItemInfo * getMapItem(Nat32 id, BufferMap *pMap){ ItemInfo *pItem = &pMap->item[0]; while(pItem->id != NOTYPE && pItem->id < kMAXITEM){ if(pItem->id == id) return pItem; pItem++; } return NULL; }/* getMapItem() */ /************************************************************************/ /* Function : getMapItem */ /* Purpose : Get Data Item from Map by Name */ /* Inputs : Map, Item ID */ /* Outputs : pointer to Item, NULL on failure */ /************************************************************************/ Byte * getItemData(Nat32 id, BufferMap *pMap){ ItemInfo *pItem = getMapItem(id,pMap); if(pItem != NULL) return pItem->pData; return NULL; }/* getItemData() */ /************************************************************************/ /* Function : prRawBuffer */ /* Purpose : Print Raw Buffer Data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void prRawBuffer(ArgosInMsg *pMsg, Nat32 oflags, Nat32 options){ Nat32 i; for(i=0;imsg.rawb.by_data[i]); if( ((i+1)%16) == 0) printf("\n"); } }/* prRawBuffer() */ Void prNULL( ArgosInMsg *pMsg, struct _BufferMap *pMap, Nat32 oflags, Nat32 options){ DEBUG(("prNULL\n\n")); } Void prNullFunc( struct _ItemInfo *pItem, Nat32 oflags, Nat32 options){ DEBUG(("prNullFunc\n\n")); } /************************************************************************/ /* Function : prMapDefault */ /* Purpose : Print Map Data Using Item Default Printers */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void prMapDefault( ArgosInMsg *pMsg, struct _BufferMap *pMap, Nat32 oflags, Nat32 options){ int i; Flt64 day; ItemInfo *pItem; DEBUG(("prMapDefault\n\n")); day = DAY(pMsg->first_msg); if(oflags|fCONSOLE){ prRawBuffer(pMsg,oflags,options); } if(oflags|fARCHIVE){ } if(oflags|fHTML){ } }/*end prMapDefault()*/ /************************************************************************/ /* Function : prMap0_0 */ /* Purpose : Print Map Data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void prMap0_0( ArgosInMsg *pMsg, struct _BufferMap *pMap, Nat32 oflags, Nat32 options){ int i; Flt64 day; ItemInfo *pItem; Nat16 *pPCO2; Flt64 *pPITCH1200,*pPITCH1230,*pROLL1200,*pROLL1230; Flt64 *pTEMP1200,*pTEMP1230,*pDEPTH1200,*pDEPTH1230; DEBUG(("prMap0_0\n\n")); day = DAY(pMsg->first_msg); prRawBuffer(pMsg,oflags,options); if(oflags|fCONSOLE){ pPCO2 = (Nat16 *)getItemData(PCO2_12BIT,pMap); printf("pCO2 "); for ( i = 0; i < CHEM_SAMPLES; i++ ){ printf("%4d ",*(pPCO2+i)); } printf("\n"); pPITCH1200=(Flt64 *)getItemData(_0M_1200_PRR620_PITCH,pMap); pROLL1200 = (Flt64 *)getItemData(_0M_1200_PRR620_ROLL,pMap); pTEMP1200 = (Flt64 *)getItemData(_0M_1200_PRR600_TEMP,pMap); pDEPTH1200 = (Flt64 *)getItemData(_0M_1200_PRR600_DEPTH,pMap); pPITCH1230 = (Flt64 *)getItemData(_0M_1230_PRR620_PITCH,pMap); pROLL1230 = (Flt64 *)getItemData(_0M_1230_PRR620_ROLL,pMap); pTEMP1230 = (Flt64 *)getItemData(_0M_1230_PRR600_TEMP,pMap); pDEPTH1230 = (Flt64 *)getItemData(_0M_1230_PRR600_DEPTH,pMap); printf("1200 pitch %6.1f roll %6.1f temp %7.2f depth %7.2f\n", *pPITCH1200,*pROLL1200, *pTEMP1200,*pDEPTH1200); printf("1230 pitch %6.1f roll %6.1f temp %7.2f depth %7.2f\n", *pPITCH1230,*pROLL1230, *pTEMP1230,*pDEPTH1230); } if(oflags|fARCHIVE){ for ( i = 0; i < CHEM_SAMPLES; i++ ){ print_sensor( CO2_FILE, "%8.4f %4d\n", day + CHEM_TIME(i), *(pPCO2+i)); } print_sensor( SPEC_MISC_FILE, "%8.4f %6.1f %6.1f %7.2f %7.2f %6.1f %6.1f %7.2f %7.2f\n", day, *pPITCH1200,*pROLL1200, *pTEMP1200,*pDEPTH1200, *pPITCH1230,*pROLL1230, *pTEMP1230,*pDEPTH1230); } if(oflags|fHTML){ } }/*end prMap0_0()*/ /************************************************************************/ /* Function : prMap0_1 */ /* Purpose : Print Map Data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void prMap0_1( ArgosInMsg *pMsg, struct _BufferMap *pMap, Nat32 oflags, Nat32 options){ int i; Flt64 day; Nat16 *pPCO2; Flt64 *pTEMP1200,*pDEPTH1200; char *pISUS; DEBUG(("prMap0_1\n\n")); prRawBuffer(pMsg,oflags,options); day = DAY(pMsg->first_msg); if(oflags|fCONSOLE){ printf("pCO2 "); pPCO2 = (Nat16 *)getItemData(PCO2_12BIT,pMap); for ( i = 0; i < CHEM_SAMPLES; i++ ){ printf("%4d ",*(pPCO2+i)); } printf("\n"); pTEMP1200 = (Flt64 *)getItemData(_0M_1200_PRR600_TEMP,pMap); pDEPTH1200 = (Flt64 *)getItemData(_0M_1200_PRR600_DEPTH,pMap); pISUS = (char *)getItemData(_0M_ISUS_REC0_NO3,pMap); printf("1200 temp %7.2f depth %7.2f\n",pTEMP1200,*pDEPTH1200); printf("ISUS %s\n",pISUS); } if(oflags|fARCHIVE){ for ( i = 0; i < CHEM_SAMPLES; i++ ){ print_sensor( CO2_FILE, "%8.4f %4d\n", day + CHEM_TIME(i), *(pPCO2+i)); } print_sensor( SPEC_MISC_FILE, "%6.1f %7.2f\n",day,*pTEMP1200,*pDEPTH1200); print_sensor( ISUS_FILE,"%s\n",*pISUS); } if(oflags|fHTML){ } }/*end prMap0_1()*/ /************************************************************************/ /* Function : prMap1_0 */ /* Purpose : Print Map Data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void prMap1_0( ArgosInMsg *pMsg, struct _BufferMap *pMap, Nat32 oflags, Nat32 options){ int i; Flt64 day; ItemInfo pItem; Flt64 *pED, *pLU; Nat16 *pERR; char *edChan[ASPEC_CHANS]={"Ed412","Ed443","Ed490","Ed510","Ed555","Ed656","PAR "}; char *luChan[ASPEC_CHANS]={"Lu412","Lu443","Lu490","Lu510","Lu555","Lu656","Lu683"}; DEBUG(("prMap1_0\n\n")); pED = (Flt64 *)getItemData(_0M_1200_PRR620_ED,pMap); pLU = (Flt64 *)getItemData(_0M_1200_SATA_LU,pMap); pERR = (Nat16 *)getItemData(_0M_PRR_ERRCNT0,pMap); day = DAY(pMsg->first_msg); prRawBuffer(pMsg,oflags,options); if(oflags|fCONSOLE){ printf("Day %8.5f\n",day); for ( i = 0; i < ASPEC_CHANS; i++ ){ printf("%s %9.5f %s %9.5f\n",edChan[i],*(pED+i),luChan[i],*(pLU+i)); } printf("\nSpec Error Count %u\n",*pERR); } if(oflags|fARCHIVE){ print_sensor( SPEC_NOON_FILE, "%8.4f ", day); for ( i = 0; i < ASPEC_CHANS; i++ ){ print_sensor( SPEC_NOON_FILE, "%9.5f ", *(pED+i) ); } for ( i = 0; i < ASPEC_CHANS; i++ ){ print_sensor( SPEC_NOON_FILE, "%9.5f ", *(pLU+i) ); } print_sensor( SPEC_NOON_FILE, "%u\n", *pERR ); } if(oflags|fHTML){ for ( i = 0; i < ASPEC_CHANS; i++ ){ } for ( i = 0; i < ASPEC_CHANS; i++ ){ } } }/*end prMap1_0()*/ /************************************************************************/ /* Function : prMap2_0 */ /* Purpose : Print Map Data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void prMap2_0( ArgosInMsg *pMsg, struct _BufferMap *pMap, Nat32 oflags, Nat32 options){ int i; Flt64 day; ItemInfo pItem; Flt64 *pED, *pLU; Nat16 *pERR; char *edChan[ASPEC_CHANS]={"Ed412","Ed443","Ed490","Ed510","Ed555","Ed656","PAR "}; char *luChan[ASPEC_CHANS]={"Lu412","Lu443","Lu490","Lu510","Lu555","Lu656","Lu683"}; DEBUG(("prMap2_0\n\n")); pED = (Flt64 *)getItemData(_0M_1200_PRR620_ED,pMap); pLU = (Flt64 *)getItemData(_0M_1200_SATA_LU,pMap); pERR = (Nat16 *)getItemData(_0M_PRR_ERRCNT0,pMap); day = DAY(pMsg->first_msg); prRawBuffer(pMsg,oflags,options); if(oflags|fCONSOLE){ printf("Day %8.5f\n",day); for ( i = 0; i < ASPEC_CHANS; i++ ){ printf("%s %9.5f %s %9.5f\n",edChan[i],*(pED+i),luChan[i],*(pLU+i)); } printf("\nSpec Error Count %u\n",*pERR); } if(oflags|fARCHIVE){ print_sensor( SPEC_0M_1230_FILE, "%8.4f ", day); for ( i = 0; i < ASPEC_CHANS; i++ ){ print_sensor( SPEC_0M_1230_FILE, "%9.5f ", *(pED+i) ); } for ( i = 0; i < ASPEC_CHANS; i++ ){ print_sensor( SPEC_0M_1230_FILE, "%9.5f ", *(pLU+i) ); } print_sensor( SPEC_0M_1230_FILE, "%u\n", *pERR ); } if(oflags|fHTML){ for ( i = 0; i < ASPEC_CHANS; i++ ){ } for ( i = 0; i < ASPEC_CHANS; i++ ){ } } }/*end prMap2_0()*/ /************************************************************************/ /* Function : prMap2_1 */ /* Purpose : Print Map Data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void prMap2_1( ArgosInMsg *pMsg, struct _BufferMap *pMap, Nat32 oflags, Nat32 options){ int i; Flt64 day; ItemInfo pItem; Flt64 *pED; char *pISUS; Nat16 *pERR; char *edChan[ASPEC_CHANS]={"Ed412","Ed443","Ed490","Ed510","Ed555","Ed656","PAR "}; char *luChan[ASPEC_CHANS]={"Lu412","Lu443","Lu490","Lu510","Lu555","Lu656","Lu683"}; DEBUG(("prMap2_1\n\n")); pED = (Flt64 *)getItemData(_0M_1230_PRR620_ED,pMap); pISUS = (char *)getItemData(_0M_ISUS_REC1_NO3,pMap); pERR = (Nat16 *)getItemData(_0M_PRR_CHCNT,pMap); prRawBuffer(pMsg,oflags,options); day = DAY(pMsg->first_msg); if(oflags|fCONSOLE){ printf("Day %8.5f\n",day); for ( i = 0; i < ASPEC_CHANS; i++ ){ printf("%s %9.5f \n",edChan[i],*(pED+i)); } printf("ISUS %s \n",pISUS); printf("Total PRR Channels %u\n",*pERR); } if(oflags|fARCHIVE){ print_sensor( SPEC_0M_1230_FILE, "%8.4f ", day); for ( i = 0; i < ASPEC_CHANS; i++ ){ print_sensor( SPEC_0M_1230_FILE, "%9.5f ", *(pED+i) ); } print_sensor( ISUS_FILE,"%s\n",*pISUS); print_sensor( SPEC_0M_1230_FILE, "%u\n", *pERR ); } if(oflags|fHTML){ for ( i = 0; i < ASPEC_CHANS; i++ ){ } for ( i = 0; i < ASPEC_CHANS; i++ ){ } } }/*end prMap2_1()*/ /************************************************************************/ /* Function : prMap3_0 */ /* Purpose : Print Map Data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void prMap3_0( ArgosInMsg *pMsg, struct _BufferMap *pMap, Nat32 oflags, Nat32 options){ Nat32 i; Flt64 day; ItemInfo pItem; Int32 *pPCO2,*pHour; Flt64 *pOASIS,*pOTemp,*pOBat,*pABat; Flt64 *p0M_Fluor,*p20M_Fluor; DEBUG(("prMap3_0\n\n")); pPCO2 = (Int32 *)getItemData(PCO2_CAL_12BIT,pMap); pHour = pPCO2+1; pOASIS = (Flt64 *)getItemData(OASIS_DAT,pMap); pOTemp = pOASIS; pOBat = pOASIS+1; pABat = pOASIS+2; p0M_Fluor = (Flt64 *)getItemData(_0M_WETSTAR_FLUOR,pMap); p20M_Fluor = (Flt64 *)getItemData(_20M_WETSTAR_FLUOR,pMap); prRawBuffer(pMsg,oflags,options); day = DAY(pMsg->first_msg); if(oflags|fCONSOLE){ printf("pCO2 Cal %3d @ %02d00 local time\n",*pPCO2,*pHour); printf("Oasis Temp: %5.2f Oasis Battery: %8.2f Argos Battery: %8.2f\n",*pOTemp, *pOBat, *pABat); printf(" 0M Wetstar "); for ( i = 0; i < CHEM_SAMPLES; i++ ) { printf( "%6.3f ",*(p0M_Fluor+i)); } printf("\n20M Wetstar "); for ( i = 0; i < CHEM_SAMPLES-2; i++ ) { printf( "%6.3f ",*(p20M_Fluor+i)); } printf("\n\n"); } if(oflags|fARCHIVE){ print_sensor( CO2_CAL_FILE, "%8.4f %3d %02d00\n", day, *pPCO2,*(pPCO2+1)); print_sensor( OASIS_FILE, "%8.4f %5.2f %8.2f %8.2f\n", day, *pOTemp, *pOBat, *pABat ); for ( i = 0; i < CHEM_SAMPLES; i++ ) { print_sensor( WETSTAR_FILE, "%8.4f %6.3f %6.3f\n", day + CHEM_TIME(i), *(p0M_Fluor+i),*(p20M_Fluor+i) ); } } if(oflags|fHTML){ } }/*end prMap3_0()*/ /************************************************************************/ /* Function : prMap4_0 */ /* Purpose : Print Map Data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void prMap4_0( ArgosInMsg *pMsg, struct _BufferMap *pMap, Nat32 oflags, Nat32 options){ int i; Flt64 day; ItemInfo pItem; Flt64 *pED, *pLU; Nat16 *pERR; char *edChan[ASPEC_CHANS]={"Ed412","Ed443","Ed490","Ed510","Ed555","Ed656","PAR "}; char *luChan[ASPEC_CHANS]={"Lu412","Lu443","Lu490","Lu510","Lu555","Lu656","Lu683"}; DEBUG(("prMap4_0\n\n")); pED = (Flt64 *)getItemData(_20M_1200_PRR600_ED,pMap); pLU = (Flt64 *)getItemData(_20M_1200_PRR600_LU,pMap); day = DAY(pMsg->first_msg); prRawBuffer(pMsg,oflags,options); if(oflags|fCONSOLE){ printf("Day %8.5f\n20M PRR600 1200h\n",day); for ( i = 0; i < ASPEC_CHANS; i++ ){ printf("%s %9.5f %s %9.5f\n",edChan[i],*(pED+i),luChan[i],*(pLU+i)); } } if(oflags|fARCHIVE){ print_sensor( SPEC_NOON_FILE, "%8.4f ", day); for ( i = 0; i < ASPEC_CHANS; i++ ){ print_sensor( SPEC_20_FILE, "%9.5f ", *(pED+i) ); } for ( i = 0; i < ASPEC_CHANS; i++ ){ print_sensor( SPEC_20_FILE, "%9.5f ", *(pLU+i) ); } } if(oflags|fHTML){ for ( i = 0; i < ASPEC_CHANS; i++ ){ } for ( i = 0; i < ASPEC_CHANS; i++ ){ } } }/*end prMap4_0()*/ /************************************************************************/ /* Function : prMap5_0 */ /* Purpose : Print Map Data */ /* Inputs : */ /* Outputs : None */ /************************************************************************/ Void prMap5_0( ArgosInMsg *pMsg, struct _BufferMap *pMap, Nat32 oflags, Nat32 options){ int i; Flt64 day; ItemInfo pItem; Flt64 *pED, *pLU; Nat16 *pERR; char *edChan[ASPEC_CHANS]={"Ed412","Ed443","Ed490","Ed510","Ed555","Ed656","PAR "}; char *luChan[ASPEC_CHANS]={"Lu412","Lu443","Lu490","Lu510","Lu555","Lu656","Lu683"}; DEBUG(("prMap5_0\n\n")); pED = (Flt64 *)getItemData(_20M_1230_PRR600_ED,pMap); pLU = (Flt64 *)getItemData(_20M_1230_PRR600_LU,pMap); day = DAY(pMsg->first_msg); prRawBuffer(pMsg,oflags,options); if(oflags|fCONSOLE){ printf("Day %8.5f\n20M PRR600 1230h\n",day); for ( i = 0; i < ASPEC_CHANS; i++ ){ printf("%s %9.5f %s %9.5f\n",edChan[i],*(pED+i),luChan[i],*(pLU+i)); } } if(oflags|fARCHIVE){ print_sensor( SPEC_NOON_FILE, "%8.4f ", day); for ( i = 0; i < ASPEC_CHANS; i++ ){ print_sensor( SPEC_20_FILE, "%9.5f ", *(pED+i) ); } for ( i = 0; i < ASPEC_CHANS; i++ ){ print_sensor( SPEC_20_FILE, "%9.5f ", *(pLU+i) ); } } if(oflags|fHTML){ for ( i = 0; i < ASPEC_CHANS; i++ ){ } for ( i = 0; i < ASPEC_CHANS; i++ ){ } } }/*end prMap5_0()*/ /************************************************************************/ /* Function : crcOneWord */ /* Purpose : Check CRC-12 on one 16 bit word */ /* Inputs : Initial CRC, word to check */ /* Outputs : Resulting CRC */ /************************************************************************/ Nat16 crcOneWord( Nat16 initCRC, Nat16 wordToCheck ) { Reg Nat32 bitCnt; Reg Nat16 crc; crc = initCRC; for ( bitCnt = 0; bitCnt < 16; bitCnt++ ) { crc <<= 1; if ( wordToCheck & (0x8000 >> bitCnt) ) crc |= 1; if ( crc & CRC_MSB ) crc ^= CRC12; } return( crc ); } /* crcOneWord() */ /************************************************************************/ /* Function : checkCRC */ /* Purpose : Check CRC-12 on incoming message */ /* Inputs : Word Message Pointer */ /* Outputs : TRUE if CRC is OK, else FALSE */ /* Comment : OASIS uses the standard CRC-12 polynomial 0x180f */ /* However, it puts the checksum and type information in */ /* the first word of the message, which it checks LAST */ /************************************************************************/ MBool checkCRC( WordMsg *msgp ) { Reg Nat32 cnt; Reg Nat16 crc; for ( cnt = 1, crc = 0; cnt < ARGOS_BUFFER_WORDS; cnt++ ) crc = crcOneWord( crc, getIntelword((Byte *)&msgp->wd_data[cnt]) ); return( crcOneWord(crc, getIntelword((Byte *)&msgp->wd_data[0])) == 0 ); } /* checkCRC() */ /************************************************************************/ /* Function : printOneMsg */ /* Purpose : Print one received ARGOS message */ /* Inputs : Message Pointer */ /* Outputs : None */ /************************************************************************/ Void printOneMsg( ArgosInMsg *msgp ) { int item=0; int buffer=1,key=1; ItemInfo *pItem; BufferMap *pMap; buffer = MSGTYPE(msgp); if ( !checkCRC(&msgp->msg.raww) ) return; if ( !decode_all && !decode_msg[buffer] ) return; printf("Buffer %d Map %d\n",buffer,KEY(gKey,buffer)); pMap = &bufferMap[buffer][KEY(gKey,buffer)]; pItem = &pMap->item[0]; /* Extract data items in map */ for(item=0; ( pItem->id != NOTYPE && itempExFunc(msgp,pItem,gKey); } /* Call map output function */ pMap->pPrFunc(msgp, pMap,gOutputFlags,gPrintOptions); if(gOutputFlags&&fCONSOLE) printf("\n"); }/* printOneMsg() */ /************************************************************************/ /* Function : msgMatch */ /* Purpose : See if two ARGOS messages are the same */ /* Inputs : Two Message ptrs */ /* Outputs : TRUE if match, else FALSE */ /************************************************************************/ MBool msgMatch( ByteMsg *msgp1, ByteMsg *msgp2 ) { Int32 i; for ( i = 0; i < ARGOS_BUFFER_BYTES; i++ ) if ( msgp1->by_data[i] != msgp2->by_data[i] ) return( FALSE ); return( TRUE ); } /* msgMatch() */ /************************************************************************/ /* Function : findMatchingMessage */ /* Purpose : Find a matching ARGOS message from those already received*/ /* Inputs : Message ptr */ /* Outputs : Message number of matching message, or ERROR */ /************************************************************************/ Int32 findMatchingMessage( ByteMsg *msgp ) { Nat32 i; for ( i = 0; i < messageCount; i++ ) if ( msgMatch(msgp, &messages[i].msg.rawb) ) return( i ); return( ERROR ); } /* findMatchingMessage() */ /************************************************************************/ /* Function : getLine */ /* Purpose : Get one line of ARGOS message */ /* Inputs : FILE pointer, buffer ptr */ /* Outputs : MSG_OK or END_OF_FILE */ /************************************************************************/ MsgRtn getLine( FILE *fp, char * buffer ) { Reg Int32 len; buffer[0] = '\0'; while( TRUE ) { if ( fgets(buffer, kMAXLINE, fp) == NULL ) return( END_OF_FILE ); if ( (len = strlen(buffer)) > 0 ) { if ( buffer[len] == '\n' ) buffer[len] = '\0'; return( MSG_OK ); } } } /* getLine() */ /************************************************************************/ /* Function : getSvcArgosMsg */ /* Purpose : Get an ARGOS message in Service Argos format */ /* Inputs : FILE ptr, Buffer ptr, message ptr, time ptr, number of msgs*/ /* Outputs : Message return code */ /************************************************************************/ MsgRtn getSvcArgosMsg( FILE *fp, char *buffer, WordMsg *msgp, struct tm *tmPtr, Int32 *nmsgs ) { Nat32 i, j, dat[4]; if ( getLine(fp, buffer) == END_OF_FILE ) return( END_OF_FILE ); if ( sscanf(buffer, " %d-%d-%d %d:%d:%d %d %x %x %x %x", &tmPtr->tm_year, &tmPtr->tm_mon, &tmPtr->tm_mday, &tmPtr->tm_hour, &tmPtr->tm_min, &tmPtr->tm_sec, nmsgs, &dat[0], &dat[1], &dat[2], &dat[3]) < 11 ) return( BAD_MSG ); tmPtr->tm_year -= 1900; tmPtr->tm_mon -= 1; for ( i = 0; i < 4; i++ ) msgp->wd_data[i] = (Nat16)dat[i]; for ( i = 4; i < ARGOS_BUFFER_WORDS; i += 4 ) { if ( getLine(fp, buffer) == END_OF_FILE ) return( END_OF_FILE ); if ( sscanf(buffer, " %x %x %x %x", &dat[0], &dat[1], &dat[2], &dat[3]) < 4 ) return( BAD_MSG ); for ( j = 0; j < 4; j++ ) msgp->wd_data[i + j] = (Nat16)dat[j]; } return( MSG_OK ); } /* getSvcArgosMsg() */ /************************************************************************/ /* Function : getMessages */ /* Purpose : Get all incoming ARGOS messages */ /* Inputs : FILE pointer */ /* Outputs : None */ /************************************************************************/ Void getMessages( FILE *fp, char *buffer ) { struct tm msgTime, *tmPtr; time_t msg_time_t; MsgRtn state; ArgosUnion msg; Int32 msgNum, nmsgs; nMessages = messageCount = 0; bzero( (void *)messages, sizeof(messages) ); time( &msg_time_t ); tmPtr = gmtime( &msg_time_t ); memcpy( (void *)&msgTime, (void *)tmPtr, sizeof(struct tm) ); msgTime.tm_isdst = 0; state = MSG_OK; while ( state != END_OF_FILE ) { nmsgs = 1; state = getSvcArgosMsg( fp, buffer, &msg.raww, &msgTime, &nmsgs ); if ( state == MSG_OK ) { msg_time_t = mktime( &msgTime ); if ( (msgNum = findMatchingMessage(&msg.rawb)) != ERROR ) { if ( msg_time_t < messages[msgNum].first_msg ) messages[msgNum].first_msg = msg_time_t; if ( msg_time_t > messages[msgNum].last_msg ) messages[msgNum].last_msg = msg_time_t; messages[msgNum].msg_cnt += nmsgs; } else { if ( messageCount >= kMAXMESSAGES ) { printOneMsg( &messages[0] ); memmove( (void *)messages, (void *)&messages[1], (kMAXMESSAGES - 1) * sizeof(ArgosInMsg) ); messageCount--; } messages[messageCount].first_msg = msg_time_t; messages[messageCount].last_msg = msg_time_t; messages[messageCount].msg_cnt = nmsgs; memcpy( (void *)&messages[messageCount].msg.rawb, (void *)&msg, sizeof(ArgosUnion) ); nMessages += nmsgs; messageCount++; } } } } /* getMessages() */ /************************************************************************/ /* Function : decodeFile */ /* Purpose : Decode one ARGOS message file */ /* Inputs : File name */ /* Outputs : None */ /************************************************************************/ Void decodeFile( char *filename ) { Reg Nat32 i; Reg FILE *fp; MLocal char buffer[kMAXLINE]; if ( (fp = fopen(filename, "rb")) == (FILE *)NULL ) fprintf(stderr, "Cannot open %s\n", filename); else { getMessages( fp, buffer ); for ( i = 0; i < messageCount; i++ ) printOneMsg( &messages[i] ); } close_sensor_files(); } /* decodeFile() */