package com.mq.mylibrary.rfid.io.service;

import android.util.Log;

import java.util.HashMap;

public class RfidPacket {
	private final int DATA_LENGTH = 256;
	
	private boolean mbPrefix1;
	private boolean mbPrefix2;
	private boolean mbDataTrans;
	private int miLength;
	private int miDeviceId;
	private int miCmd;
	private int miStatus;
	
	private byte[] mbData = new byte[DATA_LENGTH];
	private int miDataIndex = 0;
	
	private byte[] mbDataActural;
	
	public static final int STATUS_SUCC = 0x00;
	
	public RfidPacket(){
		clean();
	}
		
	public void putByte(byte bData){
		if(miDataIndex >= DATA_LENGTH){
			clean();
			return;
		}
		
		Log.d("RfidResponse", "putByte:"+Integer.toHexString(bData&0xFF));
		
		if(mbDataTrans){
			mbDataTrans = false;
			return;
		}
		
		if(bData == (byte)0xAA){
			if(!mbPrefix1){
				mbPrefix1 = true;
				mbPrefix2 = false;
				return;
			}
			if(!mbPrefix2){
				mbPrefix1 = false;
				mbPrefix2 = false;
				return;
			}
			//if(!mbDataTrans){
				mbDataTrans = true;
				mbData[miDataIndex++] = bData;				
				return;
			//}			
		}else if(bData == (byte)0xBB){
			if(!mbPrefix1){
				return;
			}
			if(!mbPrefix2){
				mbPrefix2 = true;
				miDataIndex = 0;
				mbDataTrans = false;
				return;
			}
			mbData[miDataIndex++] = bData;
			return;
		}else{
			if(!mbPrefix1){
				return;
			}
			if(!mbPrefix2){
				//0xAA 0xBB
				mbPrefix1 = false;
				return;
			}
			mbData[miDataIndex++] = bData;
			return;
		}
	}
	
	public void clean(){
		mbPrefix1 = false;
		mbPrefix2 = false;
		mbDataTrans = false;
		miDataIndex = 0;
		mbDataActural = null;
	}
	
	public boolean isComplete(){ 
				
		miLength = ((mbData[0]&0xFF) | ((mbData[1]&0xFF)<<8)) & 0xFFFF;
		
		if(miLength >= DATA_LENGTH){
			return false;
		}
		
		if(miLength <= 5){
			return false;
		}
		
		if(miDataIndex != miLength+2){
			return false;
		}
		
		miDeviceId = ((mbData[2]&0xFF) | ((mbData[3]&0xFF)<<8))&0xFFFF;
		
		miCmd = ((mbData[4]&0xFF) | ((mbData[5]&0xFF)<<8))&0xFFFF;
		
		miStatus = mbData[6];
		
		if(miLength > 6){
			mbDataActural = new byte[miLength-6];
			for(int i=0; i<miLength-6; i++){
				mbDataActural[i] = mbData[7+i];
			}
		}
		
		//check crc
		return true;
	}
	
	public RfidPacket(RfidPacket packet){
		for(int i=0; i<DATA_LENGTH; i++){
			mbData[i] = packet.getData(i);
		}
		
		miLength = packet.getLength();
		miDeviceId = packet.getDeviceId();
		miCmd = packet.getCmd();
		miStatus = packet.getStatus();
		
		mbDataActural = packet.getActualData();
	}
	
	public int getLength() { return miLength;}
	
	public int getDeviceId(){ return miDeviceId;}
	
	public int getCmd(){ return miCmd;}
	
	public int getStatus() { return miStatus;}
	
	public byte[] getActualData(){
		return mbDataActural;
	}
	
	public String getActualDataHex(){
		if(mbDataActural == null){
			return null;
		}
		StringBuffer sb = new StringBuffer();
		for(int i=0; i<mbDataActural.length; i++){
			sb.append(Integer.toHexString(mbDataActural[i]&0xFF));
			sb.append(" ");
		}
		return sb.toString();
	}
	
	public byte getData(int i){
		return mbData[i];
	}
		
