Package uk.co.nimp.scard

Source Code of uk.co.nimp.scard.SmartwareTerminalManager$Win32CardDll$card_CfgXType

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

import com.atolsystems.atolutilities.AStringUtilities;
import com.atolsystems.atolutilities.ATimeUtilities;
import java.util.List;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallFunctionMapper;
import java.io.File;
import java.io.IOException;
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.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import uk.co.nimp.smartcard.AnswerToReset;
import static uk.co.nimp.scard.SmartwareTerminalManager.Win32MlOsMainDll.*;
import static uk.co.nimp.scard.SmartwareTerminalManager.Win32CardDll.*;
import uk.co.nimp.smartcard.Apdu;

public class SmartwareTerminalManager extends GenericTerminalManager {

//public static final int unknown_constant=-1  ;
    static public interface Win32MlOsMainDll extends Library {
        /*-----------------------------------------------------------------------*
        Common error codes
         *-----------------------------------------------------------------------*/

        public static final int sys__err = 0;
        public static final int sys__ok = 0;    /* Every thing's OK */

        public static final int sys__noobj = 1 + sys__err;  /* Object not found */

        public static final int sys__noop = 2 + sys__err;  /* Operation not found */

        public static final int sys__arg = 3 + sys__err;  /* Wrong parameter */

        public static final int sys__timeout = 4 + sys__err;  /* Timeout */

        public static final int sys__resp = 5 + sys__err;  /* Too long answer length */

        public static final int sys__escape = 6 + sys__err;  /* User escape */

        public static final int sys__mem = 7 + sys__err;  /* Wrong memory model */

        public static final int sys__nodrv = sys__noobj;
        /*-----------------------------------------------------------------------*
        APPLICATION INTERFACE
         *-----------------------------------------------------------------------*/
//public static final int sysct_wait=  sysobj_Wait;//this is actualy a function, not a constant
//public static final int sysct_exec=  sysobj_Call;

        /*  struct {
        unsigned long Mode;    // Mode and parameter mask
        char IniPath[256+1];   // .INI file (ex: "C:\\MLOS.INI") or ""
        char AppName[32+1];    // Appli name or ""
        #if !config_CONSO && config_WIN32
        HWND  syst_PrintWnd;      // 0 or Print window
        #endif
        char * Options;        // 0 or Options
        err_Type (* syst_PrintFunc)(char *);  // 0 or Print function
        } mloscfg_Type;*/
        public static class mloscfg_Type extends Structure {
            //public long Mode=0;    // Mode and parameter mask

            public int Mode = 0;    // Mode and parameter mask
            public byte[] IniPath = new byte[256 + 1];   // .INI file (ex: "C:\\MLOS.INI") or ""
            public byte[] AppName = new byte[32 + 1];    // Appli name or ""
            //#if !config_CONSO && config_WIN32
            //public Pointer  syst_PrintWnd;      // 0 or Print window
            public int syst_PrintWnd = 0;
            //#endif
            //public Pointer Options;        // 0 or Options
            public int Options = 0;
            //public Pointer syst_PrintFunc;  // 0 or Print function
            public int syst_PrintFunc = 0;
        }
        /*-----------------------------------------------------------------------*
        Init specific data
         *-----------------------------------------------------------------------*/
        /*err_Type mloscfg_Init(
        mloscfg_Type * Cfg  // (IN): Cfg with default
        );*/

        int mloscfg_Init(mloscfg_Type Cfg)// (IN): Cfg with default

        /*-----------------------------------------------------------------------*
        Create tasks of configuration
         *-----------------------------------------------------------------------*/
//err_Type mloscfg_Start(mloscfg_Type * Cfg);
        int mloscfg_Start(mloscfg_Type Cfg);
        /*-----------------------------------------------------------------------*
        End tasks of configuration
         *-----------------------------------------------------------------------*/
//err_Type mloscfg_End(mloscfg_Type * Cfg);

        int mloscfg_End(mloscfg_Type Cfg);

        /*err_Type err_Msg( err_Type Erno,    // (IN): Error code
        char ** pMsg    // (OUT): Message
        );*/
        int err_Msg(int Erno, // (IN): Error code
                PointerByReference pMsg // (OUT): Message
                );
        /*long err_Msg(   long Erno,    // (IN): Error code
        String[] pMsg    // (OUT): Message
        );*/
    }

