/******************************************************************************
 * Copyright (c) 2004, 2008 IBM Corporation
 * All rights reserved.
 * This program and the accompanying materials
 * are made available under the terms of the BSD License
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/bsd-license.php
 *
 * Contributors:
 *     IBM Corporation - initial implementation
 *****************************************************************************/

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <cfgparse.h>
#include <time.h>
#include <calculatecrc.h>
#include <product.h>
#include "createcrc.h"

int createHeaderImage(int);
unsigned int calCRCEthernet32(unsigned char *TextPtr,
			      unsigned long int TextLength,
			      unsigned int AccumCRC);
int createCRCParameter(uint64_t * ui64RegisterMask,
		       unsigned int *iRegisterLength);
uint64_t calCRCbyte(unsigned char *TextPtr, uint32_t Residual,
		    uint64_t AccumCRC);
uint64_t calCRCword(unsigned char *TextPtr, uint32_t Residual,
		    uint64_t AccumCRC);
uint64_t checkCRC(unsigned char *TextPtr, uint32_t Residual, uint64_t AccumCRC);

/* file length in bytes */
static uint64_t ui64globalFileSize = 0;
/* space for the file stream >= 4MB + 4bytes */
static unsigned char pucFileStream[4400000];
/* header length in bytes */
static uint64_t ui64globalHeaderSize = 0;
/* flag to filter detect the header in buildDataStream() */
static int iglobalHeaderFlag = 1;
static uint64_t ui64Generator1;

/**
 * Build the file image and store it as Data Stream of bytes
 * calculate a first CRC for the first file and
 * catch the position of this CRC
 */
int
buildDataStream(unsigned char *pucbuf, int size)
{
	if (ui64globalFileSize + size > sizeof(pucFileStream)) {
		printf("Error: File size is too big!\n");
		return -1;
	}

	/* copy the data into the destination buffer */
	memcpy(pucFileStream + ui64globalFileSize, pucbuf, size);
	ui64globalFileSize += size;

	if (iglobalHeaderFlag == 1) {	// catch header

		ui64globalHeaderSize = ui64globalFileSize;
		iglobalHeaderFlag = 0;
	}

	return 0;
}

/**
 * write Header.img
 */
int
createHeaderImage(int notime)
{
	int iCounter;
	uint64_t ui64RomAddr, ui64DataAddr;
	time_t caltime;
	struct tm *tm;
	char *pcVersion;
	char dastr[16] = { 0, };
	unsigned long long da = 0;

	union {
		unsigned char pcArray[FLASHFS_HEADER_DATA_SIZE];
		struct stH stHeader;
	} uHeader;

	/* initialize Header */
	memset(uHeader.pcArray, 0x00, FLASHFS_HEADER_DATA_SIZE);

	/* read driver info */
	if (NULL != (pcVersion = getenv("DRIVER_NAME"))) {
		strncpy(uHeader.stHeader.version, pcVersion, 16);
	} else if (NULL != (pcVersion = getenv("USER"))) {
		strncpy(uHeader.stHeader.version, pcVersion, 16);
	} else if (pcVersion == NULL) {
		strncpy(uHeader.stHeader.version, "No known user!", 16);
	}

	if (!notime) {
		/* read time and write it into data stream */
		if ((caltime = time(NULL)) == -1) {
			printf("time error\n");
		}
		if ((tm = localtime(&caltime)) == NULL) {
			printf("local time error\n");
		}
		// length must be 13 instead 12 because of terminating
		// NUL. Therefore uH.stH.platform_revison must be
		// writen later to overwrite the terminating NUL
		if (strftime(dastr, 15, "0x%Y%m%d%H%M", tm) == 0) {
			printf("strftime error\n");
		}
		da = cpu_to_be64(strtoll(dastr, NULL, 16));
	}
	memcpy(uHeader.stHeader.date, &da, 8);

	/* write Magic value into data stream */
	strncpy(uHeader.stHeader.magic, FLASHFS_MAGIC, 8);
	/* write platform name into data stream */
	strcpy(uHeader.stHeader.platform_name, FLASHFS_PLATFORM_MAGIC);
	/* write platform revision into data stream */
	strcpy(uHeader.stHeader.platform_revision, FLASHFS_PLATFORM_REVISION);


	/* fill end of file info (8 bytes of FF) into data stream */
	uHeader.stHeader.ui64FileEnd = -1;

	/* read address of next file and address of header date, both are 64 bit values */
	ui64RomAddr = 0;
	ui64DataAddr = 0;
	for (iCounter = 0; iCounter < 8; iCounter++) {
		/* addr of next file */
		ui64RomAddr = (ui64RomAddr << 8) + pucFileStream[FLASHFS_ROMADDR + iCounter];
		/* addr of header data */
		ui64DataAddr = (ui64DataAddr << 8) + pucFileStream[FLASHFS_DATADDR + iCounter];
	}

	/* calculate final flash-header-size and flash-file-size */
	/* calculate end addr of header */
	ui64globalHeaderSize = (uint32_t) ui64DataAddr + (uint32_t) FLASHFS_HEADER_DATA_SIZE;
	/* cut 64 bit to place CRC for File-End */
	ui64globalHeaderSize -= 8;
	/* add 64 bit to place CRC behind File-End */
	ui64globalFileSize += 8;

	if (ui64globalHeaderSize >= ui64RomAddr) {
		printf("%s\n", "--- Header File to long");
		return 1;
	}

	/* fill free space in Header with zeros */
	memset(&pucFileStream[ui64DataAddr], 0, (ui64RomAddr - ui64DataAddr));
	/* place data to header */
	memcpy(&pucFileStream[ui64DataAddr], uHeader.pcArray,
	       FLASHFS_HEADER_DATA_SIZE);

	/* insert header length into data stream */
	*(uint64_t *) (pucFileStream + FLASHFS_HEADER_SIZE_ADDR) =
	    cpu_to_be64(ui64globalHeaderSize);

	/* insert flash length into data stream */
	*(uint64_t *) (pucFileStream + ui64DataAddr + FLASHFS_FILE_SIZE_ADDR) =
	    cpu_to_be64(ui64globalFileSize);

	/* insert zeros as placeholder for CRC */
	*(uint64_t *) (pucFileStream + ui64globalHeaderSize - 8) = 0;
	*(uint64_t *) (pucFileStream + ui64globalFileSize - 8) = 0;

	return 0;
}

