NFC Reader ACR122U 和 libnfc.driver.acr122_usb 无法写入 USB(结果太大)
NFC Reader ACR122U and libnfc.driver.acr122_usb Unable to write to USB (Result too large)
我尝试在 Mac OSX Mojave 10.14.6 和 libnfc 上使用 ACR122 USB NFC-Reader,当我使用时出现 "Unable to write to USB (Result too large)" 错误尝试使用命令 LIBNFC_LOG_LEVEL=3 nfc-list
:
info libnfc.config Unable to open file: /usr/local/etc/nfc/libnfc.conf
debug libnfc.config key: [device.allow_autoscan], value: [false]
info libnfc.config Unknown key in config line: device.allow_autoscan = false
debug libnfc.config key: [device.allow_intrusive_scan], value: [false]
info libnfc.config Unknown key in config line: device.allow_intrusive_scan = false
debug libnfc.config key: [device.log_level], value: [3]
info libnfc.config Unknown key in config line: device.log_level = 3
debug libnfc.general log_level is set to 3
debug libnfc.general allow_autoscan is set to true
debug libnfc.general allow_intrusive_scan is set to false
debug libnfc.general 0 device(s) defined by user
nfc-list uses libnfc 1.7.1
debug libnfc.driver.acr122_usb device found: Bus 020 Device 020 Name ACS ACR122
debug libnfc.general 1 device(s) found using acr122_usb driver
debug libnfc.driver.acr122_usb 3 element(s) have been decoded from "acr122_usb:020:020"
debug libnfc.driver.acr122_usb TX: 62 00 00 00 00 00 00 01 00 00
error libnfc.driver.acr122_usb Unable to write to USB (Result too large)
debug libnfc.general Unable to open "acr122_usb:020:020".
nfc-list: ERROR: Unable to open NFC device: acr122_usb:020:020
当我开始进行故障排除时,我遇到了 "Unable to Claim USB Interface" 错误,其他人也遇到过。所以我从 Whosebug question and this github 我发现的问题中尝试了以下内容:
- 使用
brew install libnfc
安装 libnfc --> 出现 "Unable to Claim..." 错误。
- 使用 sudo -> 无变化
- 禁用 PC/SC 守护程序 -> 没有做任何事情
- 正在编辑
/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
-> 没有帮助
- 卸载libnfc,自己编译项目并禁用ifreader。我尝试使用 acr122_usb 和 acr122_pcsc 这两个驱动程序构建它 -> 现在出现 "Unable to write to USB (Result too large)" 错误。
- 编译为:
autoreconf -iv && ./configure --with-drivers=acr122_usb && make clean && make && make install
sudo launchctl remove com.apple.ifdreader
sudo launchctl stop com.apple.ifdreader
现在排除故障后,我仍然被错误困住了,不知道如何解决这个问题。 readers 灯不再闪烁红色,但从错误中可以清楚地看出设备已连接到计算机并且可用。
作为辅助节点:我通过 USB 集线器连接 reader,因为 reader 没有 USB C 电缆,但这应该不是问题。有没有人有同样的问题或我可以尝试的其他方法?
你的第 4 步,编辑 /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
对我有用,这是我能找到的唯一干净的解决方案。
这里有一个简短的描述你需要做什么:
- 禁用'System Integrity Protection'
- 从 plist 的 3 个数组 ifdFriendlyName、ifdVendorID 和 ifdProductID 中删除 3 个匹配行(具有相同的数组索引!)
/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
- 启用'System Integrity Protection'
在我的案例中,三行是条目号 370:
- ifdFriendlyName="ACS ACR122U PICC Interface"
- ifdVendorID=0x072F
- ifdProductID=0x2200
详细步骤说明:
- 拔下您的 NFC 卡 reader
- 关闭OSX
- 在启动 Mac 的同时按住键盘上的
<cmd>+<R>
键 以进入恢复模式
- 在恢复模式下使用 'Utility' 菜单打开终端 Window
- 执行命令
csrutil disable
- 正常重启你的Mac
打开终端window并执行以下命令:
sudo -i
cd /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents
cp Info.plist Info.plist.orig
patch -l -p0 <<EOF
--- Info.plist.orig 2019-12-07 20:26:36.000000000 +0100
+++ Info.plist 2019-12-07 20:26:40.000000000 +0100
@@ -471,7 +471,6 @@
<string>0x1050</string>
<string>0x1050</string>
<string>0x1050</string>
- <string>0x072F</string>
<string>0x09C3</string>
<string>0x03EB</string>
<string>0x0A5C</string>
@@ -864,7 +863,6 @@
<string>0x0405</string>
<string>0x0406</string>
<string>0x0407</string>
- <string>0x2200</string>
<string>0x0008</string>
<string>0x6016</string>
<string>0x5800</string>
@@ -1257,7 +1255,6 @@
<string>Yubico Yubikey 4 OTP+CCID</string>
<string>Yubico Yubikey 4 U2F+CCID</string>
<string>Yubico Yubikey 4 OTP+U2F+CCID</string>
- <string>ACS ACR122U PICC Interface</string>
<string>ActivCard ActivCard USB Reader V2</string>
<string>ATMEL VaultIC460</string>
<string>Broadcom Corp 5880</string>
EOF
正常重启您的 Mac
- 插入您的 NFC 卡reader
- 测试 nfc 实用程序现在是否正常工作,例如通过调用
nfc-scan-device
- 关闭OSX
- 按住键盘上的
<cmd>+<R>
键,然后启动 Mac 进入恢复模式
- 使用 'Utility' 菜单打开终端 Window
- 执行命令
csrutil enable
- 正常重启你的Mac
@anderssonjohan 给出了正确答案 in his post,但他发布的 plist 文件不一致,因为他只删除了一行而不是三行。
最初的问题是,守护程序 system/com.apple.ifdreader
加载用户级驱动程序 /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle
即 based on pcsc-lite 并声明 USB 设备的所有权。要使 libnfc 可以访问 reader 卡,您可以
- 告诉 ifd-ccid 忽略 USB 设备(我会告诉你如何实现)
- 告诉 libnfc 使用 pcsc-lite
- 完全禁用 ifdreader 守护程序(我认为这有风险,尤其是在系统升级时)
这个问题我做了两个回答:
- 本文假设您对终端和恢复环境中的路径比较熟悉。无需像我的其他答案中所述那样禁用 'System Integrity Protection' 并需要多次重新启动,您也可以仅通过一次重新启动来完成此操作
- 另一个答案需要更多步骤(尤其是重启),我之前已经写过了。它会暂时禁用 'System Integrity Protection',当您忘记再次启用它时会有风险。
您可以执行以下命令来显示服务状态:
launchctl list com.apple.ifdreader
launchctl blame system/com.apple.ifdreader
仅仅杀死守护进程或禁用它是行不通的,当系统检测到其ID在其Info.plist中列出的USB设备时,它会自动(重新)启动,因此您需要删除USB ID来自 /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
.
不幸的是,该文件在 MacOS Mojave 10.14.6 中受 'System Integrity Protection' 保护,因此您只能在启动到恢复模式时修改它并在那里修改或禁用'System Integrity Protection' 使用 csrutil disable
可以在普通用户环境中修改它。
这些是您需要执行的步骤:
- 准备新的 Info.plist 并保留原始备份(见下文)
- 关闭 OSX
- 按住键盘上的
<cmd>+<R>
键,然后启动 Mac 进入恢复模式
- 使用 'Utilities' 菜单打开 'Terminal' Window
- 将原来的
/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
换成你准备的
在进入恢复模式之前,您需要知道可以在哪些路径下找到文件,因为根文件系统不同,您的普通根文件系统将安装在 /Volumes/<TheNameOfYourSystemDisk>,因此在进入恢复模式之前在 Finder 中查找此名称。
例如,我的系统驱动器名为 Macintosh HD
,路径为:
- 我的主目录:
/Volumes/Macintosh HD/Users/michael
- pinfo 文件:
/Volumes/Macintosh HD/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
在我的示例中,最好的方法是 chroot '/Volumes/Macintosh HD'
能够使用大多数常规 CLI 命令。
要创建新的 Info.plist 文件,您可以使用我的其他答案中的小补丁。或者您可以使用更灵活的附加 python 脚本。只需调用脚本,它就会在当前目录的子目录 SmartCardService_disable
中创建更改后的 Info.plist 文件:
#!/usr/bin/env python3
import os, re, plistlib
from shutil import copyfile
plistFile = "/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist"
plistFileBak = "Info.plist.orig"
plistFileOut = "Info.plist"
workDir = "SmartCardService_disable"
usbFriendlyNamePattern = ".*ACS.*ACR122.*"
def findDevicesByFriendlyName(pl, usbFriendlyNamePattern) :
reUsbFriendlyName = re.compile(usbFriendlyNamePattern, re.IGNORECASE)
indexes = []
for index, item in enumerate(pl["ifdFriendlyName"]):
if reUsbFriendlyName.fullmatch(item) :
indexes.append(index)
return indexes
def makePlistCopy() :
try:
os.mkdir(workDir)
except FileExistsError:
pass
except:
raise Exception("Unable to create work directory")
os.chdir(workDir)
try:
os.stat(plistFileBak)
except FileNotFoundError:
copyfile(plistFile, plistFileBak)
except:
raise Exception("Unable to copy plist file")
makePlistCopy()
pl = plistlib.readPlist(plistFileBak)
indexes = findDevicesByFriendlyName(pl, usbFriendlyNamePattern)
indexes.sort(reverse = True)
for index in indexes:
del pl["ifdFriendlyName"][index]
del pl["ifdVendorID"][index]
del pl["ifdProductID"][index]
plistlib.writePlist(pl, plistFileOut)
该脚本可以很容易地修改以移除其他卡片 readers,只需将 usbFriendlyNamePattern = ".*ACS.*ACR122.*"
更改为任何其他模式即可。
第一个解决方案是我需要的,但是启用 SIP、更改驱动程序和恢复 SIP 对我来说太多了,只是为了我们的 reader 禁用 PC/SC。
如果您在某些 PC/SC 兼容的 macOS 应用程序中使用 reader,则此解决方案不适合您。
我找到了没有 enable/disable SIP 的解决方案。
- 安装非系统驱动程序,在我的例子中是 https://www.acs.com.hk/download-driver-unified/12835/ACS-Unified-INST-MacOSX-1182-P.zip,它是 acsccid 驱动程序。
- 在本地系统找到这样的文件夹 /usr/local/libexec/SmartCardServices/drivers/ifd-acsccid。bundle/Contents
它不受 SIP 保护,因为它是 /usr/local 并且它是用户驱动程序
- 修改文件Info.plist第一个答案是如何描述的
- 拔下再插上 reader - LED 不工作(这是预期的!)
- 确保 lsusb 在列表中显示你的 reader
- libnfc 使用 acr122_usb 驱动程序
在这种情况下,macos 系统会忽略系统驱动程序,因为安装了用户驱动程序并从中应用了所有配置,即使设备已被忽略。
经过测试并与来自 master 和 macos BigSur 11.6 的最新版本的 libnfc 配合使用
注意:为了能够与 gen3 fob 正常工作,我建议从 master 编译和安装 libnfc,一些新的更改已经完成但尚未发布 (
我尝试在 Mac OSX Mojave 10.14.6 和 libnfc 上使用 ACR122 USB NFC-Reader,当我使用时出现 "Unable to write to USB (Result too large)" 错误尝试使用命令 LIBNFC_LOG_LEVEL=3 nfc-list
:
info libnfc.config Unable to open file: /usr/local/etc/nfc/libnfc.conf
debug libnfc.config key: [device.allow_autoscan], value: [false]
info libnfc.config Unknown key in config line: device.allow_autoscan = false
debug libnfc.config key: [device.allow_intrusive_scan], value: [false]
info libnfc.config Unknown key in config line: device.allow_intrusive_scan = false
debug libnfc.config key: [device.log_level], value: [3]
info libnfc.config Unknown key in config line: device.log_level = 3
debug libnfc.general log_level is set to 3
debug libnfc.general allow_autoscan is set to true
debug libnfc.general allow_intrusive_scan is set to false
debug libnfc.general 0 device(s) defined by user
nfc-list uses libnfc 1.7.1
debug libnfc.driver.acr122_usb device found: Bus 020 Device 020 Name ACS ACR122
debug libnfc.general 1 device(s) found using acr122_usb driver
debug libnfc.driver.acr122_usb 3 element(s) have been decoded from "acr122_usb:020:020"
debug libnfc.driver.acr122_usb TX: 62 00 00 00 00 00 00 01 00 00
error libnfc.driver.acr122_usb Unable to write to USB (Result too large)
debug libnfc.general Unable to open "acr122_usb:020:020".
nfc-list: ERROR: Unable to open NFC device: acr122_usb:020:020
当我开始进行故障排除时,我遇到了 "Unable to Claim USB Interface" 错误,其他人也遇到过。所以我从
- 使用
brew install libnfc
安装 libnfc --> 出现 "Unable to Claim..." 错误。 - 使用 sudo -> 无变化
- 禁用 PC/SC 守护程序 -> 没有做任何事情
- 正在编辑
/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
-> 没有帮助 - 卸载libnfc,自己编译项目并禁用ifreader。我尝试使用 acr122_usb 和 acr122_pcsc 这两个驱动程序构建它 -> 现在出现 "Unable to write to USB (Result too large)" 错误。
- 编译为:
autoreconf -iv && ./configure --with-drivers=acr122_usb && make clean && make && make install
sudo launchctl remove com.apple.ifdreader
sudo launchctl stop com.apple.ifdreader
- 编译为:
现在排除故障后,我仍然被错误困住了,不知道如何解决这个问题。 readers 灯不再闪烁红色,但从错误中可以清楚地看出设备已连接到计算机并且可用。
作为辅助节点:我通过 USB 集线器连接 reader,因为 reader 没有 USB C 电缆,但这应该不是问题。有没有人有同样的问题或我可以尝试的其他方法?
你的第 4 步,编辑 /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
对我有用,这是我能找到的唯一干净的解决方案。
这里有一个简短的描述你需要做什么:
- 禁用'System Integrity Protection'
- 从 plist 的 3 个数组 ifdFriendlyName、ifdVendorID 和 ifdProductID 中删除 3 个匹配行(具有相同的数组索引!)
/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
- 启用'System Integrity Protection'
在我的案例中,三行是条目号 370:
- ifdFriendlyName="ACS ACR122U PICC Interface"
- ifdVendorID=0x072F
- ifdProductID=0x2200
详细步骤说明:
- 拔下您的 NFC 卡 reader
- 关闭OSX
- 在启动 Mac 的同时按住键盘上的
<cmd>+<R>
键 以进入恢复模式 - 在恢复模式下使用 'Utility' 菜单打开终端 Window
- 执行命令
csrutil disable
- 正常重启你的Mac
打开终端window并执行以下命令:
sudo -i cd /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents cp Info.plist Info.plist.orig patch -l -p0 <<EOF --- Info.plist.orig 2019-12-07 20:26:36.000000000 +0100 +++ Info.plist 2019-12-07 20:26:40.000000000 +0100 @@ -471,7 +471,6 @@ <string>0x1050</string> <string>0x1050</string> <string>0x1050</string> - <string>0x072F</string> <string>0x09C3</string> <string>0x03EB</string> <string>0x0A5C</string> @@ -864,7 +863,6 @@ <string>0x0405</string> <string>0x0406</string> <string>0x0407</string> - <string>0x2200</string> <string>0x0008</string> <string>0x6016</string> <string>0x5800</string> @@ -1257,7 +1255,6 @@ <string>Yubico Yubikey 4 OTP+CCID</string> <string>Yubico Yubikey 4 U2F+CCID</string> <string>Yubico Yubikey 4 OTP+U2F+CCID</string> - <string>ACS ACR122U PICC Interface</string> <string>ActivCard ActivCard USB Reader V2</string> <string>ATMEL VaultIC460</string> <string>Broadcom Corp 5880</string> EOF
正常重启您的 Mac
- 插入您的 NFC 卡reader
- 测试 nfc 实用程序现在是否正常工作,例如通过调用
nfc-scan-device
- 关闭OSX
- 按住键盘上的
<cmd>+<R>
键,然后启动 Mac 进入恢复模式 - 使用 'Utility' 菜单打开终端 Window
- 执行命令
csrutil enable
- 正常重启你的Mac
@anderssonjohan 给出了正确答案 in his post,但他发布的 plist 文件不一致,因为他只删除了一行而不是三行。
最初的问题是,守护程序 system/com.apple.ifdreader
加载用户级驱动程序 /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle
即 based on pcsc-lite 并声明 USB 设备的所有权。要使 libnfc 可以访问 reader 卡,您可以
- 告诉 ifd-ccid 忽略 USB 设备(我会告诉你如何实现)
- 告诉 libnfc 使用 pcsc-lite
- 完全禁用 ifdreader 守护程序(我认为这有风险,尤其是在系统升级时)
这个问题我做了两个回答:
- 本文假设您对终端和恢复环境中的路径比较熟悉。无需像我的其他答案中所述那样禁用 'System Integrity Protection' 并需要多次重新启动,您也可以仅通过一次重新启动来完成此操作
- 另一个答案需要更多步骤(尤其是重启),我之前已经写过了。它会暂时禁用 'System Integrity Protection',当您忘记再次启用它时会有风险。
您可以执行以下命令来显示服务状态:
launchctl list com.apple.ifdreader
launchctl blame system/com.apple.ifdreader
仅仅杀死守护进程或禁用它是行不通的,当系统检测到其ID在其Info.plist中列出的USB设备时,它会自动(重新)启动,因此您需要删除USB ID来自 /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
.
不幸的是,该文件在 MacOS Mojave 10.14.6 中受 'System Integrity Protection' 保护,因此您只能在启动到恢复模式时修改它并在那里修改或禁用'System Integrity Protection' 使用 csrutil disable
可以在普通用户环境中修改它。
这些是您需要执行的步骤:
- 准备新的 Info.plist 并保留原始备份(见下文)
- 关闭 OSX
- 按住键盘上的
<cmd>+<R>
键,然后启动 Mac 进入恢复模式 - 使用 'Utilities' 菜单打开 'Terminal' Window
- 将原来的
/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
换成你准备的
在进入恢复模式之前,您需要知道可以在哪些路径下找到文件,因为根文件系统不同,您的普通根文件系统将安装在 /Volumes/<TheNameOfYourSystemDisk>,因此在进入恢复模式之前在 Finder 中查找此名称。
例如,我的系统驱动器名为 Macintosh HD
,路径为:
- 我的主目录:
/Volumes/Macintosh HD/Users/michael
- pinfo 文件:
/Volumes/Macintosh HD/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
在我的示例中,最好的方法是 chroot '/Volumes/Macintosh HD'
能够使用大多数常规 CLI 命令。
要创建新的 Info.plist 文件,您可以使用我的其他答案中的小补丁。或者您可以使用更灵活的附加 python 脚本。只需调用脚本,它就会在当前目录的子目录 SmartCardService_disable
中创建更改后的 Info.plist 文件:
#!/usr/bin/env python3
import os, re, plistlib
from shutil import copyfile
plistFile = "/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist"
plistFileBak = "Info.plist.orig"
plistFileOut = "Info.plist"
workDir = "SmartCardService_disable"
usbFriendlyNamePattern = ".*ACS.*ACR122.*"
def findDevicesByFriendlyName(pl, usbFriendlyNamePattern) :
reUsbFriendlyName = re.compile(usbFriendlyNamePattern, re.IGNORECASE)
indexes = []
for index, item in enumerate(pl["ifdFriendlyName"]):
if reUsbFriendlyName.fullmatch(item) :
indexes.append(index)
return indexes
def makePlistCopy() :
try:
os.mkdir(workDir)
except FileExistsError:
pass
except:
raise Exception("Unable to create work directory")
os.chdir(workDir)
try:
os.stat(plistFileBak)
except FileNotFoundError:
copyfile(plistFile, plistFileBak)
except:
raise Exception("Unable to copy plist file")
makePlistCopy()
pl = plistlib.readPlist(plistFileBak)
indexes = findDevicesByFriendlyName(pl, usbFriendlyNamePattern)
indexes.sort(reverse = True)
for index in indexes:
del pl["ifdFriendlyName"][index]
del pl["ifdVendorID"][index]
del pl["ifdProductID"][index]
plistlib.writePlist(pl, plistFileOut)
该脚本可以很容易地修改以移除其他卡片 readers,只需将 usbFriendlyNamePattern = ".*ACS.*ACR122.*"
更改为任何其他模式即可。
第一个解决方案是我需要的,但是启用 SIP、更改驱动程序和恢复 SIP 对我来说太多了,只是为了我们的 reader 禁用 PC/SC。
如果您在某些 PC/SC 兼容的 macOS 应用程序中使用 reader,则此解决方案不适合您。
我找到了没有 enable/disable SIP 的解决方案。
- 安装非系统驱动程序,在我的例子中是 https://www.acs.com.hk/download-driver-unified/12835/ACS-Unified-INST-MacOSX-1182-P.zip,它是 acsccid 驱动程序。
- 在本地系统找到这样的文件夹 /usr/local/libexec/SmartCardServices/drivers/ifd-acsccid。bundle/Contents 它不受 SIP 保护,因为它是 /usr/local 并且它是用户驱动程序
- 修改文件Info.plist第一个答案是如何描述的
- 拔下再插上 reader - LED 不工作(这是预期的!)
- 确保 lsusb 在列表中显示你的 reader
- libnfc 使用 acr122_usb 驱动程序
在这种情况下,macos 系统会忽略系统驱动程序,因为安装了用户驱动程序并从中应用了所有配置,即使设备已被忽略。
经过测试并与来自 master 和 macos BigSur 11.6 的最新版本的 libnfc 配合使用
注意:为了能够与 gen3 fob 正常工作,我建议从 master 编译和安装 libnfc,一些新的更改已经完成但尚未发布 (