Newer
Older
CardRegister / src / hayashi / yuu / pasori / felica / Felica.java
@yuuhayashi yuuhayashi on 26 Jan 2014 5 KB version 2010-03-19
package hayashi.yuu.pasori.felica;

import com.sun.jna.Pointer;

/**
 * このプログラムのソースは、
 * [亜細亜大学であがたが行う授業に関するサイトです。]から流用したものです。
 * 	http://itasan.mydns.jp/wiki.cgi/ASIA?page=Java%A4%CE%B1%FE%CD%D1%A1%A7Felica%A5%AB%A1%BC%A5%C9%A5%EA%A1%BC%A5%C0#p0
 *
 * プログラムの実行には、
 * 		[Java Native Access (jna.jar)]
 * 			< https://jna.dev.java.net/ >
 * と、
 * 		[felicalib (felicalib.dll)]
 * 			< http://felicalib.tmurakam.org/ >
 *  が、別途必要になります。
 *
 * @author hayashi
 *
 */
public class Felica
{
    final public static short WILDCARD = 0xFF;        // ワイルドカード
    final public static short SUICA = 0x03;

	/**
	 * 'PaSoRi'にかざされているFeliCaカードのIDm部分を10回読み出す。
	 * 100ms間隔で300回読む。
	 * @param args	引数はない
	 */
	public static void main(String[] args) throws Exception {
    	Felica task = new Felica();
		for (int i = 0; i < 300; i++) {
			try {
				String result = (String) task.getID(Felica.WILDCARD);
				if (result != null) {
					System.out.println(result);
				}
			}
			catch (FelicaException fe) {
				System.out.println(fe.toString());
			}

            try {
                Thread.sleep(100);	// 0.1秒間隔で読む。
            }
            catch (InterruptedException e) {}
		}
		task.close();
	}

    Pointer pasoriHandle;
    Pointer felicaHandle;

    /**
     * コンストラクタ。ここでFelicaカードリーダへのハンドルを取得している
     * @throws FelicaException
     */
    public Felica() throws Exception {
        pasoriHandle = FelicaLib.INSTANCE.pasori_open(null);
        if (pasoriHandle == null) {
            throw new Exception("felicalib.dllを開けません");
        }
        if (FelicaLib.INSTANCE.pasori_init(pasoriHandle) != 0) {
            throw new Exception("PaSoRiに接続できません");
        }
    }

    /**
     * PaSoRi ハンドルをクローズする
     * Felicaカードリーダに関する処理を終了する際に呼ぶメソッド
     * 		【 void pasori_close(pasori *p) 】
     */
    public void close() {
        if (felicaHandle != Pointer.NULL) {
            FelicaLib.INSTANCE.felica_free(felicaHandle);
        }
        if (pasoriHandle != Pointer.NULL) {
            FelicaLib.INSTANCE.pasori_close(pasoriHandle);
        }
    }

    /**
     * FeliCa をポーリングする
     * 		【 felica* felica_polling(pasori *p, uint16 systemcode, uint8 RFU, uint8 timeslot) 】
     *
     * @param systemCode
     * @throws FelicaException
     */
    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("カード読み取り失敗");
        }
    }

    /**
     * IDm 取得
     * 		【 void felica_getidm(felica *f, uint8 *buf) 】
     *
     * @return
     * @throws 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;
    }

    /**
     * PMm 取得
     * 		【 void felica_getpmm(felica *f, uint8 *buf) 】
     *
     * @return
     * @throws FelicaException
     */
    public byte[] getPMm() throws FelicaException {
        if (felicaHandle == Pointer.NULL) {
            throw new FelicaException("no polling executed.");
        }
        byte[] buf = new byte[8];
        FelicaLib.INSTANCE.felica_getpmm(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]);
    }

    /**
     * FelicaカードのPMmを取得するメソッド
     *
     * @param systemCode システムコード(例えばSuicaは0x03、ワイルドカードは0xFF)
     * @return カードのID番号?
     * @throws FelicaException
     */
    public String getPM(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_getpmm(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]);
    }
}