LoginSignup
11
10

More than 5 years have passed since last update.

Windows+GoでNFC/Felicaにアクセスしてみた

Last updated at Posted at 2015-12-14

概要

Goでfelicalib.dllを使ってIDM/PMMを取得するサンプル。
ソース自体はDLLの呼び出しをしてるだけなので、どちらかと言えば覚書。
(felicalib.dllに対するパスがハードコーディングされてるので修正してください。)

必要なもの

サンプルコード

nfc-sample.go
package main

import (
    "log"
    "syscall"
    "unsafe"
)

func main() {
    // ここにfelicalib.dllのパスを入力。
    var tPath = "D:/tools/felicalib-0.4.2/felicalib.dll"

    dll, err := syscall.LoadDLL(tPath)
    if err != nil {
        log.Fatal(err)
    }
    defer dll.Release()

    // define procedures
    pasori_open, err := dll.FindProc("pasori_open")
    if err != nil {
        log.Fatal(err)
    }
    pasori_close, err := dll.FindProc("pasori_close")
    if err != nil {
        log.Fatal(err)
    }
    pasori_init, err := dll.FindProc("pasori_init")
    if err != nil {
        log.Fatal(err)
    }
    felica_polling, err := dll.FindProc("felica_polling")
    if err != nil {
        log.Fatal(err)
    }
    felica_free, err := dll.FindProc("felica_free")
    if err != nil {
        log.Fatal(err)
    }
    felica_getidm, err := dll.FindProc("felica_getidm")
    if err != nil {
        log.Fatal(err)
    }
    felica_getpmm, err := dll.FindProc("felica_getpmm")
    if err != nil {
        log.Fatal(err)
    }
//  felica_read_without_encryption02, err := dll.FindProc("felica_read_without_encryption02")
//  if err != nil {
//      log.Fatal(err)
//  }

    // errorチェックは、第一返り値の結果を判定
    // 第三返り値(lastErr)はいつもsuccess
    // lastErr != nilでチェックすると、successのときも値が入っている。
    tPasori, _, _ := pasori_open.Call(0)
    println("open", tPasori)
    if(tPasori == uintptr(0)) {
        log.Fatal("多分、端末が接続されてない")
    }
    defer pasori_close.Call(tPasori)

    ret, _, _ := pasori_init.Call(tPasori)
    println("init", ret)
    if(ret != 0) {
        log.Fatal("エラー出ることあるの?")
    }

    // tFelicaは、C側で内部的にメモリ確保されてる。
    // 従って多分開放しないと駄目
    tFelica, _, _ := felica_polling.Call(tPasori, 0xFFFF, 0, 0)
    println("poll", tFelica)
    if(tFelica == uintptr(0)) {
        log.Fatal("NFCカードの読み込み失敗。")
    }
    defer felica_free.Call(tFelica)

    // tFelicaで確保されえいる領域の一部を取得する。
    // 従って、失敗することはまずない。
    tIdm := uint64(1) // make([]byte, 8) ほんとはbyte[8]で取りたいんだけど、ちょいやり方不明orz
    felica_getidm.Call(tFelica, uintptr(unsafe.Pointer(&tIdm)))
    println("gIdm", tIdm)

    tPmm := uint64(1)
    felica_getpmm.Call(tFelica, uintptr(unsafe.Pointer(&tPmm)))
    println("gPmm", tPmm)
}
11
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10