/************************************************************************/
/* 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 <stdio.h>
#include <logTypes.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*/
  FILE			*datFP;					/* FILE ptr for data file			*/
  FILE			*idxFP;					/* FILE ptr 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					*/
  TimeOfDay		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;								/************************************/


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

Errno	log_init(Void);
Void	logFlush(Void);
Void	logClear(Void);
Void	log_pwrdown(Void);
Void	log_pwrup(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);

#endif	/* INClogh */