    static public interface Win32CardDll extends Library {
//public static final int sys__noobj=unknown_constant  ;
//public static final int sys__arg=unknown_constant  ;


        /*----------------------------------------------------------------------*
        Card Object Codes
         *----------------------------------------------------------------------*/

        /* Contact Interfaces */
        public static final int sys_CdId = 0x10// Secu card
        public static final int sys_CdpId = 0x18// Perso card
        public static final int sys_Cd1Id = 0x10// Contact Card 1
        public static final int sys_Cd2Id = 0x18// Contact Card 2
        public static final int sys_Cd3Id = 0x20// Contact Card 3
        public static final int sys_Cd4Id = 0x28// Contact Card 4
        public static final int sys_Cd5Id = 0xD0// Contact Card 5
        public static final int sys_Cd6Id = 0xD8// Contact Card 6
        public static final int sys_Cd7Id = 0xC0// Contact Card 7
        public static final int sys_Cd8Id = 0xC8// Contact Card 8
        public static final int sys_Cd9Id = 0xB0// Contact Card 9
        public static final int sys_Cd10Id = 0xB8// Contact Card 10

        /* Contactless Interfaces */
        public static final int sys_CdP1Id = 0x40// Proximity Card 1
        public static final int sys_CdP2Id = 0x48// Proximity Card 2
        public static final int sys_CdP3Id = 0xB0// Proximity Card 3
        public static final int sys_CdP4Id = 0xB8// Proximity Card 4
        public static final int sys_CdP5Id = 0xC0// Proximity Card 5
        public static final int sys_CdP6Id = 0xC8// Proximity Card 6
        public static final int sys_CdP7Id = 0xD0// Proximity Card 7
        public static final int sys_CdP8Id = 0xD8// Proximity Card 8

