/*******************************************************************************
 * @file    TargetAC.c
 * @brief
 ******************************************************************************/
 
/*
* Copyright © 2013 Texas Instruments Incorporated - http://www.ti.com/ 
 * 
 *  Redistribution and use in source and binary forms, with or without 
 *  modification, are permitted provided that the following conditions 
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the   
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
*/

#include "TargetAC.h"
#include "TRF7970A.h"
#include "types.h"
#include "API.h"
#include <stdint.h>

typedef enum {
	FALSE_s = 0, TRUE_s
} boolean_state;

static u08_t TargetAC_sens_res[2];
static u08_t TargetAC_sel_res;
static u08_t TargetAC_pupi[4];
static u08_t TargetAC_afi;
static u08_t TargetAC_crc_aid[2];
static volatile u08_t TargetAC_number_apli;
static u08_t TargetAC_nfcid1[10]; //ISO/IEC 18092 11.2.1.26 NFCID1 contents and cascade levels
static u08_t TargetAC_nfcid2[8];


void RF_ReadCont(u08_t adr, u08_t *buf, u08_t len);
unsigned char RF_Read(u08_t adr);
unsigned char RF_Write(u08_t adr, u08_t value);
void RF_WriteRaw(u08_t *cmd, u08_t len);
void RF_WriteCmd(u08_t cmd);
unsigned char RF_AAC();
void _printf(char *fmt, ...);
void setSelectedFrameType(unsigned char type);

u08_t RF_writeFIFO(u08_t *pbuf, u08_t crc_bit, u08_t length, u08_t broken_bits);
void RF_resetFIFO(void);

unsigned char getSelectedFrameType();

#define CRC_ENABLE_t 0x01
#define CRC_DISABLE_t 0x00

#define TARGET_CID   {0x08, 0x01, 0x02, 0x03}
u08_t TargetCID[7] = TARGET_CID;

volatile u08_t isSelected = 0x00;

u08_t isTagSelected() {
	return isSelected;
}

void NFCTarget_init() {
	isSelected = 0x00;
	RF_AAC();
}
void NFCTarget_init_light() {
	isSelected = 0x00;
}


