Команды ACR122U терпят неудачу после переподключения, если я не жду 2 секунды

У меня проблема со считывателем ACR122U при попытке запустить команды после неудачной команды и повторного подключения. Возьмем, к примеру, следующий код, который я использую для определения типа подключенного тега:

private CardTerminal terminal; //ACR1222L or ACR122U
...
private void detectTagType(timeout: Long)
{        
    terminal.waitForCardPresent(timeout);
    Card card = terminal.connect("*")
    // Check the ATR bytes for ultralight values
    if (isUltralight(card.getATR().getBytes()))
    {
        try
        {
            // Runs the native GET_VERSION command (0x60)
            byte[] version = getDesfireVersion(card);
            // Check the version bytes for EV1 values
            if (isUltralightEV1(version))
            {
                // Is an ultralight ev1
            }
            else
            {
                // Another tag
            }
        }
        catch (MyNFCException exception)
        {
            // Possible UltralightC since it does not support the GET_VERSION command            
            // Reconnect to tag to wake up from failed command
            card.disconnect(true)
            Card cardC = terminal.connect("*") 

            // The code works if I add Thread.sleep(2000); here            

            // Try running the AUTHENTICATE command (0x1A) as explained here http://stackoverflow.com/questions/11897813/distinguish-mifare-ultralight-from-mifare-ultralight-c
            if (tryRunUltralighcAuthenticateCommand(cardC))
            {
                // Is an ultralight C
            }
            else
            {
                // Unkonwn tag
            }
        }
}

// The following methods run the corresponding native commands wrapping them 
// as described here https://stackoverflow.com/questions/42542610/authenticating-ultralight-ev1-with-pc-sc-reader/42563617#42563617. 
// (Wrapping with them with the InCommunicateThru and the correct header depending on the reader, 
// i.e. {0xE0, 0x00, 0x00, 0x24, 0x00} for the ACR1222L and {0xFF, 0x00, 0x00, 0x00, 0x00} for the ACR122U)

private byte[] getDesfireVersion(Card card) throws MyNFCException 
{
    // Runs the GET_VERSION command and returns the bytes returned by the tag. 
    // If the tag does not support the command raises a MyNFCException 
}

private boolean tryRunUltralightcAuthenticateCommand(Card card)
{
    // Runs the Ultralight C AUTHENTICATE command (0x1A) and returns true if it succeeds and false if it fails
}

Когда я тестирую этот код с тегом Ultralight C и считывателем ACR122U, команда AUTHENTICATE (tryRunUltralighcAuthenticateCommand) в результате получает {D5 43 01} (т. е. тайм-аут). Однако, если я запускаю тот же код со считывателем ACR1222L и тем же тегом, он работает, как и ожидалось, то есть команда выполняется успешно. Кроме того, если я заставлю свою программу ждать 2 секунды (с Thread.sleep(2000)) после повторного подключения, она также будет работать со считывателем ACR122U, как и ожидалось (но это, очевидно, не решение).

Я получаю такое же поведение после любой неудачной команды с любым тегом. Например, если я попытаюсь аутентифицировать Ultralight EV1 с неправильным паролем, переподключиться, а затем выполнить любую команду, она будет работать со считывателем ACR1222L, но завершится ошибкой с кодом {D5 43 01} на ACR122U (если только я не переношу свою программу для через 2 секунды после повторного подключения).

Я попытался отключиться без сброса тега (card.disconnect(false)) и вообще не подключаться повторно (в этом случае я получаю ошибку CRC {D5 43 02} после неудачной команды).

Есть ли что-то, что мне не хватает? Или какой-либо другой обходной путь для этой проблемы, кроме того, что мой поток спит в течение 2 секунд после каждого повторного подключения?


person jesm00    schedule 28.04.2017    source источник


Ответы (1)


Это ограничение/конструкция драйверов ACS; просто как это работает. Мне еще предстоит найти способ обойти это.

person craig.tadlock    schedule 01.05.2020