/************************************************************************/
/* Copyright 2003 - 2016 MBARI											*/
/************************************************************************/
/* Summary	: Log record types for the OASIS mooring controller			*/
/* Filename : log.h														*/
/* Author	: Robert Herlien (rah)										*/
/* Project	: OASIS Mooring Replacement (OASIS3)						*/
/* Revision : 0.1														*/
/* Created	: 01/07/2003 from OASIS log.h								*/
/*																			*/
/* 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:												*/
/* 07jan2003 rah - created from OASIS log.h								*/
/* 23nov2009 rah - Log Protocol version 2								*/
/* 09may2016 rah - Log Protocol version 3								*/
/************************************************************************/

#ifndef INClogh
#define INClogh			1

#include <fatFs/ff.h>
#include <time.h>


/****************************************/
/*		Data Logging					*/
/****************************************/

/* 9may2016, rah - This now implements version 3 of the log file format,	*/
/* which uses a 32 bit record number, ASCII Instrument ID, and trailing sync*/
/*																			*/
/* Log memory is divided into Log Blocks (LogBlk).	Each Log Block is saved */
/* in a pair of files: (.DAT and .IDX), and contains RECS_PER_BLK records.	*/
/* Although 2**18 blocks are theoretically supported, (for 2**14 blk size), */
/* the actual number is limited by the fact that we leave 5 decimal digits	*/
/* in the file name, which limits the number of log blocks to 100000.		*/
/* Also, to achieve this number of records, the disk must be formatted for	*/
/* FAT32, since FAT16 will more severely limit the number of files in the	*/
/* root directory (normally to about 2000 DAT/IDX pairs).					*/


typedef Nat32	LogBlk;					/* Log block == file number OASnnnnn*/
typedef Nat32	LogRecNum;				/* Record number					*/
#define LogPtr	LogRecNum				/* LogPtr now is just LogRecNum		*/


/* Set number of records per log block with LOG_BLK_SHIFT		*/
/* You'll get 2**LOG_BLK_SHIFT records per block				*/
/* E.g., 14 yields 16384 records/block							*/
/*		 16 yields 65536 records/block, etc						*/
/* Other parameters are calculated from this value				*/

#define LOG_BLK_SHIFT	14

#define RECS_PER_BLK	(1<<LOG_BLK_SHIFT) /* Number of records per Log file */
#define LOG_BLK_MASK	(RECS_PER_BLK - 1)
#define MIN_FREE_KB		128				   /* Below this we'll delete a Log Blk*/

#define BlkNum(recnum)	  (((recnum)>>LOG_BLK_SHIFT) & LOG_BLK_MASK)
#define RecOffset(recnum) ((recnum) & LOG_BLK_MASK)
#define RecNum(logblk)	  ((logblk)<<LOG_BLK_SHIFT)

typedef enum							/************************************/
{										/* Return code for isLogged			*/
	LOG_OK = 0,							/* Record is in memory				*/
	LOG_TOO_BIG,						/* Record number not yet logged		*/
	LOG_TOO_SMALL						/* Record was erased for space		*/
} LogRtn;								/************************************/


typedef struct							/************************************/
{										/* File ptrs for one log block		*/
	LogBlk		blk;					/* Block number						*/
	LogRecNum	firstUnflushedRec;		/* Record offset of first unflushed rec*/
	MBool		isOpen;					/* TRUE if datFP and idxFP are valid*/
	FIL			datFP;					/* FatFs FIL for data file			*/
	FIL			idxFP;					/* FatFs FIL for index file			*/
} LogFileDesc;							/************************************/


/****************************************/
/*		Log Record Definitions			*/
/****************************************/

										/************************************/
#define LOG_SYNC		0xAA			/* Sync char to ensure start of rec */
#define LOG_TRAILSYNC	0x55			/* Sync char to ensure end of rec	*/
#define LOG_NAMESIZE	16				/* Size of log_instrumentName		*/
										/************************************/
typedef struct							/************************************/
{										/* LogRecHdr - Logging Record Header*/
	Byte			log_syncc;			/* Sync chr - used internally by log*/
	Byte			log_version;		/* Version of log format			*/
	Byte			log_instrumentName[16]; /* ASCII name of instrument		*/
	Nat16			log_type;			/* Record type - see below			*/
	LogRecNum		log_rcd;			/* Record number					*/
	time_t			log_time;			/* Record time						*/
	Nat16			log_len;			/* Num bytes in log_data + trailSync*/
} LogRecHdr;							/************************************/


#define LOG_CHUNK		1024			/* For reading log file in chunks	*/
										/* See putOneLogRec() in usrcmd1.c	*/

typedef struct							/************************************/
{										/* LogRec - 1 chunk of log record	*/
	LogRecHdr		log_hdr;			/* Log Header						*/
	Byte			log_data[LOG_CHUNK]; /* Log Data						*/
	Byte			log_trailSync;		/* Trailing sync char				*/
} LogRec;								/************************************/


/****************************************/
/* From the former logTypes.h			*/
/* We now have just 2 types, defined here*/
/****************************************/

#define LOG_ASCII   	0       		/* ASCII record type                */
#define LOG_BIN		    1   	    	/* Binary record type               */

#define LOG_PROTOCOL2	150				/* First 32 bit logging protocol	*/
#define LOG_PROTOCOL3	151				/* First OASIS5 logging protocol	*/


/****************************************/
/* Function Declarations				*/
/****************************************/

Errno	log_init(void);
void	logDoFlush(void);
void	logFlush(void);
void	logClear(void);
LogRtn	isLogged(LogPtr lp);
Int32	logGetRec(LogPtr lp, LogRec *logp, Nat16 offset);
void	logNextBlk(LogPtr *lp);
void	logPutRec(LogRecHdr *hdrp, Byte *dp);
LogRecNum logGetCurrentLogPtrs(LogRecNum *newest, LogRecNum *oldest);
void	logError(Word vect);
void	logOasisStatus(Word onoff);
void	log_drv(Driver *dp);
void	logbin_drv(Driver *dp);
void	file_drv(Driver *dp);

#endif	/* INClogh */
