0

我想以编程方式控制智能卡读卡器 ACS ACR1281U-C1 的蜂鸣器,但我不确定如何正确理解如何使用 ESCAPE 命令。

我使用 python 3.9.6 + pyscard 2.0.1。视窗 10 (x64)。

我已经安装了 ACS 驱动程序(版本 4.2.8.0)。

ACS(应用程序编程接口 V1.11)的文档指出:

阅读器的外设控制命令是通过使用 PC_to_RDR_Escape 实现的。注意:驱动程序会自动添加 Class、INS 和 P1。

在附录 C 中,转义命令显示为 2079。

但是,sdk 提供了一些示例(在 Java 中),其中转义命令显示为 3500,并且明确传输了 Class、INS 和 P1 字段。

我可以复制两种方式来发送这个外围控制,但我不确定哪种方法是最好的,而且文档也不广泛。

1) SCARD_CTL_CODE(2079) 用 2079 计算 ESCAPE 命令,驱动程序会自动添加 Class、INS 和 P1 [0xE0, 0x00, 0x00],所以我不需要将它们放在命令中。这似乎更符合 API 文档:

IOCTL_CCID_ESCAPE = SCARD_CTL_CODE(2079)
BUZZER_LONG = [0x28, 0x01, 0xB0]
response = cardservice.connection.control(IOCTL_CCID_ESCAPE, BUZZER_LONG)

SCARD_CTL_CODE(3500) 用 3500 计算 ESCAPE 命令,我必须在命令中显式添加 Class、INS 和 P1。这更符合 SDK 中的 Java 示例:

IOCTL_CCID_ESCAPE3500 = SCARD_CTL_CODE(3500)
BUZZER_LONG3500 = [0xE0, 0x00, 0x00, 0x28, 0x01, 0xB0]
response = cardservice.connection.control(IOCTL_CCID_ESCAPE3500, BUZZER_LONG3500)

为什么会有这种差异?什么是正确的方法?

from smartcard.CardType import ATRCardType
from smartcard.CardRequest import CardRequest
from smartcard.Exceptions import CardRequestTimeoutException, SmartcardException
from smartcard.util import toHexString, toBytes, BinStringToHexList, PACK
from time import sleep
from smartcard.scard import SCARD_CTL_CODE

# prepare escape command
IOCTL_CCID_ESCAPE3500 = SCARD_CTL_CODE(3500)
IOCTL_CCID_ESCAPE = SCARD_CTL_CODE(2079)

# reader commands
READ_UID = [0xFF,0xCA,0x00,0x00,0x00]
BUZZER_LONG = [0x28, 0x01, 0xB0]
BUZZER_LONG3500 = [0xE0, 0x00, 0x00, 0x28, 0x01, 0xB0]

# card centric approach - could be any card type    
cardtype = ATRCardType( toBytes('3B 8F 80 01 80 4F 0C A0 00 00 03 06 03 00 07 00 00 00 00 6C') )

cardrequest = CardRequest( timeout=15, cardType=cardtype )

while True:
    choice = input('Put a card on the reader and press ENTER...').upper()
    if choice == 'Q':
        break
    try:
        cardservice = cardrequest.waitforcard()
    except CardRequestTimeoutException:
        print('Timeout')
        continue
    cardservice.connection.connect()
    # read/write ... do stuff with the card.
    try:
        # beeps with 2079 control code without Class, INS and P1 
        response = cardservice.connection.control(IOCTL_CCID_ESCAPE, BUZZER_LONG)
        sleep(1)
        # beeps with 3500 control code and command including Class, INS and P1 
        response = cardservice.connection.control(IOCTL_CCID_ESCAPE3500, BUZZER_LONG3500)
    except SmartcardException as err:
        print(f"{err=}, {type(err)=}")
4

0 回答 0