/*********************************************************************
 * CRC calculaton
 * we use the CCITT standard
 * 			CCITT		CRC16		CRC32
 * 			16 bits		16 bits		32 bits
 * Divisor		0x1021		0x8005		0x04C11DB7	
 * Initial remainder	0xFFFF		0x0000		0xFFFFFFFF
 * Final XOR Value 	0x0000		0x0000		0xFFFFFFFF
 *******************************************************************/
//#include <stdio.h>
//#include <stdlib.h>

#define POLYNOMIAL		0x1021
#define INITIAL_REMAINDER	0xFFFF
#define FINAL_XOR_VALUE		0x0000

typedef unsigned short width;	// 16 bits

#define WIDTH 	(8*sizeof(width))
#define TOPBIT 	(1 << (WIDTH - 1))

width crcTable[256];		// this is our lookup table


/**********************************************************
 * crcInit()
 * Initialize the CRC lookup table
 * NOTES: The mod 2 binary division is implemented here
 ***********************************************************/ 

void crcInit()
{
	width 	remainder;
	width 	dividend;
	int 	bit;

	/* perform binary long division, one bit at a time */
	for (dividend = 0; dividend < 256; dividend++) {
		/* initialize the remainder */
		remainder = dividend << (WIDTH - 8);

		/* shift and XOR with polynomial */
		for (bit = 0; bit < 8; bit++) {
			/* try to divide the current data bit */
			if (remainder & TOPBIT) 
				remainder = (remainder << 1) ^ POLYNOMIAL;
			else
				remainder = remainder << 1;
		}
		crcTable[dividend] = remainder;
	}
} 


/**********************************************************
 * crcCompute()
 * Compute CRC checksum of a binary message block 
 * NOTES: The CRC of the data - width == unsigned short
 ***********************************************************/ 

width crcCompute(char* message,int nBytes)
{
	unsigned int	offset;
	unsigned char 	byte;
	width		remainder = INITIAL_REMAINDER;

	/* divide the message by polynomial, a byte at a time */
	for (offset = 0; offset < nBytes; offset++) {
		byte = (remainder >> (WIDTH - 8)) ^message[offset];
		remainder = crcTable[byte] ^ (remainder << 8);
	}
	return (remainder ^ FINAL_XOR_VALUE);

}
/*
int main()
{
	unsigned int crcInt;
	char* cmdPtr;
	static char buffer[1024];
	int n;		
	char cmd[256] = "1|2|3\n";

	unsigned int crcBot;
	int ntokens;
	int str_len;
	int index_tel[50];
	
	crcInit();	
	cmdPtr = cmd;	
	while (*cmdPtr++ != '\n');
	*(--cmdPtr) = 0;
	n = strlen(cmd);
	printf("n is %d\n", n);
	crcInt = crcCompute(cmd, n);
       	printf("crc is: %u\n", crcInt);	
	snprintf(buffer, 1024, "%s %u%c", cmd, crcInt, '\n'); 
	printf(buffer);
	n = 12;
	buffer[n - 1] = 0;
			
	ntokens = parse(buffer, ' ', index_tel, n - 1, 50);
	str_len = strlen(&buffer[index_tel[0]]);
	if (ntokens == 2) 
		crcBot = crcCompute(&buffer[index_tel[0]], str_len);
	printf("crcTop %X\n", crcInt);
	printf("crcBot %X\n", crcBot);
	printf("string is now: %s", &buffer[index_tel[1]]);

	if (crcBot != our_atoi(&buffer[index_tel[1]])) {
		printf("crc Error\n");
		//rt_com_write("BAD CRC\n");
	} else {
		printf("crc correct\n");
	}

	return 0;
}
*/
