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


import com.mq.mylibrary.rfid.io.service.Tools;

public class TXFRAME {
	public static byte TX_HEAD_NONE = -2;
	public static byte TX_TAIL_NONE = -3;
	public static byte TX_CRC_ERROR = -4;
	public static byte TX_MACNO_ERROR = -5;
	public static byte TX_COLL_ERROR = -6;
	public static byte TX_MCU_TIMEOUT = -7;
	public static byte TX_PARITY_ERROR = -8;
	public static byte TX_FRAMING_ERROR = -9;
	public static byte TX_FIFO_VOFL = -10;
	public static byte TX_READ_EE_ERROR = -11;
	public static byte TX_EE_ERROR = -12;
	public static byte TX_ACK_ERROR = -13;
	public static byte TX_WTX_ERROR = -14;
	public static byte TX_END_ERROR = -14;

	public static byte MACNO = (byte) 0xFF;
	static byte DLE = 0x10;
	static byte STX = 0x02;
	static byte ETX = 0x03;
	static byte ACK = 0x06;
	static byte WTX = (byte) 0xFA;
	static byte ACKc = 0x07;
	static byte NACK = 0x15;
	static byte OK = 0x01;
	static byte BLACK = 0x00;

	public static byte TX_COUNT = 100;
	static byte TX_APDU_FRAME = 1;

	public static byte CRC0 = 0;
	public static byte CRC1 = 1;
	public static byte CRC2 = 2;
	public static byte CRC3 = 3;

	public static short ISO14443_CMDA = 0x0A00;
	public static short ISO14443_CMDB = 0x0B00;

	static byte WTX_ERROR_LEN = 3;
	// 密钥长度
	static byte ISO14443A_KEY_LEN = 6;
	// 每块字节数
	static byte ISO14443A_BLOCK_LEN = 16;
	// NFC卡每块字节数
	static byte ISO14443NFC_BLOCK_LEN = 4;
	// 每扇区总块数
	static byte ISO14443A_BLOCKSPERSECTOR = 4;
	// 不带校验位的UID长度
	static byte ISO14443A_NOCHECK_UID_LEN = 4;
	static byte TX_GENERAL_FRAME = 0;

	public static int TX_BUF_LEN = 256 * 2;
	public byte[] tx_data = new byte[TX_BUF_LEN];
	public byte[] rx_data = new byte[TX_BUF_LEN];
	public byte mac_no;
	public int tx_len;
	public int rx_len;
	public byte crc_enable;
	public byte bit_framing;
	public byte timeout_count;
	public static byte ISO14443A_UID_LEN = 5;
	static short cmd = 0;

	static short cmd_2 = 0;

	static void tx_iso14443_init_cmd() {
		cmd = 0;
	}

	static TXFRAME tx_make_version(TXFRAME frame) {

		frame.mac_no = MACNO;
		frame.tx_len = 2;
		frame.tx_data[0] = 'V';
		frame.tx_data[1] = 0x00;

		return frame;
	}

	static void tx_make_register(TXFRAME frame, byte reg, byte val) {
		frame.mac_no = MACNO;
		frame.tx_len = 3;
		frame.tx_data[0] = 'W';
		frame.tx_data[1] = reg;
		frame.tx_data[2] = val;
	}

