試してみたブログ

AI関連・iPhone/Pixelなどのガジェット・音声入力・サーマルプリンタなど興味をある事をどんどん試してみた際の記録

家の家計簿を見直す

背景

  • 今まで月に1度、レシートをベースに紙の家計簿につけていた
  • 家計簿がいっぱいになったのでデジタル化を進めたい

試してみた

  • moneyfoward meに集約する
  • クイックペイで払った物がレシートと二重計上になってしまう・・
  • 同じカードを使ってたりするので、見せたくない物も出てしまう
  • 運用をもう少し考える

dbtのカラムリネージを作った

背景

  • dbtのリネージはすごい便利だが、カラムレベルまで追えなくて困っていた

tameshitemita.blog

  • 上記でBQでやろうと思っていたが、なかなか社内での調整が出来ず、作る事にした

試してみた

  • ClaudeCodeで作成
  • CLIで動作するようにツリー状で上流・下流が出る様にした
  • 詰まったポイントとしては、structネストされたカラムのリネージは、SQLファイルを手動で追跡処理をいれる必要があった

Santek EZ Sign NFC電子ペーパーディスプレイをMacで使うのにPaSoRiの何が問題だったか

tameshitemita.blog

(AIに記事書かせています)

PaSoRi RC-S300 で NFC e-ink ディスプレイのリフレッシュができない問題と原因

TL;DR

Sony PaSoRi RC-S300 を macOS で使って NFC 電子ペーパー(Santek EZ Sign NFC)に画像を書き込むことはできるが、画面リフレッシュコマンド(約24秒かかる)がタイムアウトで失敗する。原因は PaSoRi の CCID ドライバが NFC の WTX(Waiting Time Extension)フレームを host に伝播しないため。Android では問題なく動作する。


背景

EZ Sign NFC は NFC 経由で画像データを転送できる e-ink ディスプレイだ。公式アプリは Android/iOS のみ対応なので、Mac + PaSoRi RC-S300 で PC から直接書き込めるツールを Python(pyscard)で自作した。

画像データの転送(F0D3 コマンド)までは完璧に動く。問題はその後の 画面リフレッシュ だった。

何が起きるか

NFC プロトコルでの画面更新は2段階になっている:

F0D4058000  → 68C6(リフレッシュ準備OK)
F0D4850000  → 9000(約24秒後、リフレッシュ完了)

2つ目の F0D4850000 は e-ink パネルの物理的な画面書き換えをトリガーする。4色モデルでは完了まで約24秒かかり、その間 NFC タグは応答を返さない。

Android の NFC スタックでは、タグが NFC レイヤの WTX(Waiting Time Extension)フレーム を送信し、ホスト側がそれを受け入れて接続を維持する。結果として24秒後に 9000(成功)が返ってくる。

一方、Mac + PaSoRi では 約5秒でタイムアウトして Transaction failed になる

原因:CCID ドライバの WTX 非対応

NFC カード(ISO 14443-4 / ISO-DEP)が長時間の処理を行う場合、カードはホストに対して WTX フレームを送信して「まだ処理中だから待って」と伝える。

通常の流れ:

Host → Card: F0D4850000(リフレッシュ実行)
Card → Host: WTX request(まだ処理中)
Host → Card: WTX response(了解、待つ)
  ... 24秒間、WTX のやり取りが繰り返される ...
Card → Host: 9000(完了)

PaSoRi RC-S300 は USB CCID(Chip/Smart Card Interface Devices)プロトコルでホストと通信するが、WTX フレームをカードから受信しても、それを USB 側の host に伝えない(あるいはそもそも処理しない)

これは PaSoRi 固有の問題ではなく、CCID ドライバの非対応リーダーリストでも複数のリーダーで「Time extension requests を host に伝播しない」問題が報告されている。

試したこと(全滅)

1. PC/SC の transmit タイムアウト延長

pyscard の connection.transmit() はデフォルトで CCID ドライバのタイムアウトに従う。Python 側でいくら待とうとしても、CCID レイヤで切断される。

結果: 約5秒でタイムアウト。

2. USB 直接通信(pyusb) + bBWI 最大値

PC/SC を迂回し、pyusb で PaSoRi に直接 CCID メッセージを送る方式。CCID の PC_to_RDR_XfrBlock メッセージの bBWI(Block Waiting Time Integer)を 0xFF(最大値)に設定して送信した。

header = struct.pack('<BIBBBH',
    0x6F,   # PC_to_RDR_XfrBlock
    len(apdu),
    0,      # bSlot
    seq,    # bSeq
    0xFF,   # bBWI = 最大待ち時間
    0x0000, # wLevelParameter
)