        /*----------------------------------------------------------------------*
        CARD Error Codes
         *----------------------------------------------------------------------*/
        public static final int card__Ok = 0x00;
        public static final int card__err = sys_CdId;
        public static final int card__no_card = card__err;  // No card
        public static final int card__card_gone = card__err + 1// Card pulled out
        public static final int card__card_off = card__err + 2// Card is not powered
        public static final int card__timeout = card__err + 3// Card mute
        public static final int card__reemit = card__err + 4// Too many parity errors
        public static final int card__comm = card__err + 5// Communication error
        public static final int card__lng = card__err + 6// header LNG != exchanged lng
        public static final int card__sw12 = card__err + 7// sw1-sw2 != 90H-00H
        public static final int card__NA = card__err + 8// Card Operation Not Available
        public static final int card__Type = card__err + 9// Invalid interface or model selected
        public static final int card__Open = card__err + 10// Interface not opened
        public static final int card__Coupler = Win32MlOsMainDll.sys__noobj;  // Bad Coupler Number
        public static final int card__NullPtr = Win32MlOsMainDll.sys__arg;    // NullPtr
        public static final int card__Ko = card__comm;  // General Error
        /*----------------------------------------------------------------------*
        Card Models

        Contact models Range : [00h...0Fh], [C0h...FFh]
        Contactless models Range : [10h...BFh]
         *----------------------------------------------------------------------*/
// ICC models
        public static final int card_ModelCAsync = 0x02// ISO 7816
        public static final int card_ModelCIsoEh = 0x03// ISO 7816 for Enhanced SW reader
        public static final int card_ModelCUsb = 0x05// ICC USB Cards
        public static final int card_ModelCRaw = 0x0F// RAW
// PICC models
        public static final int card_ModelPMifare = 0x18// MIFARE I
        public static final int card_ModelP14443A = 0x58// ISO 14443-A with SW Modem
        public static final int card_ModelP14443B = 0x38// ISO 14443-B with SW Modem
        public static final int card_ModelP14443A_RC = 0x28// ISO 14443-A with RC Modem
        public static final int card_ModelP14443B_RC = 0x88// ISO 14443-B with RC Modem
        public static final int card_ModelPFeliCa = 0x48// FeliCa
        public static final int card_ModelP15693 = 0x68// ISO 15693
        public static final int card_ModelPIcode = 0x78// Icode
        public static final int card_ModelPPayPassA = 0x59// PAYPASS-A with SW Modem
        public static final int card_ModelPPayPassB = 0x39// PAYPASS-B with SW Modem
        public static final int card_ModelPPayPassA_RC = 0x29// PAYPASS-A with RC Modem
        public static final int card_ModelPPayPassB_RC = 0x89// PAYPASS-B with RC Modem
// ICC Checksum type (T=1)
        public static final int card_T1CheckLRC = 0;
        public static final int card_T1CheckCRC = 1;
// card Object buffers sizes
        public static final int card_ATRMaxL = 40// Max length of ATR
        public static final int card_BufMaxL = 255// Max length of card data
        public static final int card_InfoMaxL = 56// Max length of info
// Default card methods timeout
        public static final int card_TimeoutOp = 6000// 6 seconds
        /*----------------------------------------------------------------------*
        card_CfgXType : Card Extended Configuration Structure
         *----------------------------------------------------------------------*/
        public static final int card_CfgxFD = 0x00000001;
        public static final int card_CfgxFI = 0x00000002;
        public static final int card_CfgxDI = 0x00000004;
        public static final int card_CfgxN = 0x00000008;
        public static final int card_CfgxCD = 0x00000010;
        public static final int card_CfgxCDU = 0x00000020;
        public static final int card_CfgxWI = 0x00000040;
        public static final int card_CfgxWWT = 0x00000080;
        public static final int card_CfgxODMT = 0x00000100;
        public static final int card_CfgxODTU = 0x00000200;
        public static final int card_CfgxCWI = 0x00000400;
        public static final int card_CfgxCWT = 0x00000800;
        public static final int card_CfgxBWI = 0x00001000;
        public static final int card_CfgxBWT = 0x00002000;
        public static final int card_CfgxBGT = 0x00004000;
        public static final int card_CfgxNAD = 0x00008000;
        public static final int card_CfgxIFSD = 0x00010000;
        public static final int card_CfgxIFSC = 0x00020000;
        public static final int card_CfgxTSWT = 0x00040000;
        public static final int card_CfgxTSWWT = 0x00080000;
        public static final int card_CfgxRSTWT = 0x00100000;
        public static final int card_CfgxRSTMode = 0x00200000;
        public static final int card_CfgxT1ErrReemit = 0x00400000;
        public static final int card_CfgxPPSGT = 0x00800000;
        public static final int card_CfgxAll = 0x00FFFFFF;
        public static final int cCfgStructSize1 = 96;
        public static final int cCfgStructSize2 = 100;
        public static final int cCfgStructSize3 = 104;
// RSTMode Flag
        public static final int card_RSTModeStayOn = 0x01;
        public static final int card_RSTModeAtrGet = 0x02;


        /*public class err_Type{
        short err_Type;
        }

        public class card_NOType{
        short card_NOType;
        }

        public class syst_TType{
        short syst_TType;
        }*/
        public static class card_Type extends Structure {

            public short Size;    // sizeof card_Type
            //public card_NOType NObj;  // Node/Obj number
            public short NObj;  // Node/Obj number
            public byte Model;    // Card type
            public byte ATR[] = new byte[card_ATRMaxL]// Last Answer To Reset
            public byte ATRLg;    // Length of ATR
            public byte SW1;    // Last card procedure byte SW1
            public byte SW2;    // Last card procedure byte SW2
            //public err_Type CplStatus;  // Last card method error
            //public short CplStatus;  // Last card method error
            public int CplStatus;  // Last card method error
            //public syst_TType timeout;  // Current card methods timeout (ms)
            //public short timeout;  // Current card methods timeout (ms)
            public int timeout;  // Current card methods timeout (ms)
            public byte Pcb;  // Obsolete
            public byte PcbChain;
            public byte fPcbChain;
            public byte Check;
            public byte Buf[] = new byte[card_BufMaxL + 16]// Com buffer
            public byte Info[] = new byte[card_InfoMaxL];     // Local data
            public byte CardFlag;  // Card Object Flag
            public Pointer pHwi;  // Reference on Card Hardware Interface
        }
        public static final int SIZEOF_CARD_CFGXTYPE = 26 * 4;

