// flash2hex.c
// 24mar08 
// reads in >=0711 flash card data,
// where records are written with headers to allow better parsing
// This is the first step to unpacking, and should be followed
// by flash_hex2ascii to create the proper .raw file
// 10Mar2010, modified to work on UNIX machine, via spray_files.h

//command line input is:
// flash2hex YYM SN M_ID C n1 n2 DIAG
// where YYM is Year-Month code
// SN = Spray s/n
// M_ID = mission ID for YYM (typ 1)
// C = First character of file name : 'D' = data, 'V' = doppler files.
// n1 = first file number ( n1=xxx where first file=Dxxx)
// n2 = last  file number ( n2=yyy where  last file=Dyyy)
// DIAG=1 = display diagnostics

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "base_fnx.h"
#include "spray_files.h" // define spray sub-directories

// definitions -------------------------------------------
#define NMAX 3000  // max # dives expected
#define NLINE 512  // max # char per each line

//---packet ID format definitions -------------------------
//---following are used in flash2hex ----------------------
#define   CF_END    0xff   // end-file marker
#define   CF_EOF    -1     // end-of-file
#define   CF_LOST   -2     // parser function is lost
#define   CF_SB     '{'    // CF packet start-byte
#define   CF_EB     '}'    // CF packet end-byte
//---------------------------------------------------------

//following packet ID's are listed, but are NOT used here
/**/
#define   CF_DIVE   0x0f   // dive marker
#define   CF_GPS0   0x00   // GPS record: 0=start-mission
#define   CF_GPS1   0x01   // GPS record: 1=start-dive
#define   CF_GPS2   0x02   // GPS record: 2=end-dive
#define   CF_GPS3   0x03   // GPS record: 3=end-mission
#define   CF_ABORT  0x06   // abort status record

#define   CF_DATA   0x10   // 8s data record, version 0
#define   CF_SBE    0x30   // SBE 1Hz data
#define   CF_ADP    0x50   // ADP profile data
#define   CF_ALT    0x51   // ADP altimeter data
#define   CF_ADPS   0x52   // ADP shallow data
#define   CF_PH     0x80   // pH data
#define   CF_CONT   0xcc   // continuation of the last record
#define   CF_ENG    0xe0   // the engineering packet already contains it's version #
#define   CF_TEST   0xfe   // Test packet
/**/

// globals ------------------------------------------------
FILE  *fp_in, *fp_out;
int sn, m_id;   // Spray s/n plus mission id = m_id
char datdir[4]; // YYM of the data directory
int DIAG=0; // default is off

// prototypes ---------------------------------------------
long   open_file     (char cf, short id);
int    parse_cf_file ( void );
 

//*****************************************************************************
int main(int argc, char *argv[])   //******************************************
{
	int  id, id1, id2;
	int  stat, last_stat;
	long nbytes, nscan;
	char cf; // compact-flash file first-letter value: user-input
	char outfile[80];

   // read in the arguments ----------------------------------------
   switch (argc) //-------------------------------------------------
   { // read in the variables
   		case 8 : sscanf(argv[7],"%d",&DIAG);
   		case 7 : sscanf(argv[6],"%d",&id2);
   		case 6 : sscanf(argv[5],"%d",&id1);
   		case 5 : sscanf(argv[4],"%c",&cf);
   		case 4 : sscanf(argv[3],"%d",&m_id);
   		case 3 : sscanf(argv[2],"%d",&sn);
   		case 2 : sscanf(argv[1],"%s",datdir);
   } // end switch
   			// now query the rest of the variables
   switch (argc)
   { // query for the rest
   		case 1 :	printf ("Give 3-char date YYM to process\n");
   					scanf("%s",datdir); 
   		case 2 :	printf("Give s/n to process for date %s\n",datdir);
   					scanf("%d",&sn);
   		case 3 :	printf("Give the mission id \n");
   					scanf("%d",&m_id);
   		case 4 :	printf("Give the file-letter type (A,D, or V) \n");
   					scanf("%c",&cf);
   		case 5 :	printf("Give the first file# to process \n");
   					scanf("%d",&id1);
   		case 6 :	printf("Give the  last file# to process \n");
   					scanf("%d",&id2);
   } // end switch ------------------------------------------------
   // -------------------------------------------------------------

	printf("Program will convert %cxxx files from binary to hex\n",cf);
	printf("processing file #%d to %d\n",id1, id2);
    //-------------------------------------------------------------
    
    //open the output file ----------------------------------------
   	sprintf(outfile,"%s%s%sSpray%03d_%1d%s%c_hex.txt",
   	       Spray_Data,datdir,delim,sn,m_id,delim, cf); 
   	       //Spray_Data, delim from spray_files.h
	printf("output will go to %s\n",outfile);
	fp_out = fopen(outfile,"w"); 
	if (fp_out==NULL)
	{  
	   printf("Open outfile failed: %s\n",outfile);
	   return 0;
	}
	//--------------------------------------------------------------
	
	
	//step thru all files -------------------------------------------------
	//---------------------------------------------------------------------
	//---------------------------------------------------------------------
	for (id=id1;id<=id2;id++ )
	{

		nbytes = open_file(cf, id);  // nbytes=#bytes in file
		nscan=0;
		
		if (nbytes>0) //===============================================
		{ // then process the file
			    		
    		// the following is for >=0711 format, where packets
    		// have their own id and byte-count
    		  last_stat=-1; // status of last packet
    		  do // rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
    		  {  // keep reading packets until EOF
    		     stat = parse_cf_file(); // stat=pid
    		     if (DIAG && stat != CF_DATA ) printf("\n");
    		     if ( stat>=0 ) // keep track of good packets
    		       { last_stat=stat; nscan++; }
				 if (DIAG) printf("parsed scan %d, PID = %02x\n", nscan - 1, stat);
    		   }  while (stat>=0 ); //rrrrrrrrrrrrrrrrrrrrrrrrr
    		   
    		   if (last_stat != CF_END ) //ssssssssssssssssssss
    		   { // then file was not properly closed
    		     // could do more diagnosis here
    		     printf("Last packet in file NOT END: pid=%02x\n", 
    		             last_stat);
    		   } //ssssssssssssssssssssssssssssssssssssssssssss

    	} //===========================================================
    	
    	printf("parsed %6ld packets.\r",nscan);
		fclose(fp_in);  // close input file
	} // end for id -------------------------------------------------------
	//---------------------------------------------------------------------
	//---------------------------------------------------------------------

	fclose(fp_out);
    printf("\n flash2hex done! \n");

	return 0;
} //***************************************************************************
//*****************************************************************************


