/*
 * Copyright (c) 2003 Linuxant inc.
 * Copyright (c) 2001-2003 Conexant Systems, Inc.
 *
 * NOTE: The use and distribution of this software is governed by the terms in
 * the file LICENSE, which is included in the package. You must read this and
 * agree to these terms before using or distributing this software.
 *
 */
/*****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include "framewrk.h"
#include "ossysenv.h"
/*****************************************************************************/
#define MAX_LINE_LEN         256

/*****************************************************************************/
inline unsigned char ConvertHexDigitToNum(const char HexDigit);

/*****************************************************************************/

int main(int argc, char **argv)
{
	FILE            *fpHex = NULL;               // hex source file
	FILE            *fpBin = NULL;               // target binary file
	char            HexNo[3];                    // temp var to symbol 2 charcters as a char no.
	char            HexLine[MAX_LINE_LEN+1];     // hex text line
	UINT32          BinDataSize = 0;             // (size of the output binary file) - (the first ulong)
	unsigned char   TargetLine[MAX_LINE_LEN];    // binary line for write to target
	unsigned char   NumCount = 0;				 // number of Hex bumbers in the line
	unsigned char   Num,i;

	
	if (3 != argc)
	{
		printf("usage : firm2bin <FIRMWARE_FILENAME> <OUTPUTFILE>\n");
		return 1;
	}

	/* open the file to read */
	fpHex = fopen(argv[1],"r");
	if (NULL == fpHex)
	{
		printf("Error : can't open Yukon source file '%s' .\n",argv[1]);
		return 2;
	}
	/* open the target binary file */
	fpBin = fopen(argv[2],"wb");
	if (NULL == fpBin)
	{
		printf("Error : can't open Yukon target file '%s' .\n",argv[2]);
		fclose (fpHex);
		return 3;
	}

		

	/* loop on all the lines - creating the binary file */
	fseek(fpBin, sizeof(BinDataSize), SEEK_SET); 	/* save the first bytes to file size and lines number */

	BinDataSize  = 0;

	while ( NULL != fgets(HexLine, MAX_LINE_LEN, fpHex))
	{
		if (HexLine[0] != ':')
		{
			printf("Error : Bad target file '%s' - line doesn't start with ':' .\n",argv[1]);
			fclose(fpHex);
			fclose(fpBin);
			return 4;
		}

		NumCount = 	(strlen(HexLine) - 1)/2;
		BinDataSize += NumCount;

		// build the line to write to bin file
		for (i=0 ; i<NumCount ; i++)
		{	
			Num = 0;
			strncpy(HexNo,HexLine + (2*i) + 1,2);
			HexNo[2] = '\0';
			Num = (16 * ConvertHexDigitToNum(HexNo[0])) + (ConvertHexDigitToNum(HexNo[1]));
			TargetLine[i] = Num;
		}

		// write the line to bin file 
		fwrite(TargetLine,sizeof(unsigned char),NumCount,fpBin);
	}

	fseek(fpBin,0,SEEK_SET);
	fwrite((PVOID)&BinDataSize, sizeof(BinDataSize), 1, fpBin);
	
	/* close Yukon file */
	fclose( fpHex );
	fclose( fpBin );

	return 0;
}

/*****************************************************************************/
inline unsigned char ConvertHexDigitToNum( const char HexDigit )
{
	unsigned char temp = 0;

	if ( isdigit( HexDigit ) )
	{
		temp = (HexDigit - '0');
	}
	else if (HexDigit <= 'f' && HexDigit >= 'a')
	{
		temp = ((HexDigit - 'a')+10);
	}
	else if (HexDigit <= 'F' && HexDigit >= 'A')
	{
		temp = ( (HexDigit - 'A') + 10 );
	}
	return ( temp );
}