	public static final int COM_GET_HARDMODEL = 0x0104;
	public static final int COM_CONFIG_ISOTYPE = 0x0108;
	public static final int COM_PCD_ANTENNA = 0x010C;
	public static final int COM_REQUEST_A = 0x0201;
	public static final int COM_ANTICOLL = 0x0202;
	public static final int COM_SELECT = 0x0203;
	public static final int COM_HLTA = 0x0204;
	public static final int COM_AUTHEN = 0x0207;
	public static final int COM_M1_READ = 0x0208;
	public static final int COM_M1_WRITE = 0x0209;
	public static final int COM_M1_INIT_VALUE = 0x020A;
	public static final int COM_M1_READ_VALUE = 0x020B;
	public static final int COM_M1_DECREMENT = 0x020C;
	public static final int COM_M1_INCREMENT = 0x020D;
	public static final int COM_M1_RESTORE = 0x020E;
	public static final int COM_M1_TRANSFER = 0x020F;
	public static final int COM_TYPEA_RESET = 0x0210;
	public static final int COM_TYPEA_COS = 0x0211;
	public static final int COMUL_PCD_ANTICOL = 0x0212;
	public static final int COMUL_PCD_WRITE = 0x0213;
	public static final int COM_TYPEB_RESET = 0x0301;
	public static final int COM_HLT_B = 0x0302;
	public static final int COM_CL_DESELECT = 0x0303;
	public static final int COM_RF020_CHECK = 0x0401;
	public static final int COM_RF020_READ = 0x0402;
	public static final int COM_RF020_WRITE = 0x0403;
	public static final int COM_RF020_LOCK = 0x0404;
	public static final int COM_RF020_COUNT = 0x0405;
	public static final int COM_RF020_DESELECT = 0x0406;
	public static final int COM_SELECT_SR = 0x0501;
	public static final int COM_COMPLETION_SR = 0x0502;
	public static final int COM_READ_SR176 = 0x0503;
	public static final int COM_WRITE_SR176 = 0x0504;
	public static final int COM_PROTECT_SR176 = 0x0505;
	public static final int COM_READ_SR4K = 0x0506;
	public static final int COM_WRITE_SR4K = 0x0507;
	public static final int COM_AUTH_SR4K = 0x0508;
	public static final int COM_GETUID_SR4K = 0x0509;
	public static final int COM_PROTECT_SR4K = 0x050A;
	public static final int COM_15693_INVENTORY16 = 0x1000;
	public static final int COM_15693_INVENTORY = 0x1001;
	public static final int COM_15693_STAY_QUIET = 0x1002;
	public static final int COM_15693_SELECT = 0x1003;
	public static final int COM_15693_RESET_TO_READY = 0x1004;
	public static final int COM_15693_READ_SM = 0x1005;
	public static final int COM_15693_WRITE_SM = 0x1006;
	public static final int COM_15693_LOCK_BLOCK = 0x1007;
	public static final int COM_15693_WRITE_AFI = 0x1008;
	public static final int COM_15693_LOCK_AFI = 0x1009;
	public static final int COM_15693_WRITE_DSFID = 0x100A;
	public static final int COM_15693_LOCK_DSFID = 0x100B;
	public static final int COM_15693_GET_SYSTEM_INFO = 0x100C;
	public static final int COM_15693_GET_MULTIBLOCK_SECURITY = 0x100D;

	// all in one
	public static final int COM_ALL_ISO14443A_QUERY_UID = 0x1101;
	public static final int COM_ALL_ISO14443A_READ = 0x1102;
	public static final int COM_ALL_ISO14443A_WRITE = 0x1103;
	public static final int COM_ALL_ISO14443A_INITVALUE = 0x1104;
	public static final int COM_ALL_ISO14443A_READVALUE = 0x1105;
	public static final int COM_ALL_ISO14443A_INCREMENT = 0x1106;
	public static final int COM_ALL_ISO14443A_DECREMENT = 0x1107;
	public static final int COM_ALL_ISO14443A_SELECT = 0x1108;
	public static final int COM_ALL_ISO14443A_AUTHENWRITE = 0x1109;
	public static final int COM_ALL_ISO14443A_READCONTINUOUS = 0x110A;

	public static final int PSAM_RESET = 0x1200;
	public static final int PSAM_COS = 0x1201;
	

	private static HashMap<Integer,String> mHashMap = new HashMap<Integer,String>();
	
