しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Surface Go に内蔵されている NFC を試した

理由は分からないですが、何故か Surface Go には NFC が内蔵されています。しかし、今のところ使い道が無いらしく、本当にチップが載っているだけのようです。

こんな面白そうなチップが付いているのにもったいないと思ったので、UWP に用意されている SmartCard 周りの API を使って読み込みを行ってみます。

NFC 周りのサンプルコードは Microsoft から公式で公開されています。

iFixit の分解レポートやデバイスマネージャーを確認した限りでは NXP P3003 というチップが載っているみたいですが、情報が全くないので実際にいろんなカードをかざしてみるしか方法が無かったです。

とりあえず読み込みだけを試したかったので、非常に雑なコードを書いて Surface Go にデプロイしました。

Visual Studio を Surface Go にはインストールしていないですが、開発者モードにしておくと他の Visual Studio からリモートデバッグ出来るので便利です。

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    var deviceSelector = SmartCardReader.GetDeviceSelector(SmartCardReaderKind.Nfc);

    var devices = await DeviceInformation.FindAllAsync(deviceSelector);

    var device = devices.FirstOrDefault();

    if (device == null)
    {
        return;
    }

    var reader = await SmartCardReader.FromIdAsync(device.Id);

    if (reader == null)
    {
        return;
    }

    reader.CardAdded += Reader_CardAdded;
    reader.CardRemoved += Reader_CardRemoved;
}

private async void Reader_CardAdded(SmartCardReader sender, CardAddedEventArgs args)
{
    await AddLogAsync($"{DateTime.Now} - CardAdded");

    using (var connection = await args.SmartCard.ConnectAsync())
    {
        var iccDetection = new IccDetection(args.SmartCard, connection);

        await iccDetection.DetectCardTypeAync();

        await AddLogAsync($"{DateTime.Now} - CardName = {iccDetection.PcscCardName}");
        await AddLogAsync($"{DateTime.Now} - DeviceClass = {iccDetection.PcscDeviceClass}");
    }
}

private async void Reader_CardRemoved(SmartCardReader sender, CardRemovedEventArgs args)
{
    await AddLogAsync($"{DateTime.Now} - CardRemoved");
}

PC/SC SDK はサンプルコードと同じリポジトリにあったので、それを使いました。

ちなみに NFC のチップが付いている場所が少し分かりにくかったです。画面側からは反応しなかったのでカードを持って探したところ、裏面のカメラ左側あたりにカードを持っていくと読み込むことが出来ました。

今回用意したカードは以下の通りです。仕様的には全部用意できた気がします。

  • マイナンバーカード (NFC-B)
  • Kitaca (NFC-F)
  • e-AMUSEMENT PASS (旧型, NFC-V)
  • Aime (NFC-A)
  • NESiCA (NFC-A)

これらのカードを Surface Go にかざしていきましたが、読み込めたカードは以下の通りです。ぶっちゃけ、かなり予想外の結果となりました。

  • e-AMUSEMENT PASS
  • NESiCA

FeliCa の対応は正直期待していなかったですが、Type B も読み込めず Type A に関しても一部の仕様の場合のみ読み込みが可能でした。このままだと使い道が本気でなさそうです。

実際に読み込んだカードの情報をログを出していたので、それも載せておきます。

NESiCA は MIFARE UltraLight と認識されて、無事に読み込みが出来ました。e-AMUSEMENT PASS は聞きなれない I-CODE SLI として読み込まれました。

せめて FeliCa の非暗号化領域や Type B が読めれば、多少なりとも活用の方法が見つかりそうだったのですが、今の挙動では本気で使い道が無さそうです。ドライバレベルで対応できれば最高なのですが、この感じでは期待できないでしょう。