        public static class card_CfgXType extends Structure {

            public int StructSize;    /* Structure Size */

            public int Mask;    /* Selection Mask */

            public int FD;     /* Ratio F/D to fix the ETU value*/

            public int FI;     /* Clock rate conversion Factor */

            public int DI;     /* Baudrate adjustment factor */

            public int N;    /* Extra Guard time in Transmission */

            public int CD;    /* Character Duration in Transmission */

            public int CDU;    /* Character Duration Unit */

            public int WI;    /* Wait Integer (T=0) */

            public int WWT;    /* Work Waiting Time (T=0) */

            public int ODMT;    /* Opposite Direction Minimum Time (T=0)*/

            public int ODTU;    /* Opposite Direction Time Unit (T=0)*/

            public int CWI;    /* Character Waiting time Integer (T=1) */

            public int CWT;    /* Character Waiting Time (T=1) */

            public int BWI;    /* Block Waiting time Integer (T=1) */

            public int BWT;    /* Block Waiting Time(T=1) */

            public int BGT;    /* Block GuardTime (T=1) */

            public int NAD;    /* Node Address Byte (T=1) */

            public int IFSD;    /* IFS for the Reader (T=1) */

            public int IFSC;    /* IFS for the Card (T=1) - Read Only */

            public int TSWT;    /* TS byte Waiting Time (ATR) */

            public int TSWWT;       /* TS Work Waiting Time */

            public int RSTWT;        /* Waiting Time after Reset */

            public int RSTMode;     /* Reset Mode */

            public int T1ErrReemit;  /* Number of Reemission when Errors in T=1 */

            public int PPSGT;       /* PPS Guard Time */

        };


        /*err_Type card_Open(   card_Ref Obj,    // Card object
        uchar Model,    // (IN) Model of Communication
        card_NOType NObj);    // (IN) Physical Interface*/
        int card_Open(card_Type Obj, // Card object
                int Model, // (IN) Model of Communication
                int NObj);    // (IN) Physical Interface

        /*err_Type card_DetectGet(  card_Ref Obj,    // Card object
        ulong *Value);    // (OUT) Value */
        int card_DetectGet(card_Type Obj, // Card object
                int Value[]);    // (OUT) Value

        /*err_Type card_FreqXSet(   card_Ref Obj,    // Card object
        ulong Freq);    // (IN) Card frequency in kHz */
        int card_FreqXDef(card_Type Obj, // Card object
                int Freq);    // (IN) Card frequency in kHz

        /*err_Type card_FreqXGet(   card_Ref Obj,    // Card object
        ulong * Freq);    // (OUT) Frequency in kHz*/
        int card_FreqXGet(card_Type Obj, // Card object
                int Freq[]);    // (OUT) Frequency in kHz*/

        /*err_Type card_VccDef( card_Ref Obj,    // Card object
        ushort Vcc);    // (IN) Voltage in mV */
        int card_VccDef(card_Type Obj, // Card object
                int Vcc);    // (IN) Voltage in mV

        //err_Type card_Reset(card_Ref Obj);// Card object
        int card_Reset(card_Type Obj);
        //err_Type card_ResetWarm(card_Ref Obj);// Card object

        int card_ResetWarm(card_Type Obj);// Card object


        /*err_Type card_PPSX(   card_Ref Obj,    // Card object
        uchar * Buf,    // (IN/OUT) PPS Command / Card Answer
        card_LType LngIn,    // (IN) Data length to send
        card_LType * pLngOut);  // (IN/OUT) Max. Response / Current Response Length */
        int card_PTSX(card_Type Obj, // Card object
                byte Buf[], // (IN/OUT) PPS Command / Card Answer
                int LngIn, // (IN) Data length to send
                int pLngOut[]); // (IN/OUT) Max. Response / Current Response Length
        /*int card_InX(  card_Type Obj,    // Card object
        byte Buf[]);    // (IN) Data buffer*/

        int card_InXH(card_Type Obj, // Card object
                byte Cla, // (IN) Class
                byte Ins, // (IN) Instruction
                byte P1, // (IN) P1 parameter
                byte P2, // (IN) P2 parameter
                byte Lng, // (IN) P3 parameter : Data length
                byte Buf[]);    // (IN) Data Buffer

