2012-02-03 17 views
2

Я работаю над бесконтактным считывающим устройством RFID-карт SCM, используя Microsoft SmartCard APIs.SCardTransmit() всегда возвращает ошибку

Обычный процесс ineract с помощью смарт-карты, что я понял, это:
1. Установить контекст, используя SCardEstablishContext()
2. Перечислите все читатели, подключенные к системе с помощью SCardListReaders()
3. Выберите читателя и дождитесь, когда в него будет вставлена ​​карта.
4. После обнаружения карты функция SCardGetStatusChange() возвращается.
5. Подключите к плате через выбранный считыватель с помощью SCardConnect()
6. Поговорите с картой с помощью SCardTransmit()

Всех шагов до 5 работают отлично, что означает, что я получил правильную ручку карты. Карту можно проверить дополнительно, выпустив функцию SCardStatus(), которая возвращает согласованный протокол и ATR карты, что также является правильным. Но когда я пытаюсь отправить любую команду APDU с помощью SCardTransmit(), она возвращает ошибку (код ошибки 14, который, я думаю, SCARD_E_CANT_DISPOSE).

У меня нет ни малейшего представления о том, что происходит, или чего не хватает. Я пробовал разные APDU, например. самый базовый APDU, чтобы прочитать UID карты, выпустив {0xFF, 0xCA, 0x00, 0x00, 0x00}. Я проверил этот APDU с помощью утилиты SCM TestResMan для отладки и вернул мне правильный UID карты. Я использую карту MiFARE 1k и SCM бесконтактный SCL011 Reader.

Пожалуйста, найдите фрагмент кода SCardTransmit() ниже (все предыдущие функции возвратили успех).

SCARD_IO_REQUEST sioreq; 
sioreq.dwProtocol = 2; // SCARD_PROTOCOL_T1 
sioreq.cbPciLength = 8; 

SCARD_IO_REQUEST rioreq; 
rioreq.dwProtocol = 2; // SCARD_PROTOCOL_T1 
rioreq.cbPciLength = 8; 

byte sendbuffer[256], receivebuffer[256]; 
ULONG sendbufferLen, receivebufferLen, sizeofUID; 

sendbuffer[0] = 0xFF; // CLA - Instruction Class 
sendbuffer[1] = 0xCA; // Instruction code 
sendbuffer[2] = 0x00; // P1 - 1st parameter 
sendbuffer[3] = 0x00; // P2 - 2nd parameter 
sendbuffer[4] = 0x00; 
sendbufferLen = 0x05; 

retval = objScWrapper->SCardTransmit(hCardHandle, &sioreq, sendbuffer, 
            sendbufferLen, NULL, receivebuffer, 
            &receivebufferLen); 

Пожалуйста, дайте мне знать, если кто имеет какие-либо подсказки или указатели ...
ТИА !!

ответ

0

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

1) При подключении ж/SCardConnect вы подключаете с эксклюзивный, общий или прямой доступ? 2) Вы уверены, что когда вы подключаетесь к карте, протокол, с которым связана карта, равен T1? 3) Какова цель SCARD_IO_REQUEST rioreq; строка в образце, этот объект, похоже, не используется? 4) Я вижу, что вы просматриваете оболочку, чтобы вызвать вызов API. можете ли вы использовать внутреннюю реализацию SCardTrasmit в оболочке?

Я отредактирую этот ответ на основе обновленного заданного вам вопроса.

4

Размер получаемого буфера составляет 256 байтов, но вы запрашиваете 256 байтов (Le = 00h), а буфер приема также ожидает слова состояния (состоящие из двух байтов, SW1 и SW2).

Таким образом, я думаю, что ваш код ошибки 14 - это общая функция OUT_OF_MEMORY для буфера приема.

Ваш командный буфер слишком мал, чтобы соответствовать 5 байтам заголовка + max 255 байтов данных команды. Конечно, оба они слишком малы для обработки ADPU с расширенной длиной.

Windows в настоящее время довольно разборчива относительно размеров буфера для смарт-карт для совместимых с PCSC считывателей. Для буфера команд используйте не менее 5 + 255 = 260 байт и 256 + 2 байта для буфера приема. Повторно используйте буферы или безопасно утилизируйте их или у вас будет утечка памяти.

Смежные вопросы