1

我有两个 NFC 读取设备:ACR12U 和 ACR1252U

我在 python 中有一个简短的脚本,使用 pyscard 来读取 NFC 标签的 UID:

from smartcard.CardMonitoring import CardMonitor, CardObserver
from smartcard.util import toHexString
from smartcard.Exceptions import CardConnectionException

getuid = [0xFF, 0xCA, 0x00, 0x00, 0x00]

class transmitobserver(CardObserver):
    def update(self, observable, actions):
        (addedcards, removedcards) = actions
        for card in addedcards:
            card.connection = card.createConnection()
            try:
                card.connection.connect()
            except CardConnectionException:
                # print("Card was removed too fast!")
                return
            response, sw1, sw2 = card.connection.transmit(
                getuid)
            nfc_id = "{}".format(toHexString(response)).replace(" ", "").lower()
            return nfc_id

if __name__ == '__main__':
    cardmonitor = CardMonitor()
    cardobserver = transmitobserver()
    cardmonitor.addObserver(cardobserver)
    try:
        while True:
            pass
    except KeyboardInterrupt:
        pass

只要靠近 NFC 卡,ACR122U 就会发出嗡嗡声。ACR1252U 在靠近 NFC 时会发出嗡嗡声,当我移除它时会再次发出嗡嗡声。

我想改变这种行为,这样它们只会在我取出卡片并且卡片已被读取时才会发出嗡嗡声。我对它进行了测试,如果我取出卡片的速度太快,程序就会失败,但读卡器仍然嗡嗡作响,就像它成功了一样。

这是我第一次处理这样的事情,所以我尝试了一些试错法。

所以我想getuid = [0xFF, 0xCA, 0x00, 0x00, 0x00]是向读者发送一个读取 UID 的命令,我可以在他们的两本手册中找到它:

在此处输入图像描述

现在我想我可以用它来控制蜂鸣器。在 ACR1252U 的手册中,我发现了这个:

在此处输入图像描述

所以我尝试了以下方法:

buzzer = [0xE0, 0x00, 0x00, 0x28, 0x01, 0xFF]
response = card.connection.transmit(buzzer)

但什么都没有发生。ACR122U 有不同的指令,但同样的事情发生。谁能帮助我我做错了什么?

编辑:

我能够更接近解决方案,但是我仍然不明白 100% 发生了什么。

我在写这篇文章的时候只有一个 ACR122U,所以所有的测试都是用那个完成的。从手册中,我能够获得一堆 APDU,并且我找到了一个模拟读卡的代码,而无需将实际卡接触到设备上,因此我可以对其进行测试。

from smartcard.System import readers
from smartcard.CardConnection import CardConnection
from smartcard.scard import SCARD_SHARE_DIRECT

reader = readers()[0]
connection = reader.createConnection()
connection.connect(protocol=CardConnection.RAW_protocol, mode=SCARD_SHARE_DIRECT)
turn_off_red = [0xFF, 0x00, 0x40, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00]
r, sw1, sw2 = connection.transmit(turn_off_red)

现在我有了这个 APDU:turn_off_red = [0xFF, 0x00, 0x40, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00]

根据手册,哪个红色指示灯亮,它也可以正常工作,但只有几秒钟。即使我sleep(50)在代码末尾添加了 a,红色 LED 也只会闪烁一秒钟,然后转回来。

我认为当我尝试使用configBuzzer = [0xFF, 0x00, 0x52, 0x00, 0x00]. 它会关闭蜂鸣器几秒钟,然后再将其重新打开。

4

1 回答 1

1

两个指针

1)使用命令 APDU 发送的所有命令都具有标准的响应 APDU 格式Result(如果可用 - 大多数都有结果),SW1并且SW2

所以你应该使用代码 response, sw1, sw2 = card.connection.transmit(buzzer)

您应始终检查SW1=90hSW2=00h以确认命令成功(其他值将指示错误,有关代码含义的更多详细信息,请参见数据表)

2)您说您希望它在成功读取卡时发出嗡嗡声,但是您在读取UID时没有检查SW1SW2值是否成功。

3)该命令是手动打开蜂鸣器,非常适合当您在检查读取的和值buzzer = [0xE0, 0x00, 0x00, 0x28, 0x01, 0xFF]后手动希望指示成功但该命令不会改变阅读器的默认蜂鸣行为。SW1SW2

在 ACR1252U 上configBuzzer = [0xE0, 0x00, 0x00, 0x21, 0x01, 0x67]应该是关闭卡插入事件和卡移除事件的蜂鸣器的正确位,这是您所描述的您想要的,因此您可以在成功时手动触发蜂鸣器(再次检查SW1SW2成功)

ACR122U 更新

configBuzzer = [0xFF, 0x00, 0x52, 0x00, 0x00]

然后

response, sw1, sw2 = card.connection.transmit(configBuzzer)

这不会导致在标签检测期间蜂鸣器不开启(ACR122U 的配置选项比 ACR1252U 少)

于 2022-02-06T00:11:31.863 回答