⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclfsmcode.c

📁 开发源代码的CPU卡的COS源程序。
💻 C
字号:
/* ============================================================================   Project Name : jayaCard   Module Name  : proto/bios/tcl/tclfsmcode.c   Version : $Id: tclfsmcode.c,v 1.11 2004/01/11 09:56:31 dgil Exp $	Description: Function code for the Finite State Machine of the TCL protocol    The Original Code is jayaCard code.    The Initial Developer of the Original Code is Gilles Dumortier.	Portions created by the Initial Developer are Copyright (C) 2002-2004 the    Initial Developer. All Rights Reserved.    Contributor(s):    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; see http://www.gnu.org/licenses/gpl.html   History Rev	Description   012603 dgil	wrote it from scratch the basic architecture of the FSM   ============================================================================*/#include "precomp.h"/* ============================================================================	tcl_ffsm_start()   ========================================================================= */jbyte tcl_ffsm_start(void){	LOG("TCLFSM","tcl_ffsm_start()");	tcl_ofs = 0;	tcl_block = 1;	return TCL_FSM_RECEIVE;}/* ============================================================================	tcl_ffsm_receive()   ========================================================================= */jbyte tcl_ffsm_receive(void){	LOG("TCLFSM","tcl_ffsm_receive()");	/* catch protocol error */	if (tcl_inproc == TCL_INPROC_ERROR) {        LOG("TCLFSM","tcl_ffsm_receive() TCL_INPROC_ERROR / reset tcl_apdu");		tcl_inproc = TCL_INPROC_NONE;		tcl_apdu = 0;	}	if (tcl_getmsg) {		tcl_cnt = HAL_TCL_RECEIVE(&gInBuffer.b[tcl_apdu],sizeof(gInBuffer)-tcl_apdu,jfalse);		if (tcl_cnt<2) {			LOG3("TCLFSM","tcl_ffsm_receive: ERROR pcb=0x%.2X cid=%d tcl_cnt=%d",tcl_pcb,tcl_cid,tcl_cnt);			return TCL_FSM_RECEIVE;		}	} else {		tcl_getmsg = jtrue;	}	/* remove the CRC count */	tcl_cnt -= 2;	LOG3("TCLFSM","tcl_ffsm_receive: pcb=0x%.2X cid=%d tcl_cnt=%d",tcl_pcb,tcl_cid,tcl_cnt);	// CID checking	if ((tcl_pcb&TCL_MASK_CID)!=0) {		/* CID must match ! */		if (tcl_cid!=cos_cid) {			return TCL_FSM_RECEIVE;		} else {			tcl_has_cid = jtrue;		}	}	if (((tcl_pcb&TCL_MASK_CID)==0) && (cos_cid==0)) {		/* a PICC which does support CID shall in case its CID is 0 answer also to blocks containing no CID by using no CID */		tcl_has_cid = jfalse;	}	// IBLOCK detection =====================================================	if ((tcl_pcb&TCL_MASK_IBLOCK)==TCL_TYPE_IBLOCK) {		if (tcl_inproc == TCL_INPROC_WTX) {			return TCL_FSM_RECEIVE;		}		if (((tcl_pcb&TCL_MASK_NAD)!=0) && (tcl_inproc!=TCL_INPROC_CHAINING_PCD)) {			/* NAD following, NAD supported, first IBLOCK (or first of the chain) */			tcl_has_nad = jtrue;			return TCL_FSM_RECEIVE_IBLOCK;		}		if (((tcl_pcb&TCL_MASK_NAD)==0) && (tcl_inproc!=TCL_INPROC_CHAINING_PCD)) {			/* NAD not following, NAD supported, first IBLOCK (or first of the chain) */			tcl_has_nad = jfalse;			return TCL_FSM_RECEIVE_IBLOCK;		}		if (((tcl_pcb&TCL_MASK_NAD)!=0) && (tcl_inproc==TCL_INPROC_CHAINING_PCD)) {			/* NAD following, NAD supported, PCD is chaining - protocol error */			tcl_inproc = TCL_INPROC_ERROR;			return TCL_FSM_RECEIVE;		}		if (((tcl_pcb&TCL_MASK_NAD)==0) && (tcl_inproc==TCL_INPROC_CHAINING_PCD)) {			/* NAD not following, NAD supported, PCD is chaining */			return TCL_FSM_RECEIVE_IBLOCK;		}	}	// RBLOCK-NAK detection =================================================	if ((tcl_pcb&TCL_MASK_RBLOCK)==TCL_TYPE_RBLOCK_NAK) {		if (tcl_cnt!=0) {			return TCL_FSM_RECEIVE;		} else {			return TCL_FSM_RECEIVE_NAK;		}	}	// RBLOCK-ACK detection =================================================	if ((tcl_pcb&TCL_MASK_RBLOCK)==TCL_TYPE_RBLOCK_ACK) {		if (tcl_cnt!=0) {			return TCL_FSM_RECEIVE;		} else {			return TCL_FSM_RECEIVE_ACK;		}	}	// SBLOCK-WTX detection =================================================	if ((tcl_pcb&TCL_MASK_SBLOCK)==TCL_TYPE_SBLOCK_WTX) {		if (tcl_cnt!=1) {			return TCL_FSM_RECEIVE;		} else {			return TCL_FSM_RECEIVE_WTX;		}	}	// SBLOCK-DESELECT detection ============================================	if ((tcl_pcb&TCL_MASK_SBLOCK)==TCL_TYPE_SBLOCK_DESELECT) {		if (tcl_cnt!=0) {			return TCL_FSM_RECEIVE;		} else {			return TCL_FSM_SEND_DESELECT;		}	}	// NO DETECTION - UNKNOWN BLOCK TYPE ====================================	return TCL_FSM_RECEIVE;}/* ============================================================================	tcl_ffsm_send_wtx()   ========================================================================= */jbyte tcl_ffsm_send_wtx(void){	LOG("TCLFSM","tcl_ffsm_send_wtx()");	#ifdef JAYA_TCL_WTX	// required WTX answer	tcl_inproc = TCL_INPROC_WTX;	// send the PCB	if (tcl_has_cid) {		HAL_TCL_INITSEND((jbyte)(TCL_MASK_CID|TCL_TYPE_SBLOCK_WTX));		HAL_TCL_SEND((jbyte)(tcl_cid | HAL_POWER_LEVEL_MEASURE()));	} else {		HAL_TCL_INITSEND((jbyte)(TCL_TYPE_SBLOCK_WTX));	}	// send power level and wtxm	HAL_TCL_SEND((jbyte)(HAL_POWER_LEVEL_MEASURE() | tcl_wtxm));	HAL_TCL_SENDGO(jfalse);	#endif /* JAYA_TCL_WTX */	return TCL_FSM_RECEIVE;}/* ============================================================================	tcl_ffsm_retransmit()   ========================================================================= */jbyte tcl_ffsm_retransmit(void){	LOG("TCLFSM","tcl_ffsm_retransmist()");	HAL_TCL_INITSEND(sav_pcb);	if ((sav_pcb & TCL_MASK_CID)!=0) {		HAL_TCL_SEND((jbyte)(HAL_POWER_LEVEL_MEASURE() | tcl_cid));	}	if ((sav_pcb & TCL_MASK_NAD)!=0) {		HAL_TCL_SEND((jbyte)((tcl_nad<<4)|(tcl_nad>>4)));	}	HAL_TCL_SENDBUF(&gOutBuffer.apdu.info[sav_apdu],tcl_ofs);	HAL_TCL_SENDGO(jfalse);	return TCL_FSM_RECEIVE;}/* ============================================================================	tcl_ffsm_send_iblock()   ========================================================================= */jbyte tcl_ffsm_send_iblock(void){    LOCAL(jbyte,headofs);	LOG("TCLFSM","tcl_ffsm_send_iblock()");    /* PCB + CRC */	headofs = 3;	/* PCB */	tcl_pcb = TCL_TYPE_IBLOCK | tcl_block;	if (tcl_has_cid) {		/* set the CID-following bit */		headofs++;		tcl_pcb |= TCL_MASK_CID;	}	if (tcl_has_nad && (tcl_apdu==0)) {		/* set the NAD-following bit */		headofs++;		tcl_pcb |= TCL_MASK_NAD;	}	if ( (headofs + ( gOutBuffer.apdu.len - tcl_apdu)) > tcl_fsd) {		tcl_pcb |= TCL_MASK_CHAINING;	}	/* save tcl_apdu and tcl_pcb for retransmit */	sav_pcb = tcl_pcb;	sav_apdu = tcl_apdu;	/* chaining ? => pre-calculate offset value before sending */	if ((tcl_pcb&TCL_MASK_CHAINING)==0) {		/* no chaining or no more chaining (last frame) */		tcl_ofs = gOutBuffer.apdu.len - tcl_apdu;	} else {		/* chaining required on the PICC side */		tcl_inproc = TCL_INPROC_CHAINING_PICC;		tcl_ofs = tcl_fsd - headofs;	}	/* send PCB, (CID) and (NAD) */	HAL_TCL_INITSEND(tcl_pcb);	if ((tcl_pcb&TCL_MASK_CID)!=0) {		HAL_TCL_SEND((jbyte)(HAL_POWER_LEVEL_MEASURE() | tcl_cid));	}	if ((tcl_pcb&TCL_MASK_NAD)!=0) {		HAL_TCL_SEND((jbyte)((tcl_nad<<4)|(tcl_nad>>4)));	}	/* PICC chaining ? */	if ((tcl_pcb&TCL_MASK_CHAINING)==0) {		/* no chaining or no more chaining (last frame) */		HAL_TCL_SENDBUF(&gOutBuffer.apdu.info[tcl_apdu],tcl_ofs);		HAL_TCL_SENDGO(jfalse);		/* reset */		tcl_apdu = 0;	} else {		HAL_TCL_SENDBUF(&gOutBuffer.apdu.info[tcl_apdu],tcl_ofs);		HAL_TCL_SENDGO(jfalse);		/* adjust pointer with number of bytes */		tcl_apdu = tcl_apdu + tcl_ofs;	}	return TCL_FSM_RECEIVE;}/* ============================================================================	tcl_ffsm_application()   ========================================================================= */jbyte tcl_ffsm_application(void){	LOG("TCLFSM","tcl_ffsm_application()");    /* internal clock is better to calculate */    HAL_INTERNAL_CLOCK();    /* reset pointer to the beginning of the buffer ! */    tcl_apdu = 0;	/* call the OS to manage the received buffer */	cos_main();    /* encapsulation management */    if ((cfg_config_flag1&CONFIG_FLAG1_T1_ENCAPS)==CONFIG_FLAG1_T1_ENCAPS) {        if ((gSeqVal&SEQVAL_GETRESPONSE)==SEQVAL_GETRESPONSE) {            /* put the answer in the buffer */            tcl_apdu = 0;            BIOS_SEND_BUF(&gOutBuffer.apdu.info[BIOS_GETRESPONSE_OFS],BIOS_GETRESPONSE_LEN);            BIOS_SEND(0x90);            BIOS_SEND(0x00);            /* getresponse has been done ! */            BIOS_BITCLR_SEQVAL(SEQVAL_GETRESPONSE);        }    }	/* re-init for receiving next blocks */	tcl_apdu = 0;	tcl_inproc = TCL_INPROC_NONE;	/* no need for co-processors : stop/reset them */	HAL_HARDWARE(HARDWARE_NONE);    /* external clock is better to communicate */    HAL_EXTERNAL_CLOCK();	return TCL_FSM_SEND_IBLOCK;}/* ============================================================================	tcl_ffsm_receive_iblock()   ========================================================================= */jbyte tcl_ffsm_receive_iblock(void){	LOG("TCLFSM","tcl_ffsm_receive_iblock()");	if ( (tcl_inproc != TCL_INPROC_NONE) && (tcl_inproc != TCL_INPROC_CHAINING_PCD)	&& (tcl_inproc != TCL_INPROC_CHAINED_PICC) ) {		/* IBLOCK allowed only in case of PCD uses chaining or start of new exchange */		return TCL_FSM_RECEIVE;	}	/* block number */	tcl_block = !tcl_block;	/* PCD chaining ? */	if ((tcl_pcb&TCL_MASK_CHAINING)==0) {		/* no chaining or last part of the chain */		return TCL_FSM_APPLICATION;	} else {		/* mark PCD chaining */		tcl_inproc = TCL_INPROC_CHAINING_PCD;		/* update tcl_apdu pointer */		tcl_apdu = tcl_apdu + tcl_cnt;		/* ACK the reception to receive the next frame */		return TCL_FSM_SEND_ACK;	}}/* ============================================================================	tcl_ffsm_receive_wtx()   ========================================================================= */jbyte tcl_ffsm_receive_wtx(void){	LOG("TCLFSM","tcl_ffsm_receive_wtx()");	#ifdef JAYA_TCL_WTX	if (tcl_inproc != TCL_INPROC_WTX) {		tcl_inproc = TCL_INPROC_ERROR;		return TCL_FSM_RECEIVE;	}	if ((gInBuffer.b[0]&TCL_MASK_WTXM)!=tcl_wtxm) {		/* not the correct WTX multiplier ! */		return TCL_FSM_RECEIVE;	}	tcl_inproc = TCL_INPROC_NONE;	#endif /* JAYA_TCL_WTX */	return TCL_FSM_HALT;			/* __x FIXME */}/* ============================================================================	tcl_ffsm_send_deselect()   ========================================================================= */jbyte tcl_ffsm_send_deselect(void){	LOG("TCLFSM","tcl_ffsm_send_deselect()");	if (tcl_has_cid) {		HAL_TCL_INITSEND((jbyte)(TCL_TYPE_SBLOCK_DESELECT | TCL_MASK_CID));		HAL_TCL_SEND((jbyte)(tcl_cid | HAL_POWER_LEVEL_MEASURE()));	} else {		HAL_TCL_INITSEND((jbyte)TCL_TYPE_SBLOCK_DESELECT);	}	HAL_TCL_SENDGO(jtrue);	HAL_TCL_SETBAUDRATE(BAUDRATE_106);	return TCL_FSM_HALT;}/* ============================================================================	tcl_ffsm_send_ack()   ========================================================================= */jbyte tcl_ffsm_send_ack(void){	LOG("TCLFSM","tcl_ffsm_send_ack()");	if (tcl_has_cid) {		HAL_TCL_INITSEND((jbyte)(TCL_TYPE_RBLOCK_ACK | TCL_MASK_CID | tcl_block));		HAL_TCL_SEND((jbyte)(tcl_cid | HAL_POWER_LEVEL_MEASURE()));	} else {		HAL_TCL_INITSEND((jbyte)(TCL_TYPE_RBLOCK_ACK | tcl_block));	}	HAL_TCL_SENDGO(jtrue); 	return TCL_FSM_RECEIVE;}/* ============================================================================	tcl_ffsm_receive_nak()   ========================================================================= */jbyte tcl_ffsm_receive_nak(void){	LOG("TCLFSM","tcl_ffsm_receive_nak()");	if ((tcl_pcb&TCL_MASK_BLOCK_NUMBER)!=tcl_block) {		return TCL_FSM_SEND_ACK;	} else {		if (tcl_inproc==TCL_INPROC_WTX) {			return TCL_FSM_SEND_WTX;		} else {			if (tcl_inproc==TCL_INPROC_CHAINING_PCD) {				return TCL_FSM_SEND_ACK;			}		}	}	return TCL_FSM_RETRANSMIT;}/* ============================================================================	tcl_ffsm_receive_ack()   ========================================================================= */jbyte tcl_ffsm_receive_ack(void){	LOG("TCLFSM","tcl_ffsm_receive_ack()");	if ( (tcl_inproc != TCL_INPROC_CHAINING_PICC) && (tcl_inproc != TCL_INPROC_CHAINED_PICC)) {		if (tcl_inproc!=TCL_INPROC_WTX) {			tcl_inproc = TCL_INPROC_ERROR;		}		return TCL_FSM_RECEIVE;	}	if ((tcl_pcb&TCL_MASK_BLOCK_NUMBER)!=tcl_block) {		/* last block of the chain already sent ! */		if (tcl_inproc==TCL_INPROC_CHAINED_PICC) return TCL_FSM_RECEIVE;		tcl_block = !tcl_block;		/* suppose this is the last block of the chain (send_iblock can change this asumption) */		tcl_inproc = TCL_INPROC_CHAINED_PICC;		return TCL_FSM_SEND_IBLOCK;	}	return TCL_FSM_RETRANSMIT;}/* =========================================================================	That's all folks !   ========================================================================= */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -