Package uk.co.nimp.scard

Source Code of uk.co.nimp.scard.Star265TerminalManager$Win32Stcp250Dll

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

import com.atolsystems.atolutilities.ACommandLineUtilities;
import com.atolsystems.atolutilities.ACommandLineUtilities.Arg;
import com.atolsystems.atolutilities.AStringUtilities;
import com.atolsystems.atolutilities.ArgSpec;
import com.atolsystems.atolutilities.MutableInteger;
import java.io.IOException;
import java.util.List;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallFunctionMapper;
import java.io.File;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import uk.co.nimp.smartcard.AnswerToReset;
import static uk.co.nimp.scard.MP300Exception.*;
import uk.co.nimp.smartcard.Apdu;

public class Star265TerminalManager extends GenericTerminalManager {
   
    static public interface Win32Stcp250Dll extends Library {
// Functions from Stcp250.dll

        //WORD MPS_ResetHard(void);
        short MPS_ResetHard();

        //void CALL SetDLLTimeOutValue(WORD timeout);
        void SetDLLTimeOutValue(int timeout);

        //WORD CALL GetDLLTimeOutValue(void);
        short GetDLLTimeOutValue();


//WORD CALL MPS_OnCmm( BYTE CplNum, DWORD Frequency, WORD *pATRLg, BYTE *pATRBuf);
        short MPS_OnCmm(int CplNum, int Frequency, ShortByReference pATRLg, byte[] pATRBuf);
//WORD CALL MPS_OffCmm( BYTE CplNum);
        short MPS_OffCmm(int CplNum);
//
//        WORD CALL MPS_SendAPDU( BYTE CplNum, DWORD Command, DWORD Lc, BYTE *pLcField, DWORD Le, BYTE *pLeField, DWORD *pLeFieldLen, WORD *SW1SW2);
        short MPS_SendAPDU( int CplNum, int Command, int Lc, byte[] pLcField,
            int Le, byte[] pLeField, LongByReference pLeFieldLen,IntByReference SW1SW2);

        //WORD CALL MPS_SendIFSRequest( BYTE CplNum, BYTE IFSValue);
//
//// Change protocol parameters
//WORD CALL MPS_ChangeProtocolParameters( BYTE CplNum, DWORD TypeParam, void *Param, DWORD ParamSize);
        //short MPS_ChangeProtocolParameters(byte NoCPL,int TypeParam, Pointer Param, int ParamSize);
    short MPS_ChangeProtocolParameters(int NoCPL,int TypeParam, byte Param[], int ParamSize);

        //WORD CALL MPS_GetProtocolParameters( BYTE CplNum, DWORD TypeParam, void *Param, DWORD SizeofParam, DWORD *pParamSize);
        short MPS_GetProtocolParameters( int CplNum, int TypeParam, Pointer Param, int SizeofParam, LongByReference pParamSize);
static public final int CPP_IFSC=          1// Force IFSC value
static public final int CPP_IFSD=          2// Force IFSD value
static public final int CPP_SIM_ATR=                 3// Change ATR specification
//static public final int CPP_INITIAL_WAITING_TIME    4  // Force initial waiting time (9600 ETU) with another value
//static public final int CPP_ATR_LEN          5  // For no ISO ATR specify ATR length
//static public final int CPP_INITIAL_ETU             6  // Change initial ETU for next MPS_OnCmm
//static public final int CPP_MAX_CLK_ATR        10  // Clock count after reset before card mute
//static public final int CPP_CLK_RST          11  // Clock count where RST is low
//static public final int CPP_STANDARD_USED      12  // Change the standard used
//  static public final int STD_ISO_7816        0  // Standard ISO 7816
//  static public final int STD_EMV_2000        1  // Standard EMV 2000
//  static public final int STD_3GPP          2  // Standard 3GPP
//static public final int CPP_ERROR_SIGNAL      14  // Enable/Disable error signal handling
//static public final int CPP_CWT            15  // Change CWT in ETU
//static public final int CPP_BWT            16  // Change BWT in ETU
//static public final int CPP_WWT            17  // Change WWT in ETU
//static public final int CPP_BGT            18  // Change BGT in ETU
//static public final int CPP_EGT            19  // Change EGT in ETU
//static public final int CPP_RGT            20  // Change RGT in ETU
//static public final int CPP_PROTOCOL_TIMEOUT    21  // Enable/Disable protocol timeout IWT,WWT,BWT et CWT
//static public final int CPP_CURRENT_F_D        22  // Change and apply current F/D factor
//static public final int CPP_TIMEOUT_NULL_BYTE    23  // NULL byte timeout in T=0 protocol
//static public final int CPP_RGT1          24  // Change RGT1 in C3 clock count
//static public final int CPP_RGT2          25  // Change RGT2 in C3 clock count
//static public final int CPP_CHECK_ATR        28  // ON or OFF for enable/disable ATR analyze
//static public final int CPP_POWER_OFF_ON_ATR_ERROR  29  // ON or OFF for enable power off on ATR analyze error
//static public final int CPP_CURRENT_PROTOCOL        31  // Protocol in use (T=0 ou T=1)
//static public final int CPP_C6CONTROL               33  // control behaviour of C6 during activation/deactivation
//static public final int CPP_CURRENT_ETU        34
//
///*-----------------------------------------------*
// * Setting voltages and miscellaneous parameters *
// *-----------------------------------------------*/
//WORD CALL MPS_VCCSelectMV( BYTE CplNum, short ValVcc);

        short MPS_VCCSelectMV(int CplNum, int ValVcc);
//static public final int VCC_MIN_MV    0L      //  0 volts
//static public final int VCC_MAX_USB_IC  3600    // +3.6 volts max in USB-IC mode
//static public final int VCC_MAX_MV    6000L    // +6 volts
//
//
//WORD CALL MPS_SetPullup(BYTE CplNum, BYTE PinNum, DWORD Pullup);
//static public final int PULLUP_IO_OFF  0    // Without pullup
//static public final int PULLUP_IO_5K  5000
//static public final int PULLUP_IO_22K  22000
//static public final int PULLUP_IO_INFINITE  1000000
//
//
//WORD CALL MPS_FrequencySelect( BYTE CplNum, DWORD Frequency);
        short MPS_FrequencySelect(int CplNum, int Frequency);
//static public final int FREQ_MIN  500000
//static public final int FREQ_MAX  10000000

//WORD MPS_ModeSelect( BYTE CplNum, BYTE Mode);
        short MPS_ModeSelect( int CplNum, int Mode);
// define for configuration mode : synchronous or asynchronous
static public final int CMM_MODE_SYNC=       1;//synchronous mode allow to force clock to high
static public final int CMM_MODE_ASYNC=      2;

//WORD MPS_PinWrite( BYTE CplNum, BYTE PinNum, BYTE PinState);
        short MPS_PinWrite( int CplNum, int PinNum, int PinState);

// Define for smart card pin name
static public final int PIN_VCC=      0//  C1
static public final int PIN_RESET=    1//  C2
static public final int PIN_CLOCK=    2//  C3
static public final int PIN_RFU1=     3//  C4
static public final int PIN_GND=      4//  C5
static public final int PIN_VPP=      5//  C6
static public final int PIN_IO=       6//  C7
static public final int PIN_RFU2=     7//  C8
static public final int PIN_FUSE=     PIN_RFU2;
static public final int PIN_RFU3=     8// INPUT TTL
static public final int PIN_RFU4=     9// OUTPUT TTL

// Define for pins VCC and VPP and pin state
static public final int OFF=         0;   // LOW TTL
static public final int ON=          1;   // HIGH TTL ( PullUp for C4,C7 and C8)
static public final int ON_MEASURE=  2;   // HIGH TTL ( True high for C4,C7 and C8)

static public final int LOW=         3;   // LOW TTL  ( For all pins same as OFF)
static public final int HIGH=        4;   // HIGH TTL ( True high for all pins)
static public final int PULLUP=      5;   // HIGH TTL ( PullUp for only C4,C7 and C8)
static public final int HZ_STATE=    6;   // High Z state ( for all pins)

/* define for APIs
*  MPS_VCCSelect
*  MPS_VIISelect
*  MPS_VPPSelect
*/
static public final int VCC_MIN=     2;     // 0.2 volts
static public final int VCC_MAX=     100;   // 10.0 volts
static public final int VPP_MIN=     5;     // 0.5 volts
static public final int VPP_MAX=     255;   // 25.5 volts
static public final int VII_MIN=     20;    // 2 volts
static public final int VII_MAX=     70;    // 7.0 volts

/* define for APIs
*  MPS_VCCSelectMV
*  MPS_VIISelectMV
*  MPS_VPPSelectMV
*/
static public final int VCC_MIN_MV=  20;     // 0.2 volts
static public final int VCC_MAX_MV=  10000// 10.0 volts
static public final int VPP_MIN_MV=  50;     // 0.5 volts
static public final int VPP_MAX_MV=  25500// 25.5 volts
static public final int VII_MIN_MV=  2000;   // 2 volts
static public final int VII_MAX_MV=  7000;   // 7.0 volts

// define for convention selection
static public final int DIRECT_CONVENTION=   1;
static public final int INVERSE_CONVENTION=  2;

// define for parity generation in transmit
static public final int EVEN_PARITY=     1;
static public final int ODD_PARITY=      2;
static public final int MARK_PARITY=     3;
static public final int SPACE_PARITY=    4;


// Define bit in StatIrq status
static public final int IRQ_VCC0=    0x01;
static public final int IRQ_VCC1=    0x02;
static public final int IRQ_VPP0=    0x04;
static public final int IRQ_VPP1=    0x08;
static public final int IRQ_VII0=    0x10;
static public final int IRQ_VII1=    0x20;