void NFC_ProcessReceivedData(u08_t * buffer) {
	u08_t res_buf[30];

	u08_t command;
	volatile u08_t index_temp;
	u08_t buf_idx = 0;

	command = buffer[0];

	isSelected = 0x00;

	switch (command) {
	//
	// Type A Commands
	//

	//
	// Received a REQA / SENS_REQ or WUPA
	//
	case 0x26:
	case 0x52:

		// Register 01h. ISO Control Register
		//
		// 106 kbps Tag Emulator 14443A mode
		//
		RF_Write(TRF79X0_ISO_CONTROL_REG, 0xA4);

		// BIT15:12 RFU
		// BIT11:8 Proprietary - 0x03
		// BIT7:6  NFCID Length - 00 - Single, 01 - Double, 11 - Triple
		// BIT5 RFU
		// BIT4:0 Bit frame anti-collision - Bit 1

		// Note: Otherwise we receive a 0x30 0x0C 0x01 from the reader
		res_buf[buf_idx++] = TargetAC_sens_res[0];
		res_buf[buf_idx++] = 0x00;
		RF_writeFIFO(res_buf,CRC_DISABLE_t,buf_idx,0);

		break;

	//
	// Received a anticollision command # 1
	//
	case 0x93:
		//_printf("\nAC_CMD");
		//
		// Cascade level 1
		//
		if (buffer[1] == 0x20) {
			//
			// Clear Buffer[5]
			//
			res_buf[4] = 0x00;
			for (index_temp = 0; index_temp < 4; index_temp++) {
				res_buf[index_temp] = TargetAC_nfcid1[index_temp];
				res_buf[4] ^= TargetAC_nfcid1[index_temp];
			}
			RF_writeFIFO(res_buf,CRC_DISABLE_t,5,0);
		}
		//
		// PCD Selected the TRF7970 based on the UID
		//
		else if (buffer[1] == 0x70) {

			// BIT5 - UID Complete, PICC Compliant with ISO / IEC 14443-4
			res_buf[buf_idx++] = TargetAC_sel_res; // SAK
			//NFCSend(&buffer[0]); //Send complete UID (93 20) / SAK ( 93 70 + UID)
			RF_writeFIFO(res_buf,CRC_ENABLE_t,buf_idx,0);

			//
			// 106 kbps Tag Emulator 14443A mode
			//
			// Register 01h. ISO Control Register
			RF_Write(TRF79X0_ISO_CONTROL_REG,  0x24);

			isSelected = 0x01;
		}

		break;

	case 0x05:
		// ATQB Packet
		res_buf[buf_idx++] = 0x50; // ATQB Start Byte
		// NFCID 3:0
		res_buf[buf_idx++] = TargetAC_pupi[0];
		res_buf[buf_idx++] = TargetAC_pupi[1];
		res_buf[buf_idx++] = TargetAC_pupi[2];
		res_buf[buf_idx++] = TargetAC_pupi[3];

		// Application Data Bytes
		res_buf[buf_idx++] = TargetAC_afi; // AFI - Public Telephony, GSM ... ( See ISO14443-3 Table 12 AFI Coding)
		res_buf[buf_idx++] = TargetAC_crc_aid[0]; // CRC_B
		res_buf[buf_idx++] = TargetAC_crc_aid[1]; // CRC_B
		// TODO TI
		res_buf[buf_idx++] = 0x01; // # of applications (1)
//		res_buf[buf_idx++] = TargetAC_number_apli; // # of applications (1)

		// Protocol Info Bytes
		res_buf[buf_idx++] = 0x00; // Date Rate Capability ( Only Support 106 kbps)
		// Max Frame/Protocol type (128 bytes / PICC compliant to -4)
		res_buf[buf_idx++] = 0x81;
		// (FWI/ADC/FO) ( FWT = 77.3mSec, ADC = coded according to AFI, CID supported)
		res_buf[buf_idx++] = 0xD5;

		RF_writeFIFO(res_buf,CRC_ENABLE_t,buf_idx,0);
		break;
	//
	// Receive ATTRIB Req
	//
	case 0x1D:
		if (buffer[1] == TargetAC_pupi[0] && buffer[2] == TargetAC_pupi[1] && buffer[3] == TargetAC_pupi[2] && buffer[4] == TargetAC_pupi[3]) {
			// ATTRIB Response
			res_buf[buf_idx++] = 0x00; // Length
			RF_writeFIFO(res_buf,CRC_ENABLE_t,buf_idx,0);

			isSelected = 0x01;
		}

		break;
	//
	// Receive SENF_F REQ
	//
	case 0x06:
		if (buffer[1] == 0x00 && buffer[2] == 0xFF && buffer[3] == 0xFF
				&& (buffer[4] == 0x01 || buffer[4] == 0x00)) {

			if (buffer[4] == 0x01){
					res_buf[buf_idx++] = 0x14; 	//SensF_Res Length
			}
			else{
				res_buf[buf_idx++] = 0x12; 	//SensF_Res Length
			}
			res_buf[buf_idx++] = 0x01;	//SensF_RES_CMD
			res_buf[buf_idx++] = TargetAC_nfcid2[0];	//NFCID2		//NFC-DEP Prot.(P2P-Target)=01;TagType3 Platform=02
						res_buf[buf_idx++] = TargetAC_nfcid2[1];
						res_buf[buf_idx++] = TargetAC_nfcid2[2];
						res_buf[buf_idx++] = TargetAC_nfcid2[3];
						res_buf[buf_idx++] = TargetAC_nfcid2[4];
						res_buf[buf_idx++] = TargetAC_nfcid2[5];
						res_buf[buf_idx++] = TargetAC_nfcid2[6];
						res_buf[buf_idx++] = TargetAC_nfcid2[7];
//			res_buf[buf_idx++] = 0x01;	//NFCID2		//NFC-DEP Prot.(P2P-Target)=01;TagType3 Platform=02
//			res_buf[buf_idx++] = 0xFE;
//			res_buf[buf_idx++] = 0x88;
//			res_buf[buf_idx++] = 0x77;
//			res_buf[buf_idx++] = 0x66;
//			res_buf[buf_idx++] = 0x55;
//			res_buf[buf_idx++] = 0x44;
//			res_buf[buf_idx++] = 0x33;
			res_buf[buf_idx++] = 0xC0;	//PAD0
			res_buf[buf_idx++] = 0xC1;
			res_buf[buf_idx++] = 0xC2;	//PAD1
			res_buf[buf_idx++] = 0xC3;
			res_buf[buf_idx++] = 0xC4;
			res_buf[buf_idx++] = 0xC5;	//MRTI_Check
			res_buf[buf_idx++] = 0xC6;	//MRTI_Update
			res_buf[buf_idx++] = 0xC7;	//PAD2
			if (buffer[4] == 0x01){
				res_buf[buf_idx++] = 0xFF;	//[RD]
			res_buf[buf_idx++] = 0xFF;
			}
			RF_writeFIFO(res_buf,CRC_ENABLE_t,buf_idx,0);

			isSelected = 0x01;
		}
		break;
	//
	// Receive HALT A/B
	//
	case 0x50:
		// Reset FIFO with an extra dummy clock

		if (getSelectedFrameType() == ISO14443A_BYTEFRAME) {

			res_buf[buf_idx++] = 0x06; //response to HLTA
		}
		if (getSelectedFrameType() == ISO14443B_BYTEFRAME) {

			res_buf[buf_idx++] = 0x00; // response to HLTB
		}
		RF_writeFIFO(res_buf,CRC_ENABLE_t,buf_idx,0);
		break;
	default:
		RF_resetFIFO();
		break;
	}

}

