You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PN532发送SELECT APDU命令至Android HCE应用失败问题排查

问题:PN532阅读器无法正确与Android HCE应用通信

我将Waveshare PN532 NFC树莓派扩展板通过SPI连接到树莓派4,尝试向Android HCE应用发送SELECT APDU命令。使用Flutter的nfc_host_card_emulation包开发了Android应用,已完成HCE配置,但通信异常。

Flutter 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(即0x11 0x11)。根据文档,SELECT APDU命令格式应为0x00 0xA4 0x04 0x00 0x05 0x0F 0x01 0x02 0x03 0x04,我也尝试在末尾添加0x00和0x02作为LE字节。

PN532阅读器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()

实际输出

运行阅读器程序和手机上的HCE应用(使用支持HCE的Nokia TA-1234,Motorola Moto G84 5G不支持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命令。

已尝试的解决方法

  • 查阅StackOverflow相关问题
  • 修改AID长度
  • 修改LE字节
  • 修改响应端口
  • 查看阅读器调试日志

预期结果

阅读器应返回应用中指定的0x11 0x11。

内容的提问来源于stack exchange,提问作者DavidCZ2051

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 23:32:27