        //WORD MPS_CardDetect( BYTE CplNum);
        short MPS_CardDetect(int CplNum);


        //STAR265 specific
        //int StartDebug(char * strport)
        int StartDebug(byte[] host);
        //WORD MPS_SendPPSCmm( BYTE CplNum, BYTE Protocol, BYTE ParamFI, BYTE ParamDI);
        short MPS_SendPPSCmm( int CplNum, int Protocol, int ParamFI, int ParamDI);
        //WORD MPS_SendPTSCmm( BYTE CplNum, BYTE FIparam, BYTE DIparam);
        short MPS_SendPTSCmm( int CplNum, int FIparam, int DIparam);
        //WORD MPS_GetCmm( BYTE CplNum, DWORD TimeOut, BYTE *pChar);
        short MPS_GetCmm( int CplNum, int TimeOut, byte[] pChar);
        //WORD MPS_PutCmm( BYTE CplNum, BYTE Val);
        short MPS_PutCmm( int CplNum, int Val);
        //WORD MPS_SetETUWidth( BYTE CplNum, WORD ClockCount) ;
        short MPS_SetETUWidth( int CplNum, int ClockCount) ;
        //WORD MPS_SendReceiveCmm( BYTE CplNum, WORD LngIn, WORD *pLngOut, BYTE*pDataIn, BYTE *pDataOut)
        short MPS_SendReceiveCmm( int CplNum, int LngIn, ShortByReference pLngOut, byte[] pDataIn, byte[] pDataOut);
        //WORD MPS_WaitETUCpt( BYTE CplNum, DWORD Count);
        short MPS_WaitETUCpt( int CplNum, int Count);
        //WORD MPS_PortInit( BYTE PortNum, BYTE BaudRate, BYTE Frame);
        short MPS_PortInit( int PortNum, int BaudRate, int Frame);
        //WORD MPS_GetVersion( char *pVersion);
        short MPS_GetVersion( byte[] pVersion);
        // Communication port
        static public final int PORT_SERIE1=     1;
        static public final int PORT_SERIE2 =    2;
        static public final int PORT_SERIESUP=   3;
        static public final int PORT_SERIEINT =  4;
        static public final int PORT_ETHERNET =  5;

        // Baudrate
        static public final int BAUDS_9600=     0;
        static public final int BAUDS_19200=    1;
        static public final int BAUDS_38400=    2;
        static public final int BAUDS_115200=   3;

        // Serial Frame
        static public final int SERIAL_NOP=        0x00;
        static public final int SERIAL_EVENP=      0x01;
        static public final int SERIAL_ODDP=       0x02;

        static public final int SERIAL_1STOP=      0x00;
        static public final int SERIAL_2STOP=      0x04;

        static public final int SERIAL_7BIT =      0x00;
        static public final int SERIAL_8BIT =      0x10 ;

        static public final int SERIAL_BINARY =    0x00;
        static public final int SERIAL_XONXOFF=    0x08;
    }

    static final int MAX_CLOCK_FOR_16CYCLES_PER_ETU=3756000;//seems to be the upper limit when using STAR260
    static final String DEFAULT_COM="COM1";
    static final String DEFAULT_COM_PARAMS=":19200,N,8,2";
    static final int DEFAULT_COUPLER=0x02;//bit0 means coupler0, bit1 coupler1...