u08_t setSensRes(u08_t* data, u08_t len) {

	int i = 0;
	for (i = 0; i < len; i++) {
		TargetAC_sens_res[i] = data[i];
	}
	return 0;
}

u08_t setSelRes(u08_t val) {
	TargetAC_sel_res = val;
	return 0;
}

u08_t setProtSel(u08_t* data, u08_t len) {

	int i = 0;
	for (i = 0; i < len; i++) {
		//TargetAC_prot_sel[i] = data[i];
	}
	return 0;
}

u08_t setPadding(u08_t* data, u08_t len) {

	int i = 0;
	for (i = 0; i < len; i++) {
		//TargetAC_Padding[i] = data[i];
	}
	return 0;
}

u08_t setSysCode(u08_t* data, u08_t len) {
	int i = 0;
	for (i = 0; i < len; i++) {
		//TargetAC_sys_code[i] = data[i];
	}
	return 0;
}

u08_t setPupi_(u08_t* data, u08_t len) {
	int i = 0;
	for (i = 0; i < len; i++) {
		TargetAC_pupi[i] = data[i];
	}
	return 0;
}

u08_t setAFI(u08_t val) {
	TargetAC_afi = val;
	return 0;
}

u08_t setCRCAid(u08_t* data, u08_t len) {
	int i = 0;
	for (i = 0; i < len; i++) {
		TargetAC_crc_aid[i] = data[i];
	}
	return 0;
}

u08_t setNumberApli(u08_t val) {
	TargetAC_number_apli = val;
	return 0;
}

u08_t setProtoInfo(u08_t* data, u08_t len) {
	int i = 0;
	for (i = 0; i < len; i++) {
		//TargetAC_proto_info[i] = data[i];
	}
	return 0;
}

u08_t setNfcid1(u08_t* data, u08_t len) {
	int i = 0;
	for (i = 0; i < len; i++) {
		TargetAC_nfcid1[i] = data[i];
	}
	return 0;
}

u08_t setNfcid2(u08_t* data, u08_t len) {
	int i = 0;
	for (i = 0; i < len; i++) {
		TargetAC_nfcid2[i] = data[i];
	}
	return 0;
}