	static void tx_make_wtx(TXFRAME frame, byte[] buf) {
		frame.mac_no = MACNO;
		frame.tx_len = WTX_ERROR_LEN;
		System.arraycopy(buf, 0, frame.tx_data, 0, WTX_ERROR_LEN);
		frame.rx_len = 0;
		frame.crc_enable = CRC3;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	static void tx_make_request(TXFRAME frame) {
		frame.mac_no = MACNO;
		frame.tx_len = 1;
		frame.tx_data[0] = 0x26;
		frame.rx_len = 0;
		frame.crc_enable = CRC0;
		frame.bit_framing = 7;
		frame.timeout_count = 3;

		tx_iso14443_init_cmd();
	}

	static void tx_make_get_uid(TXFRAME frame, int level) {
		frame.mac_no = MACNO;
		frame.tx_len = 2;
		if (level == 0)
			frame.tx_data[0] = (byte) 0x93;
		else if (level == 1)
			frame.tx_data[0] = (byte) 0x95;
		frame.tx_data[1] = 0x20;
		frame.rx_len = 0;
		frame.crc_enable = CRC0;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	static void tx_make_select_tag(TXFRAME frame, byte[] uid, int level) {
		int i = 0;

		frame.mac_no = MACNO;
		frame.tx_len = 7;
		if (level == 0)
			frame.tx_data[0] = (byte) 0x93;
		else if (level == 1)
			frame.tx_data[0] = (byte) 0x95;
		frame.tx_data[1] = 0x70;
		for (i = 0; i < ISO14443A_UID_LEN; i++) {
			frame.tx_data[i + 2] = uid[i];
		}
		frame.rx_len = 0;
		frame.crc_enable = CRC3;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	static void tx_make_load_key(TXFRAME frame, byte[] key) {
		byte[] key_tmp = new byte[ISO14443A_KEY_LEN];
		System.arraycopy(key, 0, key_tmp, 0, key_tmp.length);

		frame.mac_no = MACNO;
		frame.tx_len = ISO14443A_KEY_LEN * 2;//
		frame.rx_len = 0;
		frame.crc_enable = 0x10;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;

		int n = 0;
		for (int i = 0; i < ISO14443A_KEY_LEN; i++) {// 计算出符合格式的密码
			frame.tx_data[n] = (byte) (((~key_tmp[i]) & 0xf0) | ((key_tmp[i] >> 4) & 0x0f));
			n++;
			frame.tx_data[n] = (byte) ((((~key_tmp[i]) << 4) & 0xf0) | (key_tmp[i] & 0x0f));
			n++;
		}

	}

	static void tx_make_authentication(TXFRAME frame, byte aorb, byte block,
			byte[] uid) {
		frame.mac_no = MACNO;
		frame.tx_len = ISO14443A_KEY_LEN;
		frame.tx_data[0] = (byte) ((aorb == 0) ? 0x60 : 0x61);
		frame.tx_data[1] = block;
		frame.tx_data[2] = uid[0];
		frame.tx_data[3] = uid[1];
		frame.tx_data[4] = uid[2];
		frame.tx_data[5] = uid[3];
		frame.rx_len = 0;
		frame.crc_enable = 0x23;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	static void tx_make_authentication2(TXFRAME frame) {
		frame.mac_no = MACNO;
		frame.tx_len = 0;
		frame.rx_len = 0;
		frame.crc_enable = 0x33;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	static void tx_make_read_block(TXFRAME frame, byte block) {
		frame.mac_no = MACNO;
		frame.tx_len = 2;
		frame.tx_data[0] = 0x30;
		frame.tx_data[1] = block;
		frame.rx_len = ISO14443A_BLOCK_LEN;
		frame.crc_enable = CRC3;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	static void tx_make_write_block(TXFRAME frame, byte block) {
		frame.mac_no = MACNO;
		frame.tx_len = 2;
		frame.tx_data[0] = (byte) 0xA0;
		frame.tx_data[1] = block;
		frame.rx_len = 0;
		frame.crc_enable = CRC1;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	static void tx_make_write_block2(TXFRAME frame, byte[] buf, int card_type) {
		/*
		 * if(card_type == 0x0044){ frame.tx_len = ISO14443NFC_BLOCK_LEN;
		 * System.arraycopy(buf, 0, frame.tx_data, 0, ISO14443NFC_BLOCK_LEN);
		 * }else{
		 */
		frame.tx_len = ISO14443A_BLOCK_LEN;
		System.arraycopy(buf, 0, frame.tx_data, 0, ISO14443A_BLOCK_LEN);
		// }
		frame.mac_no = MACNO;
		frame.rx_len = 0;
		frame.crc_enable = CRC1;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	static void tx_make_read_multi_block(TXFRAME frame, byte[] uid, byte block,
			byte num, byte aorb) {
		frame.mac_no = MACNO;
		frame.tx_len = 5 + ISO14443A_NOCHECK_UID_LEN;
		frame.tx_data[0] = 0x33;
		frame.tx_data[1] = 0x0a;
		frame.tx_data[2] = num;
		frame.tx_data[3] = (byte) ((aorb == 0) ? 0x60 : 0x61);
		frame.tx_data[4] = block;
		System.arraycopy(uid, 0, frame.tx_data, 5, ISO14443A_NOCHECK_UID_LEN);
	}

	static void tx_make_write_multi_block(TXFRAME frame, byte[] uid,
			byte block, byte num, byte aorb, byte[] buf) {
		frame.mac_no = MACNO;
		frame.tx_len = 5 + ISO14443A_NOCHECK_UID_LEN + num
				* ISO14443A_BLOCK_LEN;
		frame.tx_data[0] = 0x32;
		frame.tx_data[1] = 0x0a;
		frame.tx_data[2] = num;
		frame.tx_data[3] = (byte) ((aorb == 0) ? 0x60 : 0x61);
		frame.tx_data[4] = block;

		System.arraycopy(uid, 0, frame.tx_data, 5, ISO14443A_NOCHECK_UID_LEN);

		System.arraycopy(buf, 0, frame.tx_data, 5 + ISO14443A_NOCHECK_UID_LEN,
				num * ISO14443A_BLOCK_LEN);
	}

	static void tx_make_rats(TXFRAME frame) {
		frame.mac_no = MACNO;
		frame.tx_len = 2;
		frame.tx_data[0] = (byte) 0xE0;
		frame.tx_data[1] = (byte) 0x80;
		frame.rx_len = 0;
		frame.crc_enable = CRC3;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	static void tx_make_crc(byte[] data, int len) {

		byte[] src = new byte[len - 2];
		System.arraycopy(data, 2, src, 0, len - 2);
		byte[] ret = Tools.caluCRC(src);

		data[len] = ret[0];
		data[len + 1] = ret[1];
	}

	static void tx_make_head(byte[] data) {
		data[0] = DLE;
		data[1] = STX;
	}

	static void tx_make_tail(byte[] data, int len) {
		data[len] = DLE;
		data[len + 1] = ETX;
	}

	static int tx_make_frame(byte[] data, TXFRAME frame) {
		tx_make_head(data);
		data[2] = frame.mac_no;
		data[3] = '4';
		data[4] = frame.timeout_count;
		data[5] = frame.crc_enable;
		data[6] = frame.bit_framing;

		System.arraycopy(frame.tx_data, 0, data, 7, frame.tx_len);
		tx_make_crc(data, 2 + 3 + 2 + frame.tx_len);
		tx_make_tail(data, 2 + 3 + 4 + frame.tx_len);

		return tx_trans_mean(data, 2, 5 + frame.tx_len + 2 + 2 - 1);
	}

	static int tx_make_old_frame(byte[] data, TXFRAME frame) {
		tx_make_head(data);
		data[2] = frame.mac_no;

		System.arraycopy(frame.tx_data, 0, data, 3, frame.tx_len);

		tx_make_crc(data, 3 + frame.tx_len);
		tx_make_tail(data, 2 + 3 + frame.tx_len);

		return tx_trans_mean(data, 2, 1 + frame.tx_len + 2 + 2 - 1);
	}

	static int tx_trans_mean(byte[] data, int start, int end) {
		byte[] tmp = new byte[TX_BUF_LEN];
		int n = start;
		int i = 0;

		System.arraycopy(data, 0, tmp, 0, n);

		for (i = start; i <= end; i++) {
			tmp[n] = data[i];
			if (tmp[n] == DLE) {
				n++;
				tmp[n] = DLE;
			}
			n++;
		}
		tmp[n] = DLE;
		n++;
		tmp[n] = ETX;
		n++;

		System.arraycopy(tmp, 0, data, 0, n);

		return n;
	}

	static int tx_make_frame_with_type(byte[] data, TXFRAME frame, int type) {
		int len = 0;

		switch (type) {
		case 1:
			len = tx_make_frame(data, frame);
			break;
		case 0:
			len = tx_make_old_frame(data, frame);
			break;
		}

		return len;
	}

	public static int tx_back_mean(byte[] data, int start, int end) {
		int n = start;
		int m = start;

		while (n <= end) {
			data[m] = data[n];
			if (data[n] == DLE && n < end) {
				n++;
				if (data[n] != DLE) {
					m++;
					data[m] = data[n];
				}/*
				 * else if(data[n] == DLE){ m++; data[m] = data[n]; }
				 */
			}
			n++;
			m++;
		}

		return (m - 1);
	}

	static int tx_find_head_tail(byte[] data, int start, int end, byte flag) {
		int i = 0;

		if (flag == STX) {
			// i = start;

			// if ((data[0] == DLE) && (data[1] == flag)) {
			// return i;
			// }

			// return -1;

			i = start;

			while (i < end) {
				if (data[i] == DLE) {
					if (data[i + 1] == flag)
						return i;
				}

				i++;
			}
		} else {
			i = end;

			while (i > start) {
				if (data[i] == flag) {
					if (data[i - 1] == DLE)
						return i - 1;
				}

				i--;
			}
		}

		return -1;
	}

	public static int tx_find_head(byte[] data, int start, int end) {
		return tx_find_head_tail(data, start, end, STX);
	}

	public static int tx_find_tail(byte[] data, int start, int end) {
		return tx_find_head_tail(data, start, end, ETX);
	}

	public static int tx_valid_frame(byte[] data, TXFRAME frame) {
		if (data[2] != frame.mac_no)
			return -1;
		return 0;
	}

	public static int tx_check_ack_nack(byte[] recv, int len, TXFRAME frame) {
		int ret = 0;
		int head = 0;
		int tail = 0;
		int i = 0;

		ret = tx_back_mean(recv, 0, len - 1);

		byte[] recv_temp = new byte[ret + 1];
		System.arraycopy(recv, 0, recv_temp, 0, ret + 1);
		recv = recv_temp;

		// ret = len - 1;

		head = tx_find_head(recv, 0, recv.length - 1);
		if (head == -1)
			return TX_HEAD_NONE;
		head += 2;

		tail = tx_find_tail(recv, head, recv.length - 1);
		if (tail == -1) {
			byte[] recvtMP = new byte[recv.length + 2];
			System.arraycopy(recv, 0, recvtMP, 0, recv.length);
			recvtMP[recv.length] = 16;
			recvtMP[recv.length + 1] = 3;
			recv = recvtMP;
		}
		// return TX_TAIL_NONE;
		tail -= 1;

		byte[] tmp = new byte[recv.length - 2 - 2 - 2];
		System.arraycopy(recv, head, tmp, 0, recv.length - head - 2 - 2);

		byte[] crc = Tools.caluCRC(tmp);

		if (!((crc[0] == recv[recv.length - 2 - 2]) && (crc[1] == recv[recv.length - 2 - 1]))) {
			// Log.i("TX_CRC_ERROR", TX_CRC_ERROR+"");
			return TX_CRC_ERROR;
		}
		if (tx_valid_frame(recv, frame) != 0)
			return TX_MACNO_ERROR;

		if (recv[head + 2] == ACK) {
			if ((recv[head + 3] == WTX) && ((tail - head - 4) == WTX_ERROR_LEN)) {
				frame.rx_len = WTX_ERROR_LEN;
				//tmp = new byte[recv.length - head - tail - 2];// 创建电子存折文件时报错
				System.arraycopy(recv, head + 3, frame.rx_data, 0,
						WTX_ERROR_LEN);

				return TX_WTX_ERROR;
			}

			if (frame.tx_data[0] == 0x0a
					|| (frame.tx_data[0] == 0x0b && frame.tx_data[1] == 0x00)
					|| frame.tx_data[0] == WTX) {
				for (i = head + 3 + 2; i < tail; i++) {
					// 返回数据
					frame.rx_data[i - head - 3 - 2] = recv[i];
					frame.rx_len = tail - head - 4 - 2;
				}
			} else {
				for (i = head + 3; i < tail; i++) {
					// 返回数据
					frame.rx_data[i - head - 3] = recv[i];
					frame.rx_len = tail - head - 4;
				}
			}

			return 0;
		} else if (recv[head + 2] == ACKc) {
			for (i = head + 3; i < tail; i++) {
				// 返回数据
				frame.rx_data[i - head - 3] = recv[i];
				frame.rx_len = tail - head - 4;
			}

			return TX_COLL_ERROR;
		} else if (recv[head + 2] == NACK) {
			if ((recv[head + 3] & 0x80) == 0x80)
				return TX_MCU_TIMEOUT; // MCU接收超时
			if ((recv[head + 3] & 0x01) == 0x01)
				return TX_COLL_ERROR; // Coll Error
			if ((recv[head + 3] & 0x02) == 0x02)
				return TX_PARITY_ERROR; // Parity Error
			if ((recv[head + 3] & 0x04) == 0x04)
				return TX_FRAMING_ERROR;// Framing Error (SOF Err)
			if ((recv[head + 3] & 0x08) == 0x08)
				return TX_CRC_ERROR; // CRC Error
			if ((recv[head + 3] & 0x10) == 0x10)
				return TX_FIFO_VOFL; // FIFO Ovfl
			if ((recv[head + 3] & 0x20) == 0x20)
				return TX_READ_EE_ERROR;// Read EE Error
			if ((recv[head + 3] & 0x40) == 0x40)
				return TX_EE_ERROR;// EE Error
		} else if (recv[head + 2] == OK) {
			return 0;
		}
		return TX_ACK_ERROR; // 应答字错
	}

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

	int tx_check_reg(byte[] recv, int len, TXFRAME frame) {
		int ret = 0;
		int head = 0;
		int tail = 0;
		int i = 0;

		head = tx_find_head(recv, 0, len - 1);
		if (head == -1)
			return TX_HEAD_NONE;
		head += 2;

		tail = tx_find_tail(recv, head, len - 1);
		if (tail == -1)
			return TX_TAIL_NONE;
		tail -= 1;

		ret = tx_back_mean(recv, head, tail);
		tail = ret;

		// 不能确定是否正确，待检验
		byte[] tmp = new byte[recv.length - 2 - 2 - 2];
		System.arraycopy(recv, head, tmp, 0, recv.length - head - 2 - 2);

		byte[] crc = Tools.caluCRC(tmp);

		if (!((crc[0] == recv[recv.length - 2 - 2]) && (crc[1] == recv[recv.length - 2 - 1]))) {
			// Log.i("TX_CRC_ERROR", TX_CRC_ERROR+"");
			return TX_CRC_ERROR;
		}

		/*
		 * if (tx_crc(recv + head, tail - head + 1) != 0) return TX_CRC_ERROR;
		 */

		if (tx_valid_frame(recv, frame) != 0)
			return TXFRAME.TX_MACNO_ERROR;

		if (recv[head + 2] == ACK) {
			if (frame.tx_data[0] == 0x0a
					|| (frame.tx_data[0] == 0x0b && frame.tx_data[1] == 0x00)) {
				for (i = head + 3 + 2; i < tail; i++) {
					frame.rx_data[i - head - 3 - 2] = recv[i];
					frame.rx_len = tail - head - 4 - 2;
				}
			} else {
				for (i = head + 3; i < tail; i++) {
					// 返回数据
					frame.rx_data[i - head - 3] = recv[i];
					frame.rx_len = tail - head - 4;
				}
			}

			return 0;
		} else if (recv[head + 2] == ACKc) {
			for (i = head + 3; i < tail; i++) {
				// 返回数据
				frame.rx_data[i - head - 3] = recv[i];
				frame.rx_len = tail - head - 4;
			}

			return TX_COLL_ERROR;
		} else if (recv[head + 2] == NACK) {
			if ((recv[head + 3] & 0x80) == 0x80)
				return TX_MCU_TIMEOUT; // MCU接收超时
			if ((recv[head + 3] & 0x01) == 0x01)
				return TX_COLL_ERROR; // Coll Error
			if ((recv[head + 3] & 0x02) == 0x02)
				return TX_PARITY_ERROR; // Parity Error
			if ((recv[head + 3] & 0x04) == 0x04)
				return TX_FRAMING_ERROR;// Framing Error (SOF Err)
			if ((recv[head + 3] & 0x08) == 0x08)
				return TX_CRC_ERROR; // CRC Error
			if ((recv[head + 3] & 0x10) == 0x10)
				return TX_FIFO_VOFL; // FIFO Ovfl
			if ((recv[head + 3] & 0x20) == 0x20)
				return TX_READ_EE_ERROR;// Read EE Error
			if ((recv[head + 3] & 0x40) == 0x40)
				return TX_EE_ERROR; // EE Error
		}

		return TX_ACK_ERROR; // 应答字错
	}

	void tx_make_write_block3(TXFRAME frame, byte[] buf) {
		frame.mac_no = MACNO;
		frame.tx_len = 4;
		// memcpy(frame.tx_data, buf, 4);
		System.arraycopy(frame.tx_data, 0, buf, 0, 4);
		frame.rx_len = 0;
		frame.crc_enable = CRC1;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	void tx_make_initvalue(byte[] buf, byte block, byte backup) {
		int init = 0;
		int reinit = ~init;
		byte rebackup = (byte) ~backup;
		byte[] addr = new byte[ISO14443A_BLOCK_LEN / 4];

		addr[0] = backup;
		addr[1] = rebackup;
		addr[2] = backup;
		addr[3] = rebackup;

		/*
		 * memcpy(buf, init, sizeof(init));// memcpy(buf + sizeof(init),
		 * &reinit, sizeof(reinit)); memcpy(buf + sizeof(init) + sizeof(reinit),
		 * &init, sizeof(init)); memcpy(buf + sizeof(init) + sizeof(reinit) +
		 * sizeof(init), addr, sizeof(addr));
		 */

		/*
		 * System.arraycopy(buf, 0, init, dstPos, length) System.arraycopy(src,
		 * srcPos, dst, dstPos, length) System.arraycopy(src, srcPos, dst,
		 * dstPos, length) System.arraycopy(src, srcPos, dst, dstPos, length)
		 */

	}

	static void tx_make_increment(TXFRAME frame, byte block) {
		frame.mac_no = MACNO;
		frame.tx_len = 2;
		frame.tx_data[0] = (byte) 0xC1;
		frame.tx_data[1] = block;
		frame.rx_len = 0;
		frame.crc_enable = CRC1;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	static void tx_make_increment2(TXFRAME frame, byte[] buf) {
		frame.mac_no = MACNO;
		frame.tx_len = 4;// sizeof(int)
		// memcpy(frame.tx_data, buf, frame.tx_len);
		System.arraycopy(frame.tx_data, 0, buf, 0, frame.tx_len);
		frame.rx_len = 0;
		frame.crc_enable = CRC1;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	void tx_make_decrement(TXFRAME frame, byte block) {
		frame.mac_no = MACNO;
		frame.tx_len = 2;
		frame.tx_data[0] = (byte) 0xC0;
		frame.tx_data[1] = block;
		frame.rx_len = 0;
		frame.crc_enable = CRC1;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	void tx_make_decrement2(TXFRAME frame, byte[] buf) {
		frame.mac_no = MACNO;
		frame.tx_len = 4;
		// memcpy(frame.tx_data, buf, frame.tx_len);
		System.arraycopy(frame.tx_data, 0, buf, 0, frame.tx_len);
		frame.rx_len = 0;
		frame.crc_enable = CRC1;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	void tx_make_restore(TXFRAME frame, byte block) {
		frame.mac_no = MACNO;
		frame.tx_len = 2;
		frame.tx_data[0] = (byte) 0xC2;
		frame.tx_data[1] = block;
		frame.rx_len = 0;
		frame.crc_enable = CRC1;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	void tx_make_transfer(TXFRAME frame, byte block) {
		frame.mac_no = MACNO;
		frame.tx_len = 2;
		frame.tx_data[0] = (byte) 0xB0;
		frame.tx_data[1] = block;
		frame.rx_len = 0;
		frame.crc_enable = CRC1;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	void tx_make_hlta(TXFRAME frame) {
		frame.mac_no = MACNO;
		frame.tx_len = 2;
		frame.tx_data[0] = 0x50;
		frame.tx_data[1] = 0x00;
		frame.rx_len = 0;
		frame.crc_enable = CRC1;
		frame.bit_framing = 0;
		frame.timeout_count = TX_COUNT;
	}

	void tx_make_ctrl(TXFRAME frame, byte code) {
		frame.mac_no = MACNO;
		frame.tx_len = 2;
		frame.tx_data[0] = 'L';
		frame.tx_data[1] = code;
	}

	/*************************************************************************/
	void tx_make_write_sn(TXFRAME frame, byte[] data, byte len) {
		frame.mac_no = MACNO;
		frame.tx_len = 2 + len;
		frame.tx_data[0] = 'J';
		frame.tx_data[1] = len;
		// memcpy(frame.tx_data + 2, data, frame.tx_len);
		System.arraycopy(frame.tx_data, 2, data, 0, frame.tx_len);
	}

	void tx_make_read_sn(TXFRAME frame) {
		frame.mac_no = MACNO;
		frame.tx_len = 2;
		frame.tx_data[0] = 'K';
		frame.tx_data[1] = 0x00;
		frame.timeout_count = TX_COUNT;
	}

	/*************************************************************************/
	/* 14443层 */
	/*************************************************************************/
	public static short tx_iso14443_get_cmd() {
		if (cmd == 0)
			cmd = ISO14443_CMDA;
		else if (cmd == ISO14443_CMDA)
			cmd = ISO14443_CMDB;
		else if (cmd == ISO14443_CMDB)
			cmd = ISO14443_CMDA;
		return cmd;
	}

	public static void tx_make_iso14443_cmd(byte[] data) {
		short cmd = tx_iso14443_get_cmd();

		data[0] = (byte) (cmd >> 8);
		data[1] = (byte) (cmd << 8);
	}

}
