¥È¥Ã¥× ¿·µ¬ ÊÔ½¸ º¹Ê¬ °ìÍ÷ ¥½¡¼¥¹ ¸¡º÷ ¥Ø¥ë¥× PDF RSS ¥í¥°¥¤¥ó

Java¤Î±þÍÑ¡§Felica¥«¡¼¥É¥ê¡¼¥À

 É¸½à¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤ÆÆÉ¤ß¼è¤ëÎã

Java SDK 1.6°Ê¹ß¤ËÄɲ䵤줿smartcardio¤Ë¤è¤Ã¤Æ³°Éô¥é¥¤¥Ö¥é¥ê¤òÍѤ¤¤º¡¢É¸½à¥¯¥é¥¹¥é¥¤¥Ö¥é¥ê¤Î¤ß¤Ë¤è¤Ã¤ÆFelica¥«¡¼¥ÉÅù¤ÎIDm¤òÆÉ¤ß¼è¤ëÎã

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package sample.nfc;

import javax.smartcardio.Card;
import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.CommandAPDU;
import javax.smartcardio.ResponseAPDU;
import javax.smartcardio.TerminalFactory;
import javax.xml.bind.DatatypeConverter;

public class SmartCardReader implements Runnable {
    private CardTerminal terminal;
    private Card card;
    private static byte[] readUID = { (byte) 0xFF, (byte) 0xCA, (byte) 0x00, (byte) 0x00, (byte) 0x04 };    //IDm¤òÆÉ¤à¤¿¤á¤Î¡©
    public SmartCardReader() {
        try {
            terminal = TerminalFactory.getDefault().terminals().list().get(0);    //°ìÂæÌܤò·è¤áÂǤÁ
        } catch (CardException e) {
            System.err.println("ÆÉ¤ß¼è¤êµ¡¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿");
            System.exit(-1);
        }
    }
    public String readIDm() throws CardException{
        try {
            card = terminal.connect("*");
            ResponseAPDU response = card.getBasicChannel().transmit(new CommandAPDU(readUID));
            return DatatypeConverter.printHexBinary(response.getData());    //byte[]¤òʸ»úÎó¤ËÊÑ´¹
        } finally {
            card.disconnect(false);    //Îã³°¤¬È¯À¸¤·¤Æ¤â¤È¤ê¤¢¤¨¤ºÀܳ¤òÀÚ¤ë
        }
    }
    @Override
    public void run() {
        //¥«¡¼¥É¤¬ÃÖ¤«¤ì¤Æ¡¢¼è¤é¤ì¤ë¤Þ¤Ç¤Î°ìÏ¢¤ò¤Ò¤È¤Þ¤È¤á¤Ë¤·¤Æ¤¤¤ë¤¬¡¢´¶Å٤ˤè¤ê¡¢°ì¤Ä¤Î¥«¡¼¥É¤Ë¤Ä¤¤¤ÆÃ»´ü´Ö¤ËϢ³¤·¤Æµ¯¤³¤ë²ÄǽÀ­¤¬¤¢¤ë¤³¤È¤òÁÛÄꤹ¤Ù¤­
        while(true) {
            try {
                terminal.waitForCardPresent(0);
                System.out.println(readIDm());
                terminal.waitForCardAbsent(0);
            } catch (CardException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        //̵¸Â¥ë¡¼¥×¥¹¥ì¥Ã¥É¤Ç¥«¡¼¥É¤¬ÃÖ¤«¤ì¤¿»þ¤ËIDm¤òɽ¼¨¤¹¤ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó
        Thread thread = new Thread(new SmartCardReader());
        thread.start();
    }
}

 Felica¥«¡¼¥É¥ê¡¼¥À

  • C¤Ç½ñ¤«¤ì¤¿DLL(¥À¥¤¥Ê¥ß¥Ã¥¯¥ê¥ó¥¯¥é¥¤¥Ö¥é¥ê)¤Ç¤¢¤ëfelicalib.dll¤ËJNA(Java Native Access)¥é¥¤¥Ö¥é¥ê¤òÍøÍѤ·¤Æ¥¢¥¯¥»¥¹¤¹¤ëÎã

Felica¥¯¥é¥¹

  • felicalib.dll¤Î¥é¥Ã¥Ñ¡¼(wrapper)¥¯¥é¥¹¡£
  • ²¼¤ÎÎã¤ËɬÍפÊÉôʬ¤Î¤ß¤·¤«¼ÂÁõ¤·¤Æ¤¤¤Ê¤¤¡£
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package felica;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;

public class Felica {
    final public static short WILDCARD = (short) 0xFFFF;        // ¥ï¥¤¥ë¥É¥«¡¼¥É
    final public static short SUICA = 0x03;
    public interface FelicaLib extends Library {
        FelicaLib INSTANCE = (FelicaLib) Native.loadLibrary("felicalib",
                FelicaLib.class);
        Pointer pasori_open(String dummy);
        int pasori_init(Pointer pasoriHandle);
        void pasori_close(Pointer pasoriHandle);
        Pointer felica_polling(Pointer pasoriHandle, short systemCode, byte rfu, byte time_slot);
        void felica_free(Pointer felicaHandle);
        void felica_getidm(Pointer felicaHandle, byte[] data);
        void felica_getpmm(Pointer felicaHandle, byte[] data);
        int felica_read_without_encryption02(Pointer felicaHandle, int serviceCode, int mode, byte addr, byte[] data);
    }
    @SuppressWarnings("serial")
    public class FelicaException extends Exception{
        public FelicaException(String string) {
            super(string);
        }
    }
    Pointer pasoriHandle;
    Pointer felicaHandle;
    /**
     * ¥³¥ó¥¹¥È¥é¥¯¥¿¡£¤³¤³¤ÇFelica¥«¡¼¥É¥ê¡¼¥À¤Ø¤Î¥Ï¥ó¥É¥ë¤ò¼èÆÀ¤·¤Æ¤¤¤ë
     * @throws FelicaException
     */
    public Felica() throws FelicaException {
        pasoriHandle = FelicaLib.INSTANCE.pasori_open(null);
        if(pasoriHandle==null) {
            throw new FelicaException("felicalib.dll¤ò³«¤±¤Þ¤»¤ó");
        }
        if(FelicaLib.INSTANCE.pasori_init(pasoriHandle)!=0) {
            throw new FelicaException("PaSoRi¤ËÀܳ¤Ç¤­¤Þ¤»¤ó");
        }
    }
    /**
     * Felica¥«¡¼¥É¥ê¡¼¥À¤Ë´Ø¤¹¤ë½èÍý¤ò½ªÎ»¤¹¤ë¤µ¤¤¤Ë¸Æ¤Ö¥á¥½¥Ã¥É
     */
    public void close(){
        if(felicaHandle!=Pointer.NULL) {
            FelicaLib.INSTANCE.felica_free(felicaHandle);
        }
        if(pasoriHandle!=Pointer.NULL) {
            FelicaLib.INSTANCE.pasori_close(pasoriHandle);
        }
    }
    public void polling(short systemCode) throws FelicaException{
        FelicaLib.INSTANCE.felica_free(felicaHandle);
        felicaHandle = FelicaLib.INSTANCE.felica_polling(pasoriHandle, systemCode, (byte)0, (byte)0);
        if(felicaHandle==Pointer.NULL) {
            throw new FelicaException("¥«¡¼¥ÉÆÉ¤ß¼è¤ê¼ºÇÔ");
        }
    }
    public byte[] getIDm() throws FelicaException{
        if(felicaHandle==Pointer.NULL) {
            throw new FelicaException("no polling executed.");
        }
        byte[] buf = new byte[8];
        FelicaLib.INSTANCE.felica_getidm(felicaHandle, buf);
        return buf;
    }
    
    /**
     * Felica¥«¡¼¥É¤ÎIDÈÖ¹æ¤ò¼èÆÀ¤¹¤ë¥á¥½¥Ã¥É
     * @param systemCode ¥·¥¹¥Æ¥à¥³¡¼¥É(Î㤨¤ÐSuica¤Ï0x03¡¢¥ï¥¤¥ë¥É¥«¡¼¥É¤Ï0xFF)
     * @return ¥«¡¼¥É¤ÎIDÈֹ桩
     * @throws FelicaException
     */
    public String getID(short systemCode) throws FelicaException {
        FelicaLib.INSTANCE.felica_free(felicaHandle);
        felicaHandle = FelicaLib.INSTANCE.felica_polling(pasoriHandle, systemCode, (byte)0, (byte)0);
        if(felicaHandle==Pointer.NULL) {
            throw new FelicaException("¥«¡¼¥ÉÆÉ¤ß¼è¤ê¼ºÇÔ");
        }
        byte[] buf = new byte[8];
        FelicaLib.INSTANCE.felica_getidm(felicaHandle, buf);
        return String.format("%02X%02X%02X%02X%02X%02X%02X%02X", buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]);
    }
    /**
     * ¥á¥¤¥ó´Ø¿ô¡£¤³¤ì¤À¤±¤ÇÆÉ¤ß¼è¤ê¥Æ¥¹¥È¤ò¹Ô¤¦¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë50ÉÃ´ÖÆÉ¤ß¼è¤ê¤ò»î¤ß¤ë
     * @param args ¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó
     * @throws FelicaException
     */
    public static void main(String[] args) throws FelicaException {
        Felica felica = new Felica();
        for(int i=0;i<10;i++) {
            try {
                System.out.println(i+":"+felica.getID((short)0xFF));
            } catch (FelicaException e) {    //ÆÉ¤ß¼è¤ì¤Ê¤«¤Ã¤¿¤é¤½¤Î¤Þ¤Þ
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        felica.close();
    }
}

FelicaIdReader¥¯¥é¥¹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package felica;

import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;

import felica.Felica.FelicaException;

@SuppressWarnings("serial")
public class FelicaIdReader extends JFrame {
    private Felica felica;
    private JLabel label = new JLabel("ID=????????????????");
    boolean active = true;

    public FelicaIdReader() {
        super("¥Õ¥§¥ê¥«¥«¡¼¥É¥ê¡¼¥À");
        try {
            felica = new Felica();
        } catch (FelicaException e) {
            System.err.println("¥Õ¥§¥ê¥«¥«¡¼¥É¥ê¡¼¥À¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤»¤ó");
            System.exit(-1);
        }
        // ½ªÎ»»þ½èÍý¤ÎÄɲÃ
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                active = false;
                synchronized (felica) {
                    felica.close();
                }
                System.exit(0);
            }
        });
        add(label);
        pack();
        // ID¤¬Á´Éôɽ¼¨¤µ¤ì¤Ê¤¤¤³¤È¤â¤¢¤ë¤¿¤á¡¢Éý¤òÊѹ¹¤¹¤ë
        Dimension dim = getPreferredSize();
        if (dim.getWidth() < 200) {
            setPreferredSize(new Dimension(200, (int) dim.getHeight()));
            pack();
        }
        setVisible(true);
        // Felica¥«¡¼¥É¤ÎÆÉ¤ß¼è¤ê¥ë¡¼¥×
        String Id = null;
        while (active) {
            try {
                Id = felica.getID(Felica.WILDCARD);
            } catch (FelicaException e) {
                Id = null;
            }
            if (Id != null) {
                label.setText("id=" + Id);
            } else {
                label.setText("¸½ºß¥«¡¼¥É¤ÏÃÖ¤«¤ì¤Æ¤¤¤Þ¤»¤ó");
            }
            try {
                Thread.sleep(500); // 0.5É䪤­¤ËÆÉ¤ß¼è¤ê
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new FelicaIdReader();
    }
}

 »²¹Íʸ¸¥

¥é¥¤¥Ö¥é¥ê

¥½¥Õ¥È

¾ðÊó¸»

Java Native Access

Felica.java FelicaIdReader.java SmartCardReader.java chrome_material_200_percent.pak

ºÇ½ª¹¹¿·»þ´Ö¡§2016ǯ07·î21Æü 22»þ56ʬ29ÉÃ