    static protected final Throwable initException;
    static protected final Win32Stcp250Dll win32Stcp250Dll;

    static transient Map<String,Integer> couplers;

    static final String ARG_HELP = "-help";
    static final int ARG_HELP_ID = 0;
    static final String ARG_ADD_COM_PORT = "-addComPort:";
    static final int ARG_ADD_COM_PORT_ID = 1;
    static final String ARG_ADD_COUPLER = "-addCoupler:";
    static final int ARG_ADD_COUPLER_ID = 2;

    static final String CONF_FILE_NAME="Star265TerminalManager.conf";
    static final String DEFAULT_STCP250_DLL="Stcp250";//we should offer a way to override this in future

    static {
        Throwable ex;
        Win32Stcp250Dll trial;
        try {
            couplers=new HashMap<String,Integer>();
            //ports = new String[0];//make sure ports will not be null
            Map<String, Object> options = new HashMap<String, Object>();
            options.put(Library.OPTION_FUNCTION_MAPPER, new StdCallFunctionMapper());
            trial = (Win32Stcp250Dll) Native.loadLibrary(DEFAULT_STCP250_DLL, Win32Stcp250Dll.class, options);
            trial=(Win32Stcp250Dll) Native.synchronizedLibrary(trial);
            ex = null;
        } catch (Throwable e) {
            ex = e;
            trial = null;
        }
        win32Stcp250Dll = trial;
        initException = ex;
        if(null==initException){
            try {
                initContext();
            } catch (ScardException ex1) {
                Logger.getLogger(Star265TerminalManager.class.getName()).log(Level.SEVERE, null, ex1);
            }
        }
    }

    public Star265TerminalManager(){
    }
    protected String getConfFileName(){
        return CONF_FILE_NAME;
    }
    @Override
    protected void loadConfigurationImpl(File argFile) throws Exception {
        if(null!=initException)
            throw new Exception(initException);
        if(null==win32Stcp250Dll)
            throw new NullPointerException(DEFAULT_STCP250_DLL+" could not be loaded");
        try{
            if(argFile.exists()){
                ArrayList<String> argList=ACommandLineUtilities.processArgFile(argFile);
                if((null==argList) || argList.isEmpty())
                    return;
                String args[] = new String[argList.size()];
                argList.toArray(args);
                Integer curArgIndex = null;
                Arg curArg = null;
                curArgIndex = 0;

                ArgSpec argSpecs[] = {
                    new ArgSpec(ARG_HELP, ARG_HELP_ID),
                    new ArgSpec(ARG_ADD_COM_PORT, ARG_ADD_COM_PORT_ID, ArgSpec.UNLIMITED_OCCURENCE),
                    new ArgSpec(ARG_ADD_COUPLER, ARG_ADD_COUPLER_ID, ArgSpec.UNLIMITED_OCCURENCE),
                    };
                Set<ArgSpec> specs=ACommandLineUtilities.addArgFileArgSpecs(argSpecs);
                argSpecs=new ArgSpec[specs.size()];
                specs.toArray(argSpecs);
                args = ACommandLineUtilities.processArgFile(new File("").getAbsoluteFile(), args);
                ACommandLineUtilities.checkArgs(args, argSpecs);
                String curPort=DEFAULT_COM;
                while (curArgIndex < args.length) {
                    curArg = ACommandLineUtilities.getArg(args, argSpecs, curArgIndex, null);
                    if(null!=curArg){
                        switch (curArg.id) {
                            case ARG_HELP_ID:
                                StringBuilder sb=new StringBuilder();
                                sb.append("Star265TerminalManager configuration file help\n\n");
                                sb.append(ARG_ADD_COM_PORT);
                                sb.append("<name of port>\n");
                                sb.append("Add a port. Typical name looks like \"COM1\", \"COM2\" and so on\n");
                                System.out.println(sb.toString());
                                break;
                            case ARG_ADD_COM_PORT_ID:
                                curPort=curArg.value;
                                break;
                            case ARG_ADD_COUPLER_ID:
                                int couplerId=Integer.decode(curArg.value);
                                couplers.put(curPort, couplerId);
                                break;
                        }
                    }
                    curArgIndex++;
                }
            }else{
                couplers.put(DEFAULT_COM, DEFAULT_COUPLER);
            }
        }catch(Throwable e){
            throw new RuntimeException("Exception occured during processing of configuration file below\n"+argFile.getAbsolutePath()+"\n", e);
        }
    }