        /*err_Type card_OutXH(  card_Ref Obj,           // Card object
        uchar Cla,              // (IN) Class
        uchar Ins,              // (IN) Instruction
        uchar P1,               // (IN) P1 parameter
        uchar P2,               // (IN) P2 parameter
        uchar Lng,              // (IN) P3 parameter : Data length
        uchar * pBuf,           // (OUT) Buffer of Data received
        sysobj_LType * pLng);     // (OUT) Length of Data received */
        int card_OutXH(card_Type Obj, // Card object
                byte Cla, // (IN) Class
                byte Ins, // (IN) Instruction
                byte P1, // (IN) P1 parameter
                byte P2, // (IN) P2 parameter
                byte Lng, // (IN) P3 parameter : Data length
                byte pBuf[], // (OUT) Buffer of Data received
                int pLng[]);     // (OUT) Length of Data received

        //err_Type card_Off(card_Ref Obj);    // Card object
        int card_Off(card_Type Obj);    // Card object

        //err_Type card_Close(card_Ref Obj);    // Card object
        int card_Close(card_Type Obj);    // Card object

        int card_CardCfgX(card_Type Obj, // Card object
                card_CfgXType pConfig)// (IN/OUT) Configuration Structure
    }
    static protected final Throwable initException;
    static protected final Win32CardDll win32CardDll;
    static protected final Win32MlOsMainDll win32MlOsMainDll;
    static protected final Win32MlOsMainDll.mloscfg_Type conf;
    static final String CONF_FILE_NAME="SmartwareTerminalManager.conf";

    static public String couplerId2Name(int model, int couplerId) {
        StringBuilder sb = new StringBuilder("Smartware #");
        sb.append(AStringUtilities.byteToHex(couplerId >> 8));
        if (isContactModel(model)) {
            sb.append(" Contact ");
            switch (couplerId & 0xFF) {
                case sys_Cd1Id:
                    sb.append("Card 1");
                    break;
                case sys_Cd2Id:
                    sb.append("Card 2");
                    break;
                case sys_Cd3Id:
                    sb.append("Card 3");
                    break;
                case sys_Cd4Id:
                    sb.append("Card 4");
                    break;
                case sys_Cd5Id:
                    sb.append("Card 5");
                    break;
                case sys_Cd6Id:
                    sb.append("Card 6");
                    break;
                case sys_Cd7Id:
                    sb.append("Card 7");
                    break;
                case sys_Cd8Id:
                    sb.append("Card 8");
                    break;
                case sys_Cd9Id:
                    sb.append("Card 9");
                    break;
                case sys_Cd10Id:
                    sb.append("Card 10");
                    break;
                default:
                    throw new IllegalArgumentException("Invalid couplerId:0x" + Integer.toHexString(couplerId));
            }
        } else {
            sb.append(" Proximity ");
            switch (couplerId & 0xFF) {
                case sys_CdP1Id:
                    sb.append("Card 1");
                    break;
                case sys_CdP2Id:
                    sb.append("Card 2");
                    break;
                case sys_CdP3Id:
                    sb.append("Card 3");
                    break;
                case sys_CdP4Id:
                    sb.append("Card 4");
                    break;
                case sys_CdP5Id:
                    sb.append("Card 5");
                    break;
                case sys_CdP6Id:
                    sb.append("Card 6");
                    break;
                case sys_CdP7Id:
                    sb.append("Card 7");
                    break;
                case sys_CdP8Id:
                    sb.append("Card 8");
                    break;
                default:
                    throw new IllegalArgumentException("Invalid couplerId:0x" + Integer.toHexString(couplerId));
            }
        }
        return sb.toString();
    }

    public static boolean isIso7816Model(int model) {
        if ((Win32CardDll.card_ModelCAsync == model) || (Win32CardDll.card_ModelCIsoEh == model)) {
            return true;
        }
        return false;
    }

    public static boolean isContactModel(int model) {
        if ((Win32CardDll.card_ModelCAsync == model) || (Win32CardDll.card_ModelCIsoEh == model) || (Win32CardDll.card_ModelCRaw == model) || (Win32CardDll.card_ModelCUsb == model)) {
            return true;
        }
        return false;
    }

