我有一个 Waveshare PN532 NFC Raspberry Pi Hat 使用 SPI 连接到我的 Raspberry Pi 4,我正在尝试向我的 Android HCE 应用程序发送 APDU SELECT 命令。我正在使用 Flutter 和这个 package 来构建 Android 应用程序。我按照包的文档设置了 HCE 应用程序,代码如下:
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:nfc_host_card_emulation/nfc_host_card_emulation.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const App());
}
class App extends StatefulWidget {
const App({super.key});
@override
State<App> createState() => _AppState();
}
class _AppState extends State<App> {
@override
void initState() {
super.initState();
NfcHce.stream.listen((command) {
print("Received command: $command");
});
}
void test() async {
final nfcState = await NfcHce.checkDeviceNfcState();
print("NFC State: $nfcState");
}
void start() async {
await NfcHce.init(
aid: Uint8List.fromList([0x0F, 0x01, 0x02, 0x03, 0x04]),
permanentApduResponses: true,
listenOnlyConfiguredPorts: false,
);
NfcHce.addApduResponse(0, [17, 17]);
}
void stop() async {
NfcHce.removeApduResponse(0);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('NFC HCE Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
OutlinedButton(
onPressed: test,
child: const Text("TEST NFC"),
),
OutlinedButton(
onPressed: start,
child: const Text("START NFC"),
),
OutlinedButton(
onPressed: stop,
child: const Text("STOP NFC"),
),
],
),
),
),
);
}
}
该应用程序的 AID 为 0F01020304,并且还为端口 0 设置了响应,响应值为 17、17(十进制)。根据文档,SELECT APDU 命令应如下所示:
0x00 0xA4 0x04 0x00 0x05 0x0F 0x01 0x02 0x03 0x04
。我还尝试将 0x00 和 0x02 作为 LE 字节添加到末尾。
在 PN532 上,我使用的是 Waveshare 提供的 python 库。这是供读者使用的代码:
import RPi.GPIO as GPIO
from pn532 import *
if __name__ == '__main__':
try:
def send_apdu_command(apdu):
pn532.call_function(0x8E, params=apdu)
def get_apdu_response():
result = pn532.call_function(0x86, 255)
return result
pn532 = PN532_SPI(debug=False, reset=20, cs=4)
ic, ver, rev, support = pn532.get_firmware_version()
print('Found PN532 with firmware version: {0}.{1}'.format(ver, rev))
# Configure PN532 to communicate with MiFare cards
pn532.SAM_configuration()
print('Waiting for RFID/NFC card...')
while True:
# Check if a card is available to read
uid = pn532.read_passive_target(timeout=0.5)
print('.', end="")
# Try again if no card is available.
if uid is not None:
break
print('Found card with UID:', [hex(i) for i in uid])
command = [0x00, 0xA4, 0x04, 0x00, 0x05, 0x0F, 0x01, 0x02, 0x03, 0x04, 0x00]
send_apdu_command(command)
response = get_apdu_response()
print([hex(i) for i in response])
except Exception as e:
print(e)
finally:
GPIO.cleanup()
当我在手机上运行阅读器程序和应用程序时(根据该应用程序,在摩托罗拉 Moto G84 5G 上不支持 HCE 功能,因此我使用的是诺基亚 TA-1234),启动 HCE 应用程序并将手机靠近阅读器,这是阅读器程序的输出:
Found PN532 with firmware version: 1.6
Waiting for RFID/NFC card...............Found card with UID: ['0x08', '0x9a', '0xe7', '0x18']
['0x25']
“响应”为 0x25,应为应用程序中定义的 0x11 0x11。 Android 应用程序还应该使用流记录 APDU 命令,但没有任何反应。有谁知道这里可能有什么问题吗?
试过
期待 阅读器应返回应用程序中指定的值(0x11 0x11)
我找到了这个 Github 存储库并且我设法让它工作。它使用 nfcpy 库而不是 Waveshare 提供的库。 NFC帽子还需要连接UART(这是nfcpy唯一支持的)。