long open_file(char cf, short id) //*******************************************
{ // open & return #bytes in the file 
	char infile[80];
	long nbytes = 0;

   	sprintf(infile,"%s%s%sSpray%03d_%1d%sflash%s%c%03d\0",
   	       Spray_Data,datdir,delim,sn,m_id, delim,delim,cf, id); 
	
	fp_in = fopen(infile,"rb");  // open as read only binary
	printf("FILE: %s\n",infile);
	
	if (fp_in==NULL) 
	{  // could not open the file
	   printf("%s NOT found \n",infile);
	   return(0);  // no file = no bytes
	}  // else compute the number of bytes
	
	fseek(fp_in,0L,SEEK_END); //point to end
	nbytes = ftell(fp_in); 
	printf("%s has %8ld bytes: ",infile,nbytes);
	fseek(fp_in,0L,SEEK_SET);  //point to start
	
 return(nbytes);
 } //**************************************************************************
 
 
 int   parse_cf_file( void ) //************************************************
 {  // parse the >=0711 CF flash card file
    // returns the packet ID of the message
    // returns -1 if EOF
    // returns -2 if BAD packet
    // 
    // assumes the following packet format:
    // <SB><pid><nbytes><EB>
    // where SB=start-byte, EB=end-byte, pid = packet ID
    int pid, i=0, n;
    unsigned int  sb, eb, buf[256];
    int ch,dummy;
    
    sb = getc(fp_in); // check the start-bye
       //>>>if (DIAG) printf("SB=%02x ",sb);
	if (sb != CF_SB)sb = getc(fp_in);  // we're lost
    
	if (sb != CF_SB) return(CF_LOST);  // we're lost
    pid = getc(fp_in); // get the packet id
	if(DIAG)printf("Begin parse with pid = %02x\n", pid);
    n   = getc(fp_in); // get the # of data bytes
    
    if (DIAG && pid != CF_DATA) printf(" PID=%02x, nb=%3d \n         ",pid,n);
    if (n>255)
    { printf("Number data bytes bad = %d: pid=%d, start-byte=%c\n",
              n, pid, sb );
      return(CF_LOST);
    }
    
    // else so far so good
	if (n > 0)
	{
		do //--------------------------------------------------------------
		{  // read in # of bytes, or EOF
			ch = getc(fp_in);
			if (ch == -1) return(CF_EOF);
			buf[i++] = ch; // else store the value

			if (DIAG  && pid != CF_DATA)
			{
				printf("%02x.", ch);
				if ((i + 1) % 30 == 0) printf("\n         ");
			}

		} while (i < n); //--------------------------------------------------
	}
    eb = getc(fp_in); // get the end-byte
    
	if (eb != CF_EB )
	{
		printf("!!!! EB=%02x, i=%d \n", eb,i);
		//scanf("%c",&dummy);
		buf[i++] = eb; //store the value anyway
		//eb = getc(fp_in);
		
	}
		 //return(CF_LOST);  // we're lost
    
    // otherwise we've read everything in & it all looks OK
    // write out to file here
    fprintf(fp_out,"%02x %3d ",pid, n);
    for (i=0;i<n;i++) fprintf(fp_out,"%02x",buf[i]);
    fprintf(fp_out,"\n" ); // end-of-line
	if (DIAG) printf(" pid = %d (0x%02x)\n", pid, pid);
    return (pid);
 } //**************************************************************************
 


//*** END *********************************************************************

