Package uk.co.nimp.scard

Source Code of uk.co.nimp.scard.Star265Terminal

/*
*/
/**
*
* @author Sebastien Riou
*/
package uk.co.nimp.scard;

import com.atolsystems.atolutilities.MutableInteger;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.smartcardio.CardException;
import javax.smartcardio.CardNotPresentException;
import uk.co.nimp.scard.log.ScardPrintStreamLogHandler;
import uk.co.nimp.smartcard.Apdu;
import uk.co.nimp.smartcard.UnexpectedCardResponseException;
import static uk.co.nimp.scard.Star265TerminalManager.*;



class Star265Terminal extends GenericContactTerminal {

   
    final protected int couplerId;
    //int vddMillivolts = 5000;
    //int clkHertz = MAX_CLOCK_FOR_16CYCLES_PER_ETU;
    final static public int DEFAULT_FREQUENCY=MAX_CLOCK_FOR_16CYCLES_PER_ETU;
    final static public int DEFAULT_VOLTAGE=5000;

    int stoppedClkHertz=CLOCK_RUNNING;

    Star265Terminal(int couplerId, String name, boolean is260) {
        super(name);
        this.couplerId = couplerId;
        this.is260=is260;
    }

    @Override
    public boolean isCardPresent() throws ScardException {
        return Star265TerminalManager.SCardIsPresent(couplerId) == GenericTerminal.State.CARD_PRESENT;
    }

    private boolean waitForCard(boolean wantPresent, long timeout) throws ScardException {
        if (timeout < 0) {
            throw new IllegalArgumentException("timeout must not be negative");
        }
        long start = System.currentTimeMillis();
        boolean exit = false;
        boolean out = false;
        do {
            if (wantPresent) {
                if (Star265TerminalManager.SCardIsPresent(couplerId) == GenericTerminal.State.CARD_PRESENT) {
                    exit = true;
                    out = true;
                }
            } else {
                if (Star265TerminalManager.SCardIsPresent(couplerId) == GenericTerminal.State.CARD_ABSENT) {
                    exit = true;
                    out = true;
                }
            }
            if ((0 != timeout) && (System.currentTimeMillis() - start < timeout)) {
                exit = true;
            }
        } while (false == exit);
        return out;
    }

    @Override
    public boolean waitForCardPresent(long timeout) throws ScardException {
        return waitForCard(true, timeout);
    }

    @Override
    public boolean waitForCardAbsent(long timeout) throws ScardException {
        return waitForCard(false, timeout);
    }

    int curCyclePerEtu=372;
    boolean is260=false;
    @Override
    public void connectImpl(int protocol, int activation) throws ScardException, CardNotPresentException {

        try {

            //atr = SCardConnect(couplerId, vddMillivolts, clkHertz, protocol);//Overrun occurs during card data read
            //atr = SCardConnect(couplerId, vddMillivolts, clkHertz, PROTOCOL_T_0);//Overrun occurs during card data read
            //atr = SCardConnect(couplerId, vddMillivolts, 5000000, protocol);//Overrun occurs during card data read
            //atr = SCardConnect(couplerId, vddMillivolts, MAX_CLOCK_FOR_16CYCLES_PER_ETU, protocol);//ok
            //atr = SCardConnect(couplerId, vddMillivolts, 4000000, PROTOCOL_T_0);//ok
            //atr = SCardConnect(couplerId, 5000, 4000000, PROTOCOL_T_0);//ok

            if (GenericTerminal.ACTIVATION_FORCE_COLD == activation) {
                SCardDisconnect(couplerId);
            }

            int millivolts;
            if(null==vddMillivolts)
                millivolts=DEFAULT_VOLTAGE;
            else
                millivolts=vddMillivolts;
            int hertz;
            if(null==clkHertz)
                hertz=DEFAULT_FREQUENCY;
            else
                hertz=clkHertz;
            MutableInteger i=new MutableInteger();
            this.logLine(ScardLogHandler.LOG_INFO, "INFO: Setting Vdd to "+millivolts+"mV");
            this.logLine(ScardLogHandler.LOG_INFO, "INFO: Setting Frequency to "+hertz+"Hz");
            atr = SCardConnect(couplerId, millivolts, hertz, protocol, i);
            vddMillivolts=millivolts;
            clkHertz=hertz;
           
            curCyclePerEtu=i.value;
            logAtr(atr);
            if(is260){
                if((16==curCyclePerEtu) & clkHertz>MAX_CLOCK_FOR_16CYCLES_PER_ETU){
                    this.logLine(ScardLogHandler.LOG_WARNING, "WARNING: Frequency directive is "+clkHertz+" but is limited to "+MAX_CLOCK_FOR_16CYCLES_PER_ETU+" to avoid com overrun of STAR260");
                    clkHertz=MAX_CLOCK_FOR_16CYCLES_PER_ETU;
                    atr= SCardConnect(couplerId, vddMillivolts, clkHertz, protocol, i);
                    logAtr(atr);
                }
            }

            this.logLine(ScardLogHandler.LOG_INFO, "INFO: Connection established at "+curCyclePerEtu+" cycles/ETU.");

            //TODO: retrieve the actual protocol
            this.protocol = PROTOCOL_T_0;
            //basicChannel = new ChannelImpl(this, 0);
            state = State.CARD_PRESENT;
        } catch (MP300Exception e) {
            if (e.code == MP300Exception.CRET_ABSENT) {
                throw new CardNotPresentException("No card present", e);
            } else {
                throw new ScardException("connect() failed", e);
            }
        }
    }