    static public void initContext() throws ScardException {
        //System.out.println("win32Stcp250Dll=" + win32Stcp250Dll);
        if (null != initException) {
            throw new ScardException("", initException);
        }
        Runtime.getRuntime().addShutdownHook(new Thread() {

            @Override
            public void run() {
                {
                    //release all resources
                    //TODO: currently both calls return "bad argument"
                    int status = 0;
                    //status=win32Stcp250Dll.MPOS_CloseResource(RES_ID, 0);
                    //status=win32Stcp250Dll.MPOS_CloseResource(RES_ID, 1);
                    if (RET_OK != status) {
                        //throw new ScardException("MPOS_CloseResource returned " + status);
                        }
                    //status = win32Stcp250Dll.MPOS_CloseResource(RES_ID, 1);
                }
            }
        });
    }

    @Override
    public List<GenericTerminal> list() throws ScardException {
        List<GenericTerminal> terminalsList = new ArrayList<GenericTerminal>();
        if(null!=initException)
            return Collections.unmodifiableList(terminalsList);

        for(Entry<String, Integer>coupler:couplers.entrySet()){
            try {
                GenericTerminal terminal = getTerminalImpl(coupler.getKey(), coupler.getValue());
                terminalsList.add(terminal);
            } catch (MP300Exception e) {
            }
        }

        return Collections.unmodifiableList(terminalsList);
    }
    private static final Map<String, Reference<GenericTerminal>> terminals = new HashMap<String, Reference<GenericTerminal>>();

