ɸ½à¥é¥¤¥Ö¥é¥ê¤Ë¤è¤Ã¤ÆÆÉ¤ß¼è¤ëÎã
Java SDK 1.6°Ê¹ß¤ËÄɲ䵤줿smartcardio¤Ë¤è¤Ã¤Æ³°Éô¥é¥¤¥Ö¥é¥ê¤òÍѤ¤¤º¡¢É¸½à¥¯¥é¥¹¥é¥¤¥Ö¥é¥ê¤Î¤ß¤Ë¤è¤Ã¤ÆFelica¥«¡¼¥ÉÅù¤ÎIDm¤òÆÉ¤ß¼è¤ëÎã
1 |
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 |
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 |
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();
}
} |
»²¹Íʸ¸¥
¥é¥¤¥Ö¥é¥ê
- libpasori
- felicalib
¥½¥Õ¥È
- PeopleLogOnFeliCaÂбþÈÇ
¾ðÊó¸»
- ¢£¡þFeliCa ¤Ç¥½¥Õ¥È¤òºî¤ê¤Þ¤¯¤ë¥¹¥ì¡þ¢£
- tadaogi@Wiki Felica Programming
Java Native Access
- Java Native Access
- The Other Road Ahead
ºÇ½ª¹¹¿·»þ´Ö¡§2016ǯ07·î21Æü 22»þ56ʬ29ÉÃ