    @Override
    protected void disconnectImpl() throws ScardException {
        curCyclePerEtu=372;
        if (GenericTerminal.State.CARD_PRESENT != state) {
            return;
        }
        SCardDisconnect(couplerId);
    }
    @Override
    protected void forceDisconnectImpl() throws ScardException {
        curCyclePerEtu=372;
        if (GenericTerminal.State.CARD_PRESENT != state) {
            return;
        }
        ScardForceDisconnection(couplerId);
    }
    protected int dllTimeoutS=0;
    @Override
    public void setApduTimeout(int timeoutMs)throws ScardException{
        if(timeoutMs<0)
            throw new IllegalArgumentException("timeoutNs<0");
        this.dllTimeoutS=timeoutMs/1000;
        SCardSetDllTimeout(dllTimeoutS);
    }
    @Override
    public int getApduTimeout(){
        return dllTimeoutS*1000;
    }

    @Override
    public void sendApduImpl(Apdu apdu) throws ScardException, UnexpectedCardResponseException {
        int tpduHeader = (0xFF & apdu.getCla());
        tpduHeader = (tpduHeader << 8) + (0xFF & apdu.getIns());
        tpduHeader = (tpduHeader << 8) + (0xFF & apdu.getP1());
        tpduHeader = (tpduHeader << 8) + (0xFF & apdu.getP2());
        Apdu.CardResponse response = SCardTransmit(couplerId, tpduHeader, apdu.getLcDataAsBytes(), apdu.getExpectedLe());

        apdu.setResponse(response);
    }
    static final int CLOCK_RUNNING=-1;
    @Override
    public void setFrequency(int hertz) throws ScardException{
        if(CLOCK_RUNNING!=stoppedClkHertz){
            SCardClkRestore(couplerId);
        }
        if((null==clkHertz)||(clkHertz!=hertz)){
            //setFrequencyImpl(hertz);
            stoppedClkHertz=CLOCK_RUNNING;
            //To avoid overrun
            if(is260 & (16==curCyclePerEtu) & (hertz>MAX_CLOCK_FOR_16CYCLES_PER_ETU)){
                this.logLine(ScardLogHandler.LOG_WARNING, "WARNING: Frequency directive is "+hertz+" but is limited to "+MAX_CLOCK_FOR_16CYCLES_PER_ETU+" to avoid com overrun of STAR260");
                hertz=MAX_CLOCK_FOR_16CYCLES_PER_ETU;
            }else{
                this.logLine(ScardLogHandler.LOG_INFO, "INFO: Setting frequency to "+hertz+"Hz");
            }
            SCardSetClk(couplerId, hertz);
            clkHertz=hertz;
        }
    }

    @Override
    protected void InitSetClkPinCapabilities(){
        setClkPinCapabilities=new SetPinCapabilities(true,false,true);
    }

    @Override
    public void setClkPinImpl(boolean high) throws ScardException {
        if (high) {
            handleUnsupportedOperation();
            //throw new UnsupportedOperationException("Star265 terminal cannot fix the clock to high level mode");
            //SCardClkStop(couplerId, Win32Stcp250Dll.HIGH);
        } else {
            SCardClkStop(couplerId, Win32Stcp250Dll.LOW);
        }
        stoppedClkHertz=clkHertz;
        clkHertz=0;
    }

    @Override
    public void setVoltageImpl(int millivolts) throws ScardException {
        SCardSetVdd(couplerId, millivolts);
    }

    public static void main(String[] args) throws ScardException, CardException, IOException {
        try {
            Star265TerminalManager manager = new Star265TerminalManager();
            List<GenericTerminal> terminals = manager.list();
            terminals = manager.list();
            terminals = manager.list();
            if (0 == terminals.size()) {
                System.out.println("Star265 terminal not detected.");
                return;
            }
            //Star265Terminal star265 = (Star265Terminal) terminals.get(0);
            GenericTerminal star265 = terminals.get(0);
            terminals = manager.list();
            star265.addLogHandler(new ScardPrintStreamLogHandler(System.out));
            System.out.println("Please insert a card in terminal " + star265.getName());
            while (false == star265.isCardPresent()) {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Star265Terminal.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            System.out.println("Try to coldConnect to " + star265.getName());
            star265.coldConnect();
            Apdu apdu = new Apdu(0x00, 0x8A, 0x00, 0x44, 0x02);
            star265.sendApdu(apdu);
        } catch (ScardException ex) {
            Logger.getLogger(Star265Terminal.class.getName()).log(Level.SEVERE, null, ex);
        } catch (CardException ex) {
            Logger.getLogger(Star265Terminal.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
TOP

Related Classes of uk.co.nimp.scard.Star265Terminal

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.