	static{
		mHashMap.put(COM_GET_HARDMODEL, "COM_GET_HARDMODEL");
		mHashMap.put(COM_CONFIG_ISOTYPE, "COM_CONFIG_ISOTYPE");
		mHashMap.put(COM_PCD_ANTENNA, "COM_PCD_ANTENNA");
		mHashMap.put(COM_REQUEST_A, "COM_REQUEST_A");
		mHashMap.put(COM_ANTICOLL, "COM_ANTICOLL");
		mHashMap.put(COM_SELECT, "COM_SELECT");
		mHashMap.put(COM_HLTA, "COM_HLTA");
		mHashMap.put(COM_AUTHEN, "COM_AUTHEN");
		mHashMap.put(COM_M1_READ, "COM_M1_READ");
		mHashMap.put(COM_M1_WRITE, "COM_M1_WRITE");
		mHashMap.put(COM_M1_INIT_VALUE, "COM_M1_INIT_VALUE");
		mHashMap.put(COM_M1_READ_VALUE, "COM_M1_READ_VALUE");
		mHashMap.put(COM_M1_DECREMENT, "COM_M1_DECREMENT");
		mHashMap.put(COM_M1_INCREMENT, "COM_M1_INCREMENT");
		mHashMap.put(COM_M1_RESTORE, "COM_M1_RESTORE");
		mHashMap.put(COM_M1_TRANSFER, "COM_M1_TRANSFER");
		mHashMap.put(COM_TYPEA_RESET, "COM_TYPEA_RESET");
		mHashMap.put(COM_TYPEA_COS, "COM_TYPEA_COS");
		mHashMap.put(COMUL_PCD_ANTICOL, "COMUL_PCD_ANTICOL");
		mHashMap.put(COMUL_PCD_WRITE, "COMUL_PCD_WRITE");
		mHashMap.put(COM_TYPEB_RESET, "COM_TYPEB_RESET");
		mHashMap.put(COM_HLT_B, "COM_HLT_B");
		
		mHashMap.put(COM_CL_DESELECT, "COM_CL_DESELECT");
		mHashMap.put(COM_RF020_CHECK, "COM_RF020_CHECK");
		mHashMap.put(COM_RF020_READ, "COM_RF020_READ");
		mHashMap.put(COM_RF020_WRITE, "COM_RF020_WRITE");
		mHashMap.put(COM_RF020_LOCK, "COM_RF020_LOCK");
		mHashMap.put(COM_RF020_COUNT, "COM_RF020_COUNT");
		mHashMap.put(COM_RF020_DESELECT, "COM_RF020_DESELECT");
		mHashMap.put(COM_SELECT_SR, "COM_SELECT_SR");
		mHashMap.put(COM_COMPLETION_SR, "COM_COMPLETION_SR");
		mHashMap.put(COM_READ_SR176, "COM_READ_SR176");
		mHashMap.put(COM_WRITE_SR176, "COM_WRITE_SR176");
		mHashMap.put(COM_PROTECT_SR176, "COM_PROTECT_SR176");
		mHashMap.put(COM_READ_SR4K, "COM_READ_SR4K");
		
		mHashMap.put(COM_WRITE_SR4K, "COM_WRITE_SR4K");
		mHashMap.put(COM_AUTH_SR4K, "COM_AUTH_SR4K");
		mHashMap.put(COM_GETUID_SR4K, "COM_GETUID_SR4K");
		mHashMap.put(COM_PROTECT_SR4K, "COM_PROTECT_SR4K");
		mHashMap.put(COM_15693_INVENTORY16, "COM_15693_INVENTORY16");
		
		mHashMap.put(COM_15693_INVENTORY, "COM_15693_INVENTORY");
		mHashMap.put(COM_15693_STAY_QUIET, "COM_15693_STAY_QUIET");
		mHashMap.put(COM_15693_SELECT, "COM_15693_SELECT");
		mHashMap.put(COM_15693_RESET_TO_READY, "COM_15693_RESET_TO_READY");
		mHashMap.put(COM_15693_READ_SM, "COM_15693_READ_SM");
		mHashMap.put(COM_15693_WRITE_SM, "COM_15693_WRITE_SM");
		mHashMap.put(COM_15693_LOCK_BLOCK, "COM_15693_LOCK_BLOCK");
		
		mHashMap.put(COM_15693_WRITE_AFI, "COM_15693_WRITE_AFI");
		mHashMap.put(COM_15693_LOCK_AFI, "COM_15693_LOCK_AFI");
		mHashMap.put(COM_15693_WRITE_DSFID, "COM_15693_WRITE_DSFID");
		mHashMap.put(COM_15693_LOCK_DSFID, "COM_15693_LOCK_DSFID");
		mHashMap.put(COM_15693_GET_SYSTEM_INFO, "COM_15693_GET_SYSTEM_INFO");
		mHashMap.put(COM_15693_GET_MULTIBLOCK_SECURITY, "COM_15693_GET_MULTIBLOCK_SECURITY");
		
		mHashMap.put(COM_ALL_ISO14443A_QUERY_UID, "COM_ALL_ISO14443A_QUERY_UID");
		mHashMap.put(COM_ALL_ISO14443A_READ, "COM_ALL_ISO14443A_READ");
		mHashMap.put(COM_ALL_ISO14443A_WRITE, "COM_ALL_ISO14443A_WRITE");
		mHashMap.put(COM_ALL_ISO14443A_INITVALUE, "COM_ALL_ISO14443A_INITVALUE");
		mHashMap.put(COM_ALL_ISO14443A_READVALUE, "COM_ALL_ISO14443A_READVALUE");
		mHashMap.put(COM_ALL_ISO14443A_INCREMENT, "COM_ALL_ISO14443A_INCREMENT");
		mHashMap.put(COM_ALL_ISO14443A_DECREMENT, "COM_ALL_ISO14443A_DECREMENT");
		mHashMap.put(COM_ALL_ISO14443A_SELECT, "COM_ALL_ISO14443A_SELECT");
		mHashMap.put(COM_ALL_ISO14443A_AUTHENWRITE, "COM_ALL_ISO14443A_AUTHENWRITE");
		mHashMap.put(COM_ALL_ISO14443A_READCONTINUOUS, "COM_ALL_ISO14443A_READCONTINUOUS");
		
		mHashMap.put(PSAM_RESET, "PSAM_RESET");
		mHashMap.put(PSAM_COS, "PSAM_COS");
	}
	
	public String getCmdName(){
		return mHashMap.get(miCmd);
	}
}