/**
 * calculate standart ethernet 32 bit CRC
 * generator polynome is 0x104C11DB7
 * this algorithm can be used for encoding and decoding
 */
unsigned int
calCRCEthernet32(unsigned char *TextPtr, unsigned long int TextLength,
		 unsigned int AccumCRC)
{
	const unsigned int CrcTableHigh[16] = {
		0x00000000, 0x4C11DB70, 0x9823B6E0, 0xD4326D90,
		0x34867077, 0x7897AB07, 0xACA5C697, 0xE0B41DE7,
		0x690CE0EE, 0x251D3B9E, 0xF12F560E, 0xBD3E8D7E,
		0x5D8A9099, 0x119B4BE9, 0xC5A92679, 0x89B8FD09
	};
	const unsigned CrcTableLow[16] = {
		0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9,
		0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005,
		0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61,
		0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD
	};

	unsigned char *Buffer = TextPtr;
	unsigned long int Residual = TextLength;


	while (Residual > 0) {
		unsigned int Temp = ((AccumCRC >> 24) ^ *Buffer) & 0x000000ff;
		AccumCRC <<= 8;
		AccumCRC ^= CrcTableHigh[Temp / 16];
		AccumCRC ^= CrcTableLow[Temp % 16];
		++Buffer;
		--Residual;
	}
	return AccumCRC;
}