    protected static GenericTerminal getTerminalImpl(String ip, int couplerId) throws ScardException {
        int status;
        String name = "STAR265 on "+ip+" coupler"+ couplerId;
        String strport=ip+DEFAULT_COM_PARAMS;
        //String strport=ip+":38400,N,8,2";
        Reference<GenericTerminal> ref = terminals.get(name);
        GenericTerminal terminal = (ref != null) ? ref.get() : null;
        if (terminal != null) {
            return terminal;
        }

        byte[] readerBytes = AStringUtilities.StringToBytesWithFinalNull(strport);
        int bu=win32Stcp250Dll.GetDLLTimeOutValue();
        win32Stcp250Dll.SetDLLTimeOutValue(1);
        boolean is260=false;
        try{      
            status = win32Stcp250Dll.StartDebug(readerBytes);
            if (RET_OK != status) throw new MP300Exception("Fail to establish communication with " + ip, status);

            status = win32Stcp250Dll.MPS_ResetHard();
            if (RET_OK != status) throw new MP300Exception("Fail to establish communication with " + ip, status);

            byte[] version=new byte[256];
            status=win32Stcp250Dll.MPS_GetVersion(version);
            if (RET_OK != status) {
                throw new MP300Exception("MPS_GetVersion failed: ", status);
            }
            String versionStr=AStringUtilities.bytesToString(version);

            /*if(versionStr.indexOf("260")!=-1)
                is260=true;*/

            /*{//looks like we cannot change the speed of the port on the fly :-S
                status = win32Stcp250Dll.MPS_PortInit(win32Stcp250Dll.PORT_SERIE2, win32Stcp250Dll.BAUDS_9600,
                        win32Stcp250Dll.SERIAL_8BIT|win32Stcp250Dll.SERIAL_1STOP|win32Stcp250Dll.SERIAL_NOP|win32Stcp250Dll.SERIAL_XONXOFF);
                if (RET_OK != status) {
                    throw new MP300Exception("Fail to establish communication with " + ip, status);
                }
            }*/

        }catch(MP300Exception e){
            throw e;
        }finally{
            win32Stcp250Dll.SetDLLTimeOutValue(bu);
        }

        terminal = new Star265Terminal(couplerId, name, is260);
        terminals.put(name, new WeakReference<GenericTerminal>(terminal));

        return terminal;
    }
    static void SCardSetDllTimeout(int dllTimeoutS){
        win32Stcp250Dll.SetDLLTimeOutValue(dllTimeoutS);
    }
    static void SCardSetVdd(int couplerId, int vddMillivolts) throws ScardException {
        int status;
        int timeout=win32Stcp250Dll.GetDLLTimeOutValue();
        status = win32Stcp250Dll.MPS_VCCSelectMV(couplerId, vddMillivolts);
        if (RET_OK != status) throw new MP300Exception("MPS_VCCSelectMV failed, couplerId="+couplerId+", vddMillivolts="+vddMillivolts+", Dll Timeout="+timeout, status);
    }
    static void SCardSetClk(int couplerId, int clkHertz) throws ScardException {
        int status;
        //this does not work: switch to synchronous mode seems to reset async mode parameters...
        //status = win32Stcp250Dll.MPS_ModeSelect(couplerId, Win32Stcp250Dll.CMM_MODE_ASYNC);
        //if (RET_OK != status) throw new MP300Exception("MPS_ModeSelect failed", status);
        status = win32Stcp250Dll.MPS_FrequencySelect(couplerId, clkHertz);
        if (RET_OK != status) throw new MP300Exception("MPS_FrequencySelect failed", status);
    }
    static void SCardClkStop(int couplerId,int PinState) throws ScardException {
        int status;
        //this does not work: switch to synchronous mode seems to reset async mode parameters...
        //status = win32Stcp250Dll.MPS_ModeSelect(couplerId, Win32Stcp250Dll.CMM_MODE_SYNC);
        //if (RET_OK != status) throw new MP300Exception("MPS_ModeSelect failed", status);
        status = win32Stcp250Dll.MPS_PinWrite( couplerId, Win32Stcp250Dll.PIN_CLOCK, PinState);
        if (RET_OK != status) throw new MP300Exception("MPS_PinWrite failed", status);
    }
    static void SCardClkRestore(int couplerId) throws ScardException {
        int status;
        //this does not work: switch to synchronous mode seems to reset async mode parameters...
        //status = win32Stcp250Dll.MPS_ModeSelect(couplerId, Win32Stcp250Dll.CMM_MODE_ASYNC);
        //if (RET_OK != status) throw new MP300Exception("MPS_ModeSelect failed", status);
        status = win32Stcp250Dll.MPS_PinWrite( couplerId, Win32Stcp250Dll.PIN_CLOCK, Win32Stcp250Dll.ON);
        if (RET_OK != status) throw new MP300Exception("MPS_PinWrite failed", status);
    }
    static AnswerToReset SCardConnect(int couplerId, int vddMillivolts, int clkHertz, int protocol, MutableInteger cyclesPerEtu) throws ScardException {
        switch (protocol) {
            case GenericTerminal.PROTOCOL_T_0:
            //connectProtocol = SCARD_PROTOCOL_T0;
                break;
            case GenericTerminal.PROTOCOL_T_1:
            //connectProtocol = SCARD_PROTOCOL_T1;
                break;
            case GenericTerminal.PROTOCOL_ANY:
                //connectProtocol = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
                break;
            case GenericTerminal.PROTOCOL_DIRECT:
            case GenericTerminal.PROTOCOL_T_15:
            case GenericTerminal.PROTOCOL_T_CL_A:
            case GenericTerminal.PROTOCOL_T_CL_B:
            case GenericTerminal.PROTOCOL_ANY_STD_CL:
            default:
                throw new IllegalArgumentException("protocol = " + GenericTerminal.getProtocolName(protocol));
        }
        ShortByReference atrLenRef = new ShortByReference();
        atrLenRef.setValue((short) 256);
        int status;
        byte atrBuf[] = new byte[256];
        int timeout=win32Stcp250Dll.GetDLLTimeOutValue();
        status = win32Stcp250Dll.MPS_VCCSelectMV(couplerId, vddMillivolts);
        if (RET_OK != status) {
            throw new MP300Exception("MPS_VCCSelectMV failed, couplerId="+couplerId+", vddMillivolts="+vddMillivolts+", Dll Timeout="+timeout, status);
        }
        status = win32Stcp250Dll.MPS_OnCmm(couplerId, clkHertz, atrLenRef, atrBuf);
        if (RET_OK != status) {
            throw new MP300Exception("MPS_OnCmm failed", status);
        }
        short len = atrLenRef.getValue();
        AnswerToReset out=new AnswerToReset(atrBuf,0,len);
        int fi=out.getSupportedFiDi()>>4;
        int di=out.getSupportedFiDi()&0x0F;
        //System.out.println("ATR:" + out.toString());
        if(out.acceptPps() & (out.getSupportedFiDi()!=0x11)){
            byte ppsBuf[] = new byte[10];
            for (int i = 0; i < ppsBuf.length; i++) {
                ppsBuf[i] = 0;
            }
            int p=0;
            if(GenericTerminal.PROTOCOL_T_1==protocol)
                p=1;
           
           
            if(7==di){
                //not supported by STAR265
                byte fakeAtr[]=out.getData();
                di=0x06;
                fakeAtr[2]=(byte) ((out.getSupportedFiDi()&0xF0)|di);
                status = win32Stcp250Dll.MPS_ChangeProtocolParameters(couplerId, win32Stcp250Dll.CPP_SIM_ATR ,fakeAtr,fakeAtr.length);
                if (RET_OK != status) {
                    throw new MP300Exception("MPS_ChangeProtocolParameters failed",status);
                }
            }

            status = win32Stcp250Dll.MPS_SendPPSCmm( couplerId, p, fi, di);
            if (RET_OK != status) throw new MP300Exception("MPS_SendPPSCmm failed",status);
        }
        cyclesPerEtu.value= AnswerToReset.fiDi2cyclesPerEtu(fi, di);
        return out;
    }

