当前位置:  开发笔记 > 编程语言 > 正文

智能卡读卡器访问时出现未知错误0x16

如何解决《智能卡读卡器访问时出现未知错误0x16》经验,为你挑选了1个好方法。



1> Michael Rola..:

有两种方法可以通过Java Smartcard IO API与此阅读器进行交互:

    第一种是打开常规APDU传输通道(从PC/SC的角度来看,这映射到T = 0或T = 1协议).你可以使用

    Card card = getCard("*");
    

    但是,这将要求读者报告卡的存在.否则你无法以这种方式打开连接.

    然后,您可以将APDU命令发送到卡(在基本通道或逻辑通道上),您可以在基本通道上向阅读器发送特殊命令.这些特殊命令将其类字节设置为0xFF,以指示该命令旨在由读取器解释(而不是转发到卡).因此,这不适用于以0xE0开头的"外设控制"命令.

    必须使用带有控制代码的控制命令将这些"外围设备控制"命令发送到阅读器SCARD_CTL_CODE(3500).与打开卡的连接一样,getCard("*")如果读卡器上有卡,则可以使用.但是,如果您希望能够将这些命令发送到阅读器,即使没有卡,也必须以"直接"模式打开连接:

    Card card = getCard("DIRECT");
    

    然后,您可以使用该方法发送控制命令card.transmitControlCommand().此方法将控制代码作为第一个参数,将命令(作为字节数组)作为第二个参数.在基本通道或任何逻辑通道上交换命令channel.transmit()通常不能在"直接"模式下工作(因此错误代码为0x16).

    控制代码计算为

    public static final int SCARD_CTL_CODE(int command) {
        boolean isWindows = System.getProperty("os.name").startsWith("Windows");
        if (isWindows) {
            return 0x00310000 | (command << 2);
        } else {
            return 0x42000000 | command;
        }
    }
    

    请注意Windows和其他平台之间的区别.

    例如,要发送蜂鸣器控制命令,您将使用

    byte[] command = new byte[] { (byte)0xE0, (byte)0x00, (byte)0x00, (byte)0x28, (byte)0x01, (byte)0x0A };
    byte[] response = card.transmitControlCommand(SCARD_CTL_CODE(3500), command);
    

    最后,请注意,通过PC/SC发送IOCTL控制代码需要特殊的驱动程序支持.具体来说,Microsoft提供的标准CCID驱动程序默认情况下不支持发送转义命令(请参阅USB CCID类驱动程序详细信息).此驱动程序仅在通过注册表值"EscapeCommandEnable"启用它们后才支持转义命令.0x1您在问题中显示的错误是这个缺少对escape命令的支持的典型结果.

    要可靠地支持阅读器的所有功能(包括转义命令),您需要在其网站上使用ACS提供的"PC/SC驱动程序"包.

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有