/**
 * create CRC Parameter:  CRC Polynome, Shiftregister Mask and length
 *
 *   ui64Generator[0] = 0;
 *   ui64Generator[1] = 0x42F0E1EB;
 *   ui64Generator[1] = (ui64Generator[1] << 32) + 0xA9EA3693;
 *   iRegisterLength = 63;
 *   ui64RegisterMask =  0xffffffff;
 *   ui64RegisterMask = ((ui64RegisterMask) << 32) + 0xffffffff;
 *
 *    ucl=0x00000000ffffffff = Mask for 32 bit LSFR to cut down number of bits
 *    in the variable to get the same length as LFSR
 *
 *    il = length of LSFR = degree of generator polynom reduce il by one to calculate the degree
 *    of the highest register in LSFR
 *
 *    Examples:
 *    CRC-16 for Tap:		x16 + x15 + x2 + 1
 *     generator = 0x8005,	il = 16,	ucl = 0x000000000000FFFF
 *
 *    CRC-16 for Floppy:		x16 + x12 + x5 +1
 *     generator = 0x1021,	il = 16,	ucl = 0x000000000000FFFF
 *
 *    CRC-32 for Ethernet:	x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
 *     generator = 0x04C11DB7,	il = 32,	ucl = 0x00000000FFFFFFFF
 *
 *    CRC-64 SP-TrEMBL	x64 + x4 + x3 + x + 1 (maximal-length LFSR)
 *     generator = 0x1B,	il = 64,	ucl = 0xFFFFFFFFFFFFFFFF
 *
 *    CRC-64 improved
 *     x64 + x63 + x61 + x59 + x58 + x56 + x55 + x52 + x49 + x48 + x47 + x46+ x44 +
 *     x41 + x37 + x36 + x34 + x32 + x31 + x28 + x26 + x23 + x22 + x19 + x16 + x13 +
 *     x12 + x10 + x9 + x6 + x4 + x3 + 1
 *     (see http://www.cs.ud.ac.uk/staff/D.Jones/crcbote.pdf)
 *     generator = 0xAD93D23594C9362D,  il = 64,    ucl = 0xFFFFFFFFFFFFFFFF
 *
 *    CRC-64 DLT1 spec
 *     x64 + x62 + x57 + x55 + x54 + x53 + x52 + x47 + x46 + x45 + x40 + x39 + x38 + x37 +
 *     x35 + x33 + x32 + x31 + x29 + x27 + x24 + x23 + x22 + x21 + x19 + x17 + x13 + x12 +
 *     x10 + x9 + x7 + x4 + x + 1
 *     (see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-182.pdf  -> page63)
 *     generator = 0x42F0E1EBA9EA3693
 *
 *    CRC-64 from internet G(x)= 1006003C000F0D50B
 */
int
createCRCParameter(uint64_t * ui64RegisterMask, unsigned int *uiRegisterLength)
{
	enum Generators { Tape_16, Floppy_16, Ethernet_32, SPTrEMBL_64,
		SPTrEMBL_improved_64, DLT1_64
	};
	enum Generators Generator;

	Generator = CRC_METHODE;
	switch (Generator) {
	case Tape_16:{
			*ui64RegisterMask = 0x0000ffff;
			ui64Generator1 = 0x00008005;
			*uiRegisterLength = 16;
			break;
		}
	case Floppy_16:{
			*ui64RegisterMask = 0x0000ffff;
			ui64Generator1 = 0x00001021;
			*uiRegisterLength = 16;
			break;
		}
	case Ethernet_32:{
			*ui64RegisterMask = 0xffffffff;
			ui64Generator1 = 0x04C11DB7;
			*uiRegisterLength = 32;
			break;
		}
	case SPTrEMBL_64:{
			*ui64RegisterMask = 0xffffffff;
			*ui64RegisterMask =
			    ((*ui64RegisterMask) << 32) + 0xffffffff;
			ui64Generator1 = 0x0000001B;
			*uiRegisterLength = 64;
			break;
		}
	case SPTrEMBL_improved_64:{
			*ui64RegisterMask = 0xffffffff;
			*ui64RegisterMask =
			    ((*ui64RegisterMask) << 32) + 0xffffffff;
			ui64Generator1 = 0xAD93D235;
			ui64Generator1 = (ui64Generator1 << 32) + 0x94C9362D;
			*uiRegisterLength = 64;
			break;
		}
	case DLT1_64:{
			*ui64RegisterMask = 0xffffffff;
			*ui64RegisterMask =
			    ((*ui64RegisterMask) << 32) + 0xffffffff;
			ui64Generator1 = 0x42F0E1EB;
			ui64Generator1 = (ui64Generator1 << 32) + 0xA9EA3693;
			*uiRegisterLength = 64;
			break;
		}
	}
	(*uiRegisterLength)--;

	return 0;
}

/**
 *  Check CRC by using Linear Feadback Shift Register (LFSR)
 */