    static Apdu.CardResponse SCardTransmit(int couplerId, int command, byte[] lcData, int le) throws ScardException {

        LongByReference actualLeByRef= new LongByReference();
        actualLeByRef.setValue(le);
        IntByReference internalSw=new IntByReference();
        internalSw.setValue(0);
        byte[] leData=new byte[le];
        int internalLe=le;
        if(0==le)
            internalLe=NO_LE;
        if(256==le)
            internalLe=0;
        int lc=lcData.length;
        if(0==lc)
            lc=NO_LC;
        int status = win32Stcp250Dll.MPS_SendAPDU( couplerId, command, lc,  lcData,
            internalLe, leData, actualLeByRef,internalSw);
        if (RET_OK != status) {
            int timeout=win32Stcp250Dll.GetDLLTimeOutValue();

            throw new MP300Exception("MPS_SendAPDU failed, timeout value="+timeout,status);
        }
        int actualLe=(int)actualLeByRef.getValue();
        if(actualLe!=le){
            byte[] actualLeData=new byte[actualLe];
            for(int i=0;i<actualLe;i++)
                actualLeData[i]=leData[i];
            leData=actualLeData;
        }
        Apdu.CardResponse out=new Apdu.CardResponse(leData,(short)internalSw.getValue());

        return out;
    }

    static void SCardDisconnect(int couplerId) throws MP300Exception {
        int status = win32Stcp250Dll.MPS_OffCmm(couplerId);
        if (RET_OK != status) {
            throw new MP300Exception("MPS_OffCmm failed",status);
        }
    }
    static void ScardForceDisconnection(int couplerId) throws MP300Exception {
        int status = win32Stcp250Dll.MPS_ResetHard();
        if (RET_OK != status) {
            throw new MP300Exception("MPS_ResetHard",status);
        }
    }

    static GenericTerminal.State SCardIsPresent(int couplerId) throws ScardException {
        int status = win32Stcp250Dll.MPS_CardDetect(couplerId);
        GenericTerminal.State out;
        switch (status) {
            case RET_OK:
                out = GenericTerminal.State.CARD_PRESENT;
                break;
            case CRET_ABSENT:
                out = GenericTerminal.State.CARD_ABSENT;
                break;
            default:
                throw new MP300Exception("MPS_CardDetect failed", status);
        }
        return out;
    }

    static public final int NO_LC=       0x80000000// No Lc field in CAPDU
    static public final int LC_EXTENDED= 0x40000000// Extended Lc field in CAPDU
    static public final int NO_LC_SEND=  0x20000000// The Lc field is not transmit
    //
    static public final int NO_LE =      0x80000000// No Le field in CAPDU
    static public final int LE_EXTENDED= 0x40000000// Extended Le field in CAPDU
    static public final int NO_LE_SEND=  0x20000000// The Le field is not transmit

    static public final int BATCH_EXECUTE_STOP_ON_ERROR=0;
    static public final int BATCH_EXECUTE_IGNORE_ERRORS=1;

///*******************
// * SYSTEM API CALL *
// *******************/
//// Define programming head number
//static public final int CPL0    0
//static public final int CPL1    1
//static public final int CPL2  2
//static public final int CPL3  3
//static public final int CPL4  4
//static public final int CPL5  5
//static public final int CPL6  6
//static public final int CPL7  7
//static public final int CPL8  8
//static public final int CPL9  9
//static public final int CPL10  10
//static public final int CPL11  11
//



}
TOP

Related Classes of uk.co.nimp.scard.Star265TerminalManager$Win32Stcp250Dll

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.