    public static void main(String args[]) throws ScardException {
        System.out.println(win32CardDll);
        SmartwareTerminalManager manager = new SmartwareTerminalManager();
        manager.list();
    }

    public SmartwareTerminalManager() {
    }
    protected String getConfFileName(){
        return CONF_FILE_NAME;
    }

    @Override
    protected void loadConfigurationImpl(File argFile) throws IOException {

    }

    static final String DEFAULT_CARD_DLL="CARD";//we should offer a way to override this in future
    static final String DEFAULT_MLOSMAIN_DLL="MLOSMAIN";//we should offer a way to override this in future

    static {
        Throwable ex = null;
        Win32CardDll trial = null;
        Win32MlOsMainDll win32MlOsMainDllTrial = null;
        Win32MlOsMainDll.mloscfg_Type confTrial = null;
        try {
            Map<String, Object> options = new HashMap<String, Object>();
            //options.put(Library.OPTION_FUNCTION_MAPPER, new StdCallFunctionMapper());
            Native.setProtected(true);
            trial = (Win32CardDll) Native.loadLibrary(DEFAULT_CARD_DLL, Win32CardDll.class, options);

        } catch (Throwable e) {
            ex = e;
            trial = null;
        }
        win32CardDll = trial;

        try {
            Map<String, Object> options = new HashMap<String, Object>();
            //options.put(Library.OPTION_FUNCTION_MAPPER, new StdCallFunctionMapper());
            win32MlOsMainDllTrial = (Win32MlOsMainDll) Native.loadLibrary(DEFAULT_MLOSMAIN_DLL, Win32MlOsMainDll.class, options);
            confTrial = new Win32MlOsMainDll.mloscfg_Type();
            int status = win32MlOsMainDllTrial.mloscfg_Init(confTrial);
            if (Win32CardDll.card__Ok != status) {
                throw new SmartwareException("mloscfg_Init failed", status);
            }

            confTrial.IniPath = AStringUtilities.StringToBytesWithFinalNull("C:\\mlos.ini");
            confTrial.AppName = AStringUtilities.StringToBytesWithFinalNull("");

            status = win32MlOsMainDllTrial.mloscfg_Start(confTrial);
            if (Win32CardDll.card__Ok != status) {
                throw new SmartwareException("mloscfg_Start failed", status);
            }
        } catch (Throwable e) {
            ex = e;
            win32MlOsMainDllTrial = null;
        }
        win32MlOsMainDll = win32MlOsMainDllTrial;
        initException = ex;
        conf = confTrial;
        if (null == initException) {
            try {
                initContext();
            } catch (ScardException ex1) {
                Logger.getLogger(SmartwareTerminalManager.class.getName()).log(Level.SEVERE, null, ex1);
            }
        }
    }

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