uint64_t
calCRCbyte(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC)
{

	uint64_t ui64Mask, ui64Generator0;
	uint8_t ui8Buffer;
	unsigned int uiRegisterLength;
	int iShift;

	createCRCParameter(&ui64Mask, &uiRegisterLength);

	ui8Buffer = (*cPtr);
	while (ui32NoWords > 0) {
		for (iShift = 7; iShift >= 0; iShift--) {

			ui64Generator0 = (AccumCRC >> uiRegisterLength);
			AccumCRC <<= 1;
			ui64Generator0 &= 0x01;
			ui64Generator0 = (0 - ui64Generator0);
			AccumCRC ^= (ui64Generator1 & ui64Generator0);
		}
		AccumCRC ^= ui8Buffer;
		AccumCRC &= ui64Mask;
		ui32NoWords -= 1;
		cPtr += 1;
		ui8Buffer = (*cPtr);
	}
	return AccumCRC;
}

/**
 *  Check CRC by using Linear Feadback Shift Register (LFSR)
 */
uint64_t
calCRCword(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC)
{

	uint64_t ui64Mask, ui64Generator0;
	uint16_t ui16Buffer;
	unsigned int uiRegisterLength;
	int iShift;

	createCRCParameter(&ui64Mask, &uiRegisterLength);

	if ((ui32NoWords % 2) != 0) {
		/* if Data string does not end at word boundery add one byte */
		ui32NoWords++;
		cPtr[ui32NoWords] = 0;
	}
	ui16Buffer = ((*(cPtr + 0)) * 256) + (*(cPtr + 1));
	while (ui32NoWords > 0) {
		for (iShift = 15; iShift >= 0; iShift--) {
			ui64Generator0 = (AccumCRC >> uiRegisterLength);
			AccumCRC <<= 1;
			ui64Generator0 &= 0x01;
			ui64Generator0 = (0 - ui64Generator0);
			AccumCRC ^= (ui64Generator1 & ui64Generator0);
		}
		AccumCRC ^= ui16Buffer;
		AccumCRC &= ui64Mask;
		ui32NoWords -= 2;
		cPtr += 2;
		ui16Buffer = ((*(cPtr + 0)) * 256) + (*(cPtr + 1));
	}
	return AccumCRC;
}

uint64_t
checkCRC(unsigned char *cPtr, uint32_t ui32NoWords, uint64_t AccumCRC)
{

	enum Generators { Ethernet_32 };
	enum Generators Generator;
	uint64_t ui64Buffer = AccumCRC;

	Generator = CRC_METHODE;

	switch (Generator) {
	case Ethernet_32:{
			/* (ui32NoWords - 4),no need of 4 bytes 0x as
			 * with shift-register method */
			AccumCRC =
			    calCRCEthernet32(cPtr, (ui32NoWords - 4), AccumCRC);
			break;
		}
	default:{
			AccumCRC = calCRCword(cPtr, ui32NoWords, AccumCRC);
			break;
		}
	}

	if (calCRCbyte(cPtr, ui32NoWords, ui64Buffer) != AccumCRC) {
		printf("\n --- big Endian - small Endian problem --- \n");
		AccumCRC--;
	}

	return (AccumCRC);
}

/**
 *  insert header and file CRC into data stream
 *  do CRC check on header and file
 *  write data stream to disk
 */
int
writeDataStream(int iofd, int notime)
{
	uint64_t ui64FileCRC = 0, ui64HeaderCRC = 0, ui64RegisterMask;
	unsigned int uiRegisterLength;

	if (0 != createHeaderImage(notime)) {
		return 1;
	}

	createCRCParameter(&ui64RegisterMask, &uiRegisterLength);

	/* calculate CRC */
	ui64HeaderCRC = checkCRC(pucFileStream, ui64globalHeaderSize, 0);
	*(uint64_t *) (pucFileStream + ui64globalHeaderSize - 8) =
	    cpu_to_be64(ui64HeaderCRC);

	ui64FileCRC = checkCRC(pucFileStream, ui64globalFileSize, 0);
	*(uint64_t *) (pucFileStream + ui64globalFileSize - 8) =
	    cpu_to_be64(ui64FileCRC);

	/* check CRC-implementation */
	ui64HeaderCRC = calCRCword(pucFileStream, ui64globalHeaderSize, 0);
	ui64FileCRC = calCRCword(pucFileStream, ui64globalFileSize, 0);

	if ((ui64HeaderCRC != 0) || (ui64FileCRC != 0)) {
		printf("\n\n %s \n %s \n\n", "CRCs not correct implemented.",
		       " ---> Data will not be written do disk.");
		return -1;
	}

	/* write file image to disk */
	if (0 < write(iofd, pucFileStream, ui64globalFileSize))
		return 0;

	printf("<< write failed >>\n");
	return -1;
}