USB の read タイムアウトも60秒に設定。

結果: ICC_MUTE(カード無応答)が返る。PaSoRi は bBWI パラメータを無視していると考えられる。

3. タイムアウト後に再接続 + ステータスポーリング

F0D4850000 がタイムアウトした後、25秒待ってからカードを再起動(ICC Power On)し、PIN 再認証してから F0DE(ステータスポーリング)コマンドを送る方式。

# 25秒待機
time.sleep(25)
# カード再接続
ccid_power_on(ep_out, ep_in, seq)
# PIN 再認証
ccid_send(ep_out, ep_in, bytes.fromhex("002000010420091210"), seq)
# ポーリング
ccid_send(ep_out, ep_in, bytes.fromhex("F0DE000001"), seq)

結果: ポーリングは通るが、019000(処理中)が永続し、009000(完了)に到達しない。タイムアウトでの切断がリフレッシュプロセス自体を中断してしまっている可能性が高い。

4. 5秒間隔で再接続リトライ

タイムアウト後に何度も再接続して F0D4850000 を再送する方式。

結果: 毎回タイムアウト。リフレッシュが途中で中断されるため、画面が中途半端な状態になる。

結論:PaSoRi では解決不可能

問題は PaSoRi のファームウェアレベルにある。ソフトウェア側でできることは何もない。

根本的な解決策: - WTX に対応した NFC リーダーに変える(ACR1252U 等、ただし要検証) - Windows で試す(公式アプリが Windows + PaSoRi で動作するため、Windows の CCID ドライバは WTX を処理できる可能性がある)

実用的な回避策

現在は「Mac で画像書き込み、Android でリフレッシュ」という二段構えで運用している。

Step 1: Mac で画像データを書き込む

python write_only.py image.png

F0D3(データ転送)は数秒で完了するので PaSoRi で問題ない。最後に F0D4058000 → 68C6 が返ればデータ書き込み成功。

Step 2: Android でリフレッシュを実行

Android スマホの NFC で EZ Sign にタッチし、以下のコマンドを送信:

002000010420091210  → 9000(PIN認証)
F0D4058000          → 68C6(リフレッシュ開始)
F0D4850000          → 9000(24秒後、リフレッシュ完了)

自作の Flutter アプリか、APDU Sender Contactless で送信できる。

学び

  • NFC リーダーは「NFC が読める」だけでは足りない。長時間応答を待つユースケースでは WTX 対応 が必須
  • CCID 仕様上 bBWI でタイムアウトを制御できるはずだが、実装がそれを尊重するかはリーダー次第
  • USB レベルで直接 CCID メッセージを組み立てても、ファームウェアが対応していなければ意味がない
  • 「PC/SC で動く」と「長いトランザクションが通る」は別の話

参考リンク

Santek EZ Sign NFC電子ペーパーディスプレイを買ったのでmacから書き込みをしてみる

背景

  • 下記の製品を買った

Santek EZ Sign® NFC電子ペーパーディスプレイ|2.9/4.2インチ 4色表示|電池不要・IP65防塵防水santekdisplay.com

  • アプリでの画像読み込みが重く、何度もアプリ再起動したりした
  • mac上でclaude codeでサクッと画面の作成をして転送したい

試してみた

  • まずはmacでNFCを読める様にNFCリーダーを購入

www.sony.co.jp

  • androidを繋いでアプリからリバースエンジニアリング
  • macからpasoriを使って書き込みが出来る様に変更
  • リフレッシュの部分で問題が出て2時間ほど費やす

より早くする為に

  • 最初からandroidのキャプチャを実施すべきだった
    • このせいで割と出戻りが多かった
  • type-cの変換アダプタが1個しかなかったのでもう1個常備する
  • 実行ログを都度貼り付けていたので、実行時にファイルに残す様にしてそこを見て貰う様にする

結果

  • 結局、macとpasoriのデバイス上の制限で思った物は作れなかった
  • androidアプリでリフレッシュを実施する必要がある
    • androidアプリはリフレッシュ専用アプリを作ったので思った物を作ってmacで書き込んで、androidリフレッシュのみする運用
  • 次回NFCリーダーを買うときは仕様を確認する

技術書典20をチェックする

techbookfest.org

  • 今日から開催されている
  • オンラインでも本が買える
  • 遠方なので行けないが本をチェックしていきたい

気になった本

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

techbookfest.org

あとで買う