            @Override
            public void run() {
                {
                    //release all resources
                    for (Reference<SmartwareTerminal> tRef : terminals.values()) {
                        try {
                            SmartwareTerminal t = tRef.get();
                            if(null==t) continue;
                            if(null==t.card) continue;
                            int status = win32CardDll.card_Close(t.card);
                            if (Win32CardDll.card__Ok != status) {
                                throw new SmartwareException("card_Close failed", status);
                            }
                        } catch (SmartwareException ex) {
                            Logger.getLogger(SmartwareTerminalManager.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }
        });
    }

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

        try {
            GenericTerminal terminal = getTerminalImpl(Win32CardDll.card_ModelCIsoEh, Win32CardDll.sys_CdId);
            terminalsList.add(terminal);
        } catch (ScardException e) {
        }

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

    protected static GenericTerminal getTerminalImpl(int model, int couplerId) throws ScardException {

        String name = couplerId2Name(model, couplerId);
        Reference<SmartwareTerminal> ref = terminals.get(name);
        SmartwareTerminal terminal = (ref != null) ? ref.get() : null;
        if (terminal != null) {
            return terminal;
        }

        Win32CardDll.card_Type card = new Win32CardDll.card_Type();
        int status = win32CardDll.card_Open(card, model, couplerId);
        if (Win32CardDll.card__Ok != status) throw new SmartwareException("card_Open failed", status);
        //card.timeout=3*60*1000;//3 minutes as timeout
        card.timeout = 1000;//1s as timeout

        //System.out.println(card);

        card_CfgXType configX = new card_CfgXType();
        configX.StructSize = configX.size();//SIZEOF_CARD_CFGXTYPE;  // Initialize StructSize Field
        configX.Mask = 0;
        status = win32CardDll.card_CardCfgX(card, configX);    // Read the current configuration
        if (Win32CardDll.card__Ok != status) throw new SmartwareException("card_CardCfgX failed", status);
        //System.out.println("WI="+configX.WI+", WWT="+configX.WWT);

        configX.N = 255;//12ETU for T=0 and 11ETU for T=1
        configX.ODMT = 12;//12ETU in case of direction change
        configX.TSWT = 400;//ATR should start not before 400cycles after reset release
        configX.RSTWT = 0;//no waiting time after ATR
        configX.RSTMode = 0x03;//keep card activated even if ATR is invalid and return the invalid ATR
        configX.PPSGT = 0;//no waiting time after PPS
        configX.Mask = (win32CardDll.card_CfgxN | win32CardDll.card_CfgxODMT | win32CardDll.card_CfgxTSWT | win32CardDll.card_CfgxRSTWT | win32CardDll.card_CfgxRSTMode | win32CardDll.card_CfgxPPSGT);
        configX.Mask = 0;
        status = win32CardDll.card_CardCfgX(card, configX);    // Update parameters
        if (Win32CardDll.card__Ok != status) throw new SmartwareException("card_CardCfgX failed", status);
       

        //System.out.println(card);

        terminal = new SmartwareTerminal(card, model, couplerId, name);
        terminals.put(name, new WeakReference<SmartwareTerminal>(terminal));

        return terminal;
    }

    static void SCardSetVdd(card_Type card, int vddMillivolts) throws ScardException {
        int status = win32CardDll.card_VccDef(card, vddMillivolts);
        if (Win32CardDll.card__Ok != status) {
            throw new SmartwareException("card_VccDef failed", status);
        }
    }

    static void SCardSetClk(card_Type card, int clkHertz) throws ScardException {
        int status = win32CardDll.card_FreqXDef(card, clkHertz / 1000);
        if (Win32CardDll.card__Ok != status) {
            throw new SmartwareException("card_FreqXDef failed", status);
        }
    }

    static int SCardGetClk(card_Type card) throws SmartwareException {
        int clkHertz[] = new int[1];
        int status = win32CardDll.card_FreqXGet(card, clkHertz);
        if (Win32CardDll.card__Ok != status) {
            throw new SmartwareException("card_FreqXGet failed", status);
        }
        return clkHertz[0] * 1000;
    }

    static AnswerToReset SCardConnect(card_Type card, int protocol, int activation, boolean autoPps) 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));
        }

        int status;

        if (GenericTerminal.ACTIVATION_FORCE_COLD == activation) {
            status = win32CardDll.card_Reset(card);
            if (Win32CardDll.card__Ok != status) {
                throw new SmartwareException("card_Reset failed", status);
            }
        } else {
            status = win32CardDll.card_ResetWarm(card);
            if (Win32CardDll.card__Ok != status) {
                throw new SmartwareException("card_ResetWarm failed", status);
            }
        }
        //status=win32CardDll.card_CardCfgX(card, configX);    // get parameters
        //System.out.println("WI="+configX.WI+", WWT="+configX.WWT);

        AnswerToReset out = new AnswerToReset(card.ATR, 0, card.ATRLg);

        //System.out.println("ATR:" + out.toString());
        int fiDi = out.getSupportedFiDi();
        if(autoPps && out.acceptPps() && (out.getSupportedFiDi()!=0x11)){
            int pLngOut[] = new int[1];
            pLngOut[0] = 10;
            byte ppsBuf[] = new byte[pLngOut[0]];
            ppsBuf[0] = (byte) 0xFF;
            if (GenericTerminal.PROTOCOL_T_1 == protocol) {
                ppsBuf[1] = 0x11;
            } else {
                ppsBuf[1] = 0x10;
            }
            ppsBuf[2] = (byte) fiDi;
            for (int i = 3; i < ppsBuf.length; i++) {
                ppsBuf[i] = 0;
            }
            status = win32CardDll.card_PTSX(card, ppsBuf, 3, pLngOut);
            if (Win32CardDll.card__Ok != status) {
                throw new SmartwareException("card_PTSX failed", status);
            }

            //System.out.println("PPS response:" + AStringUtilities.bytesToHex(ppsBuf, 0, pLngOut[0]));
        }

        return out;
    }

    static public int getStatusWord(card_Type card) {
        int out = 0xFF & card.SW1;
        out = out << 8;
        out |= 0xFF & card.SW2;
        return out;
    }

    static Apdu.CardResponse SCardTransmit(card_Type card, Apdu apdu) throws ScardException {
        Apdu.CardResponse out;

        int tpduLe = apdu.getExpectedLe();
        byte[] leData = new byte[tpduLe];
        if (256 == tpduLe) {
            tpduLe = 0;
        }
        int actualTpduLeRef[] = new int[1];

        byte[] lcData = apdu.getLcDataAsBytes();
        byte tpduLc = (byte) (lcData.length & 0xFF);
        int apduCase = apdu.getIsoApduCase();
        int status;
        long start = System.nanoTime();

        int timeoutBu = card.timeout;
        card.timeout = 3 * 60 * 1000;//3 minutes as timeout
        try {
            switch (apduCase) {
                case Apdu.CASE1:
                case Apdu.CASE3S:
                    status = win32CardDll.card_InXH(card,
                            (byte) apdu.getCla(),
                            (byte) apdu.getIns(),
                            (byte) apdu.getP1(),
                            (byte) apdu.getP2(),
                            tpduLc, lcData);
                    if (Win32CardDll.card__Ok != status) {
                        throw new SmartwareException("card_InXH failed, time from start of APDU to failure:" + ATimeUtilities.getUserFriendlyTimeUs(System.nanoTime() - start), status);
                    }
                    out = new Apdu.CardResponse(getStatusWord(card));
                    break;
                case Apdu.CASE2S:
                    status = win32CardDll.card_OutXH(card,
                            (byte) apdu.getCla(),
                            (byte) apdu.getIns(),
                            (byte) apdu.getP1(),
                            (byte) apdu.getP2(),
                            (byte) tpduLe, leData, actualTpduLeRef);
                    if (Win32CardDll.card__Ok != status) {
                        throw new SmartwareException("card_InXH failed, time from start of APDU to failure:" + ATimeUtilities.getUserFriendlyTimeUs(System.nanoTime() - start), status);
                    }
                    int actualTpduLe = actualTpduLeRef[0];
                    if (actualTpduLe != apdu.getExpectedLe()) {
                        byte[] actualLeData = new byte[actualTpduLe];
                        for (int i = 0; i < actualTpduLe; i++) {
                            actualLeData[i] = leData[i];
                        }
                        leData = actualLeData;
                    }
                    out = new Apdu.CardResponse(leData, getStatusWord(card));
                    break;
                default:
                    throw new ScardException("Apdu case not supported: 0x" + Integer.toHexString(apduCase));
            }
        } finally {
            card.timeout = timeoutBu;
        }

        return out;
    }

    static void SCardDisconnect(card_Type card) throws SmartwareException {
        int status = win32CardDll.card_Off(card);
        if (Win32CardDll.card__Ok != status) {
            throw new SmartwareException("card_Off failed", status);
        }
    }

    static GenericTerminal.State SCardIsPresent(card_Type card) throws ScardException {
        int value[] = new int[1];
        int status = win32CardDll.card_DetectGet(card, value);
        if (Win32CardDll.card__Ok != status) {
            throw new SmartwareException("card_DetectGet failed", status);
        }
        GenericTerminal.State out;
        switch (value[0]) {
            case 0:
                out = GenericTerminal.State.CARD_ABSENT;
                break;
            case 1:
                out = GenericTerminal.State.CARD_PRESENT;
                break;
            default:
                throw new ScardException("card_DetectGet returned a unsupported value: " + value[0]);
        }
        return out;
    }
}
TOP

Related Classes of uk.co.nimp.scard.SmartwareTerminalManager$Win32CardDll$card_CfgXType

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.