/*
 * Copyright (C) 2007-2008 Arnaud Ysmal <wiidevel@stacktic.org>
 *
 * others.c (TransferMii)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "tmii.h"

extern char wm_read;
extern char wm_update;

extern unsigned char wii_mac[3];

/* Checks and corrects crc */
void crcCheck()
{
	int byteidx, bitidx, crc=0, i;
 
	if (!wm_read && !wiimoteRead())
		return;
	printf("Checking crc...\n");
	for (byteidx=0; byteidx<BLOCK_SIZE-2; byteidx++)
		for (bitidx=7; bitidx>=0; bitidx--)
			crc = (((crc<<1)|((miiblock[byteidx]>>bitidx)&0x1))^
			       (((crc&0x8000)!=0)?0x1021:0));
	for (i=16; i>0; i--)
		crc = ((crc << 1) ^ (((crc & 0x8000) != 0) ? 0x1021 : 0));

	if ((crc & 0xffff) != ((miiblock[BLOCK_SIZE-2]<<8)|(miiblock[BLOCK_SIZE-1]))) {
		printf("wrong crc !\nCorrecting...\n");
		miiblock[BLOCK_SIZE-2] = (crc>>8)&0xFF;		
		miiblock[BLOCK_SIZE-1] = crc&0xFF;
		wm_update = TRUE;
		printf("Corrected !\n");
	} else {
		printf("crc is correct !\n");
	}
}

/* string(XX:XX:XX) to unsigned char[3] */
char parseMacAddress(char *macaddr)
{
	if (macaddr==NULL || macaddr[2]!=':' ||  macaddr[5]!=':' ||
	   macaddr[8]!='\0')
		return FALSE;
    
	if (macaddr[0] >= '0' && macaddr[0] <= '9') {
		wii_mac[0] = (macaddr[0]-'0')<<4;
	} else if ((macaddr[0]&0xDF) >= 'A' && (macaddr[0]&0xDF)<='F') {
		wii_mac[0] = ((macaddr[0]&0xDF)-'A'+10)<<4;
	} else {
		wii_mac[0] = 0;
		return FALSE;
	}

	if (macaddr[1] >= '0' && macaddr[1] <= '9') {
		wii_mac[0] += (macaddr[1]-'0');
	} else if ((macaddr[1]&0xDF) >= 'A' && (macaddr[1]&0xDF)<='F') {
		wii_mac[0] += ((macaddr[1]&0xDF)-'A'+10);
	} else {
		wii_mac[0] = 0;
		return FALSE;
	}

	if (macaddr[3] >= '0' && macaddr[3] <= '9') {
		wii_mac[1] = (macaddr[3]-'0')<<4;	
	} else if ((macaddr[3]&0xDF) >= 'A' && (macaddr[3]&0xDF)<='F') {
		wii_mac[1] = ((macaddr[3]&0xDF)-'A'+10)<<4;
	} else {
		wii_mac[0] = 0;
		wii_mac[1] = 0;
		return FALSE;
	}

	if (macaddr[4] >= '0' && macaddr[4] <= '9') {
		wii_mac[1] += (macaddr[4]-'0');	
	} else if ((macaddr[4]&0xDF) >= 'A' && (macaddr[4]&0xDF)<='F') {
		wii_mac[1] += ((macaddr[4]&0xDF)-'A'+10);
	} else {
		wii_mac[0] = 0;
		wii_mac[1] = 0;
		return FALSE;
	}
	
	if (macaddr[6] >= '0' && macaddr[6] <= '9') {
		wii_mac[2] = (macaddr[6]-'0')<<4;	
	} else if ((macaddr[6]&0xDF) >= 'A' && (macaddr[6]&0xDF)<='F') {
		wii_mac[2] = ((macaddr[6]&0xDF)-'A'+10)<<4;
	} else {
		wii_mac[0] = 0;
		wii_mac[1] = 0;
		wii_mac[2] = 0;
		return FALSE;
	}

	if (macaddr[7] >= '0' && macaddr[7] <= '9') {
		wii_mac[2] += (macaddr[7]-'0');	
	} else if ((macaddr[7]&0xDF) >= 'A' && (macaddr[7]&0xDF)<='F') {
		wii_mac[2] += ((macaddr[7]&0xDF)-'A'+10);
	} else {
		wii_mac[0] = 0;
		wii_mac[1] = 0;
		wii_mac[2] = 0;	
		return FALSE;
	}
	return TRUE;
}

void beu16toascii(uint16_t *src, char *dest)
{
	char *tmp = (char*)src;

	dest[0] = tmp[1];
	dest[1] = tmp[3];
	dest[2] = tmp[5];
	dest[3] = tmp[7];
	dest[4] = tmp[9];
	dest[5] = tmp[11];
	dest[6] = tmp[13];
	dest[7] = tmp[15];
	dest[8] = tmp[17];
	dest[9] = tmp[19];
}

void asciitobeu16(char *src, uint16_t *dest)
{
	dest[0] = src[0];
	dest[1] = src[1];
	dest[2] = src[2];
	dest[3] = src[3];
	dest[4] = src[4];
	dest[5] = src[5];
	dest[6] = src[6];
	dest[7] = src[7];
	dest[8] = src[8];
	dest[9] = src[9];
}
