PaSoRiを使ってNFCで遊ぶ

## NFCリーダーについて

rc-s300では、nfcpyは対応してない(らしい)。
実際に購入してみてセットアップしてみたが、動かなかった。

今回はrc-s380を利用しています。

![IMG_5512.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955514/957cbd53-5d92-7135-f208-f745d1e2125e.jpeg)

![IMG_5513.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955514/011a5404-f2da-3432-f9a1-42ce46f93152.jpeg)

画像上がrc-s300
画像下がrc-s380

amazonで探すと上のs300が沢山出てきます。騙されないようにしましょう。
rc-s380はもう販売が終了してる　2025/2/9時点
中古やヤフオクを探しましょう

## セットアップ

セットアップなしではnfcpy君は認識してくれないのでセットアップを行う。

nfcリーダーをpcにさす

### Zadig編

Zadigをダウンロード

https://zadig.akeo.ie/#

optionsから List All Devicesを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955514/ff99a300-5767-a598-7a73-e3a738aad203.png)

接続してるnfcデバイスを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955514/19c46b5e-7103-9e7a-2b61-45eaf34595ca.png)

Reinstall Driverをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955514/2083d611-d4eb-5dbb-283c-ceff8752a84f.png)

### libusb編

libusbをダウンロードします

https://github.com/libusb/libusb/releases

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3955514/d9763130-4793-b0ed-d7cd-10deb13d08fb.png)

libusb-1.0.27.7z

私は↑を選択しました。

zipファイルなので解凍します。

```MS64\dll\libusb-1.0.dll``` を ```C:\Windows\System32``` に
```MS32\dll\libusb-1.0.dll``` を ```C:\Windows\SysWOW64``` に移動。

64bit想定で行っています。

## nfcpyライブラリのインストール

```
pip install nfcpy
```

## 実際に使ってみようちゃんねる

### 読み取り編

https://github.com/nfcpy/nfcpy

```
git clone https://github.com/nfcpy/nfcpy.git

cd nfcpy
cd examples

python tagtool.py
```

てきとうな交通系ICや学生証などのnfc機器を近づける。

```
[nfc.clf] searching for reader on path usb
[nfc.clf] using SONY RC-S380/S NFC Port-100 v1.11 at usb:001:012
** waiting for a tag **
Type3Tag ID=xxxxxxxxxxxxxx PMM=xxxxxxxxxxxx SYS=xxxx
```
このような感じで出力されたら大丈夫です

### 書き込み編

https://nfcpy.readthedocs.io/en/latest/topics/get-started.html#emulate-a-card

documentに書き込みの方法があったので利用

```
import nfc
import struct

ndef_data_area = bytearray(64 * 16) # NDEFデータエリアとしてバイト配列を初期化
ndef_data_area[0] = 0x10  # NDEFのバージョン ('1.0')
ndef_data_area[1] = 12    # 読み取り可能な最大ブロック数
ndef_data_area[2] = 8     # 書き込み可能な最大ブロック数
ndef_data_area[4] = 63    # NDEFデータが格納可能なブロック数
ndef_data_area[10] = 1    # 読み取りと書き込みの許可設定
ndef_data_area[14:16] = struct.pack('>H', sum(ndef_data_area[0:14]))  # 最初の14バイトのデータの合計値を16ビットの整数にして格納

# NDEFデータの読み取りを行う
def ndef_read(block_number, rb, re):
    if block_number < len(ndef_data_area) / 16:
        first, last = block_number*16, (block_number+1)*16
        block_data = ndef_data_area[first:last]
        return block_data

# NDEFデータの書き込み
def ndef_write(block_number, block_data, wb, we):
    global ndef_data_area
    if block_number < len(ndef_data_area) / 16:
        first, last = block_number*16, (block_number+1)*16
        ndef_data_area[first:last] = block_data
        return True
    
# NFCタグの初期化を行う関数
def on_startup(target):
    idm, pmm, sys = '03FEFFE011223344', '01E0000000FFFF00', '12FC' #ここを任意の値に変更
    target.sensf_res = bytearray.fromhex('01' + idm + pmm + sys)
    target.brty = "212F"
    return target

# NFCタグが接続されたときの処理
def on_connect(tag):
    print("tag activated")
    tag.add_service(0x0009, ndef_read, ndef_write)
    tag.add_service(0x000B, ndef_read, lambda: False)
    return True

# NFCリーダーの起動と待機
with nfc.ContactlessFrontend('usb:054c:06c1') as clf:
    while clf.connect(card={'on-startup': on_startup, 'on-connect': on_connect}):
        print("tag released")
```

実際に読みとってみると変更した値が出力された

何かに応用したものもつくってみようかな

続き
https://qiita.com/yama4936/items/e6c5d16c64fc1bb6dab2