Считыватель NFC ACR122U и libnfc.driver.acr122_usb Невозможно записать на USB (слишком большой результат)

Я пытаюсь использовать ACR122 USB NFC-Reader в Mac OSX Mojave 10.14.6 с libnfc, и у меня возникает ошибка «Невозможно записать на USB (слишком большой результат)», когда я пытаюсь использовать команду 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

Когда я начал устранять неполадки, у меня была ошибка «Невозможно заявить права на интерфейс USB», которая была и у других людей. Итак, я попробовал следующие вещи из этого вопроса о переполнении стека и эту проблему с github, которую я обнаружил:

  1. установить libnfc с brew install libnfc -> Получена ошибка «Невозможно заявить ...».
  2. Использование sudo -> Без изменений
  3. Отключить демон PC / SC -> Ничего не делал
  4. Редактирование /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist -> Не помогло
  5. Uninstall libnfc, compile the project myself and disable ifreader. I tried to build it with both drivers acr122_usb and acr122_pcsc -> Got now a "Unable to write to USB (Result too large)" error instead.
    • Compile with: autoreconf -iv && ./configure --with-drivers=acr122_usb && make clean && make && make install
    • sudo launchctl remove com.apple.ifdreader
    • sudo launchctl stop com.apple.ifdreader

После устранения неполадок я застрял с ошибкой и не знаю, как решить проблему. Индикатор считывателя больше не мигает красным, но из-за ошибки устройство явно подключено к компьютеру и доступно.

В качестве побочного узла: я подключаю ридер через USB-концентратор, так как у ридера нет кабеля USB C, но это не должно быть проблемой. У кого-нибудь была такая же проблема или другой подход, который я мог бы попробовать?


person Me7e0r    schedule 10.09.2019    source источник


Ответы (2)


Ваш шаг 4, редактирование /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist сработал для меня, и это единственное чистое решение, которое я смог найти.

Вот краткое описание того, что вам нужно сделать:

  • отключить защиту целостности системы
  • удаляет 3 совпадающие строки (с тем же индексом массива!) из 3 массивов ifdFriendlyName, ifdVendorID и ifdProductID из списка /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
  • включить "Защита целостности системы"

В моем случае три строки были записью под номером 370:

  • ifdFriendlyName = "Интерфейс ACS ACR122U PICC"
  • ifdVendorID = 0x072F
  • ifdProductID = 0x2200

Подробное пошаговое описание:

  1. отключите устройство чтения карт NFC
  2. выключить OSX
  3. удерживайте клавиши <cmd>+<R> на клавиатуре при запуске Mac, чтобы перейти в режим восстановления
  4. в режиме восстановления откройте окно терминала с помощью меню «Утилиты»
  5. выполнить команду csrutil disable
  6. перезагрузите ваш Mac в обычном режиме
  7. откройте окно Терминала и выполните следующие команды:

    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
    
  8. перезагрузите ваш Mac в обычном режиме

  9. подключите устройство чтения карт NFC
  10. проверьте, работают ли утилиты nfc, например позвонив по телефону nfc-scan-device
  11. выключить OSX
  12. удерживая нажатыми клавиши <cmd>+<R> на клавиатуре, запустите Mac, чтобы войти в режим восстановления.
  13. откройте окно терминала с помощью меню «Утилита»
  14. выполнить команду csrutil enable
  15. перезагрузите ваш Mac в обычном режиме

@anderssonjohan давал правильный ответ в своем сообщении, но опубликованный им файл plist был непоследовательным, потому что он удалил только одну строку вместо трех.

person Michael Dreher    schedule 07.12.2019
comment
Это не работает, потому что файл автоматически создается заново. - person Paul Bénéteau; 05.02.2020
comment
Вы выполнили команду csrutil disable, это означает, что вы выполнили шаги с 1 по 6, как описано? Я сделал это 2 месяца назад, и мои изменения все еще остались нетронутыми. Когда драйвер обновится, вам, вероятно, придется снова его исправить. - person Michael Dreher; 06.02.2020
comment
для Каталины Вы должны запустить эту команду mount -uw / перед cp Info.plist Info.plist.orig - person Maxime; 09.03.2020

Первоначальная проблема заключается в том, что демон system/com.apple.ifdreader загружает драйвер уровня пользователя /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle, который основан на pcsc-lite и заявляет о праве собственности на USB-устройство. Чтобы сделать кардридер доступным для libnfc, вы можете:

  • скажите ifd-ccid игнорировать USB-устройство (я расскажу, как этого добиться)
  • скажите libnfc использовать pcsc-lite
  • полностью отключить демон ifdreader (я считаю это рискованным, особенно при обновлении системы)

Я дал два ответа на этот вопрос:

  1. Предполагается, что вы немного больше знакомы с Терминалом и путями в среде восстановления. Вместо отключения `` Защиты целостности системы '' и необходимости нескольких перезагрузок, как описано в другом моем ответе, вы также можете сделать это с помощью только одной перезагрузки.
  2. Другой ответ требует дополнительных действий (особенно перезагрузок), и я писал его раньше. Он временно отключает «Защиту целостности системы», что сопряжено с риском, если вы забудете включить ее снова.

Вот несколько команд, которые вы можете выполнить, чтобы показать статус службы:

launchctl list com.apple.ifdreader
launchctl blame system/com.apple.ifdreader

Просто убить демона или отключить его не получится, он автоматически (повторно) запускается, когда система обнаруживает USB-устройство, идентификатор которого указан в ее Info.plist, поэтому вам необходимо удалить идентификаторы USB из /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist.

К сожалению, этот файл защищен «Защитой целостности системы» в MacOS Mojave 10.14.6, поэтому вы можете изменить его только при загрузке в режим восстановления и изменить его там или отключить там «Защиту целостности системы» с помощью csrutil disable, чтобы иметь возможность изменить его. в обычной пользовательской среде.

Вот шаги, которые вам нужно сделать:

  1. подготовьте новый Info.plist и сохраните резервную копию оригинала (см. ниже)
  2. выключить OSX
  3. удерживайте клавиши <cmd>+<R> на клавиатуре, а затем запустите Mac, чтобы войти в режим восстановления
  4. откройте окно «Терминал» с помощью меню «Утилиты»
  5. Замените оригинальный /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' иметь возможность использовать большинство обычных команд интерфейса командной строки.

Чтобы создать новый файл Info.plist, вы можете использовать небольшой патч из моего другого ответа. Или вы можете использовать прикрепленный скрипт python, который более гибок. Просто вызовите сценарий, и он создаст измененный файл Info.plist в подкаталоге SmartCardService_disable текущего каталога:

#!/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)

Скрипт можно легко адаптировать для удаления других картридеров, просто измените usbFriendlyNamePattern = ".*ACS.*ACR122.*" на любой другой шаблон.

person Michael Dreher    schedule 08.12.2019